{
  "openapi": "3.0.0",
  "info": {
    "title": "Rentu External API v2",
    "description": "Внешнее API Rentu для интеграций торговых центров: выручка, чеки, посещаемость, аномалии, состояние касс.\n\nЭто машиночитаемый справочник методов. Повествовательная документация — как получить доступ, чем отличаются тарифы, что повторять при ошибке — на отдельном сайте документации.\n\n## Базовый URL\n\n| Среда | URL |\n|---|---|\n| Production | `https://api.rentu.ru/api/external/v2` |\n| Stage | `https://stage-api.rentu.ru/api/external/v2` |\n\n## Авторизация\n\n`POST /auth/token` меняет пару `client_id` + `client_secret` на JWT. Токен живёт час и передаётся заголовком `Authorization: Bearer <token>`. Токены v1 и v2 несовместимы в обе стороны.\n\nКлюч принадлежит сотруднику торгового центра: доступные центры определяются его ролями и проверяются на каждом запросе. Сняли роль — центр пропадает из выдачи, отдельно отзывать ключ не нужно.\n\n## Конверт ответа\n\nУспех — `{\"success\": true, \"data\": ..., \"meta\": ...}`, ошибка — `{\"success\": false, \"error\": {\"code\": ..., \"message\": ..., \"details\": ...}}`.\n\n**Ветвитесь по `error.code`, а не по HTTP-статусу**: одному статусу соответствует несколько кодов. Повторять имеет смысл только `token_expired` (после обновления токена), `rate_limited` (после `Retry-After`), `rights_unavailable`, `traffic_unavailable` и `internal_error`.\n\n## Тарифы\n\nТариф — свойство **торгового центра**, а не ключа: один ключ может покрывать несколько центров на разных тарифах.\n\n| | Basic | PRO |\n|---|---|---|\n| Период в одном запросе, подневные данные | 31 день | 366 дней |\n| Период в одном запросе, месячные итоги | 12 месяцев | 36 месяцев |\n| Самая свежая дата | вчера | сегодня |\n| Чеки и аномалии | — | да |\n| Посещаемость по часам, по зоне и по точке | — | да |\n| Расчётный товарооборот (turnover) | — | да |\n| Начисленная аренда (rent) и OCR | — | да |\n| Средний чек, выручка на м² | — | да |\n| Частота | 60/мин, 5 000/сутки | 300/мин, 50 000/сутки |\n\n## Форматы\n\nДенежные суммы — целые **копейки**. Даты в параметрах — `YYYY-MM-DD`. Моменты времени в ответах — ISO 8601 со смещением таймзоны центра; сама зона приходит в `meta.time_zone`. Границы суток считаются в таймзоне центра, а не в UTC.\n\n## Лимиты частоты\n\nСчитаются по **торговому центру**, а не по ключу: сотрудники одного центра делят общий бюджет запросов. Заводить дополнительные ключи ради скорости бесполезно. На успешных ответах приходят `X-RateLimit-Limit`, `X-RateLimit-Remaining` и `X-RateLimit-Reset` для минутного окна; на `429` — ещё и `Retry-After`.\n",
    "version": "1.0"
  },
  "paths": {
    "/api/external/v2/sc/{sc_id}/anomalies": {
      "get": {
        "summary": "Anomalies of the shopping centre",
        "tags": [
          "Anomalies v2"
        ],
        "description": "Аномалии продаж, найденные системой: те же, что видит менеджер ТЦ.\nТолько тариф PRO. Период задаётся `start_date`/`end_date` (до 366 дней),\nграницы суток считаются в таймзоне ТЦ.\nФильтры: `shop_id`, `status` (`new`, `completed`, `archived`),\n`level` (`high`, `medium`, `low`). Сортировка — от свежих к старым.\nПагинация `page`/`per_page` (по умолчанию 100, максимум 500).\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79edaf693b5442dc002"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "lists anomalies with their type, level and shop": {
                    "summary": "lists anomalies with their type, level and shop",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b79edaf693b5442dc012",
                          "status": "new",
                          "magnitude": 43.91,
                          "date": "2026-08-05T14:46:54+04:00",
                          "created_at": "2026-08-07T14:46:54+04:00",
                          "type": 982,
                          "type_title": "Средний чек возврата значительно превышает средний чек прихода",
                          "level": "high",
                          "shop_id": "6a75b79edaf693b5442dc004",
                          "shop_name": "Сбыт ОП Римма",
                          "title": "Аномально высокий процент расчета за безналичный расчет",
                          "description": "Как правило идет сокрытие выручки за наличный расчет",
                          "period": [
                            "2026-08-04T03:08:08+04:00",
                            "2026-08-05T11:45:41+04:00"
                          ]
                        }
                      ],
                      "meta": {
                        "pagination": {
                          "page": 1,
                          "per_page": 100,
                          "total": 1
                        },
                        "time_zone": "Europe/Samara"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/anomalies_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/attendance": {
      "post": {
        "summary": "Submit daily attendance",
        "tags": [
          "Attendance submission v2"
        ],
        "description": "Приём посещаемости за сутки от собственных счётчиков ТЦ. Доступно\nна любом тарифе.\n\nОбязательны `date` и `visitors`. `scope` задаёт адресата тем же\nсловарём, что и чтение посещаемости: `sc` — периметр всего центра\n(по умолчанию), `zone` — отдельная зона, и тогда обязателен `zone_id`\nиз справочника зон. При `scope=sc` передавать `zone_id` нельзя.\n\nДата в будущем отклоняется, граница считается в таймзоне ТЦ.\nПовторный вызов за те же сутки перезаписывает значение.\n\nВ API v1 это были два отдельных метода — по ТЦ и по зоне; здесь они\nсведены в один.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79edaf693b5442dc018"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          },
          {
            "name": "Content-Type",
            "in": "header",
            "example": "application/x-www-form-urlencoded"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "examples": {
                "writes the daily count to the perimeter area": {
                  "summary": "writes the daily count to the perimeter area",
                  "value": "date=2026-08-06&visitors=5000"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "writes the daily count to the perimeter area": {
                    "summary": "writes the daily count to the perimeter area",
                    "value": {
                      "success": true,
                      "data": {
                        "date": "2026-08-06",
                        "scope": "sc",
                        "zone_id": null,
                        "visitors": 5000
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/attendance_write_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      },
      "get": {
        "summary": "Attendance of the shopping centre",
        "tags": [
          "Attendance v2"
        ],
        "description": "Посещаемость по данным системы подсчёта. Период — `start_date`/`end_date` по тарифу.\n\n`granularity`: `day` (по умолчанию), `week`, `month` — Basic; `hour` — только PRO,\nи период для него не больше 31 дня.\n`scope`: `sc` (по умолчанию) — Basic; `zone` (с `zone_id` из справочника зон)\nи `shop` (с `shop_id`) — только PRO. Неподходящее тарифу значение — 403 `plan_required`.\n\nМетки периода: дата для `day`/`week`/`month`, время со смещением ТЦ для `hour`.\nЕсли ТЦ или точка не покрыты зонами подсчёта, `data` пустой — это не ошибка.\nЕсли система подсчёта в ТЦ не настроена вовсе — 404 `traffic_not_configured`;\nесли подсистема подсчёта не ответила — 503 `traffic_unavailable`, запрос можно повторить.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79edaf693b5442dc01e"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "returns daily totals of the shopping centre": {
                    "summary": "returns daily totals of the shopping centre",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "date": "2026-08-06",
                          "visitors_in": 415,
                          "visitors_out": 878
                        }
                      ],
                      "meta": {
                        "granularity": "day",
                        "scope": "sc",
                        "time_zone": "Europe/Samara"
                      }
                    }
                  },
                  "returns hourly rows with the centre offset and keeps the last day whole": {
                    "summary": "returns hourly rows with the centre offset and keeps the last day whole",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "date": "2026-08-06T12:00:00+07:00",
                          "visitors_in": 83,
                          "visitors_out": 445
                        }
                      ],
                      "meta": {
                        "granularity": "hour",
                        "scope": "sc",
                        "time_zone": "Asia/Krasnoyarsk"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/attendance_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/auth/token": {
      "post": {
        "summary": "Issue access token",
        "tags": [
          "Auth v2"
        ],
        "description": "Выдача токена по client_credentials (client_id + client_secret выдаются командой Rentu).\nТокен живёт 1 час, передаётся в заголовке `Authorization: Bearer <token>`.\nТокены v2 не работают в v1 и наоборот.\n\nКлюч принадлежит сотруднику ТЦ, и доступ к данным определяется его ролями:\nотобрали роль — ТЦ пропадает из выдачи, отдельный отзыв ключа не нужен.\n\nГлубина данных зависит от тарифа **торгового центра**, а не ключа: один\nключ может покрывать несколько ТЦ на разных тарифах. Частота запросов\nтоже считается по ТЦ — сотрудники одного ТЦ делят общий лимит.\n",
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          },
          {
            "name": "Content-Type",
            "in": "header",
            "example": "application/json"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "issues a short-lived bearer JWT bound to the client": {
                  "summary": "issues a short-lived bearer JWT bound to the client",
                  "value": {
                    "client_id": "94d4bae0-590d-445a-bcb3-820afcab7471",
                    "client_secret": "v2-client-secret-000000000000000000000000000000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "issues a short-lived bearer JWT bound to the client": {
                    "summary": "issues a short-lived bearer JWT bound to the client",
                    "value": {
                      "success": true,
                      "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI5NGQ0YmFlMC01OTBkLTQ0NWEtYmNiMy04MjBhZmNhYjc0NzEiLCJhdWQiOiJleHRlcm5hbC12MiIsImp0aSI6IjYxNWFkZTgyLTQ4ZTMtNGQ1Yi1hZjVhLTdhNGYzNmUyNDRlNCIsImlhdCI6MTc4NjA5OTYxNSwiZXhwIjoxNzg2MTAzMjE1fQ.leqfwhHZYqisr7uWNX75T3fAYFjVrG02ls5bwzsFyIjN7VXtljMo0zsWH5n0_9e0gZOOPYKHLQlR66_BITqD1A",
                      "token_type": "Bearer",
                      "expires_in": 3600
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/auth_token_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/events": {
      "post": {
        "summary": "Register an event of the shopping centre",
        "tags": [
          "Events v2"
        ],
        "description": "Приём событий ТЦ — акций, распродаж, ремонтов. Доступно на любом тарифе:\nза передачу данных нам мы денег не берём.\n\nОбязательны `name`, `description`, `event_type`, `start_date`, `end_date`.\n`event_type` — `calendar`, `marketing` или `other`; служебные типы платформы\nснаружи не принимаются. `shop_ids` — точки, к которым относится событие,\nпроверяются по этому ТЦ. `color` — HEX вида `#RRGGBB`, по умолчанию серый;\nдругие записи цвета (`rgb(...)`, имена) не принимаются.\n\nМетод создаёт **новое** событие. Полный дубль — совпали название, тип\nи обе даты в рамках ТЦ — отклоняется с 409 `already_exists_in_sc`.\nСуществующее событие при этом не меняется: чтобы поправить описание или\nцвет, редактируйте событие в интерфейсе ТЦ.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79fdaf693b5442dc02f"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          },
          {
            "name": "Content-Type",
            "in": "header",
            "example": "application/x-www-form-urlencoded"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "examples": {
                "registers the event and returns it": {
                  "summary": "registers the event and returns it",
                  "value": "name=%D0%A7%D1%91%D1%80%D0%BD%D0%B0%D1%8F+%D0%BF%D1%8F%D1%82%D0%BD%D0%B8%D1%86%D0%B0&description=%D0%A1%D0%BA%D0%B8%D0%B4%D0%BA%D0%B8+%D0%B2%D0%BE+%D0%B2%D1%81%D1%91%D0%BC+%D0%A2%D0%A6&event_type=marketing&start_date=2026-08-07&end_date=2026-08-10&shop_ids[]=6a75b79fdaf693b5442dc031"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "registers the event and returns it": {
                    "summary": "registers the event and returns it",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "6a75b79fdaf693b5442dc041",
                        "name": "Чёрная пятница",
                        "description": "Скидки во всём ТЦ",
                        "event_type": "marketing",
                        "color": "#EAEAEA",
                        "sell_location_ids": [
                          "6a75b79fdaf693b5442dc031"
                        ],
                        "start_date": "2026-08-07",
                        "end_date": "2026-08-10"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/events_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/shops/{shop_id}/kkts": {
      "get": {
        "summary": "Cash registers of the shop",
        "tags": [
          "Kkts v2"
        ],
        "description": "Кассы торговой точки и признаки их состояния: статус подключения,\nкогда пришёл последний чек, открыта ли смена, когда заканчивается ФН.\nДаты — ISO 8601 в таймзоне ТЦ, сама зона в `meta.time_zone`.\nПагинации нет — касс у точки единицы.\nАрхивные кассы по умолчанию не отдаются. Чтобы получить их вдобавок\nк действующим, передайте `archived=true`; отличать их можно по полю `is_archived`.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79fdaf693b5442dc046"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79fdaf693b5442dc048"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "lists the cash registers of the shop with their state": {
                    "summary": "lists the cash registers of the shop with their state",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b79fdaf693b5442dc056",
                          "model": "[\"quia\", \"voluptate\"]",
                          "reg_id": "0000000000000001",
                          "serial_number": "0000000001",
                          "connection_status": "active",
                          "connection_from": "2026-07-08T00:00:00+05:00",
                          "provider": "[\"blanditiis\", \"optio\"]",
                          "fiscal_number": "1730851221196410",
                          "is_archived": false,
                          "first_document_datetime": "2026-07-31T17:46:55+07:00",
                          "last_document_datetime": "2026-08-07T17:46:55+07:00",
                          "last_open_shift_datetime": "2026-08-07T17:46:55+07:00",
                          "fn_expiration_datetime": "2027-08-07T17:46:55+07:00"
                        }
                      ],
                      "meta": {
                        "time_zone": "Asia/Krasnoyarsk"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/kkts_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/shops/{shop_id}/receipts": {
      "get": {
        "summary": "Shop receipts",
        "tags": [
          "Receipts v2"
        ],
        "description": "Почековая выгрузка (только тариф PRO). Все суммы — в копейках,\nдаты-время — ISO 8601 с явным смещением таймзоны ТЦ.\nТребуется полная пара дат: created (`start_created_date`+`end_created_date`)\nи/или received (`start_received_date`+`end_received_date`); каждая пара — не больше 30 дней.\n                Пагинация `page`/`per_page` (по умолчанию 500, максимум 1000), метаданные в `meta.pagination`.\n\n`document_types` — какие типы фискальных документов выгружать, через запятую.\nПо умолчанию только продажи: `receipt`, `delivery`, `form_of_strict_accountability`.\nПолный список значений — в описании поля `document_type`; неизвестное значение даёт 422.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79fdaf693b5442dc05b"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b79fdaf693b5442dc05d"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "returns receipts with kkt attributes and ISO8601 datetimes with offset": {
                    "summary": "returns receipts with kkt attributes and ISO8601 datetimes with offset",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b79fdaf693b5442dc073",
                          "document_type": "receipt",
                          "created_datetime": "2026-08-04T13:46:55+03:00",
                          "received_datetime": "2026-08-04T13:46:55+03:00",
                          "kkt_id": "6a75b79fdaf693b5442dc06c",
                          "kkt_reg_id": "0000000000000002",
                          "kkt_serial_number": "0000000002",
                          "kkt_fiscal_drive_number": "9320108124571161",
                          "fiscal_document_number": null,
                          "shift_number": null,
                          "shift_check_number": null,
                          "operation_type": 4,
                          "total_sum": 74,
                          "cash_sum": 38,
                          "ecash_sum": 13,
                          "advanced_sum": 146,
                          "full_prepayment_sum": 67,
                          "partial_prepayment_sum": 53,
                          "prepaid_sum": 80,
                          "credit_sum": 63,
                          "provision_sum": 83,
                          "nds_no_sum": 54,
                          "nds_0_sum": 96,
                          "nds_5_sum": 0,
                          "nds_7_sum": 0,
                          "nds_10_sum": 85,
                          "nds_18_sum": 46,
                          "nds_20_sum": 84,
                          "nds_22_sum": 0,
                          "nds_105_sum": 0,
                          "nds_107_sum": 0,
                          "nds_110_sum": 70,
                          "nds_118_sum": 96,
                          "nds_120_sum": 35,
                          "nds_122_sum": 0,
                          "items_count": null
                        },
                        {
                          "id": "6a75b79fdaf693b5442dc071",
                          "document_type": "receipt",
                          "created_datetime": "2026-08-05T13:46:55+03:00",
                          "received_datetime": "2026-08-05T13:46:55+03:00",
                          "kkt_id": "6a75b79fdaf693b5442dc06c",
                          "kkt_reg_id": "0000000000000002",
                          "kkt_serial_number": "0000000002",
                          "kkt_fiscal_drive_number": "9320108124571161",
                          "fiscal_document_number": null,
                          "shift_number": null,
                          "shift_check_number": null,
                          "operation_type": 4,
                          "total_sum": 14,
                          "cash_sum": 17,
                          "ecash_sum": 57,
                          "advanced_sum": 134,
                          "full_prepayment_sum": 14,
                          "partial_prepayment_sum": 54,
                          "prepaid_sum": 44,
                          "credit_sum": 25,
                          "provision_sum": 98,
                          "nds_no_sum": 68,
                          "nds_0_sum": 89,
                          "nds_5_sum": 0,
                          "nds_7_sum": 0,
                          "nds_10_sum": 26,
                          "nds_18_sum": 33,
                          "nds_20_sum": 18,
                          "nds_22_sum": 0,
                          "nds_105_sum": 0,
                          "nds_107_sum": 0,
                          "nds_110_sum": 0,
                          "nds_118_sum": 57,
                          "nds_120_sum": 79,
                          "nds_122_sum": 0,
                          "items_count": null
                        },
                        {
                          "id": "6a75b79fdaf693b5442dc06f",
                          "document_type": "receipt",
                          "created_datetime": "2026-08-06T13:46:55+03:00",
                          "received_datetime": "2026-08-06T13:46:55+03:00",
                          "kkt_id": "6a75b79fdaf693b5442dc06c",
                          "kkt_reg_id": "0000000000000002",
                          "kkt_serial_number": "0000000002",
                          "kkt_fiscal_drive_number": "9320108124571161",
                          "fiscal_document_number": null,
                          "shift_number": null,
                          "shift_check_number": null,
                          "operation_type": 1,
                          "total_sum": 18,
                          "cash_sum": 87,
                          "ecash_sum": 70,
                          "advanced_sum": 128,
                          "full_prepayment_sum": 93,
                          "partial_prepayment_sum": 11,
                          "prepaid_sum": 44,
                          "credit_sum": 60,
                          "provision_sum": 99,
                          "nds_no_sum": 27,
                          "nds_0_sum": 24,
                          "nds_5_sum": 0,
                          "nds_7_sum": 0,
                          "nds_10_sum": 61,
                          "nds_18_sum": 29,
                          "nds_20_sum": 19,
                          "nds_22_sum": 0,
                          "nds_105_sum": 0,
                          "nds_107_sum": 0,
                          "nds_110_sum": 51,
                          "nds_118_sum": 85,
                          "nds_120_sum": 35,
                          "nds_122_sum": 0,
                          "items_count": null
                        }
                      ],
                      "meta": {
                        "pagination": {
                          "page": 1,
                          "per_page": 500,
                          "total": 3
                        },
                        "time_zone": "Europe/Moscow"
                      }
                    }
                  },
                  "returns only the requested types": {
                    "summary": "returns only the requested types",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b7a0daf693b5442dc092",
                          "document_type": "shift_opening_report",
                          "created_datetime": "2026-08-06T17:46:56+07:00",
                          "received_datetime": "2026-08-06T17:46:56+07:00",
                          "kkt_id": "6a75b7a0daf693b5442dc089",
                          "kkt_reg_id": "0000000000000003",
                          "kkt_serial_number": "0000000003",
                          "kkt_fiscal_drive_number": "1012739612411085",
                          "fiscal_document_number": null,
                          "shift_number": null,
                          "shift_check_number": null,
                          "operation_type": 3,
                          "total_sum": 20,
                          "cash_sum": 61,
                          "ecash_sum": 37,
                          "advanced_sum": 86,
                          "full_prepayment_sum": 54,
                          "partial_prepayment_sum": 28,
                          "prepaid_sum": 46,
                          "credit_sum": 47,
                          "provision_sum": 92,
                          "nds_no_sum": 40,
                          "nds_0_sum": 41,
                          "nds_5_sum": 0,
                          "nds_7_sum": 0,
                          "nds_10_sum": 85,
                          "nds_18_sum": 75,
                          "nds_20_sum": 55,
                          "nds_22_sum": 0,
                          "nds_105_sum": 0,
                          "nds_107_sum": 0,
                          "nds_110_sum": 74,
                          "nds_118_sum": 60,
                          "nds_120_sum": 76,
                          "nds_122_sum": 0,
                          "items_count": null
                        }
                      ],
                      "meta": {
                        "pagination": {
                          "page": 1,
                          "per_page": 500,
                          "total": 1
                        },
                        "time_zone": "Asia/Krasnoyarsk"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/receipts_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/reports/shops/{shop_id}/by_days": {
      "get": {
        "summary": "Shop info by days",
        "tags": [
          "Reports v2"
        ],
        "description": "Дневные агрегаты торговой точки. Все суммы — в копейках.\nПагинация `page`/`per_page` (по умолчанию 100, максимум 366), метаданные в `meta`.\nТариф Basic: данные до вчера (D+1), период до 92 дней. Тариф PRO: включая сегодня, период до 366 дней.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a0daf693b5442dc096"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a0daf693b5442dc098"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "returns day rows identical to v1 projection with pagination meta and timezone": {
                    "summary": "returns day rows identical to v1 projection with pagination meta and timezone",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "date": "2026-08-04",
                          "kkts_count": 0,
                          "receipts_count": 510,
                          "income_receipts_count": 2185.0,
                          "refund_receipts_count": 592.0,
                          "income_sum": 82000,
                          "income_without_nds_sum": 866100,
                          "refund_sum": 924000,
                          "refund_without_nds_sum": 258800,
                          "cash_sum": 3524,
                          "ecash_sum": 1093,
                          "advanced_sum": 5025,
                          "full_prepayment_sum": 4048,
                          "partial_prepayment_sum": 171,
                          "prepaid_sum": 7373,
                          "credit_sum": 6049,
                          "provision_sum": 6711,
                          "refund_cash_sum": 7824,
                          "refund_ecash_sum": 3091,
                          "refund_prepaid_sum": 6082,
                          "refund_credit_sum": 7733,
                          "refund_provision_sum": 1692,
                          "nds_no_sum": 8627,
                          "nds_0_sum": 8859,
                          "nds_5_sum": 222,
                          "nds_7_sum": 5411,
                          "nds_10_sum": 3707,
                          "nds_18_sum": 2508,
                          "nds_20_sum": 3633,
                          "nds_22_sum": 4860,
                          "nds_105_sum": 9269,
                          "nds_107_sum": 7140,
                          "nds_110_sum": 8357,
                          "nds_118_sum": 2225,
                          "nds_120_sum": 5689,
                          "nds_122_sum": 9826,
                          "refund_nds_no_sum": 9746,
                          "refund_nds_0_sum": 4438,
                          "refund_nds_5_sum": 7548,
                          "refund_nds_7_sum": 4844,
                          "refund_nds_10_sum": 9875,
                          "refund_nds_18_sum": 5055,
                          "refund_nds_20_sum": 8834,
                          "refund_nds_22_sum": 3933,
                          "refund_nds_105_sum": 9894,
                          "refund_nds_107_sum": 6657,
                          "refund_nds_110_sum": 53,
                          "refund_nds_118_sum": 8187,
                          "refund_nds_120_sum": 7407,
                          "refund_nds_122_sum": 7723,
                          "turnover": 0
                        },
                        {
                          "date": "2026-08-05",
                          "kkts_count": 0,
                          "receipts_count": 191,
                          "income_receipts_count": 289.0,
                          "refund_receipts_count": 4097.0,
                          "income_sum": 35900,
                          "income_without_nds_sum": 212400,
                          "refund_sum": 482900,
                          "refund_without_nds_sum": 881400,
                          "cash_sum": 9577,
                          "ecash_sum": 9941,
                          "advanced_sum": 16161,
                          "full_prepayment_sum": 9610,
                          "partial_prepayment_sum": 2573,
                          "prepaid_sum": 1463,
                          "credit_sum": 586,
                          "provision_sum": 2963,
                          "refund_cash_sum": 3936,
                          "refund_ecash_sum": 1766,
                          "refund_prepaid_sum": 5189,
                          "refund_credit_sum": 8958,
                          "refund_provision_sum": 4897,
                          "nds_no_sum": 9702,
                          "nds_0_sum": 8690,
                          "nds_5_sum": 5768,
                          "nds_7_sum": 2779,
                          "nds_10_sum": 9989,
                          "nds_18_sum": 8964,
                          "nds_20_sum": 78,
                          "nds_22_sum": 7730,
                          "nds_105_sum": 939,
                          "nds_107_sum": 6900,
                          "nds_110_sum": 7292,
                          "nds_118_sum": 6543,
                          "nds_120_sum": 1400,
                          "nds_122_sum": 4621,
                          "refund_nds_no_sum": 4946,
                          "refund_nds_0_sum": 5520,
                          "refund_nds_5_sum": 2823,
                          "refund_nds_7_sum": 6672,
                          "refund_nds_10_sum": 5900,
                          "refund_nds_18_sum": 4923,
                          "refund_nds_20_sum": 6248,
                          "refund_nds_22_sum": 9774,
                          "refund_nds_105_sum": 6807,
                          "refund_nds_107_sum": 5936,
                          "refund_nds_110_sum": 3099,
                          "refund_nds_118_sum": 8577,
                          "refund_nds_120_sum": 2455,
                          "refund_nds_122_sum": 9326,
                          "turnover": 0
                        },
                        {
                          "date": "2026-08-06",
                          "kkts_count": 0,
                          "receipts_count": 401,
                          "income_receipts_count": 4993.0,
                          "refund_receipts_count": 4190.0,
                          "income_sum": 25800,
                          "income_without_nds_sum": 18700,
                          "refund_sum": 300300,
                          "refund_without_nds_sum": 434500,
                          "cash_sum": 1733,
                          "ecash_sum": 4562,
                          "advanced_sum": 19108,
                          "full_prepayment_sum": 8801,
                          "partial_prepayment_sum": 5583,
                          "prepaid_sum": 3188,
                          "credit_sum": 2518,
                          "provision_sum": 1392,
                          "refund_cash_sum": 12,
                          "refund_ecash_sum": 4692,
                          "refund_prepaid_sum": 78,
                          "refund_credit_sum": 7946,
                          "refund_provision_sum": 5445,
                          "nds_no_sum": 896,
                          "nds_0_sum": 2782,
                          "nds_5_sum": 8918,
                          "nds_7_sum": 1921,
                          "nds_10_sum": 3172,
                          "nds_18_sum": 3264,
                          "nds_20_sum": 234,
                          "nds_22_sum": 3565,
                          "nds_105_sum": 6106,
                          "nds_107_sum": 1333,
                          "nds_110_sum": 1280,
                          "nds_118_sum": 4308,
                          "nds_120_sum": 5919,
                          "nds_122_sum": 554,
                          "refund_nds_no_sum": 3092,
                          "refund_nds_0_sum": 8258,
                          "refund_nds_5_sum": 7901,
                          "refund_nds_7_sum": 8910,
                          "refund_nds_10_sum": 2143,
                          "refund_nds_18_sum": 3722,
                          "refund_nds_20_sum": 3504,
                          "refund_nds_22_sum": 234,
                          "refund_nds_105_sum": 4373,
                          "refund_nds_107_sum": 5056,
                          "refund_nds_110_sum": 8032,
                          "refund_nds_118_sum": 6464,
                          "refund_nds_120_sum": 3239,
                          "refund_nds_122_sum": 6374,
                          "turnover": 0
                        }
                      ],
                      "meta": {
                        "pagination": {
                          "page": 1,
                          "per_page": 100,
                          "total": 3
                        },
                        "time_zone": "Asia/Irkutsk"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/reports/shops_by_days_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "rejects today (freshness D+1) with machine-readable code": {
                    "summary": "rejects today (freshness D+1) with machine-readable code",
                    "value": {
                      "success": false,
                      "error": {
                        "code": "fresh_data_requires_pro",
                        "message": "Конечная дата за сегодняшний день доступна только на тарифе PRO (Basic — данные до вчера)",
                        "details": {
                          "end_date": [
                            "за сегодняшний день доступна только на тарифе PRO (Basic — данные до вчера)"
                          ]
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/error_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/reports/shops/{shop_id}/by_months": {
      "get": {
        "summary": "Shop info by months",
        "tags": [
          "Reports v2"
        ],
        "description": "Месячные итоги торговой точки: то же, что показывает отчёт ТЦ. Все суммы — в копейках.\nГраницы периода задаются датами `start_date`/`end_date` и расширяются до целых месяцев.\nПагинации нет: строк не больше, чем месяцев в разрешённом периоде.\nТариф Basic: период до 92 дней, данные до вчера (D+1). Тариф PRO: до 366 дней, включая сегодня,\nи дополнительно поля `average_check_sum`, `revenue_per_area`, `ocr`.\nДетализация по типам оплат и ставкам НДС — в `by_days`.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a0daf693b5442dc0d9"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a0daf693b5442dc0db"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "returns month totals in kopecks, oldest first": {
                    "summary": "returns month totals in kopecks, oldest first",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "date": "2026-06",
                          "receipts_count": 0,
                          "income_receipts_count": 21.36,
                          "refund_receipts_count": 44.27,
                          "income_sum": 9347,
                          "income_without_nds_sum": 8296,
                          "refund_sum": 2066,
                          "refund_without_nds_sum": 1116,
                          "manual_turnover": 60947,
                          "is_manual": true,
                          "visitors": 0,
                          "area_size": 20.2,
                          "is_outdoor": true
                        },
                        {
                          "date": "2026-07",
                          "receipts_count": 42,
                          "income_receipts_count": 40.0,
                          "refund_receipts_count": 2.0,
                          "income_sum": 123456,
                          "income_without_nds_sum": 100000,
                          "refund_sum": 1234,
                          "refund_without_nds_sum": 1000,
                          "manual_turnover": 0,
                          "is_manual": false,
                          "visitors": 500,
                          "area_size": 0.0,
                          "is_outdoor": false
                        }
                      ]
                    }
                  },
                  "adds the analytics fields, revenue per area in kopecks": {
                    "summary": "adds the analytics fields, revenue per area in kopecks",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "date": "2026-06",
                          "receipts_count": 0,
                          "income_receipts_count": 69.76,
                          "refund_receipts_count": 14.16,
                          "income_sum": 8002,
                          "income_without_nds_sum": 3638,
                          "refund_sum": 9381,
                          "refund_without_nds_sum": 6149,
                          "manual_turnover": 43616,
                          "is_manual": true,
                          "visitors": 0,
                          "area_size": 86.1,
                          "is_outdoor": false,
                          "turnover": 0,
                          "rent": 63809412,
                          "average_check_sum": 0,
                          "revenue_per_area": 0,
                          "ocr": 78.7
                        },
                        {
                          "date": "2026-07",
                          "receipts_count": 42,
                          "income_receipts_count": 40.0,
                          "refund_receipts_count": 2.0,
                          "income_sum": 123456,
                          "income_without_nds_sum": 100000,
                          "refund_sum": 1234,
                          "refund_without_nds_sum": 1000,
                          "manual_turnover": 0,
                          "is_manual": false,
                          "visitors": 500,
                          "area_size": 0.0,
                          "is_outdoor": false,
                          "turnover": 123456,
                          "rent": 0,
                          "average_check_sum": 2938,
                          "revenue_per_area": 70000,
                          "ocr": 12.5
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/reports/shops_by_months_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/sensors/{external_id}/traffic": {
      "post": {
        "summary": "Submit hourly traffic from a counter",
        "tags": [
          "Sensor traffic v2"
        ],
        "description": "Почасовая выгрузка со стороннего счётчика посещаемости. Доступно\nна любом тарифе.\n\nСчётчик адресуется своим `external_id` — тем, под которым он заведён\nпри подключении. Отдельного справочника счётчиков в API нет:\nидентификатор принадлежит стороне, которая передаёт данные.\n\n`data` — до 1000 записей за вызов, каждая с `datetime` (начало часа,\nISO 8601), `in` и `out`. Повторная присылка того же часа перезаписывает\nзначения.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a0daf693b5442dc100"
          },
          {
            "name": "external_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "gate-1"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          },
          {
            "name": "Content-Type",
            "in": "header",
            "example": "application/x-www-form-urlencoded"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "examples": {
                "stores an hourly row per entry": {
                  "summary": "stores an hourly row per entry",
                  "value": "data[][datetime]=2026-08-06T12%3A00%3A00&data[][in]=120&data[][out]=90&data[][datetime]=2026-08-06T13%3A00%3A00&data[][in]=200&data[][out]=180"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "stores an hourly row per entry": {
                    "summary": "stores an hourly row per entry",
                    "value": {
                      "success": true,
                      "data": {
                        "external_id": "gate-1",
                        "written": 2
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/sensor_traffic_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/shopping_centers": {
      "get": {
        "summary": "Shopping centres available to the key owner",
        "tags": [
          "Shopping centers v2"
        ],
        "description": "Точка входа: ТЦ, в которых у владельца ключа есть роль.\nОтсюда берутся `sc_id` для всех остальных запросов.\nПагинации нет — список ограничен ролями сотрудника.\nТЦ, заблокированный по оплате, в списке остаётся, но данные по нему отдают 402.\nРоли сняли — ТЦ пропадает из списка сам, отдельного отзыва ключа не нужно.\nСервис прав недоступен — 503 `rights_unavailable`, а не пустой список.\n",
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "returns the centres the owner has a role in, sorted by title": {
                    "summary": "returns the centres the owner has a role in, sorted by title",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b7a1daf693b5442dc10a",
                          "title": "А ТЦ в скоупе",
                          "prefix": "eum23",
                          "address": "301076 Россия, Уфа, улица Береговая, 118 кв. 191",
                          "time_zone": "Asia/Vladivostok",
                          "rent_area_size": 17845.0,
                          "total_area_size": 56376.0,
                          "expected_quantity": 74,
                          "external_id": "6700a5ce-a4e3-43b8-a368-013c07ea7e20",
                          "phone": "+7 (939) 588-42-85",
                          "city": {
                            "id": "6a75b7a1daf693b5442dc109",
                            "name": "Нижний Новгород",
                            "time_zone": "Asia/Vladivostok"
                          }
                        },
                        {
                          "id": "6a75b7a1daf693b5442dc107",
                          "title": "Б ТЦ в скоупе",
                          "prefix": "eveniet22",
                          "address": "305277 Россия, Киров, Ленина проспект, 935",
                          "time_zone": "Asia/Yekaterinburg",
                          "rent_area_size": 10452.0,
                          "total_area_size": 53912.0,
                          "expected_quantity": 30,
                          "external_id": "91c73cac-ee41-4b0f-8a84-462cda1b98b3",
                          "phone": "+7 (948) 878-40-48",
                          "city": {
                            "id": "6a75b7a1daf693b5442dc106",
                            "name": "Оренбург",
                            "time_zone": "Asia/Yekaterinburg"
                          }
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/shopping_centers_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/shops": {
      "get": {
        "summary": "Shops of the shopping centre",
        "tags": [
          "Shops v2"
        ],
        "description": "Список торговых точек ТЦ. Отсюда берутся `shop_id` для отчётов и выгрузки чеков.\nПагинация `page`/`per_page` (по умолчанию 100, максимум 500), метаданные в `meta.pagination`.\nАрхивные точки по умолчанию не отдаются. Чтобы получить их вдобавок\nк действующим, передайте `archived=true`; отличать их можно по полю `is_archived`.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc112"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "lists the shops of the centre with the ids used by the other endpoints": {
                    "summary": "lists the shops of the centre with the ids used by the other endpoints",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "6a75b7a1daf693b5442dc114",
                          "name": "Трейд ОП Вячеслав",
                          "external_id": null,
                          "is_archived": false,
                          "position": {
                            "name": "Любовь Блохина"
                          }
                        },
                        {
                          "id": "6a75b7a1daf693b5442dc121",
                          "name": "Торг ЗАО СбытТрейд",
                          "external_id": null,
                          "is_archived": false,
                          "position": {
                            "name": "Щукин Алексей Германович"
                          }
                        },
                        {
                          "id": "6a75b7a1daf693b5442dc12e",
                          "name": "Пром ИП РязаньПромСнабТрейд",
                          "external_id": null,
                          "is_archived": false,
                          "position": {
                            "name": "Русаков Антон Макарович"
                          }
                        }
                      ],
                      "meta": {
                        "pagination": {
                          "page": 1,
                          "per_page": 100,
                          "total": 3
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/shops_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/traffic_areas": {
      "get": {
        "summary": "Traffic counting areas of the shopping centre",
        "tags": [
          "Traffic areas v2"
        ],
        "description": "Зоны подсчёта посещаемости ТЦ. Отсюда берётся `zone_id` для `attendance`.\nВ `shop_ids` — торговые точки, попадающие в зону.\nПагинации нет — зон у ТЦ единицы. Служебные зоны офисов арендаторов не отдаются.\nЕсли в ТЦ система подсчёта не настроена, ответ — 404 `traffic_not_configured`.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc13e"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "lists the counting areas with the shops that fall into them": {
                    "summary": "lists the counting areas with the shops that fall into them",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": 5,
                          "title": "Главный вход",
                          "description": "Quo dolorem consequuntur dolor.",
                          "traffic_type": "passage",
                          "shop_ids": [
                            "6a75b7a1daf693b5442dc141"
                          ]
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/traffic_areas_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/shops/{shop_id}/turnover_config": {
      "get": {
        "summary": "Turnover settings applied to the shop",
        "tags": [
          "Turnover config v2"
        ],
        "description": "Настройки, по которым посчитан `turnover` в отчётах: какие типы операций входят\nв товарооборот и какая доля возвратов из него вычитается.\nНастройка берётся у точки, если она задана, иначе у ТЦ — источник в поле `source`\n(`shop`, `shopping_center` или `default`, если не задана нигде).\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc151"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc154"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "falls back to the settings of the shopping centre": {
                    "summary": "falls back to the settings of the shopping centre",
                    "value": {
                      "success": true,
                      "data": {
                        "source": "shopping_center",
                        "refund": true,
                        "vat": false,
                        "advanced": true,
                        "prepayment": true,
                        "provision": true,
                        "prepaid": false,
                        "credit": false,
                        "correction": false,
                        "max_refund_part_in_turnover": 40,
                        "last_recalculation_date": "2026-05-30"
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/turnover_config_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    },
    "/api/external/v2/sc/{sc_id}/shops/{shop_id}/turnover": {
      "post": {
        "summary": "Submit declared turnover for a month",
        "tags": [
          "Turnover submission v2"
        ],
        "description": "Приём задекларированного товарооборота точки за месяц. Для арендаторов\nбез подключённой кассы или с данными, которые не доходят через ОФД.\nДоступно на любом тарифе.\n\nОбязательны `month` и `turnover`. `month` — любая дата внутри месяца,\nмесяц берётся целиком. `receipts_count` и `visitors_count` необязательны.\n\n**Суммы в копейках.** Одноимённый метод API v1 принимал рубли, поэтому\nпри переносе интеграции значение нужно умножить на 100.\n\nМетод идемпотентен по паре «точка + месяц»: повторный вызов за тот же\nмесяц перезаписывает значения, а не добавляет вторую запись. Месяц\nзаводится автоматически, если его ещё нет. Будущий месяц отклоняется,\nграница считается в таймзоне торговой точки.\n\nЗаписанное значение возвращается в `by_months` полем `manual_turnover`\nи участвует в расчёте OCR.\n",
        "parameters": [
          {
            "name": "sc_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc164"
          },
          {
            "name": "shop_id",
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "6a75b7a1daf693b5442dc166"
          },
          {
            "name": "Accept",
            "in": "header",
            "example": "application/json"
          },
          {
            "name": "Content-Type",
            "in": "header",
            "example": "application/x-www-form-urlencoded"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "examples": {
                "stores the declared turnover in kopecks": {
                  "summary": "stores the declared turnover in kopecks",
                  "value": "month=2026-07-01&turnover=12345600&receipts_count=42&visitors_count=500"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json; charset=utf-8": {
                "examples": {
                  "stores the declared turnover in kopecks": {
                    "summary": "stores the declared turnover in kopecks",
                    "value": {
                      "success": true,
                      "data": {
                        "shop_id": "6a75b7a1daf693b5442dc166",
                        "month": "2026-07",
                        "manual_turnover": 12345600,
                        "manual_receipts_count": 42,
                        "manual_visitors_count": 500
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "/Users/morder/Work/rentu/backend/.claude/worktrees/ext3-ras/spec/support/schemas/external/v2/turnover_s.json"
                }
              }
            },
            "headers": {
              "Content-Type": {
                "description": "application/json; charset=utf-8"
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Anomalies v2",
      "description": ""
    },
    {
      "name": "Attendance submission v2",
      "description": ""
    },
    {
      "name": "Attendance v2",
      "description": ""
    },
    {
      "name": "Auth v2",
      "description": ""
    },
    {
      "name": "Events v2",
      "description": ""
    },
    {
      "name": "Kkts v2",
      "description": ""
    },
    {
      "name": "Receipts v2",
      "description": ""
    },
    {
      "name": "Reports v2",
      "description": ""
    },
    {
      "name": "Sensor traffic v2",
      "description": ""
    },
    {
      "name": "Shopping centers v2",
      "description": ""
    },
    {
      "name": "Shops v2",
      "description": ""
    },
    {
      "name": "Traffic areas v2",
      "description": ""
    },
    {
      "name": "Turnover config v2",
      "description": ""
    },
    {
      "name": "Turnover submission v2",
      "description": ""
    }
  ],
  "x-tagGroups": [
    {
      "name": "external/v2",
      "tags": [
        "Anomalies v2",
        "Attendance submission v2",
        "Attendance v2",
        "Auth v2",
        "Events v2",
        "Kkts v2",
        "Receipts v2",
        "Reports v2",
        "Sensor traffic v2",
        "Shopping centers v2",
        "Shops v2",
        "Traffic areas v2",
        "Turnover config v2",
        "Turnover submission v2"
      ]
    }
  ]
}
