> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trycordage.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Integrate Cordage workflows into your applications

The Cordage Webhook API allows you to programmatically trigger workflows, monitor execution status, and retrieve generated outputs. Use this API to integrate AI workflows into external applications, automation pipelines, or custom tools.

## Base URL

All API requests should be made to:

```
https://api.trycordage.com/api/webhooks
```

## Authentication

All endpoints require authentication using an API key. Include your API key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer cordage_xxxxxxxxxxxx
```

<Warning>
  Keep your API keys secure. Never expose them in client-side code or public repositories.
</Warning>

### Getting an API Key

1. Navigate to **Workspace Settings** in the Cordage app
2. Click **API Keys** in the sidebar
3. Click **Create API Key**
4. Copy and securely store your key (it won't be shown again)

## Rate Limits

Rate limits are applied per API key:

| Operation                            | Limit               |
| ------------------------------------ | ------------------- |
| Trigger workflow                     | 60 requests/minute  |
| Read operations (get run, list runs) | 120 requests/minute |
| Kill run                             | 30 requests/minute  |

Rate limit headers are included in all responses:

```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 45
```

## Quick Start

### 1. Trigger a Workflow

```bash theme={null}
curl -X POST https://api.trycordage.com/api/webhooks/YOUR_WEBHOOK_KEY/trigger \
  -H "Authorization: Bearer cordage_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A beautiful sunset over mountains"}'
```

Response:

```json theme={null}
{
  "run_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "Workflow started",
  "node_count": 5
}
```

### 2. Check Run Status

```bash theme={null}
curl https://api.trycordage.com/api/webhooks/YOUR_WEBHOOK_KEY/runs/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer cordage_xxxxxxxxxxxx"
```

Response when completed:

```json theme={null}
{
  "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"
  ]
}
```

## Run Status Values

| Status      | Description                            |
| ----------- | -------------------------------------- |
| `pending`   | Run is queued but hasn't started       |
| `running`   | Workflow is actively executing         |
| `completed` | All nodes finished successfully        |
| `failed`    | One or more nodes encountered an error |
| `cancelled` | Run was manually cancelled             |

## Error Handling

All errors return a JSON object with an `error` field:

```json theme={null}
{
  "error": "Webhook not found"
}
```

For rate limit errors, a `retry_after` field indicates when to retry:

```json theme={null}
{
  "error": "Rate limit exceeded.",
  "retry_after": 30
}
```

## SDK Examples

<CodeGroup>
  ```python Python theme={null}
  import requests

  API_KEY = "cordage_xxxxxxxxxxxx"
  WEBHOOK_KEY = "your_webhook_key"
  BASE_URL = "https://api.trycordage.com/api/webhooks"

  headers = {"Authorization": f"Bearer {API_KEY}"}

  # Trigger workflow
  response = requests.post(
      f"{BASE_URL}/{WEBHOOK_KEY}/trigger",
      headers=headers,
      json={"prompt": "A beautiful landscape"}
  )
  run = response.json()
  print(f"Started run: {run['run_id']}")

  # Poll for completion
  import time
  while True:
      status = requests.get(
          f"{BASE_URL}/{WEBHOOK_KEY}/runs/{run['run_id']}",
          headers=headers
      ).json()

      if status["status"] in ["completed", "failed", "cancelled"]:
          break
      time.sleep(2)

  print(f"Outputs: {status.get('outputs', [])}")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "cordage_xxxxxxxxxxxx";
  const WEBHOOK_KEY = "your_webhook_key";
  const BASE_URL = "https://api.trycordage.com/api/webhooks";

  const headers = {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json"
  };

  // Trigger workflow
  const triggerResponse = await fetch(
    `${BASE_URL}/${WEBHOOK_KEY}/trigger`,
    {
      method: "POST",
      headers,
      body: JSON.stringify({ prompt: "A beautiful landscape" })
    }
  );
  const run = await triggerResponse.json();
  console.log(`Started run: ${run.run_id}`);

  // Poll for completion
  const pollStatus = async () => {
    while (true) {
      const response = await fetch(
        `${BASE_URL}/${WEBHOOK_KEY}/runs/${run.run_id}`,
        { headers }
      );
      const status = await response.json();

      if (["completed", "failed", "cancelled"].includes(status.status)) {
        return status;
      }
      await new Promise(r => setTimeout(r, 2000));
    }
  };

  const result = await pollStatus();
  console.log("Outputs:", result.outputs);
  ```
</CodeGroup>
