Threadline

Integrations & API

What it is

Two ways for Threadline and your other software to work together:

  • Webhooks. Threadline tells another tool when something happens. See Webhooks for the plain-language explanation.
  • The REST API. Another tool asks Threadline to do something, such as add a contact or send a message.

This page is the technical reference for both. Parts of it are written for a developer or for someone comfortable with tools like n8n and Zapier.

The problem it solves

Your customer data should not have to be typed twice. A website form, an online shop, a CRM and Threadline each hold part of the picture. Connecting them means:

  • a customer who fills in a form on your website is added to Threadline and gets a WhatsApp message, with nobody doing anything;
  • an order placed in your shop sends a "your order has shipped" message;
  • every lead from Threadline lands in your spreadsheet or CRM.

How it works

  • For webhooks, you add an endpoint under Webhooks and choose its events. Threadline sends a message to that address each time one happens.
  • For the API, you create an access token under Developer, API tokens in the sidebar. The token is a long password that another program uses to prove it may act for your workspace. You decide what each token is allowed to do.

Creating an API token

  1. Go to Developer, API tokens in the sidebar. Your plan must include API access.
  2. Enter a name, so you remember what the token is for, for example "Zapier".
  3. Choose what it may do:
    • Tick Full access for everything, including anything added later. Use it only for a program you fully trust.
    • Or tick only the abilities that tool needs. See the list below.
  4. Optionally set an expiry date (a date in the future, up to five years away). After that date the token stops working and answers 401 with a clear message.
  5. Create it and copy the token straight away. It is shown only once.

If a token is lost or may have leaked, click Revoke and make a new one. A revoked token stops working at once. The token list shows each token's expiry and when it was last used.

Abilities (what a token may do)

Ability Lets the program…
messages:send Send texts and templates.
contacts:read / contacts:write Read contacts, segments and tags / create, change, delete and tag contacts.
conversations:read / conversations:write Read conversations and messages / set a conversation's status or close it.
campaigns:read / campaigns:write Read campaigns and their recipients / create, launch, pause and resume them.
templates:read / templates:write Read WhatsApp templates / create drafts and submit them to Meta.
automations:trigger List automations and start one for a contact.
webhooks:write Manage webhook endpoints.
ai:read / ai:write List assistants and knowledge bases / add knowledge and ask an assistant.
deals:read / deals:write Read pipelines and deals / create and move deals.
bookings:read / bookings:write Read bookable services, free times and bookings / create and cancel bookings.
analytics:read Read the summary numbers.

Treat a token like a password. Anyone who has it can read your contacts or send messages as your business, within what the token allows. Never put it in a public web page or share it in chat.

The rest of this page gives the exact formats.

1. Webhooks

Add an endpoint under Webhooks (see Webhooks). Every delivery is an HTTP POST of JSON, with the same envelope for every event:

{
  "event": "message.received",
  "data": { },
  "timestamp": "2026-10-05T10:00:00+00:00"
}

Verifying the signature

Each delivery carries X-Threadline-Signature-256: sha256=<hex>. It is an HMAC-SHA256 of the raw request body, keyed with your endpoint's signing secret. Compute it yourself and compare in constant time; reject the request if it doesn't match.

$expected = 'sha256='.hash_hmac('sha256', $rawBody, $secret);
$valid = hash_equals($expected, $_SERVER['HTTP_X_THREADLINE_SIGNATURE_256'] ?? '');

Events and their data

message.received: a customer sent a message.

{
  "message": { "id": 912, "conversation_id": 55, "text": "Hi, is this in stock?", "has_image": false, "received_at": "2026-10-05T10:00:00+00:00" },
  "contact": { "id": 7, "name": "Ana Silva", "phone": "15551234567", "email": null, "channel_id": 2, "channel_type": "whatsapp", "opted_in": false }
}

contact.created: { "contact": { …same shape as above… } }

lead_form.submitted:

{
  "lead_form": { "id": 3, "title": "Book a demo" },
  "contact": { "id": 7, "name": "Ana Silva", "phone": "15551234567", "email": "ana@example.com", "channel_id": 2, "channel_type": "whatsapp", "opted_in": false },
  "conversation_id": 55,
  "answers": [ { "label": "Your name", "value": "Ana" }, { "label": "Email", "value": "ana@example.com" } ],
  "completed_at": "2026-10-05T10:05:00+00:00"
}

conversation.escalated: { "conversation_id": 55, "reason": "keyword" }. The reason is one of fallback_phrase, human_requested, keyword or repeated_question.

conversation.closed: { "conversation_id": 55 }

answer.fallback: { "conversation_id": 55, "kb_id": 4, "question": "Do you ship to Nepal?" }

deal.created, deal.stage_changed, deal.won, deal.lost:

{
  "deal": {
    "id": 31, "title": "Website redesign", "value": 1500, "currency": "USD", "probability": 50,
    "stage": "Proposal", "stage_kind": "open", "pipeline": "Sales Pipeline",
    "contact_id": 7, "conversation_id": 55, "owner_user_id": 2,
    "expected_close_on": "2026-11-01", "source_channel_type": "whatsapp",
    "won_at": null, "lost_at": null, "lost_reason": null
  },
  "from_stage": "Qualified"
}

