LeadBind Docs

REST API and instant triggers

Keys, leads, appointments, calls, messages, and event subscriptions for Zapier, Make, and n8n.

The LeadBind REST API is plain JSON over HTTPS. It is what Zapier, Make, n8n and your own code use to read your leads, appointments, calls and texts, to create and update leads, to book and cancel, and to hear about events the moment they happen.

Base URL: https://leadbind.org/api/v1

Keys

Every request carries an API key in a header:

Authorization: Bearer lb_live_...

X-API-Key: lb_live_... works too. Create a key under Menu, then Lead sources, then AI access (leadbind.org/agent/ai-access). See Keys and permissions.

A key belongs to one account, and every request acts on that account only. There is no account id to send, and no way to reach another account with any id you send. An id from another account answers 404, the same as an id that does not exist.

Scope What it allows
read Every GET, and subscribing a URL to events (a subscription only receives what a read key could already read)
write Creating and updating leads, notes, booking and cancelling

There is no way to send a text or place a call through the REST API. That is on purpose: an automation built in a hurry could reach people outside their consent or outside calling hours. Use the app, or MCP with the dial scope, which carries those checks.

A revoked or expired key answers 401 straight away.

Responses and errors

A success is { "data": ... } with a 2xx status. A list also has next_offset: pass it back as offset for the next page, and stop when it is null.

A failure is always this shape, with a real HTTP status:

{ "error": { "code": "not_found", "message": "Lead not found." } }
Status code Means
400 invalid_request A field is missing, the wrong type, too long, or not one we take. The message names it. Unknown fields are refused, never ignored.
401 unauthorized No key, or the key is not valid (revoked, expired, or copied incompletely)
402 payment_required Event subscriptions need an active plan
403 forbidden The key lacks the scope this route needs
404 not_found No such record on your account
409 conflict That time was just taken. Read availability again.
413 payload_too_large The body is over 32 KB
422 rejected LeadBind understood the request and said no, for example a booking without consent. The message says why.
429 rate_limited Slow down. Wait the Retry-After seconds.
502 outcome_unknown The action may or may not have happened, for example a call that got no confirmation back. Do not retry. Read back first.
502 unavailable A provider refused or failed the request. Nothing is known to have happened.
503 unavailable A read or save could not be completed just now. It is never an empty list pretending to be an answer. Try again.

Rate limits

Limits are per key, not per address, so many accounts sending through Zapier never share a budget: 240 reads and 60 writes a minute per key.

Every answer says where you stand: RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset (seconds until the window resets). A 429 carries Retry-After with the real seconds left, so you can wait exactly that long.

The whole API is described in OpenAPI 3.1 at https://leadbind.org/api/v1/openapi.json, which needs no key. Import it into Zapier, Make, n8n or any agent framework.

Safe retries

Send an Idempotency-Key header on any write. A retry with the same key returns the first answer instead of creating a second lead or a second booking.

Account

GET /me (read)

The connection test. Returns your account's name and the key's scopes.

curl https://leadbind.org/api/v1/me -H "Authorization: Bearer $LEADBIND_KEY"
{ "data": { "account": { "id": "...", "name": "Lopez Roofing", "timezone": "America/Chicago" }, "key": { "id": "...", "scopes": ["read", "write"] } } }

Leads

GET /leads (read)

Your leads, newest first. Optional stage, limit (1 to 100, default 25) and offset.

To find one person, send phone (matches the last ten digits exactly) or email (matches the address exactly, case does not matter).

GET /leads/{id} (read)

One lead in full, with its recent calls and appointments. Calls carry an outcome and a short written summary, never a recording or a transcript.

POST /leads (write)

Create a lead, or update the one you already have with the same phone or email. Phone is checked first, then email.

Field Notes
name Required to create. Up to 120 characters.
phone Required to create. A US number.
email Optional
notes On a new lead, its notes. On an existing lead, added as a new note, never a replacement.
stage One of the base pipeline stages: new, contacted, callback, hot, booked, sold, lost. A custom stage you added to your board is set in the app.
address, city, state, zip An address puts the lead on the door-mode map
source Where it came from, for your reports. Defaults to api.
curl -X POST https://leadbind.org/api/v1/leads \
  -H "Authorization: Bearer $LEADBIND_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: form-4471" \
  -d '{"name":"Maria Lopez","phone":"8325550134","email":"maria@example.com","source":"facebook-roofing"}'

