Skip to content

Update a lead

PATCH
/leads/{id}
curl --request PATCH \
--url https://app.whatsetter.com/api/v1/leads/example \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "assigned_to": "66a1f2c3d4e5f60718293a4b", "next_action_at": "2026-09-22T09:00:00.000Z", "next_action_label": "Call back", "deal_status": "open" }'

Update a lead from your CRM: status, tags, owner, next action and outcome. Only the fields you send change; at least one is required. Setting status to qualified stamps the qualification date (once).

  • assigned_to: the id of a workspace member (GET /team/members), or null to release the lead. Any other value answers 422.
  • next_action_at / next_action_label: the next human step. null on next_action_at clears both; a label needs a date.
  • deal_status: open / won / lost. A lost deal needs a lost_reason from the dashboard’s list (price, timing, unqualified, competitor, unreachable, other); it is cleared when the deal is open or won.

Every owner / next-action / outcome change is written to the lead’s journal, by the API key’s name, exactly like an edit from the dashboard. Requires scope leads:write.

id
required
string
Media typeapplication/json
object
status
string
Allowed values: qualified in_progress not_interested cold pending stopped queued
tags
Array<string>
<= 20 items
assigned_to

A member id from GET /team/members, or null to unassign.

string | null
next_action_at

ISO 8601, or null to clear the next action.

string | null format: date-time
next_action_label

Short label for the next action (needs next_action_at).

string | null
<= 80 characters
deal_status
string
Allowed values: open won lost
lost_reason

Required when deal_status is lost; ignored otherwise.

string | null
Allowed values: price timing unqualified competitor unreachable other
Example
{
"assigned_to": "66a1f2c3d4e5f60718293a4b",
"next_action_at": "2026-09-22T09:00:00.000Z",
"next_action_label": "Call back",
"deal_status": "open"
}

The updated lead

Media typeapplication/json
object
data
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
Example
{
"data": {
"id": "68e0a1b2c3d4e5f6a7b8c9d0",
"phone": "33612345678",
"whatsapp_id": "33612345678@c.us",
"name": "Marie Dupont",
"status": "in_progress",
"qualified": false,
"qualified_at": null,
"replied": true,
"campaign_id": "auto24-maroc-4-bu76",
"list_id": null,
"source": "instagram",
"source_confidence": "certain",
"tracked_link_id": "68d9aa11bb22cc33dd44ee55",
"external_reference": "4471",
"channel": "whatsapp",
"ig_username": null,
"email": "marie@acme.fr",
"tags": [
"hot"
],
"messages_count": 7,
"booking_status": null,
"assigned_to": "66a1f2c3d4e5f60718293a4b",
"stage": "conversation",
"deal_status": "open",
"lost_reason": null,
"next_action_at": "2026-09-22T09:00:00.000Z",
"next_action_label": "Call back",
"first_contact_at": "2026-09-15T10:02:11.000Z",
"last_message_at": "2026-09-18T16:40:03.000Z",
"last_message_direction": "inbound",
"created_at": "2026-09-15T10:02:11.000Z",
"updated_at": "2026-09-19T08:12:45.000Z"
}
}

Missing, unknown or revoked API key

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

Resource not found in this workspace

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

Invalid field, unknown member id, or nothing to update

Media typeapplication/json
object
error
object
code
string
message
string
Example
{
"error": {
"code": "validation_error",
"message": "\"assigned_to\" must be the id of a member of this workspace (see GET /team/members), or null."
}
}