Skip to main content
Agent integrations

Webhooks

Subscribe to Cloud Agents lifecycle events over HTTP webhooks, including endpoint management, delivery behavior, and the supported event catalog.

1. Overview

Webhooks are an event-driven push mechanism provided by Qoder Cloud Agents. When resources such as Agents or Sessions undergo lifecycle changes, the system delivers structured events via HTTP POST to developer-registered URLs — no polling required. Core Features:
  • Event-driven push — Proactive notifications on resource state changes, no client polling needed
  • Envelope structure — Uniform BetaWebhookEvent { id, created_at, data, type:"event" } format
  • Delivery semantics — At-least-once guarantee; exponential backoff retry
Use Cases:
ScenarioDescription
Async task completion notificationTrigger downstream workflows when a Session finishes
Agent configuration auditTrack Agent create/update/delete operations
Multi-Agent orchestrationDrive sub-task scheduling on Thread state changes
Ops monitoring & alertingAlert when consecutive failure count exceeds threshold

2. Domain Types

This section defines the data structures of Webhook events. The data field of each event type follows a uniform object format containing the resource ID, event type, and event-specific additional fields.

Session Lifecycle Events

Webhook Session Updated Event Data

  • WebhookSessionUpdatedEventData object { id, type }
    • id: string The Session ID that triggered the event.
    • type: "session.updated"
      • "session.updated"
      Triggered when Session metadata (such as title, metadata, etc.) is modified.

Webhook Session Deleted Event Data

  • WebhookSessionDeletedEventData object { id, type }
    • id: string The Session ID that triggered the event.
    • type: "session.deleted"
      • "session.deleted"
      Triggered when a Session is permanently deleted. All data for the Session becomes unrecoverable after deletion.

Session Status Events

Webhook Session Status Run Started Event Data

  • WebhookSessionStatusRunStartedEventData object { id, type }
    • id: string The Session ID that triggered the event.
    • type: "session.status_run_started"
      • "session.status_run_started"
      Triggered when an Agent starts a run. Signals that the Session has entered the running state and is executing user instructions.

Webhook Session Status Idled Event Data

  • WebhookSessionStatusIdledEventData object { id, type }
    • id: string The Session ID that triggered the event.
    • type: "session.status_idled"
      • "session.status_idled"
      Triggered when a turn completes and the Session returns to idle state. At this point it is safe to read the Session's latest output.

Session Thread Events

Applicable to multi-Agent collaboration scenarios. Thread events carry an additional session_thread_id field on top of the base fields, identifying the specific execution thread.

Webhook Session Thread Created Event Data

  • WebhookSessionThreadCreatedEventData object { id, type, session_thread_id }
    • id: string The Session ID that triggered the event.
    • type: "session.thread_created"
      • "session.thread_created"
      Triggered when a new Session Thread is created. Common in sub-Agent collaboration scenarios where the main Agent spawns child threads to execute tasks.
    • session_thread_id: string The associated Session Thread ID.

Webhook Session Thread Idled Event Data

  • WebhookSessionThreadIdledEventData object { id, type, session_thread_id }
    • id: string The Session ID that triggered the event.
    • type: "session.thread_idled"
      • "session.thread_idled"
      Triggered when a Session Thread finishes a run and enters idle state. Indicates the thread has completed its current task and results can be read.
    • session_thread_id: string The associated Session Thread ID.

Webhook Session Thread Terminated Event Data

  • WebhookSessionThreadTerminatedEventData object { id, type, session_thread_id }
    • id: string The Session ID that triggered the event.
    • type: "session.thread_terminated"
      • "session.thread_terminated"
      Triggered when a Session Thread is terminated. A terminated Thread cannot be recovered; a new Thread must be created to continue work.
    • session_thread_id: string The associated Session Thread ID.

Agent Lifecycle Events

Webhook Agent Created Event Data

  • WebhookAgentCreatedEventData object { id, type }
    • id: string The Agent ID that triggered the event.
    • type: "agent.created"
      • "agent.created"
      Triggered when an Agent is successfully created. The system sends this event after an Agent is created via POST /agents.

Webhook Agent Updated Event Data

  • WebhookAgentUpdatedEventData object { id, type }
    • id: string The Agent ID that triggered the event.
    • type: "agent.updated"
      • "agent.updated"
      Triggered when an Agent's configuration is updated.

