# Scrum: epics, sprints, task placement and kanban stages

Manage scrum in Bitrix24 projects: read sprint lists and the current sprint, create and rename epics, bind tasks to epics, place tasks in the backlog, set story points, manage sprint board columns. Works on top of regular [Tasks](/docs/entities/tasks) — first create the task via `POST /v1/tasks`, then place it in scrum.

**Scope:** `task` | **Base URL:** `https://vibecode.bitrix24.com/v1` | **Auth:** `X-Api-Key`

## Documentation sections

- [Scrum backlogs](/docs/scrum/backlogs) — create, update and delete backlogs
- [Scrum epics](/docs/scrum/epics) — create, read, rename and recolor epics
- [Task placement in scrum](/docs/scrum/tasks) — read and change a task's scrum row: backlog or sprint, epic, story points
- [Sprints](/docs/scrum/sprints) — list sprints, get the current sprint, read one by ID, create, update, complete and delete
- [Scrum kanban stages](/docs/scrum/stages) — the columns of a sprint board
- [Definition of Done](/docs/scrum/dod) — DoD settings and saving DoD lists
- [Sprint metrics](/docs/scrum/metrics) — Bitrix24 source data for charts and team speed

## Quick start

### 1. Create an epic

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/scrum/epics" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Chat folders", "groupId": 7 }'
```

### 2. Bind a task to an epic

The task has already been created via [`POST /v1/tasks`](/docs/entities/tasks/create) and belongs to the scrum project `groupId`. Binding automatically places it into the project backlog:

```bash
curl -X PATCH "https://vibecode.bitrix24.com/v1/scrum/tasks/59" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "epicId": 87 }'
```

## Full example: mirroring an external tracker

Create an epic, add a task in the scrum project, bind it to the epic and verify the placement. The backlog is resolved automatically.

```javascript
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.com/v1'
const GROUP_ID = 7 // scrum project, list: GET /v1/workgroups

// ── 1. Create an epic ───────────────────────────────────────────
const epicRes = await fetch(`${BASE}/scrum/epics`, {
  method: 'POST',
  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Chat folders', groupId: GROUP_ID })
})
const { data: epic } = await epicRes.json()
console.log(`Epic created, ID: ${epic.id}`)

// ── 2. Create a task in the same scrum project ──────────────────
const taskRes = await fetch(`${BASE}/tasks`, {
  method: 'POST',
  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'Lay out the folder list', groupId: GROUP_ID, responsibleId: 1 })
})
const { data: task } = await taskRes.json()
console.log(`Task created, ID: ${task.id}`)

// ── 3. Bind the task to the epic ────────────────────────────────
//     entityId omitted → the task is automatically placed into the project backlog
await fetch(`${BASE}/scrum/tasks/${task.id}`, {
  method: 'PATCH',
  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ epicId: epic.id, storyPoints: '3' })
})

