Payload Spec
Delivery format
JSON over HTTPS POST. Content-Type: application/json.
Sample payload (Custom endpoint)
{
"projectId": "3c9acfb1-c6b7-4bbc-b6c3-628af54d56c1",
"webhookEndpoint": {
"id": "ep-001",
"name": "Production Notifications",
"endpointType": "CUSTOM",
"target": "https://example.com/webhook",
"contentKey": null
},
"eventType": "OUTBOUND_CALL_ERROR",
"body": {
"subject": "[Recho] Outbound call error",
"text": "[Recho] Outbound call error\n━━━━━━━━━━━━━━\ncallId: abc-123\ncallStatus: CALLING\ncallSid: CA94b51...\nclientId: client-1\n━━━━━━━━━━━━━━\nErrors:\n - [NETWORK_ERROR] Connection timed out (phase: CONNECTING)\n━━━━━━━━━━━━━━\nTime: 2026-05-12 10:24:00",
"data": {
"callId": "abc-123",
"callStatus": "CALLING",
"callSid": "CA94b51...",
"clientId": "client-1"
},
"errors": [
{
"code": "NETWORK_ERROR",
"message": "Connection timed out",
"timestamp": "2026-05-12T10:23:45.000Z",
"where": "OutboundCallAdapter.connect",
"phase": "CONNECTING",
"stacktrace": ""
}
]
},
"authConfig": { "authType": "NONE" }
}
Slack / Teams / Email deliveries are transformed internally; only Custom endpoints receive this exact structure.
TypeScript types
Type definitions matching the sample above:
type WebhookPayload = {
projectId: string;
webhookEndpoint: WebhookEndpoint;
eventType: EventType; // e.g. 'OUTBOUND_CALL_COMPLETED' — 21 values in total (scheduled for removal)
body: WebhookBody;
authConfig: AuthConfig;
};
type WebhookEndpoint = {
id: string;
name: string;
endpointType: 'SLACK' | 'TEAMS' | 'EMAIL' | 'CUSTOM';
target: string;
contentKey: string | null;
};
type WebhookBody = {
subject: string;
text: string;
data: Record<string, string>;
errors?: CallError[]; // only on error
};
type CallError = {
code: string; // one of the values listed on /webhooks/error-codes
message: string;
timestamp: string; // ISO 8601 (UTC)
where: string;
phase: string;
stacktrace: string;
};
type AuthConfig = {
authType: 'NONE' | 'BEARER' | 'SIGNATURE_RSA_SHA256';
};
type EventType =
// Outbound calls (OUTBOUND)
| 'OUTBOUND_CALL_WAITING_FOR_CACHE'
| 'OUTBOUND_CALL_PENDING'
| 'OUTBOUND_CALL_REQUESTED'
| 'OUTBOUND_CALL_CALLING'
| 'OUTBOUND_CALL_CLOSING'
| 'OUTBOUND_CALL_COMPLETED'
| 'OUTBOUND_CALL_EXPIRED'
| 'OUTBOUND_CALL_NO_RESPONSE'
| 'OUTBOUND_CALL_CANCELED'
| 'OUTBOUND_CALL_BUSY'
| 'OUTBOUND_CALL_UNREACHABLE'
| 'OUTBOUND_CALL_MAX_ATTEMPTS_REACHED'
| 'OUTBOUND_CALL_ERROR'
| 'OUTBOUND_CALL_VOICEMAIL_REACHED'
| 'OUTBOUND_CALL_HEALTHCHECK_FAILED'
// Inbound calls (INBOUND)
| 'INBOUND_CALL_CONNECTING'
| 'INBOUND_CALL_CALLING'
| 'INBOUND_CALL_CLOSING'
| 'INBOUND_CALL_COMPLETED'
| 'INBOUND_CALL_CONCURRENCY_LIMIT_EXCEEDED'
| 'INBOUND_CALL_ERROR';
Top-level fields
| Field | Type | How to use it |
|---|---|---|
projectId | string | Originating project ID (UUID). Use for routing or authorization checks in multi-project setups. |
webhookEndpoint | WebhookEndpoint | Snapshot of the destination endpoint configuration. Use to identify which endpoint configuration produced this delivery when running multiple endpoints. |
eventType | EventType | The event kind. Scheduled for removal in a future release (see below). See the EventType union in the TypeScript types above for the full list. |
body | WebhookBody | The notification body (described below). |
authConfig | AuthConfig | Reference info about how this request was authenticated. The actual authentication verification happens in the request headers (see Authentication). The payload only carries which method was used. |
webhookEndpoint fields
| Field | Type | How to use it |
|---|---|---|
id | string | Endpoint ID (Recho-internal primary key). Use when correlating logs or contacting support. |
name | string | Endpoint name (display name in the dashboard). |
endpointType | 'SLACK' | 'TEAMS' | 'EMAIL' | 'CUSTOM' | Endpoint kind. Only Custom endpoints receive this structure verbatim. |
target | string | The configured destination (Custom: URL / Slack/Teams: Incoming Webhook URL / Email: address). Informational. |
contentKey | string | null | Template kind key. null means the default format. |
authConfig fields
| Field | Type | How to use it |
|---|---|---|
authType | 'NONE' | 'BEARER' | 'SIGNATURE_RSA_SHA256' | The authentication method applied to this delivery. The actual credentials (token / signature) live in the request headers. |
Possible authType values:
| Value | Meaning |
|---|---|
NONE | No authentication |
BEARER | Bearer token authentication (Authorization header) |
SIGNATURE_RSA_SHA256 | RSA-SHA256 signature verification (X-Recho-Signature header) |
See Authentication for the details of each method and receiver-side verification.
body fields
| Field | Type | How to use it |
|---|---|---|
subject | string | Display-oriented subject. Use as the email Subject header or as a heading in UI. |
text | string | Display-oriented formatted body (human-readable). Includes newlines (\n) and separator lines. Stream it to Slack / Teams messages, log views, or email body. Do not parse it programmatically. |
data | Record<string, string> | Machine-readable identification info. A flat string-to-string map containing keys like callId / callStatus / callSid / clientId. Read this in your program. |
errors | Array<CallError> | undefined | Present only on error. Detect errors via body.errors?.length and use the array for detail logs and notifications. |
body.data fields (call identification)
| Field | Type | How to use it |
|---|---|---|
callId | string | Unique call ID. The primary key for identifying a call in external systems. Events for the same callId are delivered in FIFO order (see Setup Guide). |
callStatus | string | Call status at the moment the notification was emitted. See Call Status Reference for the full list of values. Do not use this to detect errors (use errors array instead). |
callSid | string | Carrier-side call ID (empty string when unavailable). Use for cross-referencing with the telephony provider's logs. |
clientId | string | Optional client identifier (empty string when unspecified). Carries the application-side ID you supplied when initiating the call. |
eventType
The eventType field is scheduled to be removed in a future release. The removal timing and migration path will be announced in this documentation once finalized. Keep this in mind before building new logic that depends on eventType.
A webhook is delivered when something happens to a call. As a call progresses from start to finish, its status transitions (see Call Status Reference), and these call events — status transitions and terminal outcomes — are what trigger webhook deliveries. The eventType field carries exactly which event triggered this notification.
For example, when an outbound call reaches a busy line, one webhook with eventType: 'OUTBOUND_CALL_BUSY' is delivered for that call.
Values follow the {OUTBOUND|INBOUND}_CALL_{event} format — 21 types in total (15 outbound + 6 inbound). The items in the Notification Triggers section of the webhook settings page correspond one-to-one to these eventType values, and only the events you turn ON are delivered (events turned OFF are not delivered).
See the EventType union in the TypeScript types above for all 21 values.
body.errors[] (error details)
Included only when errors occurred: an array of one or more error objects (code / message / timestamp / where / phase / stacktrace). See Error Codes for the meaning of each field and the possible code values.