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; HMAC-SHA256 signature verification; exponential backoff retry
- Wildcard subscription โ Use
*to subscribe to all event types, simplifying integration
| Scenario | Description |
|---|---|
| Async task completion notification | Trigger downstream workflows when a Session finishes |
| Agent configuration audit | Track Agent create/update/delete operations |
| Multi-Agent orchestration | Drive sub-task scheduling on Thread state changes |
| Ops monitoring & alerting | Alert when consecutive failure count exceeds threshold |
Domain Types
This section defines the data structures of Webhook events. Thedata 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 Created Event Data
-
WebhookSessionCreatedEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.created""session.created"
POST /sessions.
-
Webhook Session Updated Event Data
-
WebhookSessionUpdatedEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.updated""session.updated"
-
Webhook Session Archived Event Data
-
WebhookSessionArchivedEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.archived""session.archived"
-
Webhook Session Deleted Event Data
-
WebhookSessionDeletedEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.deleted""session.deleted"
-
Session Status Events
Webhook Session Status Run Started Event Data
-
WebhookSessionStatusRunStartedEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.status_run_started""session.status_run_started"
-
Webhook Session Status Idled Event Data
-
WebhookSessionStatusIdledEventData object { id, type }-
id: stringThe Session ID that triggered the event. -
type: "session.status_idled""session.status_idled"
-
Session Thread Events
Applicable to multi-Agent collaboration scenarios. Thread events carry an additionalsession_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: stringThe Session ID that triggered the event. -
type: "session.thread_created""session.thread_created"
-
session_thread_id: stringThe associated Session Thread ID.
-
Webhook Session Thread Idled Event Data
-
WebhookSessionThreadIdledEventData object { id, type, session_thread_id }-
id: stringThe Session ID that triggered the event. -
type: "session.thread_idled""session.thread_idled"
-
session_thread_id: stringThe associated Session Thread ID.
-
Webhook Session Thread Terminated Event Data
-
WebhookSessionThreadTerminatedEventData object { id, type, session_thread_id }-
id: stringThe Session ID that triggered the event. -
type: "session.thread_terminated""session.thread_terminated"
-
session_thread_id: stringThe associated Session Thread ID.
-
Agent Lifecycle Events
Agent events carry an additionalversion field beyond the base fields, indicating the Agentโs configuration version number.
Webhook Agent Created Event Data
-
WebhookAgentCreatedEventData object { id, type, version }-
id: stringThe Agent ID that triggered the event. -
type: "agent.created""agent.created"
POST /agents. -
version: integerAgent version number. Set to1on initial creation.
-
Webhook Agent Updated Event Data
-
WebhookAgentUpdatedEventData object { id, type, version }-
id: stringThe Agent ID that triggered the event. -
type: "agent.updated""agent.updated"
versionincrements with each update. -
version: integerAgent version number.
-
Webhook Agent Archived Event Data
-
WebhookAgentArchivedEventData object { id, type, version }-
id: stringThe Agent ID that triggered the event. -
type: "agent.archived""agent.archived"
-
version: integerAgent version number.
-
Webhook Agent Deleted Event Data
-
WebhookAgentDeletedEventData object { id, type, version }-
id: stringThe Agent ID that triggered the event. -
type: "agent.deleted""agent.deleted"
-
version: integerAgent version number.
-
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:| Region | Address |
|---|---|
| Global | https://api.qoder.com/api/v1/cloud |
| CN | https://api.qoder.com.cn/api/v1/cloud |
POST /webhook_endpoints
Create a new Webhook endpoint. Request Parameters:| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTP or HTTPS URL to receive event deliveries (HTTPS strongly recommended for production) |
description | string | No | Endpoint description for management purposes |
events | string[] | Yes | List of subscribed event types, supports * wildcard |
201 Created
Note: signing_secret is only returned once at creation time. Store it securely. Subsequent query endpoints will not return this field.
Status Codes:
| Code | Description |
|---|---|
| 201 | Created successfully |
| 400 | Invalid request parameters (e.g., malformed URL, invalid event type) |
| 401 | Unauthorized, invalid or expired token |
| 422 | Semantic error (e.g., duplicate URL registration) |
GET /webhook_endpoints
List all Webhook endpoints under the current account. Request Parameters: None Response:200 OK
| Field | Type | Description |
|---|---|---|
id | string | Endpoint unique identifier |
url | string | URL receiving events |
description | string | Endpoint description |
events | string[] | Subscribed event types |
active | boolean | Whether enabled |
signing_secret_version | integer | Signing secret version number |
consecutive_fail | integer | Consecutive delivery failure count |
last_success_at | string | Last successful delivery time (RFC 3339) |
last_failure_at | string | Last delivery failure time (RFC 3339), null if no failures |
created_at | string | Creation time (RFC 3339) |
updated_at | string | Last update time (RFC 3339) |
GET /webhook_endpoints/{id}
Retrieve details of a specific Webhook endpoint. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
200 OK
Returns a single endpoint object with the same structure as elements in the list endpoint.
Status Codes:
| Code | Description |
|---|---|
| 200 | Success |
| 404 | Endpoint not found |
PUT /webhook_endpoints/{id}
Update the configuration of a specific Webhook endpoint. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | Update the event delivery URL |
description | string | No | Update endpoint description |
events | string[] | No | Update subscribed event types |
200 OK
Returns the full updated endpoint object.
Status Codes:
| Code | Description |
|---|---|
| 200 | Updated successfully |
| 400 | Invalid request parameters |
| 404 | Endpoint not found |
DELETE /webhook_endpoints/{id}
Permanently delete a Webhook endpoint. All undelivered events will be discarded. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
204 No Content
Status Codes:
| Code | Description |
|---|---|
| 204 | Deleted successfully |
| 404 | Endpoint not found |
POST /webhook_endpoints/{id}/test
Send a test event to the specified endpoint to verify connectivity and signature verification logic. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
202 Accepted
| Field | Type | Description |
|---|---|---|
event_id | integer | Internal ID of the test event |
delivery_rows | integer | Number of message partitions the event was published to |
| Code | Description |
|---|---|
| 202 | Test event sent |
| 404 | Endpoint not found |
POST /webhook_endpoints/{id}/enable
Enable a disabled Webhook endpoint. Once enabled, the endpoint will resume receiving event deliveries. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
200 OK
Returns the endpoint object after enabling (active: true).
Status Codes:
| Code | Description |
|---|---|
| 200 | Enabled successfully |
| 404 | Endpoint not found |
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:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook endpoint ID |
200 OK
Returns the endpoint object after disabling (active: false).
Status Codes:
| Code | Description |
|---|---|
| 200 | Disabled successfully |
| 404 | Endpoint not found |
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:
GET /webhook_events/{id}
Retrieve detailed information for a single Webhook event. Path Parameters:| Parameter | Type | Description |
|---|---|---|
id | string | Webhook event ID |
200 OK
Status Codes:
| Code | Description |
|---|---|
| 200 | Success |
| 404 | Event not found |
Error Response Format
All endpoints return a uniform error structure when an error occurs:| Field | Type | Description |
|---|---|---|
error.message | string | Human-readable error description |
error.type | string | Error category (e.g., invalid_request_error, not_found_error) |
request_id | string | Request trace ID for troubleshooting with support team |
type | string | Fixed 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.
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 Envelope Structure)
Request Headers
Each delivery includes the following HTTP headers:| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | QoderCloudAgents-Webhook/1.0 |
Webhook-Signature | HMAC-SHA256 signature in format t=<unix_epoch>,v1=<hmac_sha256_hex> |
Signature Verification
To ensure event authenticity and data integrity, every delivery carries an HMAC-SHA256 signature. Developers should verify the signature before processing events. Signature Format:signing_secretโ The secret returned when creating the endpoint (whsec_prefix)tโ Unix timestamp at signing time (seconds)raw_bodyโ Raw byte content of the request body (unparsed)
- Extract
tandv1from theWebhook-Signatureheader - Check that the timestamp is within the tolerance window (recommended 600 seconds) to prevent replay attacks
- Compute HMAC-SHA256 of
"<t>.<raw_body>"using thesigning_secret - Compare the result with
v1using timing-safe comparison
Signature Verification Code Examples
Node.js:Retry Strategy
When delivery fails, the system uses exponential backoff for retries:| Attempt | Delay | Description |
|---|---|---|
| 1st | Immediate | Initial delivery |
| 2nd | 1 second | First retry |
| 3rd | 5 seconds | Second retry |
| 4th | 30 seconds | Final retry |
Response Code Handling
| Response Code Range | Handling |
|---|---|
| 2xx | Delivery successful, event marked as delivered |
| 4xx | No retry, event marked as discarded (client errors should be fixed by developer) |
| 5xx | Triggers retry (temporary server failure) |
| Timeout | Triggers retry (default timeout 30 seconds) |
Automatic Degradation
When an endpointโsconsecutive_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
- Are there bugs in signature verification logic
Supported Event Types (Complete List)
Event Type Overview
| Event Type | Status | Additional data fields | Trigger Condition |
|---|---|---|---|
session.created | โ Implemented | โ | POST /sessions successfully creates Session |
session.updated | โ Implemented | โ | Session metadata modified |
session.archived | โ Implemented | โ | Session archived |
session.deleted | โ Implemented | โ | Session permanently deleted |
session.status_run_started | โ Implemented | โ | Agent starts a run |
session.status_idled | โ Implemented | โ | Turn completed, returned to idle |
session.thread_created | โ Implemented | session_thread_id | New Session Thread created |
session.thread_idled | โ Implemented | session_thread_id | Thread execution finished, entered idle |
session.thread_terminated | โ Implemented | session_thread_id | Thread terminated |
agent.created | โ Implemented | version | POST /agents creates Agent |
agent.updated | โ Implemented | version | Agent configuration updated |
agent.archived | โ Implemented | version | Agent archived |
agent.deleted | โ Implemented | version | Agent deleted |
session.pending | ๐ Allowlisted | โ | Session awaiting scheduling |
session.running | ๐ Allowlisted | โ | Session running |
session.idled | ๐ Allowlisted | โ | Session entered idle |
session.requires_action | ๐ Allowlisted | โ | Session requires human intervention |
session.status_run_failed | ๐ Allowlisted | โ | Run failed |
session.status_terminated | ๐ Allowlisted | โ | Session terminated |
session.status_rescheduled | ๐ Allowlisted | โ | Session rescheduled |
session.status_paused_pending_input | ๐ Allowlisted | โ | Paused awaiting user input |
session.status_paused_pending_approval | ๐ Allowlisted | โ | Paused awaiting approval |
session.status_paused_user_intervention | ๐ Allowlisted | โ | Paused awaiting human intervention |
session.outcome_evaluation_started | ๐ Allowlisted | โ | Outcome evaluation started |
session.outcome_evaluation_ended | ๐ Allowlisted | โ | Outcome evaluation ended |
vault.created | ๐ Allowlisted | โ | Vault created |
vault.deleted | ๐ Allowlisted | โ | Vault deleted |
vault.updated | ๐ Allowlisted | โ | Vault updated |
vault_credential.created | ๐ Allowlisted | โ | Credential created |
vault_credential.updated | ๐ Allowlisted | โ | Credential updated |
vault_credential.deleted | ๐ Allowlisted | โ | Credential deleted |
vault_credential.shared | ๐ Allowlisted | โ | Credential shared |
vault_credential.revoked | ๐ Allowlisted | โ | Credential revoked |
deployment.created | ๐ Planned | โ | Deployment created |
deployment.updated | ๐ Planned | โ | Deployment updated |
deployment.archived | ๐ Planned | โ | Deployment archived |
deployment.deleted | ๐ Planned | โ | Deployment deleted |
deployment.paused | ๐ Planned | โ | Deployment paused |
deployment.unpaused | ๐ Planned | โ | Deployment unpaused |
deployment_run.started | ๐ Planned | โ | Deployment run started |
deployment_run.failed | ๐ Planned | โ | Deployment run failed |
deployment_run.succeeded | ๐ Planned | โ | Deployment run succeeded |
environment.created | ๐ Planned | โ | Environment created |
environment.updated | ๐ Planned | โ | Environment updated |
environment.archived | ๐ Planned | โ | Environment archived |
environment.deleted | ๐ Planned | โ | Environment deleted |
memory_store.created | ๐ Planned | โ | Memory store created |
memory_store.archived | ๐ Planned | โ | Memory store archived |
memory_store.deleted | ๐ Planned | โ | Memory store deleted |
Special Event Types
| Event Type | Description |
|---|---|
* | Wildcard โ subscribes to all event types. Use ["*"] when creating an endpoint to receive all events |
webhook.test | Internal test event, triggered via POST /webhook_endpoints/{id}/test |
Status Labels
| Label | Meaning |
|---|---|
| โ Implemented | Complete event trigger points exist in the system; can be subscribed to and received normally |
| ๐ Allowlisted | Event type registered in the validation allowlist (usable in events field) but no trigger point yet |
| ๐ Planned | Event type defined at the API design level but not yet registered in the allowlist |
Envelope Structure
All Webhook events are wrapped in a uniform envelope structure for delivery.Base Envelope Structure
Thread Event Envelope
Thread events include an additionalsession_thread_id field in data:
Agent Event Envelope
Agent events include an additionalversion field in data:
Field Descriptions
| Field | Type | Description |
|---|---|---|
id | string | Event unique identifier. Format: whevt_ + unique identifier, deterministically generated from the eventโs idempotency key |
created_at | string | Event creation time, RFC 3339 UTC format |
type | string | Fixed value "event", identifies this as an event envelope |
data | object | Event payload containing trigger resource information |
data.id | string | ID of the resource that triggered the event (Session ID or Agent ID) |
data.type | string | Event type string, e.g., "session.created", "agent.updated" |
data.session_thread_id | string | (Thread events only) Associated Session Thread ID |
data.version | integer | (Agent events only) Agent configuration version number |
Idempotency Handling
Theid 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:
- Use
idas a unique key for deduplication - Check whether the
idhas already been consumed before processing - Ensure event processing logic is idempotent
Planned Events (Coming Soon)
The following event types have been aligned at the API design level and will be rolled out as their respective resource features go live. Specific timelines depend on product requirements.deployment.* (Deployment Lifecycle, 6 events)
| Event Type | Trigger Condition |
|---|---|
deployment.created | New deployment created |
deployment.updated | Deployment configuration updated |
deployment.archived | Deployment archived |
deployment.deleted | Deployment deleted |
deployment.paused | Deployment paused (stops triggering new runs) |
deployment.unpaused | Deployment resumed (resumes triggering runs) |
deployment_run.* (Deployment Run Status, 3 events)
| Event Type | Trigger Condition |
|---|---|
deployment_run.started | A deployment run starts execution |
deployment_run.failed | Deployment run failed |
deployment_run.succeeded | Deployment run completed successfully |
environment.* (Environment Management, 4 events)
| Event Type | Trigger Condition |
|---|---|
environment.created | Runtime environment created |
environment.updated | Environment configuration updated |
environment.archived | Environment archived |
environment.deleted | Environment deleted |
memory_store.* (Memory Store, 3 events)
| Event Type | Trigger Condition |
|---|---|
memory_store.created | Memory store instance created |
memory_store.archived | Memory store archived |
memory_store.deleted | Memory store deleted |
vault.* (Vault, 3 events)
| Event Type | Trigger Condition |
|---|---|
vault.created | Vault created |
vault.updated | Vault configuration updated |
vault.deleted | Vault deleted |
vault_credential.* (Credential Management, 5 events)
| Event Type | Trigger Condition |
|---|---|
vault_credential.created | New credential added to vault |
vault_credential.updated | Credential information updated |
vault_credential.deleted | Credential deleted |
vault_credential.shared | Credential shared with other Agents |
vault_credential.revoked | Credential sharing permissions revoked |
Appendix A: Quick Start Guide
Step 1: Create a Webhook Endpoint
Step 2: Save the signing_secret
Retrieve thesigning_secret from the creation response and store it securely for later signature verification.
Step 3: Implement the Receiver
Implement the Webhook receiver endpoint in your service, ensuring:- Verify the
Webhook-Signaturesignature - Use the event
idfor idempotent deduplication - Return
200 OKto acknowledge receipt - Process business logic asynchronously (avoid timeouts)
Step 4: Send a Test Event
Step 5: Verify and Go Live
After confirming test events are received correctly, youโre ready for production use.Appendix B: Best Practices
| Practice | Description |
|---|---|
| Signature verification | Always verify Webhook-Signature, reject invalid requests |
| Idempotent processing | Use event id for deduplication to prevent duplicate consumption |
| Fast response | Receiver should return 2xx within 5 seconds; run time-consuming logic asynchronously |
| Timestamp validation | Reject events outside the tolerance window to prevent replay attacks |
| Precise subscription | Only subscribe to needed event types to reduce unnecessary network overhead |
| Monitoring & alerting | Monitor consecutive_fail metric to detect delivery anomalies promptly |