# Contact companies

Links companies to a contact, replaces the whole set, reads the list, and unlinks companies one at a time or all at once. A binding stores the company's position in the list and the primary-company flag. Unlinked companies stay in the CRM.

A contact with companies always has one primary company. Its ID arrives in the contact's `companyId` field, and the IDs of all linked companies arrive in the `companyIds` field in `sort` order. The `companyIds` field is writable: passing it to [`PATCH /v1/contacts/:id`](/docs/entities/contacts/update) replaces the whole set of companies, just like [`PUT /v1/contacts/:id/companies`](./companies-set.md). Companies missing from the array are unlinked.

Bitrix24 API: `crm.contact.company.items.get`, `crm.contact.company.add`, `crm.contact.company.items.set`, `crm.contact.company.delete`, `crm.contact.company.items.delete`
Scope: `crm`

## Operations

- [List contact companies](./companies-list.md) — `GET /v1/contacts/:id/companies`
- [Replace contact companies](./companies-set.md) — `PUT /v1/contacts/:id/companies`
- [Link a company to a contact](./companies-create.md) — `POST /v1/contacts/:id/companies`
- [Unlink a company from a contact](./companies-delete-delete.md) — `DELETE /v1/contacts/:id/companies/:relatedId`
- [Unlink all companies from a contact](./companies-delete.md) — `DELETE /v1/contacts/:id/companies`

## Key fields

Fields of a single contact–company binding. They arrive in every `data` element, and `companyId`, `isPrimary`, and `sort` can be passed when linking and replacing.

| Field | Description |
|------|----------|
| `companyId` | Company ID. List: [`GET /v1/companies`](/docs/entities/companies/list) |
| `isPrimary` | The contact's primary company. `true` on exactly one binding |
| `sort` | The company's position in the list. The list of bindings arrives sorted by this field |
| `roleId` | Binding role. `roleId` from the request is not saved; the response has `0` |

## What to know before you start

1. **A contact with companies always has a primary one.** The first linked company becomes primary, even if `isPrimary: false` is passed. `isPrimary: true` when linking or replacing moves the flag to that company. When replacing without `true`, the first element of the `items` array becomes primary, even if it does not have the lowest `sort`. If several elements have `true`, the first of them becomes primary. If you unlink the primary company, the first of the remaining companies in `sort` order becomes primary.
2. **Company existence is not checked.** Linking and replacing accept an ID that does not belong to any company, respond `200`, and save such a binding. Check the ID with [`GET /v1/companies/:id`](/docs/entities/companies/get) before linking.
3. **The list does not check the contact.** For an ID that does not belong to any contact, the list responds `200` with an empty `data` array, as for a contact without companies. Linking, replacing, and both unlink operations respond `404 ENTITY_NOT_FOUND` for such an ID.
4. **Repeated calls behave differently.** Linking the same company again returns `409 RELATION_ALREADY_EXISTS`, unlinking one company again returns `404 ENTITY_NOT_FOUND`, and unlinking all companies again still returns `204`.
5. **Write method responses.** Linking and replacing return the whole list of bindings after the change; both unlink operations return `204 No Content` with an empty body.

## Typical scenario

1. Find a company: [`GET /v1/companies`](/docs/entities/companies/list) with a filter on company fields.
2. See which companies are already linked to the contact: [`GET /v1/contacts/:id/companies`](./companies-list.md).
3. Link a company and, if needed, make it primary: [`POST /v1/contacts/:id/companies`](./companies-create.md) with `isPrimary: true`.
4. Define the whole set at once, for example when syncing with an external system: [`PUT /v1/contacts/:id/companies`](./companies-set.md) with all the required companies in `items`.
5. Read the contact together with the full company records: [`GET /v1/contacts/:id?include=companyBinding`](/docs/entities/contacts/get); the companies are in `data._included.companyBindings`. With `include=company`, only the primary company arrives, in `data._included.company`.

## Limits

| Limit | Value |
|-------|----------|
| List pagination | None: [`GET /v1/contacts/:id/companies`](./companies-list.md) returns all of the contact's bindings in one call |
| List read rate | Route limit: 300 requests per minute per Bitrix24 account; all API keys of the account share one limit. The current route limit is returned in the `x-ratelimit-limit` header |
| Write rate | General API limits — [Limits and optimization](/docs/optimization) |
| Companies per link call | One. To link several companies at once, use [`PUT /v1/contacts/:id/companies`](./companies-set.md) and pass the whole required set in its `items`: companies not passed are unlinked |

## See also

- [Contacts](/docs/entities/contacts)
- [Get contact](/docs/entities/contacts/get)
- [Contact fields](/docs/entities/contacts/fields)
- [Companies](/docs/entities/companies)
- [Company contacts](/docs/entities/companies/contacts)
- [Limits and optimization](/docs/optimization)
