---
title: "Upsert code-экрана из кода (CI, maketa_sync)"
method: POST
path: "/screen/push"
tags: ["screens"]
---

# Upsert code-экрана из кода (CI, maketa_sync)

`POST /screen/push`

## Request

- Base URL: `https://maketa.pro/maketa/api`
- URL: `https://maketa.pro/maketa/api/screen/push`
- Auth: API key in header `x-maketa-key`

Требует проектный ключ mk_pk_ этой доски в заголовке x-maketa-key (песочный mk_sb_ здесь не действует). Upsert по стабильному `key` (например, роуту), каждая загрузка — новая версия. `screen` — экран модели v2 (`slots` + `nodes`); старый плоский `{objects:[…]}` пока принимается ради ещё не переписанных экстракторов, но новый код должен слать дерево.

## Request body

- object
  - `id` string, required
  - `key` string, required: Стабильный ключ экрана, 1–80 симв. [A-Za-z0-9_./-]
  - `screen` Screen, required: Экран модели v2: метаданные, `slots` (что стоит сверху, в теле, снизу и поверх) и `nodes` — плоская карта узлов, дерево внутри неё задают массивы `children`. Абсолютных координат нет ни у одного узла. kind: design (правится) | code (из кода, заблокирован — правки через ветку).
    - `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 на макет.
  - `meta` object
    - `repo` string
    - `route` string
    - `commit` string
    - `method` string

## Response `200`

Экран синхронизирован

- object
  - `ok` boolean
  - `screenId` string
  - `version` integer
  - `screens` integer

## Other responses

- `400`: Некорректный запрос
- `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`: too_many_screens
- `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)
