For AI agents: markdown of this page — /docs-content-en/entities/leads/contacts-create.md documentation index — /llms.txt
Link a contact to a lead
POST /v1/leads/:id/contacts
Links one contact to a lead. The lead's other contacts stay linked.
To set the full list of contacts in one call, use PUT /v1/leads/:id/contacts.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionLead ID. List: GET /v1/leads |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldcontactId |
Typenumber | Requiredyes | DescriptionContact ID. List: GET /v1/contacts. A string of digits is also accepted, for example "2939" |
FieldisPrimary |
Typeboolean | Requiredno | DescriptionMake the contact primary. The previous primary contact loses the flag. The first contact of a lead becomes primary regardless of the value |
Fieldsort |
Typenumber | Requiredno | DescriptionPosition of the contact in the list. If omitted, the link goes to the end of the list |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/leads/1001321/contacts" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactId": 2939, "isPrimary": true, "sort": 20 }'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/leads/1001321/contacts" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "contactId": 2939, "isPrimary": true, "sort": 20 }'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/1001321/contacts', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ contactId: 2939, isPrimary: true, sort: 20 }),
})
const { success, data } = await res.json()
console.log('Lead contacts:', data.length)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/1001321/contacts', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ contactId: 2939, isPrimary: true, sort: 20 }),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typearray | DescriptionAll links of the lead after linking, in sort order |
Fielddata[].contactId |
Typenumber | DescriptionContact ID. Get the contact: GET /v1/contacts/:id |
Fielddata[].isPrimary |
Typeboolean | DescriptionPrimary contact of the lead. true for exactly one link |
Fielddata[].sort |
Typenumber | DescriptionPosition of the contact in the list |
Fielddata[].roleId |
Typenumber | DescriptionRole of the contact in the lead. The link methods do not store it |
Response example
A second contact is linked to a lead that had one contact, and the new contact becomes primary:
{
"success": true,
"data": [
{ "contactId": 2937, "sort": 10, "isPrimary": false, "roleId": 0 },
{ "contactId": 2939, "sort": 20, "isPrimary": true, "roleId": 0 }
]
}
Error response example
409 — the contact is already linked to this lead:
{
"success": false,
"error": {
"code": "RELATION_ALREADY_EXISTS",
"message": "This binding already exists"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
Descriptionid is not a positive integer |
| HTTP400 | CodeMISSING_REQUIRED_FIELDS |
DescriptioncontactId is missing or is not a positive integer |
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionNo lead with this id exists |
| HTTP409 | CodeRELATION_ALREADY_EXISTS |
DescriptionThe contact is already linked to this lead |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe key has no Bitrix24 tokens attached |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key does not have the crm scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is in read-only mode. Linking requires a key with write access |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRate limit exceeded. Retry after the delay in the Retry-After header |
| HTTP502 | CodeBITRIX_UNAVAILABLE |
DescriptionBitrix24 is unavailable. Retry the request later |
Full list of common API errors — Errors.
Known specifics
- Contact existence is not checked. An ID that matches no contact is linked without an error and appears in the lead's list of links. Before linking, check the contact with
GET /v1/contacts/:id. - The role is not stored. The
roleIdfield in the body is accepted without an error but is not stored: in the response, the new link hasroleIdequal to0. - Replacement changes the primary contact and the order. Change the primary contact or the order of already linked contacts with
PUT /v1/leads/:id/contactsand pass the full desired list initems: contacts missing fromitemsare unlinked.PATCH /v1/leads/:idwith thecontactIdof an already linked contact responds with200but does not change the primary contact.