For AI agents: markdown of this page — /docs-content-en/entities/deals/contacts-create.md documentation index — /llms.txt
Link a contact to a deal
POST /v1/deals/:id/contacts
Links one contact to a deal; the deal's other contacts stay linked.
To set the full list of contacts in one call, use PUT /v1/deals/:id/contacts.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionDeal ID. List: GET /v1/deals |
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 "2923" |
FieldisPrimary |
Typeboolean | Requiredno | DescriptionMake the contact primary; the flag is removed from the previous primary contact. The first contact of a deal 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/deals/8785/contacts" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactId": 2923, "isPrimary": true, "sort": 20 }'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/deals/8785/contacts" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "contactId": 2923, "isPrimary": true, "sort": 20 }'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/deals/8785/contacts', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ contactId: 2923, isPrimary: true, sort: 20 }),
})
const { success, data } = await res.json()
console.log('Deal contacts:', data.length)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/deals/8785/contacts', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ contactId: 2923, 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 deal after linking, ordered by sort |
Fielddata[].contactId |
Typenumber | DescriptionContact ID. Get the contact: GET /v1/contacts/:id |
Fielddata[].isPrimary |
Typeboolean | DescriptionPrimary contact of the deal. true on exactly one link |
Fielddata[].sort |
Typenumber | DescriptionPosition of the contact in the list |
Fielddata[].roleId |
Typenumber | DescriptionRole of the contact in the deal. The link methods do not save it |
Response example
A second contact is linked to a deal that had one contact, and the new one becomes primary:
{
"success": true,
"data": [
{ "contactId": 2921, "sort": 10, "isPrimary": false, "roleId": 0 },
{ "contactId": 2923, "sort": 20, "isPrimary": true, "roleId": 0 }
]
}
Error response example
409 — the contact is already linked to this deal:
{
"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 deal with this id |
| HTTP409 | CodeRELATION_ALREADY_EXISTS |
DescriptionThe contact is already linked to this deal |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionNo Bitrix24 tokens are attached to the key |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key lacks the crm scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is read-only. 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 deal's list of links. Before linking, check the contact with
GET /v1/contacts/:id. - The role is not saved. A
roleIdfield in the body is accepted without an error but is not saved: the new link comes back withroleIdequal to0. - Changing an already linked contact. Linking the same contact again returns
409. Change the primary contact or the order of linked contacts throughPUT /v1/deals/:id/contactsand pass the whole required set initems: contacts left out are unlinked.