06 Line

Webhooks

Incoming SMS, delivery status and call recordings, pushed to your server, signed and retried.

06 Line sends an HTTP POST to your URL when something happens to your SMS or your calls:

EventWhen
sms.receivedAn SMS arrived on one of your lines, already reassembled if it was long
sms.statusAn SMS you sent moved to sent, delivered or failed
call.recordedThe recordings of a call are stored: a 7-day link to each track
webhook.testOnly when you ask for a test

Register a URL with POST /v1/webhook-endpoints, choosing its events. The response holds the signing secret (whsec_…), shown once, and the events sorted, without duplicates. Endpoints and their deliveries are managed with an API key: an ephemeral key gets forbidden.

Payload

{
  "id": "evt_01jbq8g6p4z2m8k1t5v3r9c7da",
  "type": "sms.received",
  "created_at": "2026-10-21T14:05:42Z",
  "data": { "id": "sms_…", "from": "+33698765432", "to": "+33612345678", "text": "OK, see you tomorrow." }
}

data is the full SMS object, the same one the API returns.

Verifying the signature

Every request carries 06line-Signature: t=<unix seconds>,v1=<signature>. The signature is the hex HMAC-SHA256 of <t>.<raw body> with your endpoint secret. Recompute it on the raw body, before any JSON parsing, compare in constant time, and reject requests older than 5 minutes to stop replays. The quickstart has the code for Node.js, Python and Go.

Answering

Answer any 2xx within 10 seconds. Do the slow work after answering, from a queue: a slow answer counts as a failure. Redirects are not followed: a 3xx is a failure too.

Retries

Anything else than a 2xx within 10 seconds is retried for 24 hours, the waits growing: 30 s, 1 min, 2 min, 5 min, 10 min, 30 min, 1 h, 2 h, 4 h, then every 6 h. Each wait varies by ±20 %, so an endpoint coming back up is not hit by every delivery at the same second. After 24 hours the delivery is failed. Deleting the endpoint fails its waiting deliveries at once.

Delivery is at least once and in no guaranteed order:

  • the same event may arrive twice: skip it when you already processed its id;
  • sms.status with sent may arrive after delivered: trust the status with the latest created_at, or fetch the message with GET /v1/sms/{id}.

Logs

Every try is kept: GET /v1/webhook-endpoints/{id}/deliveries lists the deliveries of an endpoint, newest first, with the body sent and, for each try, the HTTP status, the error, the start of your answer and how long it took. Filter by status (failed to find what you missed) or event_type, and pass next_cursor as before for the next page; limit goes from 1 to 100 (20 by default). In the dashboard, open an endpoint from the Webhooks page for the same log, with the same filters.

Testing

POST /v1/webhook-endpoints/{id}/test, or Send a test in the dashboard, sends a webhook.test event right away, once, signed like the others, and answers with what your endpoint replied. It is the fastest way to check your signature verification.

Testing locally

Webhook URLs must be HTTPS and reach a public address: private, loopback and carrier-grade NAT (100.64.0.0/10) addresses are refused. A name must resolve when the endpoint is created, to public addresses only; it is checked again at each delivery, since a name can change. To receive webhooks on your laptop, use a tunnel such as cloudflared or ngrok.

On this page