201 with {"data":{"id":"...","created":true}} for a new lead, or 200 with "created": false and the fields that changed for an existing one.

A new lead alerts you and fires lead.created, like a lead from any other door. It does not start a speed-to-lead call. To have LeadBind call a new lead within seconds, send it to your lead webhook instead, which checks consent and calling hours first.

PATCH /leads/{id} (write)

Change only the fields you send. notes here replaces the notes; to add one, use the next route. A stage change fires lead.status_changed.

POST /leads/{id}/notes (write)

{"note": "..."}, up to 1000 characters. Added with a timestamp; every earlier note is kept.

Appointments

GET /availability (read)

Open slots for the next two weeks, grouped by date. Optional timezone (for example America/Chicago) and calendar (a calendar's short name).

GET /appointments (read)

Upcoming appointments from now, in time order. Optional from and to (dates such as 2026-11-01; a bare to date includes that whole day), lead_id, limit, offset.

POST /appointments (write)

Book a slot that GET /availability returned.

Field Notes
start_time Required. The slot's start, exactly as availability returned it.
name, email, phone Required. The confirmation goes to this email.
consent Required. true only when the customer really agreed to be contacted. LeadBind refuses false.
timezone Optional. The zone start_time is in.

The same checks as your public booking page run: open hours, double booking, minimum notice. A time that was just taken answers 409.

POST /appointments/{id}/cancel (write)

The booking is kept as canceled, its slot opens again, and its calendar event is removed. Cancelling one that is already canceled succeeds with already_canceled: true.

Calls and texts

GET /calls (read)

Recent calls, newest first: direction, outcome, duration, who called, the linked lead and appointment, and a short summary. Optional direction (inbound or outbound), limit, offset. Never a recording or a transcript.

GET /messages (read)

Your text messages, newest first. Optional phone (the other person), direction, limit, offset.

Instant triggers

Subscribe a URL to an event and LeadBind posts to it the moment the event happens. This is what powers instant triggers in Zapier, Make and n8n.

POST /hooks (read)

curl -X POST https://leadbind.org/api/v1/hooks \
  -H "Authorization: Bearer $LEADBIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.zapier.com/hooks/standard/123/abc/","event":"call.missed"}'

Send url (or target_url) and event, or events as a list. The URL must be public https. Answers 201 with the subscription's id and its signing secret. The secret is shown once, on this answer only.

Subscriptions made here appear on your Developer page, where you can see deliveries, send a test, or pause one.

DELETE /hooks/{id} (read)

Removes a subscription made through the API. A subscription you set up by hand in the app is not removable here.

GET /hooks/samples?event=... (read)

A list with one example delivery for that event, in exactly the shape a real delivery has. It is your latest real one when you have had that event, otherwise a written example marked "sample": true.

Events

Event When
lead.created A new lead arrives from any door: the lead webhook, a website form, a chat, a landing page, a first-time booker, an inbound caller, the app, or this API
lead.status_changed A lead changes stage
call.completed A call finishes
call.missed An inbound call ends with nobody talking to the caller
message.received A text comes in. A STOP reply is included with optOut: true.
appointment.booked An appointment is booked
appointment.updated An appointment is moved, corrected, confirmed, done, or a no-show
appointment.cancelled An appointment is cancelled, from any place
payment.received A customer payment goes through
deal.won / deal.lost A deal is marked won or lost

What a delivery looks like

{
  "id": "6f1c2a9e-0d3b-4c55-9a8e-2f7d1b0c4e11",
  "event": "call.missed",
  "data": { "id": "...", "direction": "inbound", "callerPhone": "+18325550134", "durationSeconds": 4, "outcome": "hung_up_early", "leadId": "..." },
  "sent_at": "2026-11-10T15:04:05.000Z"
}

id is the same for every URL that hears this event and for every retry of it, so dedupe on it. Each request also carries:

Header Value
X-LeadBind-Event The event name
X-LeadBind-Delivery One id per URL per event, the same on every retry
X-LeadBind-Signature sha256= and the HMAC SHA-256 of the raw body, keyed with the subscription's secret

Check the signature against the raw body before you trust a delivery:

const crypto = require("crypto");
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-leadbind-signature"]));

Retries and stopping

Answer with any 2xx within five seconds. Anything else is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, then given up.

Answer 410 Gone and LeadBind stops at once and switches that subscription off. That is how Zapier tells a sender a Zap was turned off.

Recordings, transcripts and call summaries are never in a delivery.

Was this page helpful?