Developer API
LeadSignal captures and scores your DM leads. The Developer API is how those leads reach the rest of your stack: pull them with a simple REST endpoint, or have LeadSignal push each one to your system the moment it lands, with signed webhooks. The API exposes your leads and their attribution — nothing else.
Getting a token
API access is included on Pro and Enterprise plans. An admin creates tokens in the dashboard under Settings → General → Developer API & webhooks. The token is shown once, at creation — store it in the system that will use it. Tokens are scoped to your account, revocable at any time, and each token's last use is visible in Settings.
Authentication
Send the token as a bearer credential on every request:
curl https://lead-signal.ai/api/v1/ping \
-H "Authorization: Bearer ls_live_your_token_here"
GET /api/v1/ping confirms the token works and returns its name and scopes.
Rate limits
120 requests per minute per token. Beyond that, requests return 429 with a Retry-After header. If you are syncing on a schedule, use the since parameter below rather than re-pulling everything.
GET/api/v1/leads
Your captured leads, newest first. Requires the leads:read scope (all tokens have it).
| Parameter | Meaning |
|---|---|
limit | Page size, 1–200. Default 50. |
offset | Skip this many rows — page with next_offset from the previous response. |
since | ISO 8601 timestamp. Switches to sync mode: only leads changed after this time, ordered oldest change first — poll with the last updated_at you processed. |
{
"data": [
{
"id": "1f0c6a2e-…",
"name": "Brandi Underwood",
"first_name": "Brandi",
"last_name": "Underwood",
"ig_username": "brandi.fit",
"email": "brandi@example.com",
"phone": null,
"channel": "instagram",
"tier": "HOT",
"score": 78,
"source": "instagram_comment",
"source_detail": "keyword:CORTISOL",
"keyword": "CORTISOL",
"status": null,
"booked": false,
"booked_at": null,
"customer": false,
"archived": false,
"assignee": null,
"last_message_at": "2026-08-10T16:44:02.113Z",
"created_at": "2026-08-10T16:43:36.907Z",
"updated_at": "2026-08-10T16:44:02.113Z"
}
],
"has_more": true,
"next_offset": 50
}
keyword is the comment or DM keyword that captured the lead, already parsed out of source_detail for you. tier is the AI's current qualification: NEW, LOW, NURTURE, WARM, HOT, READY or DISQUALIFIED.
GET/api/v1/leads/:id
A single lead by id, same shape as above under data. 404 if the id is not one of your leads.
Webhooks
Instead of polling, subscribe an https endpoint in Settings → General → Developer API & webhooks and LeadSignal will POST each event to it as it happens.
| Event | Fires when |
|---|---|
lead.created | A new lead is captured — a comment, story reply or DM turned into a lead record. |
lead.contact_captured | An email address or phone number is read out of the conversation and saved to the lead. |
lead.tier_changed | The AI re-scores the lead into a different tier. The payload carries from and to. |
lead.booked | A call is booked. |
ping | You press “Test” in Settings. |
Delivery format
POST https://your-system.com/leadsignal-hook
Content-Type: application/json
X-LeadSignal-Event: lead.created
X-LeadSignal-Delivery: 7c1d9a04-…
X-LeadSignal-Signature: sha256=4b7ab1c6…
{
"id": "7c1d9a04-…",
"event": "lead.created",
"created_at": "2026-08-10T16:43:37.021Z",
"data": {
"lead": { …same lead object as the REST API… }
}
}
Verifying the signature
Every subscription has its own signing secret (shown in Settings). The signature is an HMAC-SHA256 of the raw request body. Verify it before trusting a delivery:
// Node.js
const crypto = require("crypto");
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return signatureHeader.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}
Responding and retries
Answer with any 2xx status within 10 seconds — the body is ignored. Anything else counts as a failure and the delivery retries on a backoff (1 minute, then 5, 30, 2 hours, 6 hours) before being marked failed. Recent deliveries, attempt counts and the last error for each endpoint are visible in Settings.
Deliveries can arrive out of order and, rarely, more than once. Use the X-LeadSignal-Delivery id to de-duplicate, and treat the lead object inside as a snapshot — for the current state of a lead, fetch GET /api/v1/leads/:id.
Errors
| Status | Meaning |
|---|---|
400 | A parameter is malformed — the message says which. |
401 | Missing, malformed, unknown or revoked token. |
402 | Your plan does not include API access. |
403 | The token lacks the required scope. |
404 | No such lead, or an unknown endpoint. |
429 | Rate limit — wait for the Retry-After and slow down. |
Error bodies are always {"error": {"code": 401, "message": "…"}}.
Zapier, Make and friends
No native app is needed: point a “Webhooks by Zapier” catch hook (or a Make custom webhook) at a LeadSignal webhook subscription for real-time triggers, or use the REST endpoint with your token for scheduled pulls. From there, your leads can land in any CRM those platforms speak to.
Questions or a use case the API does not cover yet? Tell us — the surface is small on purpose, and it grows by request.