## Create an activity for a CRM record

`POST /v1/deals/:id/activities`

`POST /v1/leads/:id/activities`

`POST /v1/contacts/:id/activities`

`POST /v1/companies/:id/activities`

Creates an activity for the deal, lead, contact or company selected in the URL. The owner comes from the URL, so the body needs no owner fields.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|-------|----------|
| `id` (path) | number | yes | ID of the activity owner. The URL sets the owner type: `deals` — deal, type `2`, `leads` — lead, type `1`, `contacts` — contact, type `3`, `companies` — company, type `4`. IDs come from the [deal](../deals/list.md), [lead](../leads/list.md), [contact](../contacts/list.md) or [company](../companies/list.md) lists |

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|-------|----------|
| `subject` | string | yes | Activity subject. Without it — `422 BITRIX_ERROR` |
| `TYPE_ID` | integer | yes | Numeric activity type: `1` — meeting, `2` — call, `3` — task, `4` — email. The field name is passed in upper case; `typeId` is not recognized. Without the field — `422 BITRIX_ERROR` |
| `COMMUNICATIONS` | array | yes | Activity communications, an array of objects. The field name and nested keys are passed in upper case; `communications` is not recognized. Without the field — `422 BITRIX_ERROR` |
| `COMMUNICATIONS[].VALUE` | string | yes | Phone or email. Without it — `422 BITRIX_ERROR` |
| `COMMUNICATIONS[].ENTITY_TYPE_ID` | integer | no | Type of the CRM record the communication belongs to: `3` — contact, `4` — company |
| `COMMUNICATIONS[].ENTITY_ID` | integer | no | ID of that record. From the [contact list](../contacts/list.md) or the [company list](../companies/list.md) |
| `type` | string | no | Activity kind: `email`, `call`, `meeting` or `task`. This is not the numeric `TYPE_ID`. Any other value — `400 INVALID_ACTIVITY_TYPE` |
| `description` | string | no | Activity description |
| `completed` | boolean | no | Whether the activity is completed |
| `responsibleId` | number | no | Responsible employee. List — [`GET /v1/users`](../users/list.md) |
| `priority` | number | no | Activity priority |
| `direction` | number | no | Activity direction |
| `deadline`, `startTime`, `endTime` | string | no | Activity deadline, start and end. Specify the time zone offset explicitly: `2026-10-20T15:00:00+00:00` |
| `id`, `createdAt`, `updatedAt` | — | RO | Set by the system; do not pass them on creation |
| Other activity fields | any | no | Passed through unchanged under their original upper-case names, like `TYPE_ID` |

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/deals/575/activities" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "Call the customer",
  "type": "call",
  "TYPE_ID": 2,
  "completed": false,
  "responsibleId": 1,
  "COMMUNICATIONS": [
    {
      "VALUE": "+12025550123",
      "ENTITY_TYPE_ID": 3,
      "ENTITY_ID": 17
    }
  ]
}'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/deals/575/activities" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "Call the customer",
  "type": "call",
  "TYPE_ID": 2,
  "completed": false,
  "responsibleId": 1,
  "COMMUNICATIONS": [
    {
      "VALUE": "+12025550123",
      "ENTITY_TYPE_ID": 3,
      "ENTITY_ID": 17
    }
  ]
}'
```

### JavaScript — personal key

```javascript
const response = await fetch('https://vibecode.bitrix24.com/v1/deals/575/activities', {
  method: 'POST',
  headers: {
    "X-Api-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "subject": "Call the customer",
    "type": "call",
    "TYPE_ID": 2,
    "completed": false,
    "responsibleId": 1,
    "COMMUNICATIONS": [
      {
        "VALUE": "+12025550123",
        "ENTITY_TYPE_ID": 3,
        "ENTITY_ID": 17
      }
    ]
  }),
})
const result = await response.json()
if (!response.ok || !result.success) throw new Error(JSON.stringify(result.error))
console.log(result.data.id)
```

### JavaScript — OAuth application

```javascript
const response = await fetch('https://vibecode.bitrix24.com/v1/deals/575/activities', {
  method: 'POST',
  headers: {
    "X-Api-Key": "YOUR_APP_KEY",
    "Authorization": "Bearer USER_SESSION_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "subject": "Call the customer",
    "type": "call",
    "TYPE_ID": 2,
    "completed": false,
    "responsibleId": 1,
    "COMMUNICATIONS": [
      {
        "VALUE": "+12025550123",
        "ENTITY_TYPE_ID": 3,
        "ENTITY_ID": 17
      }
    ]
  }),
})
const result = await response.json()
if (!response.ok || !result.success) throw new Error(JSON.stringify(result.error))
console.log(result.data.id)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on success, HTTP `201` |
| `data` | object | The created activity. Only `id` is returned |
| `data.id` | number | ID of the created activity. The full record — [`GET /v1/activities/:id`](./get.md) |

## Response example

```json
{
  "success": true,
  "data": {
    "id": 8385
  }
}
```

## Error response example

400 — unsupported activity kind in `type`:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_ACTIVITY_TYPE",
    "message": "Invalid activity type 'sms'. Available: email, call, meeting, task"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_ACTIVITY_TYPE` | A non-empty `type` is not one of `email`, `call`, `meeting`, `task` |
| 422 | `BITRIX_ERROR` | A required field is missing, or a communication has no `VALUE`. The message names the field: `The field SUBJECT is not defined or empty.`, `The field TYPE_ID is not defined or invalid.`, `The field COMMUNICATIONS is not defined or invalid.` |
| 422 | `BITRIX_ERROR` | No owner with this `id`: `Could not find 'DEAL' with ID: 999999999` |
| 422 | `BITRIX_ERROR` | Another Bitrix24 refusal; the text is in `error.message` |
| 400 | `INVALID_PARAMS` | Bitrix24 rejected a field value |
| 404 | `ENTITY_NOT_FOUND` | Bitrix24 responded with a "not found" code |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | A read-only key cannot create activities — see [access rights](/docs/access-rights) |
| 403 | `SCOPE_DENIED` | The key lacks the `crm` scope |
| 401 | `TOKEN_MISSING` | The key has no Bitrix24 tokens configured |

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

## Known specifics

**The URL owner overrides the body.** The `ownerTypeId`, `ownerId`, `OWNER_TYPE_ID` and `OWNER_ID` body fields are replaced with the owner from the URL: the activity is always created for the record in the path.

**The contract differs from the main create method.** [`POST /v1/activities`](./create.md) accepts `typeId` and `communications` in camelCase, the owner in the body, and returns the full activity. This method accepts `TYPE_ID` and `COMMUNICATIONS` in upper case and returns only `data.id`.

## See also

- [Activities of a CRM record](./owner-list.md)
- [Create activity](./create.md)
- [Get activity](./get.md)
- [List activities](./list.md)