Webhook Agent Archived Event Data

  • WebhookAgentArchivedEventData object { id, type }
    • id: string The Agent ID that triggered the event.
    • type: "agent.archived"
      • "agent.archived"
      Triggered when an Agent is archived. After archival, the Agent no longer accepts new Session creation requests.

Webhook Agent Deleted Event Data

  • WebhookAgentDeletedEventData object { id, type }
    • id: string The Agent ID that triggered the event.
    • type: "agent.deleted"
      • "agent.deleted"
      Triggered when an Agent is deleted. All configuration data for the Agent becomes unrecoverable after deletion.

Deployment Run Events

For Deployment Run events, id is the Deployment Run ID.
  • WebhookDeploymentRunStartedEventData object { id, type: "deployment_run.started" }
  • WebhookDeploymentRunSucceededEventData object { id, type: "deployment_run.succeeded" }
  • WebhookDeploymentRunFailedEventData object { id, type: "deployment_run.failed" }

3. Webhook Endpoint API

CRUD endpoints for managing Webhook endpoints. Use these to create, query, update, and delete Webhook endpoints, as well as send test events and control endpoint enable/disable state. Base URL:
RegionAddress
Globalhttps://api.qoder.com/api/v1/cloud
CNhttps://api.qoder.com.cn/api/v1/cloud
Authentication: All endpoints require a Personal Access Token (PAT) or Service Account Token (SAT) in the request header:
Authorization: Bearer $QODER_ACCESS_TOKEN

POST /webhook_endpoints

Create a new Webhook endpoint. Request Parameters:
FieldTypeRequiredDescription
urlstringYesPublicly reachable HTTPS URL for event delivery; port 443 is required
descriptionstringNoEndpoint description for management purposes
eventsstring[]YesList of explicitly named event types; see Section 5 for allowed values
Response: 201 Created
{
  "id": "5fc05310-4d9c-447e-a4b8-f124f17e1ff0",
  "url": "https://webhook.site/your-unique-path",
  "description": "quickstart demo",
  "events": ["session.status_idled", "session.thread_idled"],
  "active": true,
  "signing_secret": "whsec_BfJDodFEzmkdjAUf19-_XthSq6KbPKmRjfm9KFWMIuk",
  "created_at": "2026-07-02T18:17:30.069191+08:00"
}
Note: signing_secret is returned only once at creation time; store it securely.
Status Codes:
CodeDescription
201Created successfully
400Invalid request parameters (e.g., URL is not a public HTTPS port 443 address, invalid event type)
401Unauthorized, invalid or expired token
422Semantic error (e.g., duplicate URL registration)
Example:
curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://webhook.site/your-unique-path",
    "description": "quickstart demo",
    "events": ["session.status_idled", "session.thread_idled"]
  }'

GET /webhook_endpoints

List all Webhook endpoints under the current account. Request Parameters: None Response: 200 OK
{
  "data": [
    {
      "id": "700e7789-edab-41cb-b60a-210d0df38ab6",
      "url": "https://myapp.example.com/hooks/qoder",
      "description": "prod app hook",
      "events": ["session.status_idled", "session.thread_idled"],
      "active": true,
      "consecutive_fail": 0,
      "last_success_at": "2026-07-02T18:08:12.666783+08:00",
      "created_at": "2026-07-02T17:47:16.073822+08:00",
      "updated_at": "2026-07-02T17:47:16.073822+08:00"
    }
  ]
}
Response Fields:
FieldTypeDescription
idstringEndpoint unique identifier
urlstringURL receiving events
descriptionstringEndpoint description
eventsstring[]Subscribed event types
activebooleanWhether enabled
consecutive_failintegerConsecutive delivery failure count
last_success_atstringLast successful delivery time (RFC 3339)
last_failure_atstringLast delivery failure time (RFC 3339), null if no failures
created_atstringCreation time (RFC 3339)
updated_atstringLast update time (RFC 3339)
Example:
curl https://api.qoder.com/api/v1/cloud/webhook_endpoints \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

GET /webhook_endpoints/{id}

