Skip to content

List leads

GET
/leads
curl --request GET \
--url 'https://app.whatsetter.com/api/v1/leads?status=qualified&channel=whatsapp&source=instagram&limit=25' \
--header 'Authorization: Bearer <token>'

Leads of the workspace, most recently active first.

Like the dashboard, the listing leaves out the participants of group-purpose campaigns (purpose: group in GET /campaigns) unless you filter on that campaign_id explicitly. Requires scope leads:read.

status
string
Allowed values: qualified in_progress not_interested cold pending stopped queued

Filter by status.

campaign_id
string

Filter by campaign. Accepts the campaign’s campaign_id slug or its document id (both returned by GET /campaigns).

phone
string

Exact lookup by phone (international format, e.g. +33612345678).

external_reference
string
<= 255 characters

Exact lookup by the id you sent on POST /campaigns/{id}/leads. The supported way to resolve “which WhatSetter lead is my record #4471?”.

channel
string
Allowed values: whatsapp instagram

Only leads reached on this channel. whatsapp also returns leads created before the channel column existed, so it always means “everything that is not Instagram”.

since
string format: date-time

Only leads active after this ISO-8601 date (on last_message_at).

source
string
Allowed values: instagram facebook tiktok youtube linkedin x snapchat pinterest google website email sms qr ads other direct list api webhook inbound manual

Where the lead came from (see the source field). Exact match on the stored value — leads created before origins were recorded stay out of a filtered listing.

tracked_link_id
string
<= 64 characters

Only leads brought by this tracked WhatsApp link (Dashboard → Liens).

limit
integer
default: 25 >= 1 <= 100
cursor
string

Opaque cursor from the previous page’s pagination.next_cursor.

Page of leads

Media typeapplication/json
object
data
Array<object>
object
id
string
phone

Digits with country code, no +

string | null
whatsapp_id
string | null
name
string | null
status
string | null
Allowed values: qualified in_progress not_interested cold pending stopped queued unknown
qualified
boolean
qualified_at
string | null format: date-time
replied
boolean
campaign_id
string | null
list_id
string | null
source

Where the lead came from. A platform value means the prospect reached WhatsApp through one of your tracked links (Dashboard → Liens) and the platform was read on the click (direct = through a link, no platform signature); list = campaign sender, api = POST /campaigns/{id}/leads, webhook = form or integration push, inbound = wrote first without a matching click, instagram with channel: instagram = Instagram automation. null on leads created before origins were recorded — derive from list_id, external_reference and channel for those.

string | null
Allowed values: instagram facebook tiktok youtube linkedin x snapchat pinterest google website email sms qr ads other direct list api webhook inbound manual
source_confidence

How the origin was established: certain (a dedicated number, a Meta ad signal, or the click’s fingerprint in the first message), probable (the most recent click on this number’s links within 45 minutes), null when no click was involved.

string | null
Allowed values: certain probable
tracked_link_id

Id of the tracked WhatsApp link that brought this lead, when one did.

string | null
external_reference

The id you sent on POST /campaigns/{id}/leads. null for leads created from the dashboard (lists, CSV import, sales-page forms).

string | null
channel

Where this conversation happens. Always set — leads that predate the channel column are reported as whatsapp.

string
Allowed values: whatsapp instagram
ig_username

Instagram handle, without the @. null on WhatsApp, where phone carries the identity. On Instagram phone is meaningless: id_lead holds an IGSID, not a number.

string | null
email
string | null
tags
Array<string>
messages_count
integer
booking_status
string | null
assigned_to

Id of the team member who owns the lead (GET /team/members); null = nobody, the AI handles it.

string | null
stage

Where the person is commercially, derived exactly like the dashboard: booked when a meeting is on the calendar, else from the status (qualified, not_interested, stopped, cold, waiting), else conversation if they replied, else contacted.

string
Allowed values: contacted conversation waiting qualified booked not_interested cold stopped
deal_status

The outcome, set by people (PATCH /leads/{id}); null when never set.

string | null
Allowed values: open won lost
lost_reason
string | null
Allowed values: price timing unqualified competitor unreachable other
next_action_at
string | null format: date-time
next_action_label
string | null
first_contact_at
string | null format: date-time
last_message_at
string | null format: date-time
last_message_direction
string | null
Allowed values: inbound outbound
created_at
string format: date-time
updated_at
string format: date-time
pagination
object
has_more
boolean
next_cursor
string | null
Example
{
"data": [
{
"status": "qualified",
"source": "instagram",
"source_confidence": "certain",
"channel": "whatsapp",
"stage": "contacted",
"deal_status": "open",
"lost_reason": "price",
"last_message_direction": "inbound"
}
]
}

Missing, unknown or revoked API key

Media typeapplication/json
object
error
object
code
string
message
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

The key lacks the required scope

Media typeapplication/json
object
error
object
code
string
message
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Invalid parameter or body (also an invalid or expired cursor)

Media typeapplication/json
object
error
object
code
string
message
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}