Webhooks enable you to trigger Cordage workflows via HTTP API, making it easy to integrate AI workflows into your applications, automation pipelines, or external services.
Overview
A webhook exposes your workflow as an API endpoint:
Your App ──HTTP POST──> Cordage API ──> Workflow Execution ──> Output URLs
Setting Up Webhooks
1. Add a Webhook Node
- Drag a Webhook node onto your canvas
- Position it as the entry point of your workflow
- A unique webhook key is automatically generated
The Webhook node can receive input parameters:
[Webhook Node]
├── prompt (text) ──────────────> [Model]
├── style (text) ────────────────>
└── image_url (string) ──────────> [Image Input]
Map webhook inputs to downstream node parameters.
3. Connect to Export
Ensure your workflow ends with an Export node:
[Webhook] ──> [Process] ──> ... ──> [Export]
The Export node’s output URLs are returned in the API response.
API Authentication
All webhook API calls require authentication:
Authorization: Bearer cordage_xxxxxxxxxxxx
Getting an API Key
- Go to Workspace Settings
- Navigate to API Keys
- Click Create API Key
- Copy and store securely (shown only once)
API keys are workspace-scoped. Keep them secret and never expose in client-side code.
API Endpoints
Trigger Workflow
Start a workflow run:
POST https://api.trycordage.com/api/webhooks/{webhook_key}/trigger
Request:
curl -X POST https://api.trycordage.com/api/webhooks/wh_abc123/trigger \
-H "Authorization: Bearer cordage_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A beautiful sunset",
"style": "photorealistic"
}'
Response:
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"message": "Workflow started",
"node_count": 5
}
Get Run Status
Check execution progress:
GET https://api.trycordage.com/api/webhooks/{webhook_key}/runs/{run_id}
Response (running):
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"created_at": "2024-01-15T10:30:00Z",
"completed_at": null,
"outputs": null
}
Response (completed):
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:32:15Z",
"outputs": [
"https://storage.trycordage.com/outputs/image_001.png"
]
}
List Runs
Get recent workflow runs:
GET https://api.trycordage.com/api/webhooks/{webhook_key}/runs?limit=10&offset=0
Cancel Run
Stop a running workflow:
POST https://api.trycordage.com/api/webhooks/{webhook_key}/runs/{run_id}/kill
Polling Pattern
Since workflows execute asynchronously, poll for completion:
import requests
import time
API_KEY = "cordage_xxxxxxxxxxxx"
WEBHOOK_KEY = "wh_abc123"
BASE_URL = "https://api.trycordage.com/api/webhooks"
headers = {"Authorization": f"Bearer {API_KEY}"}
# 1. Trigger workflow
response = requests.post(
f"{BASE_URL}/{WEBHOOK_KEY}/trigger",
headers=headers,
json={"prompt": "A mountain landscape"}
)
run_id = response.json()["run_id"]
# 2. Poll for completion
while True:
status = requests.get(
f"{BASE_URL}/{WEBHOOK_KEY}/runs/{run_id}",
headers=headers
).json()
if status["status"] == "completed":
print("Outputs:", status["outputs"])
break
elif status["status"] == "failed":
print("Error:", status.get("error"))
break
time.sleep(2) # Wait before next poll
Rate Limits
| Operation | Limit |
|---|
| Trigger | 60/minute |
| Get status | 120/minute |
| List runs | 120/minute |
| Cancel run | 30/minute |
Rate limit headers are included in responses:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 45
Error Handling
HTTP Status Codes
| Code | Meaning |
|---|
| 200 | Success |
| 400 | Bad request (invalid input) |
| 401 | Unauthorized (invalid API key) |
| 402 | Insufficient credits |
| 403 | Forbidden (wrong workspace) |
| 404 | Not found (invalid webhook/run) |
| 429 | Rate limit exceeded |
| 500 | Server error |
{
"error": "Error message here",
"retry_after": 30 // Only for 429 errors
}
Integration Examples
Node.js / JavaScript
async function generateImage(prompt) {
const API_KEY = process.env.CORDAGE_API_KEY;
const WEBHOOK_KEY = "wh_abc123";
const BASE_URL = "https://api.trycordage.com/api/webhooks";
// Trigger
const triggerRes = await fetch(`${BASE_URL}/${WEBHOOK_KEY}/trigger`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ prompt })
});
const { run_id } = await triggerRes.json();
// Poll
while (true) {
const statusRes = await fetch(
`${BASE_URL}/${WEBHOOK_KEY}/runs/${run_id}`,
{ headers: { "Authorization": `Bearer ${API_KEY}` } }
);
const status = await statusRes.json();
if (status.status === "completed") return status.outputs;
if (status.status === "failed") throw new Error("Generation failed");
await new Promise(r => setTimeout(r, 2000));
}
}
Zapier / Make / n8n
- Use HTTP/Webhook module
- Configure POST request to trigger endpoint
- Add polling loop to check status
- Use output URLs in downstream steps
Serverless Functions
# AWS Lambda / Vercel / Cloud Functions
import json
import requests
def handler(event, context):
prompt = event.get("prompt", "default prompt")
response = requests.post(
"https://api.trycordage.com/api/webhooks/wh_abc123/trigger",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"prompt": prompt}
)
return {
"statusCode": 200,
"body": json.dumps(response.json())
}
Best Practices
Use exponential backoff - When polling, increase delay between requests if the workflow is taking long.
Handle all status values - Check for “failed” and “cancelled” in addition to “completed”.
Store run IDs - Keep track of run IDs to check status later or for debugging.
Validate inputs - Check inputs before triggering to avoid wasting credits on invalid requests.
Use webhook callbacks - For long-running workflows, consider implementing callback URLs instead of polling (coming soon).
Debugging
Check Webhook Status
Verify your webhook is active in the Cordage UI:
- Open your canvas
- Click the Webhook node
- Check “Active” status in inspector
View Run History
See all runs for a webhook:
- Click the Webhook node
- Open “Run History” in inspector
- Click individual runs for details
Test Locally
Use curl or Postman to test your webhook:
# Test trigger
curl -X POST https://api.trycordage.com/api/webhooks/wh_abc123/trigger \
-H "Authorization: Bearer cordage_xxx" \
-H "Content-Type: application/json" \
-d '{"prompt": "test"}'