Retrieve details of a specific Webhook endpoint. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Response: 200 OK Returns a single endpoint object with the same structure as elements in the list endpoint. Status Codes:
CodeDescription
200Success
404Endpoint not found
Example:
curl https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6 \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

PUT /webhook_endpoints/{id}

Update the configuration of a specific Webhook endpoint. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Request Parameters:
FieldTypeRequiredDescription
urlstringNoUpdate the publicly reachable HTTPS port 443 delivery URL
descriptionstringNoUpdate endpoint description
eventsstring[]NoUpdate the explicitly named subscribed event types
Response: 200 OK Returns the full updated endpoint object. Status Codes:
CodeDescription
200Updated successfully
400Invalid request parameters
404Endpoint not found
Example:
curl -X PUT https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6 \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["session.status_idled", "session.thread_idled", "agent.updated"],
    "description": "updated prod hook"
  }'

DELETE /webhook_endpoints/{id}

Permanently delete a Webhook endpoint. All undelivered events will be discarded. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Response: 204 No Content Status Codes:
CodeDescription
204Deleted successfully
404Endpoint not found
Example:
curl -X DELETE https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6 \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

POST /webhook_endpoints/{id}/test

Send a test event to the specified endpoint to verify connectivity and payload processing logic. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Request Parameters: None Response: 202 Accepted
{"event_id": 433, "delivery_rows": 2}
Response Fields:
FieldTypeDescription
event_idintegerInternal ID of the test event
delivery_rowsintegerNumber of message partitions the event was published to
Status Codes:
CodeDescription
202Test event sent
404Endpoint not found
Example:
curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6/test \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

POST /webhook_endpoints/{id}/enable

Enable a disabled Webhook endpoint. Once enabled, the endpoint will resume receiving event deliveries. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Request Parameters: None Response: 200 OK Returns the endpoint object after enabling (active: true). Status Codes:
CodeDescription
200Enabled successfully
404Endpoint not found
Example:
curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6/enable \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

POST /webhook_endpoints/{id}/disable

Disable a Webhook endpoint. Once disabled, the endpoint will stop receiving event deliveries but will not be deleted. Path Parameters:
ParameterTypeDescription
idstringWebhook endpoint ID
Request Parameters: None Response: 200 OK Returns the endpoint object after disabling (active: false). Status Codes:
CodeDescription
200Disabled successfully
404Endpoint not found
Example:
curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints/700e7789-edab-41cb-b60a-210d0df38ab6/disable \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

GET /webhook_events

List Webhook event delivery records for auditing and troubleshooting. Request Parameters: None Response: 200 OK Returns an event list containing delivery status, timestamps, and other information. Example:
curl https://api.qoder.com/api/v1/cloud/webhook_events \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

GET /webhook_events/{id}

Retrieve detailed information for a single Webhook event. Path Parameters:
ParameterTypeDescription
idstringWebhook event ID
Response: 200 OK Status Codes:
CodeDescription
200Success
404Event not found
Example:
curl https://api.qoder.com/api/v1/cloud/webhook_events/433 \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

Error Response Format

All endpoints return a uniform error structure when an error occurs:
{
  "error": {
    "message": "Unknown event type: agent.updated",
    "type": "invalid_request_error"
  },
  "request_id": "cc865161-b25d-4d68-bad5-bf0363f6e0f9",
  "type": "error"
}
Error Fields:
FieldTypeDescription
error.messagestringHuman-readable error description
error.typestringError category (e.g., invalid_request_error, not_found_error)
request_idstringRequest trace ID for troubleshooting with support team
typestringFixed value "error"
Note: 401 responses from the authentication layer (e.g., invalid or missing Token) may not follow the business error structure above, as they are returned directly by the gateway.

4. Webhook Delivery

Delivery Method

The system delivers events to registered URLs via HTTP POST with the following format:
  • Method: POST
  • Content-Type: application/json
  • Body: JSON envelope structure (see Section 6)

Request Headers

Each delivery includes the following HTTP headers:
HeaderDescription
Content-Typeapplication/json
User-AgentQoderCloudAgents-Webhook/1.0

Retry Strategy

