A lead is another person's email address or phone number. They gave it to
your automation; treat it as the personal data it is. Reading leads needs the
leads:read scope, which is in no preset.
{
"id": "f5b3d7e2-8a41-4c96-b0e7-6d2a9c1f3e58",
"account_id": "a3d9f1c4-7b2e-4c60-9e85-1f4b6d2a0c73",
"automation_id": "d2a6f8b1-5c94-4e07-9b3a-1e7c0f4d6a25",
"network": "instagram",
"handle": "roadrunner",
"name": "R. Runner",
"email": "roadrunner@example.com",
"phone": null,
"source": "comment_to_dm",
"created_at": "2026-10-01T09:16:40+00:00"
}
Operations
GET /v1/leads
List leads
Scope leads:read.
Contact details people chose to give, newest first. Needs leads:read, which no preset includes.
Parameters
| Name | In | Type | |
|---|---|---|---|
account_id |
query | uuid |
|
limit |
query | integer |
Page size, 1 to 200. Above 200 is clamped; anything else is the default. (default 50; >= 1; <= 200) |
cursor |
query | string |
The next_cursor from the previous page. Opaque; an invalid one is 400. (max 512) |
Answers
| Status | Body | |
|---|---|---|
| 200 | LeadList |
A page of leads. |
| 400 | ErrorEnvelope |
VALIDATION_ERROR: a body that is not JSON, a field that breaks its rule (named in fields), a bad query value or cursor, or a malformed Idempotency-Key. |
| 401 | ErrorEnvelope |
UNAUTHORIZED: no key, or one that is malformed, unknown or revoked. It never says which. |
| 403 | ErrorEnvelope |
INSUFFICIENT_SCOPE: the key lacks this operation's scope. Or ORGANISATION_SUSPENDED: the key's organisation is suspended. Never about another workspace's object, which is 404. |
| 429 | ErrorEnvelope |
RATE_LIMITED: too many requests. Wait for Retry-After seconds. |
| 500 | ErrorEnvelope |
INTERNAL_ERROR: ours. Safe to retry; send the same Idempotency-Key on a POST. |
Captured leads — answers 200
Behind leads:read, which is in no preset: a lead is somebody else's address, given to your automation and not to every tool you connect.
curl "https://api.boltclaw.ai/v1/leads?limit=50" \
-H "Authorization: Bearer bc_live_EXAMPLExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const res = await fetch("https://api.boltclaw.ai/v1/leads?limit=50", {
headers: {
Authorization: `Bearer ${process.env.BOLTCLAW_KEY}`,
},
});
// 200
const data = await res.json();
DELETE /v1/leads/{id}
Delete a lead
Scope leads:read. Also social:write. Another workspace's answers 404.
Deletes the lead's contact details. Needs leads:read and social:write together.
Parameters
| Name | In | Type | |
|---|---|---|---|
id |
path | uuid |
An id this API gave you. Anything that is not one of yours is 404. (required) |
Answers
| Status | Body | |
|---|---|---|
| 200 | Deleted |
Deleted. |
| 401 | ErrorEnvelope |
UNAUTHORIZED: no key, or one that is malformed, unknown or revoked. It never says which. |
| 403 | ErrorEnvelope |
INSUFFICIENT_SCOPE: the key lacks this operation's scope. Or ORGANISATION_SUSPENDED: the key's organisation is suspended. Never about another workspace's object, which is 404. |
| 404 | ErrorEnvelope |
NOT_FOUND: no such object, or it belongs to another workspace. The two are deliberately the same answer and never 403. If the id is right, check you are using the right key. |
| 428 | ErrorEnvelope |
APPROVAL_REQUIRED on the first try, APPROVAL_PENDING on a retry before a person has decided. NOTHING HAS HAPPENED either way. The body carries approval with a url: show it to the person, and once they approve, send the identical request again with the approval id in BoltClaw-Approval. Only an AI assistant's request is ever answered this way. |
| 429 | ErrorEnvelope |
RATE_LIMITED: too many requests. Wait for Retry-After seconds. |
| 500 | ErrorEnvelope |
INTERNAL_ERROR: ours. Safe to retry; send the same Idempotency-Key on a POST. |
Shapes
The objects these operations send and answer.
Deleted
| Field | Type | |
|---|---|---|
deleted |
true |
(required) |
id |
uuid |
(required) |
Lead
| Field | Type | |
|---|---|---|
id |
uuid |
(required) |
account_id |
uuid | null |
(required) |
automation_id |
uuid | null |
(required) |
network |
any |
(required) |
handle |
string | null |
(required) |
name |
string | null |
(required) |
email |
string | null |
(required) |
phone |
string | null |
(required) |
source |
string |
(required; one of comment_to_dm, dm, api) |
created_at |
date-time |
(required) |
LeadList
| Field | Type | |
|---|---|---|
data |
Lead[] |
(required) |
next_cursor |
NextCursor |
Pass back as cursor for the next page; null on the last page. (required) |
NextCursor
Pass back as cursor for the next page; null on the last page.
string | null.