# Related data (include)

Load related entities together with the primary records in a single request. Instead of separate calls to fetch a contact, company, or assignee — pass the `include` parameter, and Vibecode returns everything in the `_included` field.

> The `include` parameter is optional and works in three places:
> - `GET /v1/{entity}/{id}?include=...` — fetch a single record
> - `GET /v1/{entity}?include=...` — fetch a list
> - `POST /v1/{entity}/search` — search (`include` in the request body as an array of strings)

## How to use

List relation names separated by commas:

### curl

```bash
curl "https://vibecode.bitrix24.com/v1/deals/741?include=contact,company" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### JavaScript

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/deals/741?include=contact,company', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()

// data._included.contacts — array of deal contacts
// data._included.company  — company (object or null)
```

Related data appears in the `_included` field of each record:

```json
{
  "success": true,
  "data": {
    "id": 741,
    "title": "Equipment delivery",
    "contactId": 71,
    "companyId": 15,
    "_included": {
      "contacts": [
        {
          "id": 71,
          "name": "John",
          "lastName": "Brown",
          "phone": [{ "VALUE": "+12025550123" }],
          "isPrimary": true,
          "sort": 10
        }
      ],
      "company": {
        "id": 15,
        "title": "Acme LLC",
        "industry": "IT"
      }
    }
  }
}
```

## Two types of relations

### One-to-one

The entity holds a reference field to the related object (for example, `companyId` on a contact). The result is a single object or `null`.

```
GET /v1/leads/50?include=contact
```

```json
{
  "data": {
    "id": 50,
    "title": "Website request",
    "contactId": 71,
    "_included": {
      "contact": {
        "id": 71,
        "name": "John",
        "lastName": "Brown"
      }
    }
  }
}
```

If the reference field is empty or equals 0, `null` is returned:

```json
{
  "_included": {
    "contact": null
  }
}
```

### Many-to-many

A relation through an intermediate table. The result is an array of objects with additional relation fields.

```
GET /v1/deals/741?include=contact
```

```json
{
  "_included": {
    "contacts": [
      {
        "id": 71,
        "name": "John",
        "lastName": "Brown",
        "isPrimary": true,
        "sort": 10,
        "roleId": 0
      },
      {
        "id": 85,
        "name": "Maria",
        "lastName": "Davis",
        "isPrimary": false,
        "sort": 20,
        "roleId": 0
      }
    ]
  }
}
```

Note: the relation name in the request is `contact` (singular), while in the response it is `contacts` (plural). Vibecode automatically pluralizes the name for arrays.

Additional relation fields (`isPrimary`, `sort`, `roleId`) are added to each object — their values come from the intermediate table, not from the entity itself.

## Usage in lists and search

### curl — list

```bash
curl "https://vibecode.bitrix24.com/v1/deals?limit=10&include=company" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### JavaScript — list

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/deals?limit=10&include=company', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data, meta } = await res.json()

for (const deal of data) {
  console.log(deal.title, '—', deal._included.company?.title ?? 'no company')
}
// meta.includeSkipped === true if records > 200
```

Response:

```json
{
  "success": true,
  "data": [
    {
      "id": 741,
      "title": "Equipment delivery",
      "companyId": 15,
      "_included": {
        "company": { "id": 15, "title": "Acme LLC" }
      }
    },
    {
      "id": 742,
      "title": "Tech support",
      "companyId": 15,
      "_included": {
        "company": { "id": 15, "title": "Acme LLC" }
      }
    }
  ],
  "meta": { "total": 150, "hasMore": true }
}
```

Vibecode deduplicates requests: if several records reference the same company, it is loaded once.

### curl — search

In search, `include` is passed in the request body as an array.

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/deals/search" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "stageId": "NEW", "amount": { "$gte": 100000 } },
    "include": ["contact", "company"],
    "limit": 50
  }'
```

### JavaScript — search

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/deals/search', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { stageId: 'NEW', amount: { $gte: 100000 } },
    include: ['contact', 'company'],
    limit: 50,
  }),
})
const { data } = await res.json()
```

## Multiple relations in one request

You can request up to 3 relations at once:

```
GET /v1/quotes/18?include=deal,contact,company
```

```json
{
  "_included": {
    "deal": { "id": 741, "title": "Equipment delivery" },
    "contact": { "id": 71, "name": "John", "lastName": "Brown" },
    "company": { "id": 15, "title": "Acme LLC" }
  }
}
```

## Limits

| Parameter | Value |
|----------|---------|
| Maximum relations per request | 3 |
| Maximum records for include | 200 |

If a list or search has more than 200 records, include is **skipped** and a flag is added to `meta`:

```json
{
  "data": [ ... ],
  "meta": {
    "hasMore": true,
    "includeSkipped": true
  }
}
```

To get related data for large result sets — reduce `limit` to 200 or less.

## Available relations per entity

You can find the available includes for a specific entity via the fields endpoint:

```bash
curl "https://vibecode.bitrix24.com/v1/deals/fields" \
  -H "X-Api-Key: YOUR_API_KEY"
```

The response contains an `include` field with the list of available relations:

```json
{
  "success": true,
  "data": {
    "fields": { ... },
    "include": ["contact", "company"]
  }
}
```

Available relations depend on the entity. Which includes a specific entity supports is stated in each method's documentation and in the `GET /v1/{entity}/fields` response (the `include` field).

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INCLUDE_LIMIT_EXCEEDED` | More than 3 relations requested |
| 400 | `INVALID_INCLUDE` | Relation not found. The response contains the list of available relations |

If an entity has no relations at all (for example, `departments`), any `include` returns `INVALID_INCLUDE` with an empty `Available:` list.

Error example:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_INCLUDE",
    "message": "Unknown include 'manager'. Available: contact, company, quote"
  }
}
```

## Related sections

- [Entity API](./entity-api.md) — CRUD operations, pagination, aggregation
- [Filtering](./filtering.md) — three filter syntaxes
- [Batch API](./batch.md) — combining calls
- [All entities](./entities-index.md) — full list of entities
- [Error codes](./errors.md) — platform error reference
