For AI agents: markdown of this page — /docs-content-en/entities/pages/blocks/create.md documentation index — /llms.txt
Add a block to a page
POST /v1/pages/:pageId/blocks
Adds a block from the Bitrix24 account block catalog to a landing page, with the catalog markup or with your own.
Fields are passed flat at the root of the JSON, without a fields wrapper. Working with pages and their blocks is covered in Pages.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
pageId (path) |
number | yes | Page ID. List: GET /v1/pages |
scope (query) |
string | no | Bitrix24 section the page belongs to: KNOWLEDGE for the knowledge base, GROUP for a workgroup knowledge base, MAINPAGE for the main page. Not passed for a page of a regular site |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | yes | Block code from the catalog. Catalog: GET /v1/block-repository. The code is the item key in the section's items |
afterId |
number | no | ID of a block on this page after which the new block is placed. List: GET /v1/pages/:pageId/blocks. Without this field, the new block is placed first on the page |
active |
boolean | no | Block visibility. false creates the block hidden. By default the block is visible. Also accepts the strings "true", "false", "1", "0" and the numbers 1, 0 |
content |
string | no | HTML markup of the block instead of the catalog markup. Without this field, the block gets the catalog markup |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/pages/20/blocks" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "03.1.three_cols_big_with_text_and_titles",
"afterId": 30,
"content": "<section class=\"landing-block\"><div class=\"container\"><h2>Hello</h2></div></section>"
}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/pages/20/blocks" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "03.1.three_cols_big_with_text_and_titles",
"afterId": 30,
"content": "<section class=\"landing-block\"><div class=\"container\"><h2>Hello</h2></div></section>"
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/pages/20/blocks', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: '03.1.three_cols_big_with_text_and_titles',
afterId: 30,
content: '<section class="landing-block"><div class="container"><h2>Hello</h2></div></section>',
}),
})
const { success, data } = await res.json()
console.log('Block ID:', data.id)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/pages/20/blocks', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: '03.1.three_cols_big_with_text_and_titles',
afterId: 30,
content: '<section class="landing-block"><div class="container"><h2>Hello</h2></div></section>',
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data |
object | The created block and how to publish it |
data.id |
number | ID of the created block in the page draft. Pass it to PATCH /v1/pages/:pageId/blocks/:blockId and DELETE /v1/pages/:pageId/blocks/:blockId |
data.version |
string | Page version the block was added to. Always draft |
data.published |
boolean | Whether the change is published. Always false |
data.publishWith |
string | The call that publishes the page together with the new block, with the page ID filled in |
Response example
{
"success": true,
"data": {
"id": 32,
"version": "draft",
"published": false,
"publishWith": "POST /v1/pages/20/publication"
}
}
Error response example
422 — the block code is not in the catalog:
{
"success": false,
"error": {
"code": "BLOCK_CANT_BE_ADDED",
"message": "Bitrix24 refused to add this block. Check that `code` is a code from GET /v1/block-repository."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | MISSING_BLOCK_CODE |
code is missing or is an empty string |
| 400 | INVALID_AFTER_ID |
afterId is not a positive integer |
| 400 | INVALID_ACTIVE |
active is not a boolean value |
| 400 | INVALID_CONTENT |
content is not a string |
| 400 | INVALID_PAGE_ID |
pageId in the path is not a positive integer |
| 400 | INVALID_SCOPE |
scope is not KNOWLEDGE, GROUP or MAINPAGE |
| 400 | INVALID_PARAMS |
Bitrix24 rejected the request: a required parameter is missing |
| 404 | ENTITY_NOT_FOUND |
The page does not exist or is not visible to the key. A knowledge base, workgroup or main page requires the scope parameter |
| 422 | BLOCK_CANT_BE_ADDED |
Bitrix24 refused to add the block: the code value is not in the catalog |
| 422 | BLOCK_WRONG_VERSION |
The catalog block requires a newer version of the sites module than the one installed on the Bitrix24 portal |
| 502 | BLOCK_ADD_UNCONFIRMED |
Bitrix24 did not return the ID of the new block: creation is not confirmed |
| 403 | BITRIX_ACCESS_DENIED |
The employee the key was issued for has no access to the page in Bitrix24 |
| 422 | BITRIX_ERROR |
Bitrix24 rejected the request; the error text is in message |
| 403 | SCOPE_DENIED |
The API key does not have the landing scope |
| 403 | WRITE_BLOCKED_READONLY_KEY |
The key is in read-only mode |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
Full list of common API errors: Errors.
Known specifics
Markup is returned in a wrapper. Reading GET /v1/pages/:pageId/blocks?content=true returns the markup from content inside a <div id="b<id>" class="block-wrapper block-<code>"> element. In the wrapper class, dots and underscores of the block code are replaced with hyphens: for 03.1.three_cols_big_with_text_and_titles it is block-03-1-three-cols-big-with-text-and-titles.
A non-existent afterId is not rejected. If the page has no block with this ID, the block is still created with a 201 response, but it lands somewhere on the page other than first or last. Before the call, take afterId from the block list, and after the call, check the new block's position with the same list.