## Dependencies of several tasks

`POST /v1/tasks/dependencies/bulk`

Returns predecessors for several tasks at once, up to 50 per call.

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `taskIds` | array | yes | Task IDs — numbers or decimal strings: `"4203"` equals `4203`. Up to 500 elements and up to 50 unique IDs; duplicates are counted once. Task list: [`GET /v1/tasks`](/docs/entities/tasks/list) |

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/dependencies/bulk" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "taskIds": [4203, "4201", 4203, 999999999]
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/dependencies/bulk" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "taskIds": [4203, "4201", 4203, 999999999]
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/dependencies/bulk', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    taskIds: [4203, '4201', 4203, 999999999],
  }),
})

const { success, data, meta } = await res.json()
for (const [taskId, deps] of Object.entries(data.results)) {
  console.log(taskId, 'depends on', deps.map((dep) => dep.id))
}
for (const [taskId, error] of Object.entries(data.errors)) {
  console.log(taskId, 'could not be read:', error.code)
}
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/dependencies/bulk', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    taskIds: [4203, '4201', 4203, 999999999],
  }),
})

const { success, data, meta } = await res.json()
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` if the request was accepted. Refusals for individual tasks are in `data.errors` |
| `data.results` | object | Task dependencies: the key is the task ID as a string, the value is an array of predecessors |
| `data.results.<taskId>[].id` | number | ID of the predecessor task. Get: [`GET /v1/tasks/:id`](/docs/entities/tasks/get) |
| `data.results.<taskId>[].title` | string \| null | Title of the predecessor task. `null` if Bitrix24 did not return it |
| `data.errors` | object | Refusals by task: the key is the task ID as a string, the value is an error object |
| `data.errors.<taskId>.code` | string | Refusal code — one of five, see "Refusals for individual tasks" below |
| `data.errors.<taskId>.message` | string | Refusal text |
| `meta.requested` | number | Number of unique IDs in the request: duplicates are counted once. Always equals `succeeded + failed` |
| `meta.succeeded` | number | How many tasks were read |
| `meta.failed` | number | How many tasks ended up in `data.errors` |
| `meta.direction` | string | Always `predecessors` |
| `meta.source` | string | Always `RELATED_TASKS` |

## Response example

The request from the examples: the duplicate `4203` is counted once, the string `"4201"` is read as a number, and task `999999999` does not exist.

```json
{
  "success": true,
  "data": {
    "results": {
      "4201": [],
      "4203": [
        {
          "id": 4199,
          "title": "Prepare the estimate"
        },
        {
          "id": 4201,
          "title": "Approve the budget"
        }
      ]
    },
    "errors": {
      "999999999": {
        "code": "TASK_NOT_FOUND",
        "message": "Task not found."
      }
    }
  },
  "meta": {
    "requested": 3,
    "succeeded": 2,
    "failed": 1,
    "direction": "predecessors",
    "source": "RELATED_TASKS"
  }
}
```

## Error response example

400 — `taskIds` contains more than 50 unique IDs:

```json
{
  "success": false,
  "error": {
    "code": "BATCH_LIMIT_EXCEEDED",
    "message": "taskIds carries 51 unique ids; at most 50 are accepted"
  }
}
```

## Errors

Refusals of the whole request:

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `BATCH_LIMIT_EXCEEDED` | More than 50 unique IDs. Message `taskIds carries N unique ids; at most 50 are accepted` |
| 400 | `BATCH_LIMIT_EXCEEDED` | More than 500 elements in the original array; checked before the elements are parsed. Message `taskIds carries N elements; at most 500 are read, and at most 50 unique ids are accepted` |
| 400 | `INVALID_PARAMS` | An element is not a positive integer. The message names its position in the original array, counting from zero: `taskIds[1] must be a positive integer id …` |
| 400 | `INVALID_REQUEST` | The body is not a JSON object. Message `Request body must be an object with a taskIds array` |
| 400 | `INVALID_REQUEST` | `taskIds` is missing, is not an array, or the array is empty. A request without a body gets the same response. Message `taskIds must be a non-empty array` |
| 401 | `MISSING_API_KEY` | `X-Api-Key` was not passed |
| 401 | `TOKEN_MISSING` | The key has no Bitrix24 tokens |
| 403 | `SCOPE_DENIED` | The key has no `task` scope |
| 415 | `FST_ERR_CTP_INVALID_MEDIA_TYPE` | A non-empty body with a `Content-Type` other than `application/json` |
| 429 | `RATE_LIMITED` | Bulk call rate exceeded. Retry the request after the delay given in the `retry-after` header |

Refusals for individual tasks arrive in `data.errors` with a `200` response — even when every task is refused. Check `data.errors`, not only `data.results`:

| Code | Description |
|-----|----------|
| `TASK_NOT_FOUND` | The task does not exist or is not visible to the key |
| `RATE_LIMITED` | Bitrix24 throttled this sub-call. Retry later |
| `OPERATION_TIME_LIMIT` | Bitrix24 asked to reduce the load. Retry later |
| `UPSTREAM_INCOMPLETE` | No usable response was received for this task |
| `DEPENDENCY_LIMIT_EXCEEDED` | The task has more than 1000 dependencies |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

**The rate limit applies per Bitrix24 account, not per key.** The bulk call is limited to 30 requests per minute per Bitrix24 account. All keys of one account share the limit, and refused requests count toward it too. The limit is divided across the platform's replicas: the effective value is in the `x-ratelimit-limit` header, and the number of requests left is in `x-ratelimit-remaining`.

## See also

- [Task dependencies](/docs/entities/tasks/dependencies)
- [Dependencies of one task](/docs/entities/tasks/dependencies-list)
- [List tasks](/docs/entities/tasks/list)
- [Update task](/docs/entities/tasks/update)
