---
title: "Сохранить сцену доски"
method: POST
path: "/save"
tags: ["boards"]
---

# Сохранить сцену доски

`POST /save`

## Request

- Base URL: `https://maketa.pro/maketa/api`
- URL: `https://maketa.pro/maketa/api/save`
- Auth: one of:
  - none
  - API key in header `x-maketa-key`

Право на запись: edit-токен в поле `edit`, ИЛИ заголовок `x-maketa-key` с песочным ключом, которым доска создана, ИЛИ сессия владельца/соавтора, ИЛИ linkAccess=edit. Оптимистичная блокировка: передавайте `baseRev` из последнего /load|/save — при более новой ревизии на сервере придёт 409 conflict. Песочный ключ: 429 quota_saves при превышении 200 сохранений/сутки.

## Request body

- object
  - `id` string, required
  - `edit` string: edit-токен (не нужен при x-maketa-key своей доски)
  - `doc` Doc, required: Документ макета `maketa.board.v2`. Экран — дерево узлов. Полное описание модели: https://maketa.pro/docs/#model
    - `v` 2: Версия модели. `2` — экран разбирается деревом (`slots` + `nodes`). Документ без `v` читается по старой плоской модели `maketa.board.v1` (`objects:[…]`) — она оставлена только ради уже сохранённых макетов и здесь не описывается; новый код всегда шлёт `"v": 2`.
    - `name` string: Имя макета (показывается в списках досок)
    - `rev` integer: Ревизия документа. Для записи используйте `baseRev` в POST /save — иначе чужие правки затираются молча.
    - `screens` Screen[], required
      - `id` string: 1–40 симв. [A-Za-z0-9_-]
      - `name` string
      - `device` string: модель из /devices.json, например iphone-15
      - `w` number: 40–4000 px
      - `h` number: 40–4000 px
      - `bg` string
      - `safe` boolean: Учитывать безопасные зоны устройства — вырез сверху и полосу-домой снизу.
      - `kind` 'design' | 'code'
      - `locked` boolean
      - `parentId` string, nullable: id родителя, если экран — ветка
      - `branches` string[]: id веток (связь двусторонняя)
      - `slots` Slots: Места экрана; любое может отсутствовать. Шапка и нижнее меню не прокручиваются, тело занимает остаток высоты, слой `over` лежит поверх всего экрана. Узел, стоящий в слоте, не может одновременно лежать внутри другого узла — это `node_two_parents`.
        - `top` string: id узла-шапки — не прокручивается
        - `body` string: id узла с прокручиваемым содержимым
        - `bottom` string: id узла нижнего меню — не прокручивается
        - `over` string[]: слой поверх: плавающие кнопки, подсказки. Ребёнок такого слоя ставится полем `at` и смещением `dx`/`dy`.
      - `nodes` object: Карта узлов экрана: ключ — id узла (1–40 симв. [A-Za-z0-9_-]), значение — сам узел. Карта, а не вложенные объекты, потому что узел адресуется по id из действий, из панели структуры и из MCP. Не больше 1000 узлов на экран и 5000 на макет.
  - `baseRev` integer: Ревизия, от которой правили (из /load)

## Response `200`

Сохранено

- object
  - `ok` boolean
  - `rev` integer
  - `updatedAt` integer

## Other responses

- `400`: Некорректный запрос
- `401`: Нет или неверный/просроченный ключ (bad_key | key_expired | no_key). hint подскажет, как получить новый.
- `402`: plan_limit — предел тарифа (только при включённых тарифах, MAKETA_PLANS=1). limit: boards | screens | bytes | collaborators | flex | mcpKeys | mcpWrite | seats; used/max — числа; upgrade — какой тариф снимает предел (pro | studio | null); hint — подсказка по-русски. Просмотр по ссылке, экспорт экрана и чтение через API не ограничиваются никогда.
- `403`: Прав нет (forbidden | quota_boards)
- `404`: Не существует (not_found)
- `409`: conflict — на сервере более новая ревизия
- `410`: Удалено навсегда (gone) — с deletedAt и reason
- `429`: Rate limit / квота (too_many | quota_saves); retryAfterMin — минут до сброса окна

---

[API](https://skmtc.dev/maketa/apis/maketa-api.md) · [All operations](https://skmtc.dev/maketa/apis/maketa-api/llms.txt) · [OpenAPI document](https://skmtc.dev/maketa/apis/maketa-api/revisions/ef044d6259d8?raw)
