## Update a to-do

`PATCH /v1/activity-todos/:id`

Changes the deadline, text, responsible user, reminders, or parent of a "To-do" activity. Pass only the fields you change, flat at the JSON root.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `id` (path) | number | yes | To-do ID. List: [`GET /v1/activities`](/docs/entities/activities/list) with the `providerId=CRM_TODO` filter |

## Request fields (body)

The body cannot be empty: pass at least one field.

| Field | Type | Required | Description |
|------|-----|:-----:|---------|
| `deadline` | string | no | New deadline in ISO 8601 format, for example `2026-11-03T15:00:00+00:00` |
| `title` | string | no | New title. Returned in the `subject` field of the response |
| `description` | string | no | New description |
| `responsibleId` | number | no | ID of the new responsible user. List: [`GET /v1/users`](/docs/entities/users/list) |
| `parentActivityId` | number | no | ID of the activity the to-do is linked to. The parent must belong to the same CRM item. Item activities: [`GET /v1/activities`](/docs/entities/activities/list) filtered by `ownerTypeId` and `ownerId` |
| `pingOffsets` | number[] | no | Reminders: integer minutes before the deadline, no less than `0`. Replaces the previous set entirely |

The activity's CRM item does not change: `ownerTypeId` and `ownerId` in the body are rejected with `400 INVALID_PARAMS`, as is any other unknown field. A `colorId` from the palette is rejected with `422`, and one outside the palette with `400` (see "Errors").

## Examples

### curl — personal key

```bash
curl -X PATCH "https://vibecode.bitrix24.com/v1/activity-todos/8379" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Review the contract and invoice",
    "pingOffsets": [0, 30]
  }'
```

### curl — OAuth application

```bash
curl -X PATCH "https://vibecode.bitrix24.com/v1/activity-todos/8379" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Review the contract and invoice",
    "pingOffsets": [0, 30]
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/activity-todos/8379', {
  method: 'PATCH',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Review the contract and invoice',
    pingOffsets: [0, 30],
  }),
})

const { data } = await res.json()
console.log(data.subject)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/activity-todos/8379', {
  method: 'PATCH',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Review the contract and invoice',
    pingOffsets: [0, 30],
  }),
})

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

## Response fields

The response is the activity read back after the update. Same shape as [`GET /v1/activities/:id`](/docs/entities/activities/get).

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | `true` on success |
| `data` | object | The updated activity, all fields: [Activity fields](/docs/entities/activities/fields) |
| `data.id` | number | Activity ID |
| `data.subject` | string | Title from the `title` field |
| `data.deadline` | string | Activity deadline in UTC |
| `data.associatedEntityId` | number | Parent activity ID, or `0` without a parent |
| `data.updatedAt` | string | Last modification time in UTC |

## Response example

Main fields are shown. Full list: [Activity fields](/docs/entities/activities/fields).

```json
{
  "success": true,
  "data": {
    "id": 8379,
    "ownerId": 8845,
    "ownerTypeId": 2,
    "providerId": "CRM_TODO",
    "associatedEntityId": 0,
    "subject": "Review the contract and invoice",
    "updatedAt": "2026-10-15T10:06:02.000Z",
    "deadline": "2026-11-03T12:00:00.000Z",
    "completed": false,
    "status": 1,
    "responsibleId": 1317,
    "description": "Call the client"
  }
}
```

## Error response example

422 — the to-do is already completed:

```json
{
  "success": false,
  "error": {
    "code": "ACTIVITY_TODO_COMPLETED",
    "message": "The to-do is completed and cannot be updated"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | `id` is not a positive integer |
| 400 | `INVALID_PARAMS` | Body validation failed: empty body, `responsibleId` or `parentActivityId` is not a positive integer, `title` or `description` is not a string, the deadline is not in ISO 8601 format, `pingOffsets` is not an array of non-negative integers, an unknown field, `colorId` outside the palette |
| 400 | `INVALID_PARAMS` | The parent activity from `parentActivityId` belongs to a different CRM item |
| 400 | `MISSING_REQUIRED_FIELDS` | The request body is not a JSON object |
| 404 | `ENTITY_NOT_FOUND` | The activity with this `id` is not a to-do: it has a different provider, for example a call or an open channel |
| 404 | `ENTITY_NOT_FOUND` | The activity with this `id` or the parent activity from `parentActivityId` does not exist. The to-do does not change |
| 422 | `ACTIVITY_TODO_COMPLETED` | The to-do is completed and cannot be changed |
| 422 | `UNSUPPORTED_ACTIVITY_BLOCKS` | The body contains a `colorId` from the palette. Color is set only on [creation](./create.md) |
| 422 | `ACTIVITY_UPDATE_NOT_APPLIED` | After the write, the activity read back did not match the request, or fields not passed in the request may not have been preserved. The update may have been applied partially: read the activity via [`GET /v1/activities/:id`](/docs/entities/activities/get) and compare it with the expected state before retrying `PATCH` |
| 502 | `BITRIX_ERROR` | Failed to read the activity data before or after the write. The update may have been applied: read the activity before retrying `PATCH` |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Read-only key |
| 403 | `SCOPE_DENIED` | The key does not have the `crm` scope |
| 401 | `TOKEN_MISSING` | The key has no Bitrix24 connection |

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

## Known specifics

**Omitted fields are preserved.** If the body contains only one of `deadline`, `description`, or `responsibleId`, only that field changes. With any other set of fields, the service reads the current activity and fills in the title, description, deadline, and reminders that the body omits.

## See also

- [Create a to-do](./create.md)
- [Get an activity](/docs/entities/activities/get)
- [Complete an activity](/docs/entities/activities/complete)
- [Reschedule the deadline](/docs/entities/activities/deadline)
- [CRM to-do activities](../todos.md)
