For AI agents: markdown of this page — /docs-content-en/entities/leads/move.md documentation index — /llms.txt
Move lead to another status
POST /v1/leads/:id/move
Moves a lead to another status — from a new request to in-progress, for example.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionLead ID. List: GET /v1/leads |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldstatusId |
Typestring | Requiredno | DescriptionIdentifier of the target status. List: GET /v1/statuses?filter[entityId]=STATUS |
FieldstageId |
Typestring | Requiredno | DescriptionA second name for the same field. Accepted interchangeably with statusId and means the same status |
Fields outside the table are ignored.
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/leads/42/move" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"statusId": "IN_PROCESS"
}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/leads/42/move" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"statusId": "IN_PROCESS"
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/42/move', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
statusId: 'IN_PROCESS',
}),
})
const { success, data } = await res.json()
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/42/move', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
statusId: 'IN_PROCESS',
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue on a successful call |
Fielddata |
Typeobject | DescriptionThe lead after the call, all fields — see Lead fields |
Fielddata.stageId |
Typestring | DescriptionThe status of the lead after the call. The value arrives in this field regardless of which name it was passed under in the request body |
Fielddata.movedTime |
Typestring | DescriptionTimestamp of the last status change, ISO 8601 |
Response example
The main fields are shown.
{
"success": true,
"data": {
"id": 42,
"title": "Website request",
"name": "Maria",
"stageId": "IN_PROCESS",
"stageSemanticId": "P",
"assignedById": 1,
"movedBy": 1,
"movedTime": "2026-08-25T10:47:20+00:00",
"updatedTime": "2026-08-25T10:47:20.000Z",
"entityTypeId": 1
}
}
Error response example
404 — no lead with that id:
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Item not found"
}
}
422 — the status that was sent was not applied (a value absent from the dictionary, for example). By that point the write had already reached Bitrix24 and the record had been re-read, so the refusal carries the re-read lead in data, and error.details carries the list of unapplied fields with their current values:
{
"success": false,
"error": {
"code": "STAGE_NOT_APPLIED",
"message": "Bitrix24 accepted the write but did not apply it: stageId requested \"BOGUS_STATUS\", still \"NEW\" after re-read. The value is likely not a valid id for this lead — check GET /v1/statuses?filter[entityId]=... (or GET /v1/deal-categories for a pipeline id) for the valid set before retrying. The record was already written and re-read: any OTHER field in the same request may have been applied, so correct the value and send only what still needs changing rather than repeating the whole body.",
"details": {
"unappliedFields": ["stageId"],
"currentValues": {
"stageId": "NEW"
}
}
},
"data": {
"id": 42,
"title": "Website request",
"name": "Maria",
"stageId": "NEW",
"entityTypeId": 1
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionNo lead with the given id |
| HTTP422 | CodeSTAGE_NOT_APPLIED |
DescriptionThe statusId or stageId that was sent was not applied: after the call the status was still the old one, for example with a value absent from the dictionary. Details are in error.message and error.details. The re-read lead is in data |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionBitrix24 rejected the call itself (not the status value specifically) — a malformed field, for example. The reason arrives in error.message, the machine-readable Bitrix24 code in error.b24Code |
| HTTP403 | CodeBITRIX_ACCESS_DENIED |
DescriptionBitrix24 denied access to the lead |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key lacks the crm scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionA key in read-only mode called a write method |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe API key has no configured tokens |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRequest limit exceeded. The response carries a Retry-After header with the recommended pause |
Full list of common API errors — Errors.
Known specifics
- An empty body is not an error. A call with no
statusId/stageIdin the body returns200, and the lead keeps its previous status: there is nothing to compare, so this is notSTAGE_NOT_APPLIED— the platform only verifies the fields that were actually sent.