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"