Bỏ qua để đến nội dung

Webhooks

Nội dung này hiện chưa có sẵn bằng ngôn ngữ của bạn.

Webhooks push events to your server as they happen, instead of you polling the API. Manage endpoints from Organization Settings → Webhooks in the dashboard, or via /api/v1/webhooks with a write:webhooks-scoped key.

POST /api/v1/webhooks
Content-Type: application/json
Idempotency-Key: <uuid>
{
"url": "https://example.com/hooks/clienta",
"events": ["conversation.created", "message.received"]
}
{
"success": true,
"data": {
"id": "wh_endpoint_123",
"url": "https://example.com/hooks/clienta",
"events": ["conversation.created", "message.received"],
"status": "active",
"consecutiveFailures": 0,
"createdAt": "2026-07-16T04:00:00.000Z",
"secret": "3n9qYVs8h1kLp0..."
}
}

Registration requires POST /api/v1/webhooks to carry an Idempotency-Key — see Idempotency.

EventFires when
conversation.createdA new conversation starts
message.receivedA new message is received in a conversation
handoff.requestedA conversation is escalated for human handoff
ticket.createdA fallback ticket is created
conversation.resolvedA conversation is marked resolved

An endpoint only receives events it subscribed to via its events list — no wildcard subscription. A typo’d event name is rejected at registration time (400), not silently accepted and never fired.

Every delivery body is a versioned envelope:

{
"type": "conversation.created",
"schemaVersion": 1,
"orgId": "org_abc123",
"createdAt": "2026-07-16T04:00:00.000Z",
"data": {
"conversationId": "conv_456",
"channelId": "chan_789",
"externalUserId": "ext_user_1"
}
}

data is a strict per-event-type allowlist — only the fields documented below are ever included, regardless of what the underlying record contains internally.

Eventdata fields
conversation.createdconversationId, channelId, externalUserId
message.receivedconversationId, messageId, role (user|assistant|agent|system)
handoff.requestedconversationId, escalationLogId, reason?
ticket.createdticketId, conversationId?, reason?
conversation.resolvedconversationId, resolvedBy

Always verify type against the event types you actually handle, and check schemaVersion if you maintain multiple payload-shape handlers going forward.

Delivery is at-least-once — design for idempotent handling on your end (key off the delivery’s event, not “did I receive exactly one call”).

  1. An event is written durably first, decoupled from delivery — a crash between “event happened” and “webhook sent” cannot lose the event.
  2. It’s fanned out into one delivery per subscribed, active endpoint.
  3. Each delivery is attempted with a leased worker — if the worker crashes mid-attempt, the lease expires and another worker safely picks it up. You will never see a delivery silently vanish because of a worker crash, though you may occasionally see the same delivery attempted twice in that specific crash window — treat delivery id/eventId as your dedupe key if that matters to you.
AttributeValue
Max attempts per delivery8
BackoffExponential — 30s base, doubling each attempt, capped at 1 hour
Terminal statessucceeded, exhausted (max attempts reached), skipped (endpoint disabled)

An endpoint that racks up 10 consecutive delivery failures is automatically disabled (status: "auto_disabled") — further events are marked skipped for that endpoint rather than retried forever against a dead receiver. Re-enable it by re-registering (or contact support if you need the existing endpoint reactivated).

GET /api/v1/webhooks/{id}/deliveries?limit=20
{
"success": true,
"data": [
{
"id": "whd_1",
"eventId": "evt_1",
"status": "succeeded",
"nextRetryAt": null,
"terminalAt": "2026-07-16T04:00:02.000Z",
"terminalReason": null,
"lastError": null,
"createdAt": "2026-07-16T04:00:00.000Z"
}
],
"nextCursor": null
}

Cursor-paginated — see Versioning → Pagination.

POST /api/v1/webhooks/{id}/test
Idempotency-Key: <uuid>

Sends a real webhook.test event through the actual signing and delivery path to that one endpoint — useful for verifying your receiver’s signature verification before subscribing to real events.

DELETE /api/v1/webhooks/{id}

Deleting an endpoint that’s already gone returns 204 — it’s a no-op, not an error, so retries are always safe.

There’s no in-place “rotate secret” call — a secret is bound to the endpoint it was issued for. To rotate:

  1. Register a new endpoint with the same url and events.
  2. Verify the new endpoint receives and correctly verifies a test event.
  3. Delete the old endpoint.
v1.16.0

In addition to webhooks, clienta.ai can send email notifications when imported content changes significantly. This applies to URL imports, Google Sheets sync, and RSS feeds.

  • Trigger: Content diff exceeds the configured threshold (default: 20%)
  • Recipients: All organization admins
  • Rate limit: Maximum 1 notification per source URL per 24 hours
  • Configuration: Adjustable per organization via organization settings

Content change notifications are separate from webhook events — they use email delivery via the platform’s email service, not HTTP callbacks.