Skip to main content
🤖 LLM Friendly: This page is available in raw Markdown format for LLM consumption:webhooks.md|Get full documentation:llms.txt/llms-full.txt

Webhooks

Configure webhook endpoints to receive real-time HTTP POST notifications when events occur in your workspace — such as incoming calls, call state changes, call endings, and contact updates.

For details on payload format, event types, retry policy, and signature verification, see the Webhooks Overview.

Endpoints​

MethodEndpointDescription
GET/webhooksList all webhook endpoints
GET/webhooks/:idGet webhook details
POST/webhooksCreate a webhook endpoint
POST/webhooks/:id/test-eventSend a test event
PATCH/webhooks/:idUpdate a webhook endpoint
DELETE/webhooks/:idDelete a webhook endpoint

The Webhook Object​

FieldTypeDescription
idstringUnique webhook identifier (prefixed with wh-)
workspace_idstringWorkspace identifier
titlestringDisplay name for the webhook
urlstringThe URL that receives event notifications
eventsstring[]Array of event names this webhook is subscribed to
headersobject[]Custom HTTP headers sent with each delivery
is_activebooleanWhether the webhook is active
secretstringSigning secret for signature verification (only returned on creation)
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp

Webhook Header Object​

FieldTypeDescription
keystringHeader name (1–35 characters)
valuestringHeader value (1–255 characters)

Available Event Names​

For complete payload structures and JSON schemas for each event, see the Webhook Event Catalog.

EventDescription
call.createdA new call has been initiated
call.answeredA call was answered by an agent or user
call.endedA call has ended
call.recording.readyA call recording audio file has finished processing, uploaded, and is ready
call.transcription.completedReal-time call transcription and Named Entity Recognition (NER) completed
contact.createdA new contact was created in the workspace
contact.updatedAn existing contact was updated
contact.deletedA contact was deleted
agent.stateAn agent's presence state was changed (available, busy, away, etc)
agent.createdA new workspace agent account was created
agent.updatedAn existing workspace agent account was updated
agent.deletedA workspace agent account was deleted
workspace.credit.updatedWorkspace credit balance was updated (e.g., call charge deduction, top-up)

List Webhooks​

GET /webhooks

Retrieve a paginated list of all webhook endpoints in the workspace.

Authentication​

Requires ApiKey with any scope.

Query Parameters​

ParameterTypeDefaultDescription
pagenumber1Page number (min: 1)
limitnumber10Items per page (min: 1, max: 100)
searchstring—Search by title
sort_fieldstringcreated_atSort field. Allowed: created_at
sort_orderstringdescSort order: asc or desc

Request​

curl -X GET "https://{workspace_id}.firetell.app/api/v1/webhooks?page=1&limit=10" \
-H "Authorization: ApiKey sk-YOUR_API_KEY"

Response​

{
"data": [
{
"id": "wh-7f3a2b1c9d4e5f6a8b0c1d2e",
"workspace_id": "yourcompany",
"title": "Call Events - Production",
"url": "https://api.example.com/webhooks/firetell",
"events": ["call.created", "call.ended"],
"headers": [
{
"key": "X-Custom-Token",
"value": "my-secret-token"
}
],
"is_active": true,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-03-20T14:00:00.000Z"
},
{
"id": "wh-9a8b7c6d5e4f3a2b1c0d9e8f",
"workspace_id": "yourcompany",
"title": "Contact Sync",
"url": "https://crm.example.com/hooks/firetell",
"events": ["contact.created", "contact.updated", "contact.deleted"],
"headers": [],
"is_active": true,
"created_at": "2026-02-10T10:00:00.000Z",
"updated_at": "2026-02-10T10:00:00.000Z"
}
],
"meta": {
"total": 2,
"page": 1,
"limit": 10,
"total_pages": 1
}
}
info

The secret field is not included in list responses. It is only returned when creating a webhook.


Get Webhook​

GET /webhooks/:id

Retrieve details of a specific webhook endpoint.

Authentication​

Requires ApiKey with full scope.

Path Parameters​

ParameterTypeDescription
idstringThe webhook ID (e.g., wh-7f3a2b1c9d4e5f6a8b0c1d2e)

Request​