// ── 4. Verify the actual placement ──────────────────────────────
const placeRes = await fetch(`${BASE}/scrum/tasks/${task.id}`, {
  headers: { 'X-Api-Key': VIBE_KEY }
})
const { data: placement } = await placeRes.json()
console.log('Placement:', placement)
```

## Endpoint reference

| Method | Path | Bitrix24 method | Description |
|-------|------|----------------|-------------|
| POST | [`/v1/scrum/epics`](/docs/scrum/epics/create) | tasks.api.scrum.epic.add | Create an epic |
| GET | [`/v1/scrum/epics`](/docs/scrum/epics/list) | tasks.api.scrum.epic.list | List epics |
| GET | [`/v1/scrum/epics/:id`](/docs/scrum/epics/get) | tasks.api.scrum.epic.get | Get an epic |
| PATCH | [`/v1/scrum/epics/:id`](/docs/scrum/epics/update) | tasks.api.scrum.epic.update | Rename / update an epic |
| GET | [`/v1/scrum/tasks/:taskId`](/docs/scrum/tasks/get) | tasks.api.scrum.task.get | Get a task's scrum placement |
| PATCH | [`/v1/scrum/tasks/:taskId`](/docs/scrum/tasks/update) | tasks.api.scrum.task.update | Place / move a task |
| GET | [`/v1/scrum/sprints`](/docs/scrum/sprints/list) | tasks.api.scrum.sprint.list | Sprints of a scrum project |
| GET | [`/v1/scrum/sprints/active`](/docs/scrum/sprints/active) | tasks.api.scrum.sprint.list | Active sprint of a project |
| GET | [`/v1/scrum/sprints/:id`](/docs/scrum/sprints/get) | tasks.api.scrum.sprint.get | Get a sprint by ID |
| GET | [`/v1/scrum/sprints/:sprintId/stages`](/docs/scrum/stages/list) | tasks.api.scrum.kanban.getStages | Columns of a sprint board |
| POST | [`/v1/scrum/sprints/:sprintId/stages`](/docs/scrum/stages/create) | tasks.api.scrum.kanban.addStage | Create a column |
| PATCH | [`/v1/scrum/stages/:stageId`](/docs/scrum/stages/update) | tasks.api.scrum.kanban.updateStage | Update a column |
| GET | [`/v1/scrum/groups/:groupId/dod/settings`](/docs/scrum/dod) | tasks.scrum.DoD.getSettings | Read DoD settings |
| GET | [`/v1/scrum/groups/:groupId/tasks/:taskId/dod/necessary`](/docs/scrum/dod) | tasks.scrum.DoD.isNecessary | Check whether DoD is needed |
| POST | [`/v1/scrum/groups/:groupId/dod/types/:typeId/settings`](/docs/scrum/dod) | tasks.scrum.DoD.saveSettings | Save DoD settings |
| POST | [`/v1/scrum/tasks/:taskId/dod/:typeId`](/docs/scrum/dod) | tasks.scrum.DoD.saveList | Save a task's DoD list |
| GET | [`/v1/scrum/groups/:groupId/burn-down`](/docs/scrum/metrics) | tasks.scrum.Sprint.getBurnDownInfo | Burn-down source data |
| GET | [`/v1/scrum/groups/:groupId/team-speed`](/docs/scrum/metrics) | tasks.scrum.Sprint.getTeamSpeedInfo | Completed-sprint flag |
| POST | [`/v1/scrum/backlogs`](/docs/scrum/backlogs/create) | tasks.api.scrum.backlog.add | Create a backlog |
| PATCH | [`/v1/scrum/backlogs/:id`](/docs/scrum/backlogs/update) | tasks.api.scrum.backlog.update | Update a backlog |
| DELETE | [`/v1/scrum/backlogs/:id`](/docs/scrum/backlogs/delete) | tasks.api.scrum.backlog.delete | Delete a backlog |
| DELETE | [`/v1/scrum/epics/:id`](/docs/scrum/epics) | tasks.api.scrum.epic.delete | Delete an epic |
| POST | [`/v1/scrum/sprints`](/docs/scrum/sprints/create) | tasks.api.scrum.sprint.add | Create a sprint |
| PATCH | [`/v1/scrum/sprints/:id`](/docs/scrum/sprints/update) | tasks.api.scrum.sprint.update | Update a sprint |
| DELETE | [`/v1/scrum/sprints/:id`](/docs/scrum/sprints/delete) | tasks.api.scrum.sprint.delete | Delete a sprint |
| POST | [`/v1/scrum/sprints/:id/start`](/docs/scrum/sprints) | tasks.api.scrum.sprint.start | Start a sprint |
| POST | [`/v1/scrum/groups/:groupId/sprints/active/complete`](/docs/scrum/sprints/complete) | tasks.api.scrum.sprint.complete | Complete the group's active sprint |
| DELETE | [`/v1/scrum/stages/:stageId`](/docs/scrum/stages) | tasks.api.scrum.kanban.deleteStage | Delete a stage |
| POST | [`/v1/scrum/sprints/:sprintId/kanban/tasks/:taskId`](/docs/scrum/stages) | tasks.api.scrum.kanban.addTask | Add a task to the board |
| DELETE | [`/v1/scrum/sprints/:sprintId/kanban/tasks/:taskId`](/docs/scrum/stages) | tasks.api.scrum.kanban.deleteTask | Remove a task from the board |

## Error codes

| HTTP | Code | Cause |
|------|-----|-------|
| 400 | `INVALID_PARAMS` | Request field validation failed |
| 400 | `TASK_NOT_IN_GROUP` | The task has no workgroup — auto-placement into the backlog is impossible |
| 403 | `SCOPE_DENIED` | The key lacks the `task` scope |
| 422 | `BACKLOG_NOT_RESOLVED` | The task's group is not a scrum project, no backlog found |
| 404 | `STAGE_NOT_FOUND_OR_NO_ACCESS` | The kanban stage does not exist, or belongs to a scrum project you cannot access |
| 404 | `ENTITY_NOT_FOUND` | The task, epic or sprint was not found, or the task is not placed in scrum |
| 422 | `BITRIX_ERROR` | Other Bitrix24 errors |

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

## See also

- [Tasks](/docs/entities/tasks)
- [Task chat](/docs/entities/tasks/chat)
- [Workgroups](/docs/entities/workgroups)
- [Limits and optimization](/docs/optimization)
