For AI agents: markdown of this page — /docs-content-en/entities/orders.md documentation index — /llms.txt
Orders
Online store order management: create, get, update, delete, search, aggregate. An order is the root entity of an online store: it begins the buyer's journey and ties together basket items, payments, shipments, and statuses.
Bitrix24 API: sale.order.*
Scope: sale
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 or POST /v1/orders/aggregate with groupBy: "personTypeId" |
currency |
string | yes | Order currency. List: GET /v1/currencies |
price |
number | no | Total order amount |
statusId |
string | no | Order status. Default — "N" (new). List: GET /v1/order-statuses?filter[type]=O |
userId |
number | no | Bitrix24 user identifier — the buyer in the online store. Source: GET /v1/users. If omitted, Bitrix24 sets a default user |
companyId |
number | no | Identifier of the CRM company linked to the order. Source: GET /v1/companies |
responsibleId |
number | no | Responsible employee. Source: GET /v1/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.
Examples
curl — personal key
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
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
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
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.
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
{
"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:
{
"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.
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.
Create-only fields. price, marked, and reasonMarked are applied when the order is created, but are ignored on update PATCH /v1/orders/:id. To change the amount after creation, edit the basket items via /v1/basket-items.
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.
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 with orderId to add products, and POST /v1/payments to register a payment.