When delivery fails, the system uses exponential backoff for retries:
AttemptDelayDescription
1stImmediateInitial delivery
2nd1 secondFirst retry
3rd5 secondsSecond retry
4th30 secondsFinal retry
A total of 4 attempts (1 delivery + 3 retries). After all failures, the event enters the dead letter queue.

Response Code Handling

Response Code RangeHandling
2xxDelivery successful, event marked as delivered
4xxNo retry, event marked as discarded (client errors should be fixed by developer)
5xxTriggers retry (temporary server failure)
TimeoutTriggers retry (default timeout 30 seconds)

Automatic Degradation

When an endpoint's consecutive_fail count exceeds 20, the system triggers a degradation warning. Developers should monitor this metric and check the following when failures persist:
  • Is the endpoint URL reachable
  • Is the SSL certificate valid
  • Is the server responding normally

5. Supported Event Types

The events below can currently be subscribed to and have live emission paths. events must contain explicitly named events from this table.
Event TypeAdditional data fieldsTrigger Condition
session.updatedSession metadata modified
session.deletedSession permanently deleted
session.status_run_startedAgent starts a run
session.status_idledTurn completed and Session returned to idle
session.thread_createdsession_thread_idNew Session Thread created
session.thread_idledsession_thread_idThread execution finished and entered idle
session.thread_terminatedsession_thread_idThread terminated
agent.createdAgent created
agent.updatedAgent configuration updated
agent.archivedAgent archived
agent.deletedAgent deleted
deployment_run.startedA Deployment Run starts execution
deployment_run.succeededA Deployment Run succeeds
deployment_run.failedA Deployment Run fails

6. Envelope Structure

All Webhook events are wrapped in a uniform envelope structure for delivery.

Base Envelope Structure

{
  "id": "whe_a1b2c3d4e5f67890",
  "created_at": "2026-07-02T10:02:16Z",
  "type": "event",
  "data": {
    "id": "sess_019f224773fe71d79c5869bd089d159c",
    "type": "session.status_idled"
  }
}

Thread Event Envelope

Thread events include an additional session_thread_id field in data:
{
  "id": "whe_a1b2c3d4e5f67890",
  "created_at": "2026-07-02T10:02:17Z",
  "type": "event",
  "data": {
    "id": "sess_019f224773fe71d79c5869bd089d159c",
    "type": "session.thread_idled",
    "session_thread_id": "sthread_019f224..."
  }
}

Field Descriptions

FieldTypeDescription
idstringUnique event identifier prefixed with whe_; it remains stable across retries of the same event
created_atstringEvent creation time, RFC 3339 UTC format
typestringFixed value "event", identifies this as an event envelope
dataobjectEvent payload containing trigger resource information
data.idstringID of the resource that triggered the event, such as a Session, Agent, or Deployment Run ID
data.typestringEvent type string, e.g., "session.status_idled", "agent.updated"
data.session_thread_idstring(Thread events only) Associated Session Thread ID

Idempotency Handling

The id field in the envelope can be used as a deduplication key. Since delivery semantics are at-least-once, the same event may be delivered multiple times. Receivers should:
  1. Use id as a unique key for deduplication
  2. Check whether the id has already been consumed before processing
  3. Ensure event processing logic is idempotent

Appendix A: Quick Start Guide

Step 1: Create a Webhook Endpoint

curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/webhooks/qoder",
    "description": "Production webhook",
    "events": ["session.status_idled", "session.thread_idled"]
  }'

Step 2: Implement the Receiver

Implement the Webhook receiver endpoint in your service, ensuring:
  1. Parse the JSON payload and handle the event according to type
  2. Use the event id for idempotent deduplication
  3. Return 200 OK to acknowledge receipt
  4. Process business logic asynchronously (avoid timeouts)

Step 3: Send a Test Event

curl -X POST https://api.qoder.com/api/v1/cloud/webhook_endpoints/{id}/test \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

Step 4: Verify and Go Live

After confirming test events are received correctly, you're ready for production use.

Appendix B: Best Practices

PracticeDescription
Idempotent processingUse event id for deduplication to prevent duplicate consumption
Fast responseReceiver should return 2xx within 5 seconds; run time-consuming logic asynchronously
Precise subscriptionOnly subscribe to needed event types to reduce unnecessary network overhead
Monitoring & alertingMonitor consecutive_fail metric to detect delivery anomalies promptly