## Create a flow

`POST /v1/tasks/flows`

Creates a task flow — a shared queue from which tasks go to the responsible employees. Flow fields are passed in the `flowData` object and sent to Bitrix24 unchanged.

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `flowData` | object | yes | Flow fields |
| `flowData.name` | string | yes | Flow name. You cannot create two flows with the same name in one Bitrix24 account |
| `flowData.plannedCompletionTime` | number | yes | Time to complete a task, in seconds, for example `86400` — one day |
| `flowData.distributionType` | string | yes | How tasks reach assignees: `manually` — a moderator assigns them, `queue` — in turn among the employees in `responsibleList`, `himself` — employees take tasks themselves |
| `flowData.responsibleList` | array | yes | Who receives the tasks: an array of pairs like `["user", "3"]`, where the second element is the employee ID as a string. With `manually`, the list holds the flow moderator. List: [`GET /v1/users`](/docs/entities/users/list) |
| `flowData.groupId` | number | no | ID of the workgroup the flow is bound to. List: [`GET /v1/workgroups`](/docs/entities/workgroups/list). If the field is not passed, a new group named after the flow is created |
| `flowData.ownerId` | number | no | Flow administrator ID. List: [`GET /v1/users`](/docs/entities/users/list). If the field is not passed, the employee on whose behalf the request is made becomes the administrator |
| `flowData.description` | string | no | Flow description. Defaults to an empty string |
| `flowData.taskCreators` | array | no | Who can submit tasks to the flow: an array of pairs. `[["meta-user", "all-users"]]` — all employees |
| `flowData.matchWorkTime` | number | no | `1` — weekends and holidays are skipped when the deadline is calculated, `0` — they are counted. Defaults to `1` |
| `flowData.responsibleCanChangeDeadline` | number | no | `1` — the assignee can change the task deadline, `0` — cannot. Defaults to `1` |
| `flowData.taskControl` | number | no | `1` — a completed task goes to its creator for review, `0` — no review. Defaults to `0` |
| `flowData.notifyAtHalfTime` | number | no | `1` — remind the assignee halfway to the deadline, `0` — no reminder. Defaults to `0` |
| `flowData.notifyOnQueueOverflow` | number | no | Notify the flow administrator when the number of tasks in the queue exceeds this value. Defaults to `null` — no notification |
| `flowData.notifyOnTasksInProgressOverflow` | number | no | Notify the flow administrator when the number of tasks in progress exceeds this value. Defaults to `null` — no notification |
| `flowData.notifyWhenEfficiencyDecreases` | number | no | Notify the flow administrator when efficiency drops below this value, in percent. Defaults to `null` — no notification |
| `analyticsParams` | object | no | Internal Bitrix24 analytics tags. They do not affect the flow |

The body must not contain keys other than `flowData` and `analyticsParams`. The `matchWorkTime`, `responsibleCanChangeDeadline`, `taskControl`, and `notifyAtHalfTime` flags are passed as the numbers `1` and `0` and come back in the response as `true` and `false`.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/flows" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowData": {
      "name": "Request processing",
      "description": "Customer requests from the website",
      "plannedCompletionTime": 86400,
      "distributionType": "queue",
      "responsibleList": [["user", "3"]]
    }
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/flows" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "flowData": {
      "name": "Request processing",
      "description": "Customer requests from the website",
      "plannedCompletionTime": 86400,
      "distributionType": "queue",
      "responsibleList": [["user", "3"]]
    }
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/flows', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    flowData: {
      name: 'Request processing',
      description: 'Customer requests from the website',
      plannedCompletionTime: 86400,
      distributionType: 'queue',
      responsibleList: [['user', '3']],
    },
  }),
})

