
# Pages

Managing landing and online-store pages on the Bitrix24 platform: create, get, update, delete. A page always belongs to a site and inherits its type, `PAGE` or `STORE`.

Bitrix24 API: `landing.landing.*`
Scope: `landing`

## Operations

- [Create a page](./pages/create.md) — `POST /v1/pages`
- [List pages](./pages/list.md) — `GET /v1/pages`
- [Get a page](./pages/get.md) — `GET /v1/pages/:id`
- [Update a page](./pages/update.md) — `PATCH /v1/pages/:id`
- [Delete a page](./pages/delete.md) — `DELETE /v1/pages/:id`
- [Search pages](./pages/search.md) — `POST /v1/pages/search`
- [Page fields](./pages/fields.md) — `GET /v1/pages/fields`
- [Aggregate pages](./pages/aggregate.md) — `POST /v1/pages/aggregate`

## Key fields

| Field | Type | Description |
|------|-----|---------|
| `id` | number | Page identifier (read-only) |
| `title` | string | Page title, up to 255 characters. Required on creation |
| `code` | string | Symbolic code of the page in the URL. If omitted, generated from `title`. Must not contain `/`. Must be unique within a site or folder — otherwise a numeric suffix is added automatically |
| `siteId` | number | Identifier of the site the page belongs to. Source: [`GET /v1/sites`](/docs/entities/sites/list). Required on creation |
| `active` | boolean | Whether the page is published. Read-only: new pages are created inactive, and publishing is done with the separate calls `POST /v1/pages/:id/publication` and `POST /v1/pages/:id/unpublish` |
| `description` | string \| null | Arbitrary page description. Comes back as `null` if not set (on the operation pages [get](./pages/get.md) / [list](./pages/list.md) the type is already `string \| null` — aligned with them here for consistency) |
| `createdById` | number | Identifier of the employee who created the page (read-only). Source: [`GET /v1/users`](/docs/entities/users) |
| `dateCreate` | datetime | Creation date (read-only) |
| `dateModify` | datetime | Last modification date (read-only) |

## What to know before you start

1. **The request body is flat.** On creation and update, pass fields directly at the root of the JSON: `{"title": "...", "code": "...", "siteId": 3}`. No `fields` wrapper is needed.
2. **Minimum for creation:** `title` + `siteId`. The remaining fields are optional.
3. **Publishing uses separate calls, and the `active` field is not accepted in the body.** On creation a page gets `active: false`. Passing `active` in `POST` or `PATCH` is rejected with `400 READONLY_FIELD`, and the rest of the request body is not applied either. To publish a page, call `POST /v1/pages/:id/publication`; to unpublish it, call `POST /v1/pages/:id/unpublish`. For knowledge base pages, workgroup pages and main pages, both calls need a `scope` parameter set to `KNOWLEDGE`, `GROUP` or `MAINPAGE` — without it the page is not found and a `404` comes back. Ordinary site pages need no such parameter.
4. **Full field list — [`GET /v1/pages/fields`](./pages/fields.md).** The endpoint returns a map of all page fields with their type, a `readonly` flag, a label and — for the nine fields that can arrive as `null` — a `nullable` flag. Key fields are listed in the "Key fields" section above, and the full list of 27 fields is on the [Page fields](./pages/fields.md) page.
5. **The response may contain additional Bitrix24 fields — in camelCase.** Besides the key fields, extra ones are returned by default — in **camelCase**, **not** in `UPPER_CASE`: `deleted`, `xmlId`, `tplId`, `sitemap`, `folder`, `folderId`, `searchContent`, `modifiedById`, `initiatorAppCode`, `rule`, `public`, `sys`, `views`, `tplCode`, `version`, `historyStep`, `datePublic` and others. Reading by the documented name `data[].XML_ID` / `MODIFIED_BY_ID` returns `undefined` — use camelCase. To get only the key fields, pass the `select` parameter in `GET /v1/pages`: `?select=id,title,code,siteId,active,description,createdById,dateCreate,dateModify`. See examples in [List pages](./pages/list.md). The `select` parameter is also available for `GET /v1/pages/:id` and `POST /v1/pages/search`.
    - The `domainId` (`DOMAIN_ID`) field is not requested by default. In the list (`GET /v1/pages`) and search (`POST /v1/pages/search`), an explicit `select=domainId` is forwarded to Bitrix24 and can return `422 BITRIX_ERROR` with the Bitrix24 code `SYSTEM_ERROR`. In the get-by-ID endpoint (`GET /v1/pages/:id`), the field is not returned even with an explicit `select`: the endpoint requests the default fields, and `select` only narrows the response; `id` is always returned. The field remains in the [Page fields](./pages/fields.md) reference.
   - The `datePublic` field arrives as `null` when Bitrix24 has no publication date for the page — the usual case even for a published page, so it is not a publication indicator. Use `active` or `public` to tell whether a page is published. The field description is on the [Page fields](./pages/fields.md) page.
