Skip to main content

Async terminal callbacks

Async runs can call your backend when execution reaches a terminal state.
curl -X POST https://developer.creao.ai/v1/runs \
  -H "Authorization: Bearer cr_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "00000000-0000-4000-8000-000000000000",
    "input": { "query": "Create a weekly sales summary" },
    "webhook_url": "https://your-server.example/webhooks/creao"
  }'
Webhook URLs must be public http or https URLs. Localhost, private network, link-local, and metadata-service targets are rejected or skipped.

Payload

Webhook payloads include the run, conversation, terminal status, and either result or error.
{
  "runId": "11111111-1111-4111-8111-111111111111",
  "status": "completed",
  "threadId": "22222222-2222-4222-8222-222222222222",
  "conversationId": "22222222-2222-4222-8222-222222222222",
  "result": {
    "text": "Done."
  }
}
Use conversationId as the public conversation identifier. threadId is included in the current payload for compatibility and has the same value for Developer API conversations. Failed run example:
{
  "runId": "11111111-1111-4111-8111-111111111111",
  "status": "failed",
  "threadId": "22222222-2222-4222-8222-222222222222",
  "conversationId": "22222222-2222-4222-8222-222222222222",
  "error": {
    "code": "EXECUTION_FAILED",
    "message": "Agent execution failed"
  }
}

Delivery behavior

CREAO retries delivery with short backoff. A 2xx response marks the webhook as delivered and sets webhook_delivered_at on the run object. Design webhook handlers to be idempotent. Use runId as your deduplication key.

Polling fallback

Webhooks are best-effort delivery. Your backend can always poll:
curl https://developer.creao.ai/v1/runs/11111111-1111-4111-8111-111111111111 \
  -H "Authorization: Bearer cr_sk_your_key_here"