Skip to content
GitHub
Get started →

Leads

The voice agent captures a lead whenever a visitor explicitly provides their contact details (name, email, phone, plus any custom fields configured for the site). Use these endpoints to pull captured leads into your CRM.

Auth: API Key. Every endpoint is scoped to the key’s site.

List leads

GET /v1/public/leads?limit=25&status=new&since=2026-04-01T00:00:00Z
Authorization: Bearer sk_live_...

Query parameters

ParamTypeDefaultNotes
limitint251–100
cursorstringopaque cursor from a previous response (next_cursor)
statusenumnew / contacted / qualified / disqualified
sinceISO 8601created_at >= since

Response

{
"data": [
{
"id": "01J...",
"site_id": "0aa06d96-13fe-...",
"session_id": "sess_xyz",
"conversation_id": "conv_abc",
"visitor_id": "v-123",
"page_url": "https://example.com/contact",
"name": "Sarah Patel",
"phone": "+15555550199",
"email": "sarah@example.com",
"data": { "company": "Acme", "use_case": "consult" },
"status": "new",
"notes": null,
"created_at": "2026-05-07T12:00:00.000Z",
"updated_at": "2026-05-07T12:00:00.000Z"
}
],
"next_cursor": "MjAyNi0wNS0wN1QxMjowMDowMC4wMDBafDAxSi4uLg",
"has_more": false
}

Pagination

Cursor-based. If has_more is true, pass next_cursor on the next call to get the next page. Cursors are stable under inserts (new leads do not shift your cursor position).

Terminal window
# First page
curl -H "Authorization: Bearer $KEY" \
"https://api.spelo.ai/v1/public/leads?limit=50"
# Next page (extract next_cursor from previous response)
curl -H "Authorization: Bearer $KEY" \
"https://api.spelo.ai/v1/public/leads?limit=50&cursor=$NEXT"

Fetch one lead

GET /v1/public/leads/{id}
Authorization: Bearer sk_live_...

Returns the same shape as a list item, wrapped in { data: ... }.

Update a lead

Update status and/or notes. Other fields are read-only.

PATCH /v1/public/leads/{id}
Authorization: Bearer sk_live_...
Content-Type: application/json
{
"status": "contacted",
"notes": "Called at 2pm — they want a follow-up demo"
}

A successful PATCH fires the lead.updated webhook (if any subscriber on this site listens for that event — see Webhooks).

Lead statuses

StatusMeaning
newJust captured. Default.
contactedYou have replied.
qualifiedThey are a real opportunity.
disqualifiedNot a fit (spam, wrong region, etc.).

These are advisory. The agent does not change status automatically — it’s yours to update from your CRM.

Custom fields

data is a JSON object containing whatever fields the site is configured to capture beyond name/email/phone. The shape comes from site_configs.lead_capture_fields.

{
"data": {
"company": "Acme",
"case_type": "personal-injury",
"preferred_contact": "phone"
}
}

See also