6. **`offset` for pagination is supported.** Vibecode returns the requested `[offset, offset + limit)` window. The `meta.total` value is the exact number of records matching the filter. For large result sets, `limit > 50` also works.
7. **Sorting is supported.** `?order[field]=asc|desc` or the short form `?sort=-field` (descending). In the [`POST /v1/pages/search`](./pages/search.md) body, use the `sort` field. Without sorting, pages are returned in ascending `siteId` order, and within a site in ascending `id` order. To count the number of pages, use `meta.total` from [List pages](./pages/list.md): `GET /v1/pages?filter[siteId]=3&limit=1` returns `meta.total` without fetching records.
8. **Date format is locale-dependent, not ISO 8601.** The `dateCreate`, `dateModify` and `datePublic` fields arrive as strings in the account's local format: `DD.MM.YYYY HH:MM:SS` (`30.12.2021 12:30:52`) in the RU locale, `MM/DD/YYYY hh:mm:ss am/pm` (`12/30/2021 12:30:52 pm`) in the EN locale. The value is returned as is, identically in the list and in the get-by-ID response. `new Date(value)` returns `Invalid Date` or swaps day and month — do not parse the date with a fixed template. The filter needs the same format: Bitrix24 does not recognize a value in another locale's format or in ISO, and returns an empty list with code 200.

## Related entities

| Entity | Endpoint | Purpose |
|----------|----------|-----------|
| Sites | [`GET /v1/sites`](/docs/entities/sites) | Page containers. Source of `siteId` for creating a page. A site can be deleted only after all its pages are deleted. |

## Typical scenario

1. Find a site: [`GET /v1/sites`](/docs/entities/sites/list).
2. View its pages: [`GET /v1/pages?filter[siteId]=3`](./pages/list.md).
3. Create a new one or update an existing one: [`POST /v1/pages`](./pages/create.md) / [`PATCH /v1/pages/:id`](./pages/update.md).
4. Delete the ones you no longer need: [`DELETE /v1/pages/:id`](./pages/delete.md).

## Limits

| Limit | Value |
|-------|----------|
| Maximum records per request | 5000 (`limit ≤ 5000`) |
| Pagination | via `offset` — the `[offset, offset + limit)` window |
| `offset` | supported — the `[offset, offset + limit)` window is applied on the Vibecode side |
| Batch requests | up to 50 operations in [`POST /v1/batch`](/docs/batch) |
| Rate limit | shared across the Vibecode API — see [Limits and optimization](/docs/optimization) |

## See also

- [Sites](/docs/entities/sites)
- [Entity API](/docs/entity-api)
- [Filtering syntax](/docs/filtering)
- [Batch](/docs/batch)
- [API reference](/docs/api-reference)

## Page actions

| Action | Route |
|---|---|
| [Move to trash](/docs/entities/pages/trash) | `POST /v1/pages/:id/trash` |
| [Restore a page](/docs/entities/pages/restore) | `POST /v1/pages/:id/restore` |
| [Copy a page](/docs/entities/pages/copy) | `POST /v1/pages/:id/copy` |
| [Move a page](/docs/entities/pages/move) | `POST /v1/pages/:id/move` |
| [Create from a template](/docs/entities/pages/from-template) | `POST /v1/pages/from-template` |
| [Page public URL](/docs/entities/pages/public-url) | `GET /v1/pages/:id/public-url` |
| [Page preview](/docs/entities/pages/preview) | `GET /v1/pages/:id/preview` |
| [Page settings](/docs/entities/pages/settings) | `GET /v1/pages/:id/settings` |
| [Find a page by path](/docs/entities/pages/resolve) | `GET /v1/pages/resolve` |
| [Page templates](/docs/entities/page-templates) | `GET /v1/page-templates` |

## Page blocks

| Operation | Route |
|---|---|
| [List page blocks](/docs/entities/pages/blocks/list) | `GET /v1/pages/:pageId/blocks` |
| [Add a block](/docs/entities/pages/blocks/create) | `POST /v1/pages/:pageId/blocks` |
| [Replace block markup](/docs/entities/pages/blocks/update) | `PATCH /v1/pages/:pageId/blocks/:blockId` |
| [Delete a block](/docs/entities/pages/blocks/delete) | `DELETE /v1/pages/:pageId/blocks/:blockId` |
| [Restore a block](/docs/entities/pages/blocks/restore) | `POST /v1/pages/:pageId/blocks/:blockId/restore` |
| [Copy a block](/docs/entities/pages/blocks/copy) | `POST /v1/pages/:pageId/blocks/:blockId/copy` |
| [Move a block](/docs/entities/pages/blocks/move) | `POST /v1/pages/:pageId/blocks/:blockId/move` |
| [Move a block up](/docs/entities/pages/blocks/up) | `POST /v1/pages/:pageId/blocks/:blockId/up` |
| [Move a block down](/docs/entities/pages/blocks/down) | `POST /v1/pages/:pageId/blocks/:blockId/down` |
| [Show a block](/docs/entities/pages/blocks/show) | `POST /v1/pages/:pageId/blocks/:blockId/show` |
| [Hide a block](/docs/entities/pages/blocks/hide) | `POST /v1/pages/:pageId/blocks/:blockId/hide` |
| [Permanently delete a block](/docs/entities/pages/blocks/purge) | `POST /v1/pages/:pageId/blocks/:blockId/purge` |
| [Permanently delete selected blocks](/docs/entities/pages/blocks/bulk-purge) | `POST /v1/pages/:pageId/blocks/bulk-purge` |

## Block reads

| Operation | Route |
|---|---|
| [Block catalog](/docs/entities/pages/catalog) | `GET /v1/block-repository` |
| [Read a page block](/docs/entities/pages/block-get) | `GET /v1/pages/:pageId/blocks/:blockId` |
| [Block content](/docs/entities/pages/block-content) | `GET /v1/pages/:pageId/blocks/:blockId/content` |
| [Catalog sample](/docs/entities/pages/catalog-content) | `GET /v1/block-repository/:code/content` |
| [Catalog manifest](/docs/entities/pages/catalog-manifest) | `GET /v1/block-repository/:code/manifest` |
