Skip to main content
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

  1. Drag a Webhook node onto your canvas
  2. Position it as the entry point of your workflow
  3. A unique webhook key is automatically generated

2. Configure Inputs

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

  1. Go to Workspace Settings
  2. Navigate to API Keys
  3. Click Create API Key
  4. 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

OperationLimit
Trigger60/minute
Get status120/minute
List runs120/minute
Cancel run30/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

CodeMeaning
200Success
400Bad request (invalid input)
401Unauthorized (invalid API key)
402Insufficient credits
403Forbidden (wrong workspace)
404Not found (invalid webhook/run)
429Rate limit exceeded
500Server error

Error Response Format

{
  "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

  1. Use HTTP/Webhook module
  2. Configure POST request to trigger endpoint
  3. Add polling loop to check status
  4. 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:
  1. Open your canvas
  2. Click the Webhook node
  3. Check “Active” status in inspector

View Run History

See all runs for a webhook:
  1. Click the Webhook node
  2. Open “Run History” in inspector
  3. 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"}'