Webhooks

Add up to ten https addresses in Settings → Connections → API and webhooks and pick the events each wants. We post a signed JSON body within about a minute of the event and retry eight times over about a day. Signatures follow the Standard Webhooks spec.

View as Markdown

Add an endpoint

An owner opens Settings → Connections → API and webhooks, adds an https address and ticks the events it wants.

  • Up to ten endpoints in a workspace.
  • Each gets a secret that starts with whsec_, shown once. You can make a new one at any time; the old one stops signing at once.
  • An endpoint can be paused. What was queued waits for it.
  • You can send a test event, ping, from the screen to check the address and the secret.
  • The screen keeps a log of every delivery for a month, with the answer your server gave.

Events

Event When data holds
lead.created A lead is made, by any means: a person, an import, your website form, the API, Tala lead
lead.status_changed A lead’s status changes lead, from, to
text.received A lead texts one of your numbers lead, text
call.ended A call ends, a rep’s or the AI caller’s lead, call
meeting.booked A call is booked on the calendar lead, meeting
payment.received A payment becomes paid lead, payment
deal.opened A deal is opened lead, deal, stage
deal.stage_changed A deal moves to another stage lead, deal, from, to
deal.won A deal moves into a won stage lead, deal, stage
deal.lost A deal moves into a lost stage lead, deal, stage
deal.cancelled A won sale is marked cancelled lead, deal, on
ping You send a test from the screen message

Worth knowing:

  • A status set again to the same value is not a change, and sends nothing.
  • A text is an event when it comes in. Texts you send are not events.
  • A move into a won or lost stage sends deal.stage_changed and deal.won or deal.lost.
  • Leads and deals brought in by a CRM import send no events.

The body

lead is the whole lead as the API returns it, or null if it has since been removed. The example above is shortened.

Object Fields
text id, body, at, number, line
call id, direction, at, duration, disposition, number, line
meeting id, starts_at, ends_at, time_zone, attendee_email, meet_url, state
payment id, amount, currency, kind, email
deal The whole deal as the API returns it

number is the lead’s number and line is yours.

JSON
{
  "id": "evt_…",
  "type": "lead.status_changed",
  "created_at": "2026-11-12T09:44:02.000Z",
  "workspace_id": 7,
  "data": {
    "lead": { "id": 123, "name": "Reed Auto Repair", "status": "Interested" },
    "from": "New",
    "to": "Interested"
  }
}

Verify the signature

Deliveries are signed to the Standard Webhooks spec. Three headers come with each one:

Header Value
webhook-id msg_…. The same on every retry, so you can drop a duplicate by it.
webhook-timestamp Seconds since 1970.
webhook-signature v1, and the base64 HMAC-SHA256 of {id}.{timestamp}.{body} with your secret.

Any Standard Webhooks library checks it. In Node:

Verify against the raw bytes you received. Parsing the JSON and writing it out again changes the body and breaks the signature.

Node.js
import { Webhook } from "standardwebhooks";

const wh = new Webhook(process.env.TALALEVEL_WEBHOOK_SECRET); // whsec_…

export async function POST(request) {
  const body = await request.text(); // the raw body, before any JSON parsing
  let event;
  try {
    event = wh.verify(body, Object.fromEntries(request.headers));
  } catch {
    return new Response("bad signature", { status: 400 });
  }
  if (event.type === "text.received") {
    // event.data.lead, event.data.text
  }
  return new Response("ok");
}

Delivery and retries

  • We post what is due every minute.
  • Any 2xx answer counts as delivered. Answer fast and do slow work afterwards; a delivery times out after 10 seconds.
  • Anything else, a timeout or a redirect is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours, 5 hours, then 10 hours twice. That is eight tries over about a day.
  • Every retry carries the same body and the same webhook-id.
  • After the last try the delivery is marked failed. You can send it again from the log.
  • Redirects are never followed.

Addresses we refuse

The address must be https, with no name and password in it. localhost, private network ranges and internal names are refused, both when you save the address and each time we connect. To test on your own machine, use a tunnel that gives you a public https address.

Questions

Which events does TalaLevel send webhooks for?
lead.created, lead.status_changed, text.received, call.ended, meeting.booked, payment.received, deal.opened, deal.stage_changed, deal.won, deal.lost and deal.cancelled, plus a ping test event.
How do I verify a TalaLevel webhook?
Deliveries are signed to the Standard Webhooks spec with your endpoint's whsec_ secret. Use any standardwebhooks library with the webhook-id, webhook-timestamp and webhook-signature headers and the raw body.
What happens if my endpoint is down?
We retry after 1 minute, 5 minutes, 30 minutes, 2 hours, 5 hours, then 10 hours twice: eight tries over about a day. After that the delivery is marked failed and can be sent again from the log.

© 2026 TalaLevel · talalevel.com · openapi.json · llms.txt · Privacy · Terms