Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dialbird.io/llms.txt

Use this file to discover all available pages before exploring further.

Dialbird delivers events to your server using the REST Hooks model: one subscription per event type per URL. Manage subscriptions with the api:webhooks scope.

Event types

EventFires when
message.incoming.receivedAn inbound SMS is received.
message.outgoing.deliveredAn outbound SMS is delivered.
call.incoming.completedAn inbound call completes.
call.outgoing.completedAn outbound call completes.

Subscribing

Create a subscription with a target_url (HTTPS) and a single event_type.
curl -X POST https://api.dialbird.com/api/v1/subscriptions \
  -H "Authorization: Bearer $DIALBIRD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "message.incoming.received",
    "target_url": "https://example.com/hooks/dialbird"
  }'
The response includes the plaintext signing_secret (prefixed whsec_) once. Store it immediately — it is never returned again. Listing subscriptions never includes it.

Delivery payload

Every delivery is an event envelope:
{
  "id": "evt_4f9a2c",
  "type": "message.incoming.received",
  "api_version": "v1",
  "occurred_at": "2026-01-15T10:00:00Z",
  "business_id": "biz_123",
  "data": { }
}
  • id — globally unique, prefixed evt_. Use it as a dedup key, since deliveries may be retried.
  • occurred_at — when the event occurred, not when it was delivered.
  • data — the event-specific payload (message/conversation/contact for message events; call/contact/user for call events).
Deliveries also carry X-Dialbird-Event-Id and X-Dialbird-Event-Type headers.
For call.*.completed events, recording_url, voicemail_url, and transcript are always null — recordings and voicemails are produced asynchronously after the call ends. They will be delivered via a dedicated call.recording.completed event (correlated by call id) in a future v1.x release.

Verifying signatures

Each delivery is signed with the X-Dialbird-Signature header:
X-Dialbird-Signature: t=1736937600,v1=<hmac_sha256_hex>
The v1 value is an HMAC-SHA256, computed over ${t}.${raw_body} using your subscription’s signing_secret. Verify it against the raw request body before parsing JSON.
import crypto from "node:crypto";

function verify(rawBody, header, signingSecret) {
  const parts = Object.fromEntries(
    header.split(",").map((kv) => kv.split("="))
  );
  const expected = crypto
    .createHmac("sha256", signingSecret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(parts.v1)
  );
}
Reject any delivery whose signature does not match.

Acknowledging and retries

Respond with any 2xx to acknowledge a delivery. Respond with 410 Gone to permanently disable the subscription. A subscription’s status reflects its delivery health:
StatusMeaning
activeDelivering normally.
failingConsecutive failures crossed the warning threshold.
disabledFailures crossed the hard limit, or the receiver returned 410 Gone.
listSubscriptions exposes consecutive_failures, last_delivered_at, and last_failed_at to help you monitor health.