const { success, data } = await res.json()
if (success) {
  console.log('Flow ID:', data.id, 'Group ID:', data.groupId)
}
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/flows', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    flowData: {
      name: 'Request processing',
      description: 'Customer requests from the website',
      plannedCompletionTime: 86400,
      distributionType: 'queue',
      responsibleList: [['user', '3']],
    },
  }),
})

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

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on success |
| `data` | object | The created flow. The set of fields is the same as in the [`GET /v1/tasks/flows/:flowId`](/docs/entities/tasks/flows-get) response |
| `data.id` | number | ID of the new flow |
| `data.creatorId` | number | ID of the employee on whose behalf the request was made |
| `data.ownerId` | number | Flow administrator ID |
| `data.groupId` | number | ID of the flow's workgroup. If the request had no `groupId`, the ID of the created group |
| `data.active` | boolean | `true` — the flow is enabled. A new flow is created enabled |
| `data.efficiency` | number | Flow efficiency in percent. For a new flow — `100` |
| `data.activity` | string | Date and time of the flow's activity in ISO 8601 format. For a new flow — the moment of creation |
| `data.taskCreators` | array | An empty array, even if `taskCreators` was passed in the request. The saved value is returned by [`GET /v1/tasks/flows/:flowId`](/docs/entities/tasks/flows-get) |
| `data.team` | array | An empty array. The flow team is returned by [`GET /v1/tasks/flows/:flowId`](/docs/entities/tasks/flows-get) |

Fields from the request come back with the passed values; fields that were not passed come back with the defaults from the request fields table.

## Response example

```json
{
  "success": true,
  "data": {
    "id": 20,
    "creatorId": 1,
    "ownerId": 1,
    "groupId": 178,
    "templateId": 0,
    "efficiency": 100,
    "active": true,
    "plannedCompletionTime": 86400,
    "activity": "2026-10-20T00:23:04+00:00",
    "name": "Request processing",
    "description": "Customer requests from the website",
    "distributionType": "queue",
    "responsibleList": [
      ["user", "3"]
    ],
    "demo": false,
    "responsibleCanChangeDeadline": true,
    "matchWorkTime": true,
    "matchSchedule": false,
    "taskControl": false,
    "notifyAtHalfTime": false,
    "notifyOnQueueOverflow": null,
    "notifyOnTasksInProgressOverflow": null,
    "notifyWhenEfficiencyDecreases": null,
    "taskCreators": [],
    "team": [],
    "trialFeatureEnabled": false
  }
}
```

## Error response example

422 — the required `distributionType` field is not passed:

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "Property distributionType cannot be null",
    "b24Code": "0"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | The body is not an object or contains keys other than `flowData` and `analyticsParams`. Message: `body must be an object with supported fields only` |
| 400 | `INVALID_PARAMS` | `flowData` is not passed or is not an object. Message: `flowData must be an object` |
| 400 | `INVALID_PARAMS` | `analyticsParams` is not an object. Message: `analyticsParams must be an object` |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 401 | `INVALID_API_KEY` | The key is not found |
| 401 | `TOKEN_MISSING` | The key has no Bitrix24 tokens |
| 403 | `SCOPE_DENIED` | The key has neither the `task` nor the `tasks` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is in read-only mode. `error.details.switchUrl` holds the address of the section where the mode is changed |
| 422 | `BITRIX_ERROR` | A required field is not passed. Messages: `Property name cannot be null`, `Property plannedCompletionTime cannot be null`, `Property distributionType cannot be null`, `'responsibleList': field's value must not be empty` |
| 422 | `BITRIX_ERROR` | `distributionType` is not one of `manually`, `queue`, `himself`. Message: `distributionType: unexpected value` |
| 422 | `BITRIX_ERROR` | `groupId` is not passed, and a group with the same name as the flow already exists on the portal, including one left over from a deleted flow. Message: `A group with this name already exists`, `error.b24Code` is `ERROR_GROUP_NAME_EXISTS` |
| 429 | `RATE_LIMITED` | The request rate to Bitrix24 or to the platform is exceeded. Retry after the delay in the `Retry-After` header |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 is unreachable or returned a server error |
| 503 | `BITRIX_TIMEOUT` | Bitrix24 did not respond in time |

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

## Known specifics

**Creation is not retried automatically.** The `502 BITRIX_UNAVAILABLE` and `503 BITRIX_TIMEOUT` responses do not tell whether the flow was created, and the platform does not retry such a request on its own. Before sending it again, look for the flow by name in [`GET /v1/tasks/flows`](/docs/entities/tasks/flows-list).

## See also

- [Flows and flow tasks](/docs/entities/tasks/flows)
- [List flows](/docs/entities/tasks/flows-list)
- [Get a flow](/docs/entities/tasks/flows-get)
- [Update a flow](/docs/entities/tasks/flows-update)
- [Toggle flow activity](/docs/entities/tasks/flows-activate)
- [Employees](/docs/entities/users)
- [Workgroups](/docs/entities/workgroups)