from_stage is present on the stage-change events only.

2. The REST API

Send your token on every request:

Authorization: Bearer kd_…
Accept: application/json

Everything is under /api/v1. A token belongs to one workspace and can only see that workspace's data. Each token is limited to 60 requests a minute; past that you get 429. A wrong, revoked or expired token gets 401; a token without the needed ability, or a workspace whose plan has no API access, gets 403.

The API reference page

You do not need this page to find every endpoint. Developer, API reference in the sidebar lists all 43 endpoints with their parameters, a ready-to-copy curl example and a sample answer, with a search box. It also has a quickstart, the error and rate-limit notes, how to check webhook signatures (with a Node example) and a download of the whole API as an OpenAPI 3 file you can load into Postman or code generators.

What the API covers

Area Examples
Account GET /me, /channels, /analytics/summary
Contacts list, create, show, update, delete, add and remove tags, /tags, /segments
Conversations list, show, read messages, set status or close
Messages POST /messages: send a text, or an approved template
Templates list, show, create a draft, submit to Meta
Campaigns list, show, recipients, create (and optionally launch), launch, pause, resume
Webhooks list, create (the secret is shown once), update, delete (URLs must be public)
Assistants and knowledge list, add text, a web page or questions and answers, ask an assistant
Automations list, start one for a contact with extra data
Deals list pipelines and deals, create in an open stage, move

Not in the API: deleting a conversation, replying as a person, and changing who handles a conversation.

Lists are paginated: the response has data, links and meta.

# Add a contact who has agreed to hear from you, with a tag
curl -X POST https://your-site.com/api/v1/contacts \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"channel_id": 2, "phone": "+1 555 123 4567", "name": "Ana", "opted_in": true, "tags": ["website-lead"]}'

opted_in is your statement that the person agreed to marketing messages. The API can set it but never takes it away.

# Send a text (queued; answers 202)
curl -X POST https://your-site.com/api/v1/messages \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"contact_id": 7, "text": "Your order has shipped!"}'

# Start a conversation with an approved template (sent at once; answers 201)
curl -X POST https://your-site.com/api/v1/messages \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"channel_id": 2, "phone": "15551234567", "template_id": 12}'

The 24-hour rule applies: on WhatsApp, Instagram and Messenger a text only goes out within 24 hours of the person's last message, and otherwise answers 422 and tells you to use a template. A template needs an approved template and a contact who has opted in.

3. Recipe: new lead → Google Sheets, with n8n

  1. In n8n, add a Webhook node. Set the method to POST and copy its production URL.
  2. In Threadline, Webhooks → Add endpoint, paste that URL and subscribe it to lead_form.submitted. Copy the signing secret.
  3. Add a lead form to your channel (see Lead Forms) and complete it once yourself so n8n receives a sample.
  4. In n8n, add a Google Sheets node after the webhook, set it to Append row, and map {{ $json.body.data.contact.name }}, {{ $json.body.data.contact.phone }} and {{ $json.body.data.answers[1].value }} to columns.
  5. Optional: add a Code node between them to check the signature (section 1) before trusting the data.
  6. Activate the workflow. Every completed form now adds a row.

4. Recipe: send a WhatsApp message from a form, with Zapier

  1. In Threadline, make a token with Create contacts and Send messages, and find your WhatsApp channel's id and an approved template's id.
  2. In Zapier, set the trigger to your form tool's New submission.
  3. Add a Webhooks by Zapier action, event Custom Request, method POST, URL https://your-site.com/api/v1/contacts, header Authorization: Bearer <token>, and a JSON body with the form's name and phone, "channel_id" and "opted_in": true if the form asks for consent.
  4. Add a second Custom Request to /api/v1/messages with {"channel_id": 2, "phone": "<the phone>", "template_id": 12}.
  5. Test and publish the Zap.

5. Other ways in

  • Automation webhook trigger. An automation can start when your system calls a private address. No API token is needed; the secret is in the address.
  • Online stores send their own webhooks to Threadline. See Online Stores.

6. Meta lead ads

Lead ads from Facebook and Instagram can create contacts for you automatically. The full setup, including Meta's approval steps, is on its own page: Meta Lead Ads.

7. WhatsApp links

Short links and QR codes that open a chat with you and show which advert brought each customer. See WhatsApp Links.

Common questions

I get 401. The token is wrong or was revoked. Create a new one.

I get 403. The token works but is not allowed to do that. Create a token with the ability you need.

I get 429. You sent more than 60 requests in a minute with that token. Wait a moment and slow down.

I get 422 when sending a text. The 24-hour window has closed for that contact. Send an approved template instead.

I get 401 and the message mentions expiry. The token's expiry date has passed. Make a new one.

API access is missing from Settings. Your plan does not include API access. See Plans & Billing.