
## Create an order

`POST /v1/orders`

Creates a new online store order. The request body is flat — no `fields` wrapper.

## Request fields (body)

| Field | Type | Required | Description |
|-------|------|:--------:|-------------|
| `lid` | string | yes | Source site identifier. For cloud Bitrix24 accounts, always `"s1"` |
| `personTypeId` | number | yes | Payer type identifier. Each Bitrix24 account has its own set of types (legal entity, individual, etc.). You can see the ID in existing orders via [`GET /v1/orders`](./list.md) or [`POST /v1/orders/aggregate`](./aggregate.md) with `groupBy: "personTypeId"` |
| `currency` | string | yes | Order currency. List: [`GET /v1/currencies`](/docs/entities/currencies) |
| `price` | number | no | Total order amount |
| `statusId` | string | no | Order status. Default — `"N"` (new). List: [`GET /v1/order-statuses?filter[type]=O`](../order-statuses/list.md) |
| `userId` | number | no | Bitrix24 user identifier — the buyer in the online store. Source: [`GET /v1/users`](/docs/entities/users). If omitted, Bitrix24 sets a default user |
| `companyId` | number | no | Identifier of the CRM company linked to the order. Source: [`GET /v1/companies`](/docs/entities/companies) |
| `responsibleId` | number | no | Responsible employee. Source: [`GET /v1/users`](/docs/entities/users) |
| `comments` | string | no | Manager's comment on the order |
| `userDescription` | string | no | Buyer's comment on the order |
| `xmlId` | string | no | External identifier for synchronization with third-party systems |
| `canceled` | boolean | no | Whether the order is canceled |
| `reasonCanceled` | string | no | Cancellation reason |
| `discountValue` | number | no | Discount value |

Full field list — [`GET /v1/orders/fields`](./fields.md).

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/orders" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "lid": "s1",
    "personTypeId": 5,
    "currency": "USD",
    "price": 12500,
    "statusId": "N",
    "userId": 1,
    "comments": "Order from the mobile app"
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/orders" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "lid": "s1",
    "personTypeId": 5,
    "currency": "USD",
    "price": 12500,
    "statusId": "N",
    "userId": 1,
    "comments": "Order from the mobile app"
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/orders', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    lid: 's1',
    personTypeId: 5,
    currency: 'USD',
    price: 12500,
    statusId: 'N',
    userId: 1,
    comments: 'Order from the mobile app',
  }),
})

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

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/orders', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    lid: 's1',
    personTypeId: 5,
    currency: 'USD',
    price: 12500,
    statusId: 'N',
    userId: 1,
    comments: 'Order from the mobile app',
  }),
})

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

## Response fields

Returns the full created order object with all fields.

| Field | Type | Description |
|------|-----|---------|
| `id` | number | Identifier of the created order |
| `accountNumber` | string | The order's sequential number in the Bitrix24 account (generated automatically) |
| `dateInsert` | datetime | Creation date |
| `dateStatus` | datetime | Date the current status was set |

Other fields — see [Order fields](./fields.md).

The order's URL in Bitrix24 is built from `id`:

```
https://<portal>.bitrix24.com/shop/orders/details/<id>/
```

`<portal>` — the Bitrix24 account domain. Access is restricted by the employee's permissions in Bitrix24.

## Response example

```json
{
  "success": true,
  "data": {
    "id": 859,
    "accountNumber": "450",
    "lid": "s1",
    "personTypeId": 5,
    "currency": "USD",
    "price": 12500,
    "discountValue": 0,
    "taxValue": 0,
    "statusId": "N",
    "dateInsert": "2026-05-13T11:42:18.000Z",
    "dateUpdate": "2026-05-13T11:42:18.000Z",
    "dateStatus": "2026-05-13T11:42:18.000Z",
    "payed": false,
    "canceled": false,
    "marked": false,
    "responsibleId": 1,
    "userId": 1,
    "companyId": null,
    "clients": [
      { "entityTypeId": 3, "entityId": 2471, "isPrimary": true, "roleId": 0, "sort": 0 }
    ],
    "comments": "Order from the mobile app",
    "xmlId": "",
    "externalOrder": false
  }
}
```

## Error response example

422 — required fields not passed:

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "Required fields: personTypeId, currency, lid"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 422 | `BITRIX_ERROR` | Required fields not passed — the message contains their list (`Required fields: ...`) |
| 400 | `READONLY_FIELD` | A read-only field was passed — `accountNumber`, `payed`, the payment and status dates, and others |
| 403 | `SCOPE_DENIED` | The API key does not have the `sale` scope |
| 401 | `TOKEN_MISSING` | The API key has no configured tokens |

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

## Known specifics

**Referenced records are not validated.** The existence of `statusId`, `userId`, `personTypeId`, `companyId` is not checked on creation — non-existent values are accepted without an error. The order is created with the values you passed, and referential integrity stays on the application side.

**`statusId` is truncated to 2 characters.** A value longer than two characters is stored truncated without an error: `statusId: "ZZZ"` is stored as `"ZZ"`. Use only real two-character status codes from [`GET /v1/order-statuses`](../order-statuses/list.md).

**Create-only fields.** `price`, `marked`, and `reasonMarked` are applied when the order is created, but are ignored on update [`PATCH /v1/orders/:id`](./update.md). To change the amount after creation, edit the basket items via [`/v1/basket-items`](../basket-items.md).

**`payed` cannot be set.** The "paid" field is managed by the payments subsystem — it is ignored on create and update and returns `false`. An attempt to pass `payed` is rejected with `400 READONLY_FIELD`. Register payments via [`POST /v1/payments`](../payments/create.md).

**The account number is generated automatically.** The `accountNumber` field is assigned on creation. It cannot be passed in the request — an attempt is rejected with `400 READONLY_FIELD`.

**Basket items and payments are added separately.** An order is a container. After `POST /v1/orders`, call [`POST /v1/basket-items`](../basket-items/create.md) with `orderId` to add products, and [`POST /v1/payments`](../payments/create.md) to register a payment.

## See also

- [List orders](./list.md)
- [Get an order](./get.md)
- [Update an order](./update.md)
- [Add a basket item](../basket-items/create.md)
- [Create a payment](../payments/create.md)
- [Batch](/docs/batch)
- [Limits and optimization](/docs/optimization)
