{"openapi":"3.1.0","info":{"title":"RKDash API","version":"2026-09-15","description":"Публичный API RKDash: заведения, меню, чеки, персонал, склад, дашборды, интеграции и AI.\n\n**Версия контракта.** Путь фиксирует мажорную версию (`/api/v1`), дата-версия приходит в заголовке `X-Api-Version` (текущая — 2026-09-15). Ломающие изменения выходят только в новом мажоре, старые дата-версии живут до даты `Sunset`.\n\n**Ключи.** Рабочий ключ начинается с `rk_live_`, тестовый — с `rk_test_`. Ключ показывается один раз при создании в разделе «Настройки → API»; хранится только его хэш.\n\n**Лимиты.** 100 запросов в минуту на ключ, всплеск до 20 в секунду. Заголовки `X-RateLimit-*`, при превышении — `429` с `Retry-After`.\n\n**Ошибки.** `application/problem+json` по RFC 7807: `{type, title, status, detail, instance, code, requestId}`.\n\n**Повторы.** POST и PATCH принимают `Idempotency-Key`: повтор с тем же телом возвращает прежний ответ, с другим — `409`.","contact":{"name":"RKDash","url":"https://rkdash.com","email":"dev@rkdash.com"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://0.0.0.0:3000/api/v1","description":"Рабочий стенд"},{"url":"http://localhost:3200/api/v1","description":"Локальная панель"}],"tags":[{"name":"Заведения","description":"Рестораны и подразделения из учётных систем"},{"name":"Меню","description":"Блюда, цены, себестоимость и фудкост"},{"name":"Продажи","description":"Чеки и выручка"},{"name":"Персонал","description":"Официанты и их статистика"},{"name":"Склад","description":"Движения склада, приходы и списания"},{"name":"Дашборды","description":"Дашборды конструктора и их данные"},{"name":"Интеграции","description":"Сервисы предприятия и доступы к ним"},{"name":"Доска","description":"Карточки задач и их движение"},{"name":"Агенты","description":"Исполнители: цифровые сотрудники и разработка платформы"},{"name":"AI","description":"Вопросы к агенту по данным ресторана"},{"name":"Вебхуки","description":"Подписки на события и журнал доставок"},{"name":"Служебное","description":"Спецификация и changelog"}],"paths":{"/restaurants":{"get":{"operationId":"restaurants_list","summary":"Список заведений","tags":["Заведения"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"filter[source]","in":"query","required":false,"description":"Только одна учётная система: `rkeeper` или `iiko`.","schema":{"type":"string","enum":["rkeeper","iiko"]}},{"name":"filter[is_active]","in":"query","required":false,"description":"Только работающие заведения (`true`).","schema":{"type":"string","enum":["true","false"]}},{"name":"filter[name]","in":"query","required":false,"description":"Поиск по названию (вхождение).","schema":{"type":"string"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Идентификатор заведения — используйте его в PATCH"},"object":{"type":"string","const":"restaurant"},"name":{"type":"string"},"source":{"type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"type":"string"},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"string"},{"type":"null"}]},"isActive":{"type":"boolean"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}]},"metrics":{"type":"object","properties":{"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastSaleDate":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["revenue","checks","avgCheck","lastSaleDate"],"additionalProperties":false},"dataFrom":{"anyOf":[{"type":"string"},{"type":"null"}]},"dataTo":{"anyOf":[{"type":"string"},{"type":"null"}]},"registryId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","object","name","source","sourceKey","city","address","isActive","comment","metrics","dataFrom","dataTo","registryId"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Заведения из витрины: R-Keeper отдаёт рестораны, iiko — подразделения. Метрики считаются за указанный период.","x-code-samples":[{"lang":"Shell","source":"curl -H \"Authorization: Bearer $RKDASH_KEY\" \"https://rkdash.com/api/v1/restaurants?limit=3\""}]},"post":{"operationId":"restaurants_create","summary":"Добавить заведение в реестр","tags":["Заведения"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string","description":"Идентификатор заведения — используйте его в PATCH"},"object":{"type":"string","const":"restaurant"},"name":{"type":"string"},"source":{"type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"type":"string"},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"string"},{"type":"null"}]},"isActive":{"type":"boolean"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}]},"metrics":{"type":"object","properties":{"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastSaleDate":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["revenue","checks","avgCheck","lastSaleDate"],"additionalProperties":false},"dataFrom":{"anyOf":[{"type":"string"},{"type":"null"}]},"dataTo":{"anyOf":[{"type":"string"},{"type":"null"}]},"registryId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","object","name","source","sourceKey","city","address","isActive","comment","metrics","dataFrom","dataTo","registryId"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Создаёт запись реестра: город, адрес, комментарий. Если заведение уже приходит из учётной системы, запись связывается с ним по `sourceKey`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Название заведения"},"source":{"description":"Учётная система, по умолчанию rkeeper","type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"description":"Ключ объекта в учётной системе (имя ресторана/подразделения)","type":"string","maxLength":200},"city":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"address":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"comment":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["name"]}}}}}},"/restaurants/{id}":{"get":{"operationId":"restaurants_get","summary":"Заведение по идентификатору","tags":["Заведения"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Идентификатор заведения — используйте его в PATCH"},"object":{"type":"string","const":"restaurant"},"name":{"type":"string"},"source":{"type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"type":"string"},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"string"},{"type":"null"}]},"isActive":{"type":"boolean"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}]},"metrics":{"type":"object","properties":{"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastSaleDate":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["revenue","checks","avgCheck","lastSaleDate"],"additionalProperties":false},"dataFrom":{"anyOf":[{"type":"string"},{"type":"null"}]},"dataTo":{"anyOf":[{"type":"string"},{"type":"null"}]},"registryId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","object","name","source","sourceKey","city","address","isActive","comment","metrics","dataFrom","dataTo","registryId"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"restaurants_update","summary":"Изменить заведение","tags":["Заведения"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string","description":"Идентификатор заведения — используйте его в PATCH"},"object":{"type":"string","const":"restaurant"},"name":{"type":"string"},"source":{"type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"type":"string"},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"string"},{"type":"null"}]},"isActive":{"type":"boolean"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}]},"metrics":{"type":"object","properties":{"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastSaleDate":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["revenue","checks","avgCheck","lastSaleDate"],"additionalProperties":false},"dataFrom":{"anyOf":[{"type":"string"},{"type":"null"}]},"dataTo":{"anyOf":[{"type":"string"},{"type":"null"}]},"registryId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","object","name","source","sourceKey","city","address","isActive","comment","metrics","dataFrom","dataTo","registryId"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Меняет поля реестра. Заведения из учётной системы правятся только здесь, не в источнике.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Название заведения"},"source":{"description":"Учётная система, по умолчанию rkeeper","type":"string","enum":["rkeeper","iiko"]},"sourceKey":{"description":"Ключ объекта в учётной системе (имя ресторана/подразделения)","type":"string","maxLength":200},"city":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"address":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"comment":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"isActive":{"type":"boolean"}}}}}}}},"/dishes":{"get":{"operationId":"dishes_list","summary":"Список блюд с фудкостом","tags":["Меню"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Поиск по названию блюда.","schema":{"type":"string"}},{"name":"filter[category]","in":"query","required":false,"description":"Категория (последний сегмент пути категорий).","schema":{"type":"string"}},{"name":"filter[foodcost_gt]","in":"query","required":false,"description":"Фудкост больше указанного, %.","schema":{"type":"number"}},{"name":"filter[foodcost_lt]","in":"query","required":false,"description":"Фудкост меньше указанного, %.","schema":{"type":"number"}},{"name":"filter[revenue_gt]","in":"query","required":false,"description":"Выручка больше указанной.","schema":{"type":"number"}},{"name":"filter[has_cost]","in":"query","required":false,"description":"Только позиции с посчитанной себестоимостью (`true`).","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","required":false,"description":"Сортировка: `revenue`, `quantity`, `foodcost`, `avg_price`, `cost`, `name`. Минус — по убыванию.","schema":{"type":"string","example":"-revenue"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"dish"},"name":{"type":"string"},"category":{"anyOf":[{"type":"string"},{"type":"null"}]},"categoryPath":{"anyOf":[{"type":"string"},{"type":"null"}]},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgPrice":{"anyOf":[{"type":"number"},{"type":"null"}]},"costPerUnit":{"anyOf":[{"type":"number"},{"type":"null"}]},"salePrice":{"anyOf":[{"type":"number"},{"type":"null"}]},"unit":{"anyOf":[{"type":"string"},{"type":"null"}]},"foodcostPct":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Фудкост, %. null — себестоимость не рассчитана"},"markupPct":{"anyOf":[{"type":"number"},{"type":"null"}]},"period":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false}},"required":["id","object","name","category","categoryPath","revenue","quantity","avgPrice","costPerUnit","salePrice","unit","foodcostPct","markupPct","period"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Выручка и количество — из продаж, себестоимость порции — из расчёта StoreHouse. `foodcostPct = null` означает, что себестоимость по позиции не рассчитана: это не ноль.","x-code-samples":[{"lang":"Shell","source":"curl -H \"Authorization: Bearer $RKDASH_KEY\" \"https://rkdash.com/api/v1/dishes?filter[foodcost_gt]=40&limit=3\""}]}},"/dishes/{id}":{"get":{"operationId":"dishes_get","summary":"Блюдо: карточка, история цен, продажи по дням","tags":["Меню"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"dish"},"name":{"type":"string"},"category":{"anyOf":[{"type":"string"},{"type":"null"}]},"categoryPath":{"anyOf":[{"type":"string"},{"type":"null"}]},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgPrice":{"anyOf":[{"type":"number"},{"type":"null"}]},"costPerUnit":{"anyOf":[{"type":"number"},{"type":"null"}]},"salePrice":{"anyOf":[{"type":"number"},{"type":"null"}]},"unit":{"anyOf":[{"type":"string"},{"type":"null"}]},"foodcostPct":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Фудкост, %. null — себестоимость не рассчитана"},"markupPct":{"anyOf":[{"type":"number"},{"type":"null"}]},"period":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false}},"required":["id","object","name","category","categoryPath","revenue","quantity","avgPrice","costPerUnit","salePrice","unit","foodcostPct","markupPct","period"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/dishes/{id}/price":{"patch":{"operationId":"dishes_price","summary":"Согласовать новую цену блюда","tags":["Меню"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"RKDash — аналитическая витрина, а не учётная система: изменение сохраняется в журнал согласованных изменений с причиной и автором, уходит в учётную систему ближайшим обменом и порождает событие `dish.updated`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"number","exclusiveMinimum":0,"maximum":1000000,"description":"Новая цена блюда"},"reason":{"description":"Причина изменения — попадает в журнал","type":"string","maxLength":500}},"required":["price"]}}}},"x-code-samples":[{"lang":"Shell","source":"curl -X PATCH -H \"Authorization: Bearer $RKDASH_KEY\" -H \"Idempotency-Key: 7f2c\" -H \"Content-Type: application/json\" -d '{\"price\": 520, \"reason\": \"рост закупки\"}' https://rkdash.com/api/v1/dishes/dish_.../price"}]}},"/checks":{"get":{"operationId":"checks_list","summary":"Чеки за период","tags":["Продажи"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"filter[restaurant]","in":"query","required":false,"description":"Заведение.","schema":{"type":"string"}},{"name":"filter[waiter]","in":"query","required":false,"description":"Официант.","schema":{"type":"string"}},{"name":"filter[min_total]","in":"query","required":false,"description":"Сумма чека не меньше.","schema":{"type":"number"}},{"name":"filter[max_total]","in":"query","required":false,"description":"Сумма чека не больше.","schema":{"type":"number"}},{"name":"sort","in":"query","required":false,"description":"`total`, `opened_at`, `date`, `positions`. Минус — по убыванию.","schema":{"type":"string","example":"-total"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"check"},"number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"date":{"anyOf":[{"type":"string"},{"type":"null"}]},"restaurant":{"type":"string"},"station":{"anyOf":[{"type":"string"},{"type":"null"}]},"waiter":{"anyOf":[{"type":"string"},{"type":"null"}]},"table":{"anyOf":[{"type":"string"},{"type":"null"}]},"orderCategory":{"anyOf":[{"type":"string"},{"type":"null"}]},"openedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"closedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"number"},{"type":"null"}]},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"positions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","object","number","date","restaurant","station","waiter","table","orderCategory","openedAt","closedAt","total","quantity","positions"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Чек собирается из строк продаж: сумма чека всегда сходится с продажами.","x-code-samples":[{"lang":"Shell","source":"curl -H \"Authorization: Bearer $RKDASH_KEY\" \"https://rkdash.com/api/v1/checks?date_from=2026-09-01&date_to=2026-09-15&limit=5\""}]}},"/checks/{id}":{"get":{"operationId":"checks_get","summary":"Чек с составом","tags":["Продажи"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"check"},"number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"date":{"anyOf":[{"type":"string"},{"type":"null"}]},"restaurant":{"type":"string"},"station":{"anyOf":[{"type":"string"},{"type":"null"}]},"waiter":{"anyOf":[{"type":"string"},{"type":"null"}]},"table":{"anyOf":[{"type":"string"},{"type":"null"}]},"orderCategory":{"anyOf":[{"type":"string"},{"type":"null"}]},"openedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"closedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"number"},{"type":"null"}]},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"positions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","object","number","date","restaurant","station","waiter","table","orderCategory","openedAt","closedAt","total","quantity","positions"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/waiters":{"get":{"operationId":"waiters_list","summary":"Официанты за период","tags":["Персонал"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"filter[restaurant]","in":"query","required":false,"description":"Заведение.","schema":{"type":"string"}},{"name":"filter[source]","in":"query","required":false,"description":"Источник: `rkeeper` или `iiko`.","schema":{"type":"string","enum":["rkeeper","iiko"]}},{"name":"filter[min_revenue]","in":"query","required":false,"description":"Выручка не меньше указанной.","schema":{"type":"number"}},{"name":"sort","in":"query","required":false,"description":"`revenue`, `checks`, `avg_check`, `name`.","schema":{"type":"string","example":"-revenue"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"waiter"},"name":{"type":"string"},"source":{"type":"string","enum":["rkeeper","iiko"]},"restaurant":{"anyOf":[{"type":"string"},{"type":"null"}]},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"positions":{"anyOf":[{"type":"number"},{"type":"null"}]},"firstShift":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastShift":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","object","name","source","restaurant","revenue","checks","avgCheck","positions","firstShift","lastShift"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Выручка, число чеков и средний чек по каждому сотруднику."}},"/waiters/{id}/stats":{"get":{"operationId":"waiters_stats","summary":"Статистика официанта","tags":["Персонал"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"waiter_stats"},"name":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false},"summary":{"type":"object","properties":{"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"anyOf":[{"type":"number"},{"type":"null"}]},"avgCheck":{"anyOf":[{"type":"number"},{"type":"null"}]},"positions":{"anyOf":[{"type":"number"},{"type":"null"}]},"restaurant":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["revenue","checks","avgCheck","positions","restaurant"],"additionalProperties":false},"byDay":{"type":"array","items":{"type":"object","properties":{"date":{"anyOf":[{"type":"string"},{"type":"null"}]},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"type":"number"},"hours":{"type":"number"}},"required":["date","revenue","checks","hours"],"additionalProperties":false}},"byHour":{"type":"array","items":{"type":"object","properties":{"hour":{"type":"string"},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]},"checks":{"type":"number"}},"required":["hour","revenue","checks"],"additionalProperties":false}},"topDishes":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["name","quantity","revenue"],"additionalProperties":false}},"notes":{"type":"array","items":{"type":"string"}}},"required":["id","object","name","period","summary","byDay","byHour","topDishes","notes"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Сводка, выручка по дням, распределение по часам и топ блюд."}},"/stock":{"get":{"operationId":"stock_report","summary":"Движения склада за период","tags":["Склад"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"search","in":"query","required":false,"description":"Поиск по названию позиции.","schema":{"type":"string"}},{"name":"filter[source]","in":"query","required":false,"description":"Только движения источника: `rkeeper`, `iiko`, `api`.","schema":{"type":"string","enum":["rkeeper","iiko","api"]}},{"name":"filter[only_below]","in":"query","required":false,"description":"Только позиции ниже порога (`true`).","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"name":{"type":"string"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}]},"outgoingQuantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"incomingQuantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"netChange":{"anyOf":[{"type":"number"},{"type":"null"}]},"costSum":{"anyOf":[{"type":"number"},{"type":"null"}]},"sources":{"type":"array","items":{"type":"string"}},"lastMovementAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lowThreshold":{"anyOf":[{"type":"number"},{"type":"null"}]},"belowThreshold":{"type":"boolean"}},"required":["name","unit","outgoingQuantity","incomingQuantity","netChange","costSum","sources","lastMovementAt","lowThreshold","belowThreshold"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Расход по номенклатуре R-Keeper, расход продуктов iiko и движения, внесённые через API. Остатков StoreHouse в витрине нет — поле `balanceAvailable` всегда `false`, и это указано в `note`."}},"/stock/movements":{"post":{"operationId":"stock_movements_create","summary":"Приход или списание","tags":["Склад"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Записывает движение в журнал склада. Если передать `lowThreshold`, позиция попадает под правило «низкий остаток»: при уходе сальдо ниже порога приходит событие `stock.low`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"restaurant":{"type":"string","minLength":1,"maxLength":200,"description":"Заведение, по которому движение"},"dish":{"anyOf":[{"type":"string","minLength":1,"maxLength":300},{"type":"object","properties":{"id":{"type":"string","description":"id блюда из /dishes"}},"required":["id"]}],"description":"Блюдо: название строкой или { id }"},"kind":{"type":"string","enum":["in","out"],"description":"in — приход, out — списание"},"quantity":{"type":"number","exclusiveMinimum":0,"description":"Количество"},"unit":{"type":"string","maxLength":40},"reason":{"type":"string","maxLength":500},"placeName":{"type":"string","maxLength":200},"occurredAt":{"description":"Дата движения (YYYY-MM-DD или ISO), по умолчанию — сегодня","type":"string","maxLength":30},"lowThreshold":{"description":"Порог низкого остатка по позиции: ниже него придёт событие stock.low","anyOf":[{"type":"number"},{"type":"null"}]}},"required":["restaurant","dish","kind","quantity"]}}}}}},"/dashboards":{"get":{"operationId":"dashboards_list","summary":"Дашборды конструктора","tags":["Дашборды"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"object":{"type":"string","const":"dashboard"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"isShared":{"type":"boolean"},"isPreset":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"widgets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"source":{"type":"string"},"chart":{"type":"string"},"measureField":{"type":"string"},"measureAgg":{"type":"string"},"groupBy":{"anyOf":[{"type":"string"},{"type":"null"}]},"groupBucket":{"anyOf":[{"type":"string"},{"type":"null"}]},"width":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","title","source","chart","measureField","measureAgg","groupBy","groupBucket","width"],"additionalProperties":false}}},"required":["id","object","name","description","isShared","isPreset","createdAt","updatedAt","widgets"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/dashboards/{id}/data":{"get":{"operationId":"dashboards_data","summary":"Данные виджетов дашборда","tags":["Дашборды"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"date_from","in":"query","required":false,"description":"Начало периода, YYYY-MM-DD. По умолчанию — 30 дней назад.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-01"}},{"name":"date_to","in":"query","required":false,"description":"Конец периода, YYYY-MM-DD (включительно).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-09-15"}},{"name":"restaurants","in":"query","required":false,"description":"Список заведений через запятую (значения из /restaurants).","schema":{"type":"string"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"object":{"type":"string","const":"dashboard_data"},"period":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false},"widgets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"chart":{"type":"string"},"source":{"type":"string"},"measure":{"type":"string"},"aggregation":{"type":"string"},"groupBy":{"anyOf":[{"type":"string"},{"type":"null"}]},"rows":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"number"}},"required":["label","value"],"additionalProperties":false}},"durationMs":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"error":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","title","chart","source","measure","aggregation","groupBy","rows","durationMs","error"],"additionalProperties":false}}},"required":["id","object","period","widgets"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Каждый виджет считается тем же кодом, что рисует панель, — цифры совпадают."}},"/integrations":{"get":{"operationId":"integrations_list","summary":"Сервисы предприятия","tags":["Интеграции"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"object":{"type":"string","const":"integration"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"connected":{"type":"boolean"},"hasAccess":{"type":"boolean"},"checkOk":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"checkMessage":{"anyOf":[{"type":"string"},{"type":"null"}]},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"required":{"type":"boolean"},"secret":{"type":"boolean"},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}]},"hint":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["key","label","required","secret","placeholder","hint"],"additionalProperties":false}},"toolsCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"toolsError":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","object","title","description","category","connected","hasAccess","checkOk","checkMessage","fields","toolsCount","toolsError"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Список сервисов платформы MCP с признаком подключённого доступа."}},"/integrations/{slug}/connect":{"post":{"operationId":"integrations_connect","summary":"Подключить сервис","tags":["Интеграции"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор сервиса, например `rkeeper`"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Сохраняет доступы к учётной системе: платформа проверяет связь и возвращает результат проверки. Секреты обратно не отдаются.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"credentials":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]},"description":"Поля доступа сервиса: ключи из `fields` в ответе GET /integrations"}},"required":["credentials"]}}}}}},"/cards":{"get":{"operationId":"cards_list","summary":"Карточки доски задач","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"filter[status]","in":"query","required":false,"description":"Колонка: `new`, `in_progress`, `review`, `done`.","schema":{"type":"string","enum":["new","in_progress","review","done"]}},{"name":"filter[priority]","in":"query","required":false,"description":"Приоритет: `low`, `medium`, `high`.","schema":{"type":"string","enum":["low","medium","high"]}},{"name":"filter[assignee]","in":"query","required":false,"description":"Исполнитель: профиль или имя из /agents.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Поиск по заголовку и описанию.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"`updatedAt`, `createdAt`, `priority`, `status`, `title`. Минус — по убыванию.","schema":{"type":"string","example":"-updatedAt"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assignee":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","object","title","description","status","priority","assignee","sortOrder","createdAt","updatedAt"],"additionalProperties":false,"description":"Карточка доски задач"}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Доска одна на панель и агента: карточка, созданная через API, сразу видна в интерфейсе и доступна диспетчеру цифровых сотрудников. Показ `include` не поддерживается — состав плоский.","x-code-samples":[{"lang":"Shell","source":"curl -H \"Authorization: Bearer ***\" \"https://rkdash.com/api/v1/cards?filter[status]=new&limit=5\""}]},"post":{"operationId":"cards_create","summary":"Завести задачу на доске","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assignee":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","object","title","description","status","priority","assignee","sortOrder","createdAt","updatedAt"],"additionalProperties":false,"description":"Карточка доски задач"},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Создаёт карточку в `kanban.db` — том же файле, из которого живёт канбан. Исполнитель берётся из /agents: неизвестный профиль отклоняется, чтобы задача не повисла без исполнителя.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300,"description":"Заголовок карточки"},"description":{"description":"Описание: что нужно сделать","type":"string","maxLength":20000},"priority":{"description":"Приоритет, по умолчанию medium","type":"string","enum":["low","medium","high"]},"assigneeId":{"description":"Профиль исполнителя из GET /agents","type":"string","minLength":1,"maxLength":64},"assigneeName":{"description":"Отображаемое имя исполнителя","type":"string","maxLength":200}},"required":["title"]}}}},"x-code-samples":[{"lang":"Shell","source":"curl -X POST -H \"Authorization: Bearer ***\" -H \"Idempotency-Key: 4f1a\" -H \"Content-Type: application/json\" -d '{\"title\": \"Проверить фудкост за неделю\", \"assigneeId\": \"analyst\"}' https://rkdash.com/api/v1/cards"}]}},"/agent-tasks":{"get":{"operationId":"agent_tasks","summary":"Задачи, которые ждут исполнителя","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"filter[assignee]","in":"query","required":false,"description":"Исполнитель: профиль или имя из /agents. Обязателен.","schema":{"type":"string","example":"analyst"}},{"name":"filter[status]","in":"query","required":false,"description":"Колонка: `new` по умолчанию, `in_progress`, `review`, `done`.","schema":{"type":"string","enum":["new","in_progress","review","done"],"example":"new"}},{"name":"limit","in":"query","required":false,"description":"Сколько задач вернуть.","schema":{"type":"number","example":"5"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assignee":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","object","title","description","status","priority","assignee","sortOrder","createdAt","updatedAt"],"additionalProperties":false,"description":"Карточка доски задач"}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"То же, что видно на доске, но глазами агента: что назначено на него и ещё не начато. Нужен агенту на своём сервере — платформа не всегда может достучаться до него сама, а забрать задачу он может этим запросом.","x-code-samples":[{"lang":"Shell","source":"curl -H \"Authorization: Bearer ***\" \"https://rkdash.com/api/v1/agent-tasks?filter[assignee]=analyst&limit=5\""}]}},"/cards/{id}":{"get":{"operationId":"cards_get","summary":"Карточка по идентификатору","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assignee":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","object","title","description","status","priority","assignee","sortOrder","createdAt","updatedAt"],"additionalProperties":false,"description":"Карточка доски задач"}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"cards_update","summary":"Двинуть карточку: статус, приоритет, исполнитель","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assignee":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","object","title","description","status","priority","assignee","sortOrder","createdAt","updatedAt"],"additionalProperties":false,"description":"Карточка доски задач"},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"То же, что перетаскивание карточки в панели: `in_progress` — «взял в работу», `done` — задача закрыта.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":20000},"status":{"description":"Колонка доски: движение карточки","type":"string","enum":["new","in_progress","review","done"]},"priority":{"type":"string","enum":["low","medium","high"]},"assigneeId":{"type":"string","minLength":1,"maxLength":64,"description":"Профиль исполнителя — значение из GET /agents"},"assigneeName":{"type":"string","maxLength":200},"sortOrder":{"description":"Порядок внутри колонки","type":"integer","minimum":0,"maximum":100000}}}}}}},"delete":{"operationId":"cards_delete","summary":"Убрать карточку с доски","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Архивация: карточка уходит с доски, история задачи сохраняется в базе."}},"/cards/{id}/comments":{"get":{"operationId":"cards_comments_list","summary":"Лента карточки","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card_comment"},"cardId":{"type":"string"},"author":{"type":"string"},"authorType":{"type":"string","enum":["user","agent"]},"content":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","object","cardId","author","authorType","content","createdAt"],"additionalProperties":false,"description":"Комментарий к карточке доски"},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Комментарии людей и итоговые отчёты агентов в одном порядке — то, что видно в ленте карточки в панели."},"post":{"operationId":"cards_comments_create","summary":"Комментарий к карточке","tags":["Доска"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"card_comment"},"cardId":{"type":"string"},"author":{"type":"string"},"authorType":{"type":"string","enum":["user","agent"]},"content":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","object","cardId","author","authorType","content","createdAt"],"additionalProperties":false,"description":"Комментарий к карточке доски"},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Отчёт агента по задаче: автор по умолчанию — исполнитель карточки. Появление комментария порождает событие `card.commented`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":10000,"description":"Текст комментария"},"author":{"description":"Автор, по умолчанию — исполнитель карточки","type":"string","minLength":1,"maxLength":200}},"required":["content"]}}}},"x-code-samples":[{"lang":"Shell","source":"curl -X POST -H \"Authorization: Bearer ***\" -H \"Idempotency-Key: 9c2\" -H \"Content-Type: application/json\" -d '{\"content\": \"Фудкост пересчитан, отчёт во вложении\"}' https://rkdash.com/api/v1/cards/t_.../comments"}]}},"/agents":{"get":{"operationId":"agents_list","summary":"Исполнители задач","tags":["Агенты"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}},{"name":"filter[kind]","in":"query","required":false,"description":"`employee` или `developer`.","schema":{"type":"string","enum":["employee","developer"]}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Профиль исполнителя — значение для assigneeId"},"object":{"type":"string","const":"assignee"},"name":{"type":"string"},"kind":{"type":"string","enum":["employee","developer"],"description":"employee — цифровой сотрудник, developer — разработка"},"role":{"type":"string"}},"required":["id","object","name","kind","role"],"additionalProperties":false,"description":"Исполнитель задач: цифровой сотрудник или профиль разработки"}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Цифровые сотрудники выполняют работу по ресторану, профили разработки — доработку платформы. Значение `id` подставляется в `assigneeId` карточки."}},"/ai/ask":{"post":{"operationId":"ai_ask","summary":"Спросить агента о данных","tags":["AI"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"object":{"type":"string","const":"ai_answer"},"question":{"type":"string"},"threadId":{"type":"string"},"answer":{"type":"string"},"agentId":{"type":"string"},"surfaceId":{"anyOf":[{"type":"string"},{"type":"null"}]},"envelopes":{"type":"array","items":{}},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"source":{"type":"string"},"validationErrors":{"type":"array","items":{}}},"required":["object","question","threadId","answer","agentId","surfaceId","envelopes","attempts","source","validationErrors"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Вопрос на русском уходит агенту `rkdash`: в ответе текст и готовая поверхность A2UI — блоки дашборда, которые можно отрисовать у себя.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":3,"maxLength":2000,"description":"Вопрос по данным ресторана, на русском"},"threadId":{"description":"Идентификатор диалога: с тем же threadId агент помнит предыдущие вопросы","type":"string","maxLength":120},"agentId":{"description":"Агент Mastra, по умолчанию rkdash","type":"string","maxLength":60},"context":{"description":"Дополнительный контекст для агента","type":"string","maxLength":4000}},"required":["question"]}}}},"x-code-samples":[{"lang":"Shell","source":"curl -X POST -H \"Authorization: Bearer $RKDASH_KEY\" -H \"Content-Type: application/json\" -d '{\"question\":\"Какая выручка за август?\",\"threadId\":\"demo-1\"}' https://rkdash.com/api/v1/ai/ask"}]}},"/webhooks":{"get":{"operationId":"webhooks_list","summary":"Подписки на события","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"lastStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"lastError":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastAttemptAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"successCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","object","url","description","events","active","createdAt","updatedAt","lastStatus","lastError","lastAttemptAt","successCount","failureCount"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"webhooks_create","summary":"Подписаться на события","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Отдаёт секрет подписи — он показывается один раз при создании.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"targetKind":{"description":"url — HTTP-приёмник, hermes_profile — профиль агента Hermes, telegram — человек в чате","type":"string","enum":["url","hermes_profile","telegram"]},"agentProfile":{"description":"Профиль Hermes, которого будит событие (значение из GET /agents)","type":"string","minLength":1,"maxLength":64},"chatId":{"description":"Чат Telegram для получателя-человека (targetKind = telegram)","type":"string","minLength":1,"maxLength":64},"deliveryMode":{"description":"wake — прогон профиля с текстом события, card — задача на доске, telegram — сообщение человеку","type":"string","enum":["http","wake","card","telegram"]},"url":{"description":"Адрес, куда шлём POST с событием (targetKind = url)","type":"string","maxLength":500,"format":"uri"},"events":{"minItems":1,"type":"array","items":{"type":"string","enum":["dish.updated","check.created","agent.run.started","agent.run.finished","agent.run.failed","agent.run.limited","agent.step","card.created","card.moved","card.done","card.commented","stock.low","task.run.started","task.run.finished","task.run.failed","etl.sync.started","etl.sync.finished","dashboard.published","etl.sync.failed","agent.needs_approval","digest.ready","booking.created","booking.waitlist.joined","runner.down","runner.up"]},"description":"События подписки. Пустой список означает «все события» только при явной передаче []"},"cardId":{"description":"Следить за одной задачей: событие уходит, только если оно про эту карточку (issue #108)","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"description":{"type":"string","maxLength":300},"active":{"type":"boolean"}},"required":["events"]}}}}}},"/webhooks/{id}":{"get":{"operationId":"webhooks_get","summary":"Подписка по идентификатору","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"lastStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"lastError":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastAttemptAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"successCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","object","url","description","events","active","createdAt","updatedAt","lastStatus","lastError","lastAttemptAt","successCount","failureCount"],"additionalProperties":false}},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"generatedAt":{"type":"string"}},"required":["requestId","limit","offset","hasMore","nextCursor","total","generatedAt"],"additionalProperties":false}},"required":["object","data","meta"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"webhooks_update","summary":"Изменить подписку","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"lastStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"lastError":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastAttemptAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"successCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","object","url","description","events","active","createdAt","updatedAt","lastStatus","lastError","lastAttemptAt","successCount","failureCount"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"targetKind":{"description":"url — HTTP-приёмник, hermes_profile — профиль агента Hermes, telegram — человек в чате","type":"string","enum":["url","hermes_profile","telegram"]},"agentProfile":{"description":"Профиль Hermes, которого будит событие (значение из GET /agents)","type":"string","minLength":1,"maxLength":64},"chatId":{"description":"Чат Telegram для получателя-человека (targetKind = telegram)","type":"string","minLength":1,"maxLength":64},"deliveryMode":{"description":"wake — прогон профиля с текстом события, card — задача на доске, telegram — сообщение человеку","type":"string","enum":["http","wake","card","telegram"]},"url":{"description":"Адрес, куда шлём POST с событием (targetKind = url)","type":"string","maxLength":500,"format":"uri"},"events":{"minItems":1,"type":"array","items":{"type":"string","enum":["dish.updated","check.created","agent.run.started","agent.run.finished","agent.run.failed","agent.run.limited","agent.step","card.created","card.moved","card.done","card.commented","stock.low","task.run.started","task.run.finished","task.run.failed","etl.sync.started","etl.sync.finished","dashboard.published","etl.sync.failed","agent.needs_approval","digest.ready","booking.created","booking.waitlist.joined","runner.down","runner.up"]},"description":"События подписки. Пустой список означает «все события» только при явной передаче []"},"cardId":{"description":"Следить за одной задачей: событие уходит, только если оно про эту карточку (issue #108)","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"description":{"type":"string","maxLength":300},"active":{"type":"boolean"}}}}}}},"delete":{"operationId":"webhooks_delete","summary":"Удалить подписку","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhooks/{id}/deliveries/{deliveryId}/replay":{"post":{"operationId":"webhooks_deliveries_replay","summary":"Повторить доставку события","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор сервиса, например `rkeeper`"},{"name":"Idempotency-Key","in":"header","required":false,"description":"Ключ повтора: запрос с тем же ключом и телом вернёт прежний ответ, с другим телом — 409.","schema":{"type":"string","example":"7f2c1a90-..."}}],"responses":{"201":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Возвращает запись журнала в очередь и выполняет попытку сразу. Новой записи не создаётся: в интерфейсе приёмника не появляется дубль."}},"/events/stream":{"get":{"operationId":"events_stream","summary":"Живой поток событий (SSE)","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"text/event-stream: `event: <тип>` и `data: <payload>`, каждые 20 секунд — keepalive.","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"Пустой ответ"}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Событие приходит в панель и активную сессию агента без перезагрузки. Живой канал и доставка вебхукам — один и тот же момент. Ключ передаётся в заголовке Authorization."}},"/webhooks/{id}/deliveries":{"get":{"operationId":"webhooks_deliveries","summary":"Журнал доставок","tags":["Вебхуки"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор объекта из списка (например `dish_...`, `rst_...`)"},{"name":"limit","in":"query","required":false,"description":"Размер страницы, по умолчанию 50, максимум 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"Курсор следующей страницы из `meta.nextCursor`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Успешный ответ","headers":{"X-RateLimit-Limit":{"description":"Лимит запросов в минуту для ключа","schema":{"type":"integer","example":100}},"X-RateLimit-Remaining":{"description":"Сколько запросов осталось в текущем окне","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Момент сброса окна (unix-время, секунды)","schema":{"type":"integer"}},"Retry-After":{"description":"Через сколько секунд повторить (при 429)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"item"},"data":{"type":"object","properties":{"id":{"type":"string"},"event":{"type":"string"},"status":{"type":"string","enum":["pending","success","failed"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"responseStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","event","status","attempts","responseStatus","error","createdAt","updatedAt"],"additionalProperties":false},"meta":{"type":"object","properties":{"requestId":{"type":"string"},"apiVersion":{"type":"string"},"generatedAt":{"type":"string"}}}},"required":["data"]}}}},"400":{"description":"Некорректный запрос: параметры не прошли проверку","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Ключ не передан, отозван или не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"У ключа нет нужной области доступа","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Объект не найден","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Конфликт: Idempotency-Key с другим телом запроса","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Тело запроса не прошло проверку схемы","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Превышен лимит: 100 в минуту, всплеск 20 в секунду","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Внутренняя ошибка","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"description":"Видно, куда и с каким результатом ушло каждое событие, включая повторные попытки."}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"rk_live_… / rk_test_…","description":"Ключ API из раздела «Настройки → API»"},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Тот же ключ, если удобнее передавать заголовком"}},"schemas":{"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"detail":{"type":"string"},"instance":{"type":"string"},"code":{"type":"string"},"requestId":{"type":"string"}},"required":["type","title","status","detail","instance","code","requestId"],"additionalProperties":false}}},"x-rate-limits":{"perMinute":100,"burstPerSecond":20}}