curl -X GET "https://{workspace_id}.firetell.app/api/v1/webhooks/wh-7f3a2b1c9d4e5f6a8b0c1d2e" \
-H "Authorization: ApiKey sk-YOUR_API_KEY"

Response​

{
"id": "wh-7f3a2b1c9d4e5f6a8b0c1d2e",
"workspace_id": "yourcompany",
"title": "Call Events - Production",
"url": "https://api.example.com/webhooks/firetell",
"events": ["call.created", "call.ended"],
"headers": [
{
"key": "X-Custom-Token",
"value": "my-secret-token"
}
],
"is_active": true,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-03-20T14:00:00.000Z"
}

Error Response​

{
"statusCode": 404,
"message": "item not found",
"error": "Not Found"
}

Create Webhook​

POST /webhooks

Create a new webhook endpoint. A signing secret is automatically generated and returned in the response — save it securely, as it will not be retrievable again.

Authentication​

Requires ApiKey with full scope.

caution

Each workspace is limited to a maximum of 20 webhook endpoints. Exceeding this limit will return a 403 Forbidden error.

Request Body​

FieldTypeRequiredDescription
titlestring✅Display name. 1–100 characters.
urlstring✅Webhook URL. Must be a valid HTTPS URL. Max 255 characters.
eventsstring[]✅Array of event names to subscribe to. At least 1 event required.
headersobject[]—Custom HTTP headers (max 3). Each with key (1–35 chars) and value (1–255 chars).

Request​

curl -X POST "https://{workspace_id}.firetell.app/api/v1/webhooks" \
-H "Authorization: ApiKey sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Call Events - Production",
"url": "https://api.example.com/webhooks/firetell",
"events": ["call.created", "call.answered", "call.ended"],
"headers": [
{
"key": "X-Custom-Token",
"value": "my-secret-token"
}
]
}'

Response​

{
"id": "wh-d4e5f6a7b8c9d0e1f2a3b4c5",
"workspace_id": "yourcompany",
"title": "Call Events - Production",
"url": "https://api.example.com/webhooks/firetell",
"events": ["call.created", "call.answered", "call.ended"],
"headers": [
{
"key": "X-Custom-Token",
"value": "my-secret-token"
}
],
"is_active": true,
"secret": "whse-a1b2c3d4e5f6a7b8c9d0e1",
"created_at": "2026-07-09T08:00:00.000Z",
"updated_at": "2026-07-09T08:00:00.000Z"
}
caution

Save the secret value immediately. The secret (prefixed with whse-) is only returned once during creation. You will need it to verify webhook signatures using HMAC-SHA256.

Error Response​

Webhook limit reached:

{
"statusCode": 403,
"message": "We currently only support up to 20 webhooks with your plan. You've reached your limit.",
"error": "Forbidden"
}

Send Test Event​

POST /webhooks/:id/test-event

Send a simulated test event to verify your webhook endpoint is working correctly. The test payload is sent immediately to the configured URL with a valid signature.

Authentication​

Requires ApiKey with full scope.

Path Parameters​

ParameterTypeDescription
idstringThe webhook ID

Request Body​

FieldTypeRequiredDescription
event_namestring✅The event type to simulate. Must be one of the events the webhook is subscribed to.

Request​

curl -X POST "https://{workspace_id}.firetell.app/api/v1/webhooks/wh-7f3a2b1c9d4e5f6a8b0c1d2e/test-event" \
-H "Authorization: ApiKey sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_name": "call.created"
}'

Success Response​

{
"success": true,
"status": 200,
"status_text": "OK",
"latency_ms": 142,
"message": "Webhook test event with respond success"
}

Failure Responses​

Endpoint returned non-success status:

{
"success": false,
"status": 500,
"status_text": "Internal Server Error",
"latency_ms": 85,
"error": "Internal Server Error",
"message": "Webhook endpoint did not respond success. status >= 300"
}

Endpoint unreachable:

{
"success": false,
"status": 0,
"latency_ms": 0,
"error": "ECONNREFUSED",
"message": "Webhook endpoint did not respond"
}

Event not subscribed:

{
"statusCode": 400,
"message": "This endpoint is not currently subscribed to this event",
"error": "Bad Request"
}

Test Payload Example​

When simulating a call.created event, the following test payload is sent to your URL:

{
"event": "call.created",
"data": {
"workspace_id": "yourcompany",
"call_id": "test_call_id_1720512000000",
"direction": "inbound",
"caller": {
"name": "Caller_name",
"number": "Caller_number"
},
"callee": {
"name": "Callee_name",
"number": "Callee_number"
},
"created_at": "2026-07-09T08:00:00.000Z"
}
}
tip

Use the test event endpoint during development to verify your webhook handler is correctly parsing payloads and validating signatures before going live.


Update Webhook​

PATCH /webhooks/:id

Update an existing webhook endpoint's configuration. All fields in the request body are required — this endpoint replaces the webhook configuration entirely.

Authentication​

Requires ApiKey with full scope.

Path Parameters​

ParameterTypeDescription
idstringThe webhook ID

Request Body​

FieldTypeRequiredDescription
titlestring✅Display name. 1–100 characters.
urlstring✅Webhook URL. Must be a valid HTTPS URL. Max 255 characters.
eventsstring[]✅Array of event names. At least 1 event required.
headersobject[]—Custom HTTP headers (max 3).

Request​

curl -X PATCH "https://{workspace_id}.firetell.app/api/v1/webhooks/wh-7f3a2b1c9d4e5f6a8b0c1d2e" \
-H "Authorization: ApiKey sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Call Events - Updated",
"url": "https://api.example.com/webhooks/firetell-v2",
"events": ["call.created", "call.ended"],
"headers": []
}'

Response​

Returns the updated webhook object:

{
"id": "wh-7f3a2b1c9d4e5f6a8b0c1d2e",
"workspace_id": "yourcompany",
"title": "Call Events - Updated",
"url": "https://api.example.com/webhooks/firetell-v2",
"events": ["call.created", "call.ended"],
"headers": [],
"is_active": true,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-07-09T09:30:00.000Z"
}
info

Updating a webhook does not regenerate the signing secret. The original secret remains valid.

Error Response​

{
"statusCode": 404,
"message": "item not found",
"error": "Not Found"
}

Delete Webhook​

DELETE /webhooks/:id

Permanently delete a webhook endpoint. Event notifications will immediately stop being delivered to this URL.

Authentication​

Requires ApiKey with full scope.

caution

This action is irreversible. Any events that occur after deletion will not be delivered to this endpoint.

Path Parameters​

ParameterTypeDescription
idstringThe webhook ID

Request​

curl -X DELETE "https://{workspace_id}.firetell.app/api/v1/webhooks/wh-7f3a2b1c9d4e5f6a8b0c1d2e" \
-H "Authorization: ApiKey sk-YOUR_API_KEY"

Response​

Returns the deleted webhook object:

{
"id": "wh-7f3a2b1c9d4e5f6a8b0c1d2e",
"workspace_id": "yourcompany",
"title": "Call Events - Production",
"url": "https://api.example.com/webhooks/firetell",
"events": ["call.created", "call.ended"],
"headers": [],
"is_active": true,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-03-20T14:00:00.000Z"
}

Error Response​

{
"statusCode": 404,
"message": "item not found",
"error": "Not Found"
}

Webhook Delivery​

Signature Verification​

Every webhook delivery includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the request body, signed with your webhook's secret.

const crypto = require("crypto");

function verifyWebhookSignature(rawBody, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

// In your Express handler:
app.post("/webhooks/firetell", (req, res) => {
const signature = req.headers["x-webhook-signature"];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
"whse-your-webhook-secret",
);

if (!isValid) {
return res.status(401).send("Invalid signature");
}

// Process the event...
res.status(200).send("OK");
});

Delivery Headers​

Each webhook delivery includes the following headers:

HeaderDescription
Content-TypeAlways application/json
X-Webhook-SignatureHMAC-SHA256 signature of the request body
X-Powered-ByFiretell service identifier
User-AgentFiretell webhook delivery agent (e.g., region@firetell.shared.webhook/1.0.2)
Custom headersAny headers you configured on the webhook endpoint

Timeout & Retries​

  • Timeout: 5 seconds per delivery attempt
  • Redirect: Not followed (maxRedirects: 0)
  • Your endpoint must respond with a status code below 300 to be considered successful
  • See Webhooks Overview for the retry policy