{
  "components": {
    "schemas": {
      "BulkBatchResponse": {
        "properties": {
          "data": {
            "description": "Результат пакета заказов с ЧАСТИЧНЫМ УСПЕХОМ: ошибки строк не блокируют остальные; деньги списываются ТОЛЬКО для `done`. LPA/QR отсутствуют: получите eSIM через GET /v1/orders/{id} по каждому `order_id`.",
            "properties": {
              "created_at": {
                "format": "date-time",
                "type": "string"
              },
              "external_ref": {
                "example": "batch-2026-001",
                "nullable": true,
                "type": "string"
              },
              "failed_lines": {
                "type": "integer"
              },
              "id": {
                "format": "uuid",
                "type": "string"
              },
              "items": {
                "items": {
                  "$ref": "#/components/schemas/BulkLineResult"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "status": {
                "description": "`pending` — в пакете остались невыполненные строки после прерывания. Повторите с ТЕМ ЖЕ `Idempotency-Key`, чтобы завершить их.",
                "enum": [
                  "pending",
                  "completed",
                  "partial",
                  "failed"
                ],
                "type": "string"
              },
              "succeeded_lines": {
                "type": "integer"
              },
              "total_charged": {
                "$ref": "#/components/schemas/Money"
              },
              "total_lines": {
                "type": "integer"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "BulkLineResult": {
        "properties": {
          "charged": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Money"
              }
            ],
            "nullable": true
          },
          "error": {
            "description": "Код ошибки `domain.reason`, например `wallet.insufficient_balance`, `esim.out_of_stock`, `order.package_not_allowed`, `wallet.velocity_exceeded`.",
            "nullable": true,
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "external_ref": {
            "example": "po-1001",
            "nullable": true,
            "type": "string"
          },
          "line_no": {
            "description": "Нумерация с 1, в порядке отправки.",
            "type": "integer"
          },
          "order_id": {
            "format": "uuid",
            "nullable": true,
            "type": "string"
          },
          "package_code": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "status": {
            "enum": [
              "pending",
              "done",
              "failed"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "BulkRequest": {
        "properties": {
          "external_ref": {
            "description": "Ваша ссылка на ВЕСЬ пакет; возвращается в ответе пакета.",
            "example": "batch-2026-001",
            "nullable": true,
            "type": "string"
          },
          "items": {
            "description": "Каждый элемент создаёт ОДИН независимый заказ. Лимит строк настраивается (по умолчанию 100); превышение даёт `internal.limit_exceeded` (422).",
            "items": {
              "properties": {
                "external_ref": {
                  "description": "Ваша ссылка ТОЛЬКО для этой строки; возвращается без изменений в результате строки.",
                  "example": "po-1001",
                  "nullable": true,
                  "type": "string"
                },
                "package_code": {
                  "description": "Код тарифа ВАШЕГО каталога, `public_sku`. НЕИЗМЕНЯЕМ для тарифа даже при смене поставщика, подходит для сверки. Пример имеет правильный ФОРМАТ, но не работает: получите реальный код из GET /v1/catalog/packages.",
                  "example": "TKE-VN-30D-X3K9F",
                  "type": "string"
                },
                "quantity": {
                  "example": 5,
                  "minimum": 1,
                  "type": "integer"
                }
              },
              "required": [
                "package_code",
                "quantity"
              ],
              "type": "object"
            },
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "CancelResponse": {
        "properties": {
          "data": {
            "properties": {
              "cancelled_at": {
                "format": "date-time",
                "type": "string"
              },
              "esim_id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "refund_suggested": {
                "description": "`true` — запрос возврата ожидает одобрения человеком, деньги ЕЩЁ НЕ переведены. `refunded.amount = 0` не означает отказ от возврата.",
                "type": "boolean"
              },
              "refunded": {
                "$ref": "#/components/schemas/Money",
                "description": "Сумма, ФАКТИЧЕСКИ ВЕРНУВШАЯСЯ в кошелёк при отмене. В рабочем режиме обычно `0`: перед выводами прочитайте `refund_suggested`."
              },
              "status": {
                "example": "cancelled",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "Cancellable": {
        "description": "Можно ли ещё отменить eSIM и почему нельзя. Прочитайте ДО POST /v1/esims/{order_item_id}/cancel. Блок присутствует ВСЕГДА и никогда не `null`.",
        "properties": {
          "allowed": {
            "type": "boolean"
          },
          "disclosed_at": {
            "description": "Время выдачи кода за пределы системы (ISO-8601 UTC), `null`, пока его никто не видел. Позволяет проверить жалобу «я не получил код, почему нельзя отменить».",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "reason": {
            "description": "Причина запрета отмены: `code_disclosed` — код выдан или показан; `wrong_status` — неподходящее состояние; `expired` — срок истёк; `not_supported` — отмена не заявлена тарифом. `null` при `allowed = true`. Термины как в `meta.reason` ошибки `esim.not_cancellable`.",
            "enum": [
              "code_disclosed",
              "wrong_status",
              "expired",
              "not_supported",
              null
            ],
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "ChangePlanRequest": {
        "properties": {
          "package_code": {
            "description": "Код тарифа ВАШЕГО каталога, `public_sku`. НЕИЗМЕНЯЕМ для тарифа даже при смене поставщика, подходит для сверки. Пример имеет правильный ФОРМАТ, но не работает: получите реальный код из GET /v1/catalog/packages.",
            "example": "TKE-VN-7D-P4M2Q",
            "type": "string"
          }
        },
        "required": [
          "package_code"
        ],
        "type": "object"
      },
      "ChangePlanResponse": {
        "properties": {
          "data": {
            "description": "Результат смены тарифа eSIM.",
            "properties": {
              "charged": {
                "$ref": "#/components/schemas/Money"
              },
              "current_plan": {
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "expires_at": {
                    "format": "date-time",
                    "nullable": true,
                    "type": "string"
                  },
                  "started_at": {
                    "format": "date-time",
                    "nullable": true,
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "esim_id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "order_id": {
                "format": "uuid",
                "type": "string"
              },
              "previous_plan": {
                "nullable": true,
                "properties": {
                  "cancelled_at": {
                    "format": "date-time",
                    "nullable": true,
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "remaining_bytes_forfeited": {
                    "format": "int64",
                    "nullable": true,
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "warning": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "CreateOrderRequest": {
        "properties": {
          "external_ref": {
            "description": "Ваша ссылка, повторяется в ответе и вебхуках.",
            "example": "po-1001",
            "nullable": true,
            "type": "string"
          },
          "include": {
            "description": "Дополнительные блоки: `[\"lpa\"]` или `[\"lpa\",\"qr\"]`. Если не указаны, `items[].install` равен `null`, и ВСЕ eSIM заказа сохраняют право на отмену. **ВОЗВРАТ КОДА СЧИТАЕТСЯ РАСКРЫТИЕМ**: запрос `lpa` закрывает возможность отмены уже при оформлении заказа.",
            "example": [
              "lpa"
            ],
            "items": {
              "enum": [
                "lpa",
                "qr"
              ],
              "type": "string"
            },
            "nullable": true,
            "type": "array"
          },
          "invoice_buyer": {
            "$ref": "#/components/schemas/MemberInvoiceBuyer"
          },
          "items": {
            "description": "Список тарифов и количества для покупки (не более 50 eSIM).",
            "items": {
              "properties": {
                "package_code": {
                  "description": "Код тарифа ВАШЕГО каталога, `public_sku`. НЕИЗМЕНЯЕМ для тарифа даже при смене поставщика, подходит для сверки. Пример имеет правильный ФОРМАТ, но не работает: получите реальный код из GET /v1/catalog/packages.",
                  "example": "TKE-VN-30D-X3K9F",
                  "type": "string"
                },
                "quantity": {
                  "description": "Количество eSIM этого тарифа для покупки (≥ 1).",
                  "example": 2,
                  "type": "integer"
                }
              },
              "required": [
                "package_code",
                "quantity"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "CreateWebhookResponse": {
        "properties": {
          "data": {
            "properties": {
              "active": {
                "description": "`false` — обработчик перестал получать новые события после паузы в панели или отзыва API-ключа (канал закрывается той же транзакцией). Успешная CHECK_HEALTH при PUT /v1/webhooks/{id} включает его снова.",
                "type": "boolean"
              },
              "created_at": {
                "format": "date-time",
                "type": "string"
              },
              "events": {
                "description": "Пусто — получать все события.",
                "items": {
                  "enum": [
                    "order.completed",
                    "order.failed",
                    "esim.delivered",
                    "esim.activated",
                    "esim.usage_threshold",
                    "esim.expiring",
                    "wallet.low_balance",
                    "catalog.updated"
                  ],
                  "type": "string"
                },
                "type": "array"
              },
              "health_check": {
                "enum": [
                  "passed"
                ],
                "type": "string"
              },
              "id": {
                "description": "ID обработчика для `/v1/webhooks/{id}`. При каждом создании выдаётся НОВЫЙ: удаление и повторное создание не восстанавливают старый обработчик.",
                "format": "uuid",
                "type": "string"
              },
              "last_delivery_at": {
                "description": "Последнее время УСПЕШНОЙ ДОСТАВКИ обработчику. `null` — доставок не было, а не ошибка доставки. Проверьте первым при жалобе на отсутствие вебхуков.",
                "format": "date-time",
                "nullable": true,
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "secret_last4": {
                "description": "Последние четыре символа секрета вебхука для проверки соответствия без раскрытия секрета. Полный секрет показывается ОДИН РАЗ при создании.",
                "type": "string"
              },
              "url": {
                "type": "string"
              },
              "webhook_secret": {
                "description": "Показывается ТОЛЬКО ОДИН РАЗ при создании (префикс `whsec_`).",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "DeleteWebhookResponse": {
        "properties": {
          "data": {
            "properties": {
              "deleted_at": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "Delivery": {
        "properties": {
          "attempts": {
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "event_id": {
            "description": "Идентификатор СОБЫТИЯ. Переотправка создаёт НОВУЮ доставку с ТЕМ ЖЕ `event_id`; удаляйте дубли по `event_id`, не по `id` доставки.",
            "format": "uuid",
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "last_attempt_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "next_retry_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "response_code": {
            "nullable": true,
            "type": "integer"
          },
          "status": {
            "enum": [
              "pending",
              "delivered",
              "failed"
            ],
            "type": "string"
          },
          "webhook_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "DeliveryListResponse": {
        "properties": {
          "data": {
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/Delivery"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Число строк по фильтру. `null`, если подсчёт слишком дорог. Конец списка определяйте по `next_cursor`, а не по этому полю.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "DeliveryReplayResponse": {
        "properties": {
          "data": {
            "properties": {
              "attempts": {
                "type": "integer"
              },
              "created_at": {
                "format": "date-time",
                "type": "string"
              },
              "event_id": {
                "description": "Идентификатор СОБЫТИЯ. Переотправка создаёт НОВУЮ доставку с ТЕМ ЖЕ `event_id`; удаляйте дубли по `event_id`, не по `id` доставки.",
                "format": "uuid",
                "type": "string"
              },
              "event_type": {
                "type": "string"
              },
              "id": {
                "format": "uuid",
                "type": "string"
              },
              "last_attempt_at": {
                "format": "date-time",
                "nullable": true,
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_retry_at": {
                "format": "date-time",
                "nullable": true,
                "type": "string"
              },
              "response_code": {
                "nullable": true,
                "type": "integer"
              },
              "status": {
                "enum": [
                  "pending",
                  "delivered",
                  "failed"
                ],
                "type": "string"
              },
              "webhook_id": {
                "format": "uuid",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "ErrorEnvelope": {
        "properties": {
          "error": {
            "properties": {
              "code": {
                "description": "Код `domain.reason` (см. таблицу ошибок).",
                "type": "string"
              },
              "field": {
                "nullable": true,
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "meta": {
                "nullable": true,
                "type": "object"
              },
              "request_id": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "type": "object"
          },
          "ok": {
            "enum": [
              false
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "error"
        ],
        "type": "object"
      },
      "Esim": {
        "properties": {
          "data": {
            "properties": {
              "cancellable": {
                "$ref": "#/components/schemas/Cancellable"
              },
              "external_ref": {
                "description": "Ваша ссылка заказа `external_ref`, переданная при покупке, для связи eSIM с вашей системой. `null`, если не указана.",
                "nullable": true,
                "type": "string"
              },
              "iccid": {
                "example": "8984012345678901234",
                "nullable": true,
                "type": "string"
              },
              "id": {
                "description": "ID eSIM для всех путей `/v1/esims/{id}/…`, он же `order_item_id` вебхуков. Если известен только ICCID, получите `id` через GET /v1/esims?iccid=….",
                "format": "uuid",
                "type": "string"
              },
              "install": {
                "$ref": "#/components/schemas/Install"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "msisdn": {
                "nullable": true,
                "type": "string"
              },
              "order_id": {
                "format": "uuid",
                "type": "string"
              },
              "package_code": {
                "description": "КОД тарифа из каталога для связи eSIM с вашим каталогом. `null` только если исходный тариф удалён из каталога.",
                "nullable": true,
                "type": "string"
              },
              "package_name": {
                "description": "Отображаемое НАЗВАНИЕ может меняться. Не используйте его как ключ сверки.",
                "type": "string"
              },
              "plan": {
                "$ref": "#/components/schemas/PlanView"
              },
              "smdp_status": {
                "example": "released",
                "nullable": true,
                "type": "string"
              },
              "status": {
                "example": "delivered",
                "type": "string"
              },
              "updated_at": {
                "format": "date-time",
                "type": "string"
              },
              "usage": {
                "$ref": "#/components/schemas/Usage"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "EsimItem": {
        "properties": {
          "cancellable": {
            "$ref": "#/components/schemas/Cancellable"
          },
          "external_ref": {
            "description": "Ваша ссылка заказа `external_ref`, переданная при покупке, для связи eSIM с вашей системой. `null`, если не указана.",
            "nullable": true,
            "type": "string"
          },
          "iccid": {
            "example": "8984012345678901234",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "ID eSIM для всех путей `/v1/esims/{id}/…`, он же `order_item_id` вебхуков. Если известен только ICCID, получите `id` через GET /v1/esims?iccid=….",
            "format": "uuid",
            "type": "string"
          },
          "install": {
            "$ref": "#/components/schemas/Install"
          },
          "msisdn": {
            "nullable": true,
            "type": "string"
          },
          "order_id": {
            "format": "uuid",
            "type": "string"
          },
          "package_code": {
            "description": "КОД тарифа из каталога для связи eSIM с вашим каталогом. `null` только если исходный тариф удалён из каталога.",
            "nullable": true,
            "type": "string"
          },
          "package_name": {
            "description": "Отображаемое НАЗВАНИЕ может меняться. Не используйте его как ключ сверки.",
            "type": "string"
          },
          "plan": {
            "$ref": "#/components/schemas/PlanView"
          },
          "smdp_status": {
            "example": "released",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "example": "delivered",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "type": "object"
      },
      "EsimListResponse": {
        "properties": {
          "data": {
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/EsimItem"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Число строк по фильтру. `null`, если подсчёт слишком дорог. Конец списка определяйте по `next_cursor`, а не по этому полю.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "EsimUsage": {
        "properties": {
          "data": {
            "properties": {
              "esim_id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "usage": {
                "$ref": "#/components/schemas/Usage"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "Install": {
        "description": "Данные для УСТАНОВКИ eSIM. `null` означает, что вы их НЕ ЗАПРАШИВАЛИ (нет `include=lpa`), а не отсутствие кода. Если кода ещё нет, блок присутствует с `lpa: null`. Ответ с этим блоком всегда имеет `Cache-Control: no-store`.",
        "nullable": true,
        "properties": {
          "android_url": {
            "nullable": true,
            "type": "string"
          },
          "apn": {
            "description": "APN для ручного ввода, если устройство не получает настройки автоматически. В текущей версии ВСЕГДА `null`, что означает «неизвестно», а не «не требуется».",
            "nullable": true,
            "type": "string"
          },
          "ios_url": {
            "nullable": true,
            "type": "string"
          },
          "lpa": {
            "description": "Код активации eSIM — секрет продажи. Этой строки достаточно для создания QR-кода у вас.",
            "example": "LPA:1$smdp.example.com$MATCH-ABC123",
            "nullable": true,
            "type": "string"
          },
          "matching_id": {
            "example": "MATCH-ABC123",
            "nullable": true,
            "type": "string"
          },
          "qr_code_base64": {
            "description": "PNG data-URI QR-кода. Только при `include=qr` в ДЕТАЛЬНОМ методе. В списках его НЕТ (около 11 КБ на строку, то есть 1,1 МБ на 100 строк); создавайте QR из `lpa`.",
            "nullable": true,
            "type": "string"
          },
          "smdp_address": {
            "example": "smdp.example.com",
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListWarning": {
        "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
        "properties": {
          "code": {
            "enum": [
              "filtered_by_key_package_filters",
              "filtered_by_provider_scope",
              "no_price_for_org",
              "price_filter_removed_rows",
              "provider_disabled",
              "capability_missing"
            ],
            "example": "no_price_for_org",
            "type": "string"
          },
          "count": {
            "example": 12,
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "message": {
            "example": "12 gói bị lược vì tổ chức bạn chưa có giá.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "MemberInvoiceBuyer": {
        "description": "Только ключи участников. Без данных используется потребительский сценарий без организации или юридического лица во Вьетнаме. Переданные данные проверяются по текущим правилам: full_name, 12-значный персональный tax_code и address/email при оформлении. Корпоративный счёт запрашивается после покупки. Тестовый режим только проверяет снимок данных и не выпускает счета MISA.",
        "nullable": true,
        "properties": {
          "address": {
            "nullable": true,
            "type": "string"
          },
          "email": {
            "nullable": true,
            "type": "string"
          },
          "full_name": {
            "nullable": true,
            "type": "string"
          },
          "legal_name": {
            "nullable": true,
            "type": "string"
          },
          "tax_code": {
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "MemberRefundRequest": {
        "properties": {
          "decided_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "decision_note": {
            "nullable": true,
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "order_id": {
            "format": "uuid",
            "type": "string"
          },
          "order_item_id": {
            "format": "uuid",
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "refunded": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Money"
              }
            ],
            "nullable": true
          },
          "requested_at": {
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "approved",
              "rejected"
            ],
            "type": "string"
          },
          "suggested": {
            "$ref": "#/components/schemas/Money"
          }
        },
        "type": "object"
      },
      "MemberRefundRequestInput": {
        "properties": {
          "reason": {
            "description": "Причина возврата, от 5 до 1000 символов после удаления пробелов по краям.",
            "maxLength": 1000,
            "minLength": 5,
            "type": "string"
          }
        },
        "required": [
          "reason"
        ],
        "type": "object"
      },
      "MemberRefundRequestListResponse": {
        "properties": {
          "data": {
            "properties": {
              "has_open_request": {
                "type": "boolean"
              },
              "items": {
                "items": {
                  "$ref": "#/components/schemas/MemberRefundRequest"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Число строк по фильтру. `null`, если подсчёт слишком дорог. Конец списка определяйте по `next_cursor`, а не по этому полю.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "MemberRefundRequestResponse": {
        "properties": {
          "data": {
            "properties": {
              "decided_at": {
                "format": "date-time",
                "nullable": true,
                "type": "string"
              },
              "decision_note": {
                "nullable": true,
                "type": "string"
              },
              "id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "order_id": {
                "format": "uuid",
                "type": "string"
              },
              "order_item_id": {
                "format": "uuid",
                "type": "string"
              },
              "reason": {
                "type": "string"
              },
              "refunded": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Money"
                  }
                ],
                "nullable": true
              },
              "requested_at": {
                "format": "date-time",
                "type": "string"
              },
              "status": {
                "enum": [
                  "pending",
                  "approved",
                  "rejected"
                ],
                "type": "string"
              },
              "suggested": {
                "$ref": "#/components/schemas/Money"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "ModeEcho": {
        "description": "Среда вызывающего ключа, соответствующая заголовку X-TKE-Mode. Организации используют tke_live_/tke_test_, участники — tke_member_live_/tke_member_test_. Рабочий и тестовый хосты проверяют режим ключа.",
        "enum": [
          "test",
          "live"
        ],
        "example": "live",
        "type": "string"
      },
      "Money": {
        "description": "Денежная сумма. ЕДИНЫЙ формат во всём `/v1`: поле не меняет тип между объектом и числом.",
        "properties": {
          "amount": {
            "description": "Целое число в минимальной единице `currency` (у VND нет дробной единицы).",
            "example": 273000,
            "format": "int64",
            "type": "integer"
          },
          "currency": {
            "example": "VND",
            "type": "string"
          }
        },
        "type": "object"
      },
      "OkEnvelope": {
        "properties": {
          "data": {
            "description": "Содержимое зависит от метода.",
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "OrderItem": {
        "properties": {
          "cancellable": {
            "$ref": "#/components/schemas/Cancellable"
          },
          "external_ref": {
            "description": "Ваша ссылка заказа `external_ref`, переданная при покупке, для связи eSIM с вашей системой. `null`, если не указана.",
            "nullable": true,
            "type": "string"
          },
          "iccid": {
            "example": "8984012345678901234",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "ID eSIM для всех путей `/v1/esims/{id}/…`, он же `order_item_id` вебхуков. Если известен только ICCID, получите `id` через GET /v1/esims?iccid=….",
            "format": "uuid",
            "type": "string"
          },
          "install": {
            "$ref": "#/components/schemas/Install"
          },
          "msisdn": {
            "nullable": true,
            "type": "string"
          },
          "order_id": {
            "format": "uuid",
            "type": "string"
          },
          "package_code": {
            "description": "КОД тарифа из каталога для связи eSIM с вашим каталогом. `null` только если исходный тариф удалён из каталога.",
            "nullable": true,
            "type": "string"
          },
          "package_name": {
            "description": "Отображаемое НАЗВАНИЕ может меняться. Не используйте его как ключ сверки.",
            "type": "string"
          },
          "plan": {
            "$ref": "#/components/schemas/PlanView"
          },
          "smdp_status": {
            "example": "released",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "example": "delivered",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "type": "object"
      },
      "OrderListItem": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "external_ref": {
            "example": "po-1001",
            "nullable": true,
            "type": "string"
          },
          "fulfillment_status": {
            "enum": [
              "fulfilled",
              "partially_fulfilled",
              "unfulfilled"
            ],
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "item_count": {
            "format": "int64",
            "type": "integer"
          },
          "net": {
            "$ref": "#/components/schemas/Money"
          },
          "public_ref": {
            "example": "TKE-DH-2A4C7Q",
            "nullable": true,
            "type": "string"
          },
          "refunded": {
            "$ref": "#/components/schemas/Money"
          },
          "status": {
            "type": "string"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "OrderListResponse": {
        "properties": {
          "data": {
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/OrderListItem"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Число строк по фильтру. `null`, если подсчёт слишком дорог. Конец списка определяйте по `next_cursor`, а не по этому полю.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "OrderResponse": {
        "properties": {
          "data": {
            "description": "Заказ партнёра.",
            "properties": {
              "created_at": {
                "format": "date-time",
                "type": "string"
              },
              "external_ref": {
                "example": "po-1001",
                "nullable": true,
                "type": "string"
              },
              "fulfillment_status": {
                "description": "Фактически выданное количество — ОТДЕЛЬНО от `status`. Заказ из 3 eSIM с 2 выданными и 1 ошибкой остаётся `status=completed`, но имеет `fulfillment_status=partially_fulfilled` и `refunded_amount > 0`.",
                "enum": [
                  "fulfilled",
                  "partially_fulfilled",
                  "unfulfilled"
                ],
                "type": "string"
              },
              "id": {
                "description": "ID заказа UUID.",
                "format": "uuid",
                "type": "string"
              },
              "idempotent_replay": {
                "description": "true при идемпотентном повторе предыдущего успешного запроса.",
                "nullable": true,
                "type": "boolean"
              },
              "invoice_no": {
                "description": "Номер счёта после выпуска.",
                "nullable": true,
                "type": "string"
              },
              "invoice_status": {
                "description": "Статус счёта с НДС заказа. `none` — ещё не выпущен.",
                "enum": [
                  "none",
                  "pending",
                  "issuing",
                  "issued",
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              "items": {
                "items": {
                  "$ref": "#/components/schemas/OrderItem"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "money_settled": {
                "description": "Завершены ли расчёты по заказу, без возврата в обработке. При `false` счёт ещё нельзя выпустить.",
                "type": "boolean"
              },
              "net": {
                "$ref": "#/components/schemas/Money"
              },
              "public_ref": {
                "description": "Короткий понятный код заказа для обращения в поддержку.",
                "example": "TKE-DH-2A4C7Q",
                "nullable": true,
                "type": "string"
              },
              "refunded": {
                "$ref": "#/components/schemas/Money"
              },
              "status": {
                "enum": [
                  "completed",
                  "pending_provider",
                  "provider_failed",
                  "cancelled"
                ],
                "type": "string"
              },
              "total": {
                "$ref": "#/components/schemas/Money"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "Package": {
        "description": "**`null` означает, что ИНФОРМАЦИИ НЕТ, а не «да» или «нет».** Не считайте пустое поле обещанием. Только значения `true`/`false` и записи, ПРИСУТСТВУЮЩИЕ в `features.apps[]`, отражают заявленные поставщиком возможности.",
        "properties": {
          "capabilities": {
            "$ref": "#/components/schemas/PackageCapabilities"
          },
          "code": {
            "description": "Код тарифа ВАШЕГО каталога, `public_sku`. НЕИЗМЕНЯЕМ для тарифа даже при смене поставщика, подходит для сверки. Пример имеет правильный ФОРМАТ, но не работает: получите реальный код из GET /v1/catalog/packages.",
            "example": "TKE-VN-30D-X3K9F",
            "type": "string"
          },
          "coverage": {
            "description": "Где работает тариф.",
            "properties": {
              "countries": {
                "description": "Коды ISO-3166 alpha-2. Пустой массив у глобальных тарифов (200 стран не перечисляются) и тарифов без заявленного покрытия.",
                "example": [
                  "CN"
                ],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "country_count": {
                "description": "Количество стран покрытия для сортировки или фильтрации многострановых тарифов без загрузки и подсчёта всего массива.",
                "example": 1,
                "type": "integer"
              },
              "group": {
                "description": "Тип покрытия: страны `country`, регион `region` или весь мир `global`. ОТКРЫТОЕ перечисление: игнорируйте неизвестные значения.",
                "example": "country",
                "type": "string"
              },
              "region": {
                "description": "Пока ВСЕГДА `null`: регионы связаны со СТРАНАМИ, а не тарифами. Значение было бы предположением. Фильтр `?region=` продолжает работать.",
                "nullable": true,
                "type": "string"
              }
            },
            "type": "object"
          },
          "data": {
            "description": "Лимит данных тарифа. ВСЕ значения в **БАЙТАХ**, не МБ/ГБ, чтобы избежать двойного округления.",
            "properties": {
              "daily_bytes": {
                "description": "ДНЕВНОЙ лимит данных в байтах. `null` для `fixed`/`unlimited`.",
                "example": 1073741824,
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "label": {
                "description": "Понятная пользователю подпись, созданная общей для всех экранов функцией.",
                "example": "1GB/ngày",
                "type": "string"
              },
              "model": {
                "description": "Учёт лимита: `daily` (на день) | `fixed` (на весь срок) | `unlimited`. ОТКРЫТОЕ перечисление: клиент ОБЯЗАН игнорировать неизвестные значения.",
                "enum": [
                  "daily",
                  "fixed",
                  "unlimited"
                ],
                "example": "daily",
                "type": "string"
              },
              "reset": {
                "description": "Момент сброса дневного лимита. Неизвестное время может лишить купившего в 22:00 почти всего первого дня. `null` — не заявлено.",
                "nullable": true,
                "properties": {
                  "at": {
                    "description": "Местное время сброса в часовом поясе `timezone` (`00:00`, `00:00:01`).",
                    "example": "00:00",
                    "nullable": true,
                    "type": "string"
                  },
                  "note": {
                    "nullable": true,
                    "type": "string"
                  },
                  "timezone": {
                    "description": "Часовой пояс сброса (`UTC+8`, `UTC+7`).",
                    "example": "UTC+8",
                    "nullable": true,
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "total_bytes": {
                "description": "Общий лимит на весь срок в байтах. `null` для `daily`/`unlimited`: произведение дневного лимита на дни не является обязательством поставщика.",
                "example": null,
                "format": "int64",
                "nullable": true,
                "type": "integer"
              }
            },
            "type": "object"
          },
          "description": {
            "description": "Описание тарифа для продажи. `null`, если ещё не написано.",
            "nullable": true,
            "type": "string"
          },
          "description_en": {
            "description": "Описание на английском. `null`, если ещё не задано.",
            "nullable": true,
            "type": "string"
          },
          "features": {
            "description": "Возможности тарифа. ТИПИЗИРОВАННЫЙ объект: массив `[]` не различает отсутствие раздачи и отсутствие сведений, а `false` и `null` различают.",
            "properties": {
              "apps": {
                "description": "Поддержка приложения по ОПЕРАЦИОННЫМ СИСТЕМАМ. **Отсутствие приложения в массиве означает ОТСУТСТВИЕ ДАННЫХ, а не поддержку.** Поставщик гарантирует только перечисленное; пока заявлен только TikTok. Объединённого флага нет намеренно: в реальном каталоге 2465 тарифов поддерживают TikTok на iPhone, но не Android. Единый флаг исказил бы почти треть каталога.",
                "items": {
                  "properties": {
                    "android": {
                      "description": "`supported` — поставщик заявляет поддержку; `blocked` — запрет; `unknown` — нет декларации для этой ОС. ОТКРЫТОЕ перечисление.",
                      "enum": [
                        "supported",
                        "blocked",
                        "unknown"
                      ],
                      "example": "blocked",
                      "type": "string"
                    },
                    "app": {
                      "description": "Код приложения в нижнем регистре, например `tiktok`.",
                      "example": "tiktok",
                      "type": "string"
                    },
                    "ios": {
                      "description": "`supported` — поставщик заявляет поддержку; `blocked` — запрет; `unknown` — нет декларации для этой ОС. ОТКРЫТОЕ перечисление.",
                      "enum": [
                        "supported",
                        "blocked",
                        "unknown"
                      ],
                      "example": "supported",
                      "type": "string"
                    },
                    "note": {
                      "nullable": true,
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              },
              "hotspot": {
                "description": "Раздача Wi-Fi другим устройствам. `null` — не заявлено и ОТЛИЧАЕТСЯ от `false`.",
                "example": true,
                "nullable": true,
                "type": "boolean"
              },
              "kyc_required": {
                "description": "Перед использованием требуется проверка личности KYC. `null` — не заявлено.",
                "example": false,
                "nullable": true,
                "type": "boolean"
              },
              "sms": {
                "description": "SMS. `false` — сообщения НЕ принимаются, в том числе банковские OTP. `null` — не заявлено.",
                "example": false,
                "nullable": true,
                "type": "boolean"
              },
              "voice": {
                "description": "Голосовые вызовы. `false` — поставщик заявляет ОТСУТСТВИЕ голоса: линия только данных не принимает вызовы. `null` — не заявлено.",
                "example": false,
                "nullable": true,
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "fup": {
            "description": "Поведение после исчерпания скоростного лимита. `null` — сведения об ограничении не заявлены.",
            "nullable": true,
            "properties": {
              "behavior": {
                "description": "`throttle` — замедление; `cutoff` — отключение; `null` — не заявлено. ОТКРЫТОЕ перечисление.",
                "enum": [
                  "throttle",
                  "cutoff",
                  null
                ],
                "nullable": true,
                "type": "string"
              },
              "high_speed_bytes": {
                "description": "Объём в БАЙТАХ на полной скорости до ограничения.",
                "example": 1048576,
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "note": {
                "nullable": true,
                "type": "string"
              },
              "speed_kbps": {
                "description": "Скорость ПОСЛЕ исчерпания скоростного лимита, кбит/с. `null` при отключении или отсутствии декларации. ОТЛИЧАЕТСЯ от `network.speed_cap_kbps`, ограничивающего весь тариф.",
                "example": 128,
                "nullable": true,
                "type": "integer"
              }
            },
            "type": "object"
          },
          "market": {
            "description": "СИСТЕМА ПОСТАВКИ, ОТКРЫТОЕ перечисление: игнорируйте неизвестные значения. Определяет запас и действия после продажи: `domestic` продаёт комплекты с пополнением, отменой и проверкой расхода; `international` заказывается у поставщика по запросу без запаса.",
            "enum": [
              "domestic",
              "international"
            ],
            "example": "international",
            "type": "string"
          },
          "name": {
            "example": "eSIM Trung Quốc Mainland Multi - 1GB/ngày - 24 ngày",
            "type": "string"
          },
          "name_en": {
            "description": "Название на английском. `null`, если ещё не задано.",
            "nullable": true,
            "type": "string"
          },
          "network": {
            "description": "Сети, в которых работает тариф.",
            "properties": {
              "apn": {
                "description": "APN для ручного ввода на Android, если устройство не подхватило его автоматически. Требуется для инструкции установки, иначе клиенту понадобится поддержка. `null` — не заявлено.",
                "example": "e-ideas",
                "nullable": true,
                "type": "string"
              },
              "carriers": {
                "description": "Операторы связи, В СЕТЯХ которых работает тариф. Характеристика eSIM, а не поставщик.",
                "items": {
                  "properties": {
                    "name": {
                      "example": "China Unicom",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              },
              "generations": {
                "description": "Доступные поколения сети (`[\"4g\", \"5g\"]`). `null` — не заявлено, а НЕ «только 2G».",
                "example": [
                  "4g",
                  "5g"
                ],
                "items": {
                  "type": "string"
                },
                "nullable": true,
                "type": "array"
              },
              "speed_cap_kbps": {
                "description": "Ограничение скорости ВСЕГО тарифа, кбит/с, в отличие от `fup.speed_kbps` после исчерпания скоростного лимита.",
                "nullable": true,
                "type": "integer"
              }
            },
            "type": "object"
          },
          "price": {
            "$ref": "#/components/schemas/Money",
            "description": "Цена ВАШЕЙ ОРГАНИЗАЦИИ через API, точно соответствующая списанию POST /v1/orders. Всегда `{amount, currency}`, не число. Закупочная цена не раскрывается."
          },
          "tags": {
            "description": "Нормализованные коммерческие метки: нижний регистр, дефисы. По ним также работают ограничения каталога ключа. Пока меток у тарифов нет, `?tag=` возвращает пустой список до начала их назначения продавцом.",
            "example": [],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "validity": {
            "description": "Срок действия тарифа и момент начала отсчёта.",
            "properties": {
              "days": {
                "example": 24,
                "type": "integer"
              },
              "install_by_days": {
                "description": "Число дней после покупки для сканирования QR и установки eSIM. `null` — не заявлено, а НЕ «устанавливайте когда угодно».",
                "example": 365,
                "nullable": true,
                "type": "integer"
              },
              "label": {
                "example": "24 ngày",
                "type": "string"
              },
              "reclaim_on_expiry": {
                "description": "Поставщик ИЗЫМАЕТ подписку после истечения тарифа: пополнение и смена становятся невозможны. Важный срок при продаже продлений. `null` — не заявлено.",
                "example": true,
                "nullable": true,
                "type": "boolean"
              },
              "starts_when": {
                "description": "КОГДА начинается срок: `on_install` (установка eSIM клиентом) | `on_purchase` (покупка) | `null`. Критически важное поле: незнание отсчёта от УСТАНОВКИ приведёт к неверному обещанию срока каждому клиенту. При `null` не обещайте точную дату.",
                "enum": [
                  "on_install",
                  "on_purchase",
                  null
                ],
                "example": "on_install",
                "nullable": true,
                "type": "string"
              },
              "unused_valid_days": {
                "description": "Число дней хранения неиспользованного тарифа до истечения срока. `null` — не заявлено, НЕ бессрочно. Отдельно от `install_by_days`: одно — срок УСТАНОВКИ, другое — ХРАНЕНИЯ.",
                "nullable": true,
                "type": "integer"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "PackageCapabilities": {
        "description": "Доступные действия ПОСЛЕ продажи из РЕАЛЬНОЙ декларации тарифа, без предположений по типу поставщика. Без декларации все флаги `false`, чтобы не обещать метод с неизбежным `422 capability.not_supported`.",
        "properties": {
          "cancel": {
            "properties": {
              "restriction": {
                "description": "`code_not_disclosed` — отмена возможна, пока НИКТО не видел код активации: не отправлен клиенту и не прочитан через панель или `?include=lpa`. Это РЕАЛЬНОЕ условие отмены. Оно ничего не говорит об установке клиентом, которую система не может знать; прежнее `unused_only` ошибочно обещало обратное.",
                "enum": [
                  "code_not_disclosed",
                  null
                ],
                "nullable": true,
                "type": "string"
              },
              "supported": {
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "plan_change": {
            "properties": {
              "policy": {
                "$ref": "#/components/schemas/PlanChangePolicy"
              },
              "supported": {
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "usage_check": {
            "properties": {
              "supported": {
                "type": "boolean"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "PackageDetail": {
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Package"
              },
              {
                "properties": {
                  "mode": {
                    "$ref": "#/components/schemas/ModeEcho"
                  }
                },
                "type": "object"
              }
            ]
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "PackageListResponse": {
        "properties": {
          "data": {
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/Package"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Общее число тарифов по фильтрам. `null` при дорогом подсчёте (международная система или без `market`). Подсчёт идёт ДО ограничений каталога ключа и наличия цены организации: это число совпадений в каталоге, а не доступных вам покупок.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "PlanChangePolicy": {
        "description": "Политика ДОБАВЛЕНИЯ НОВОГО ТАРИФА поставщика. `null` — тариф нельзя пополнить ИЛИ политика ещё не проверена. Это означает «не делайте предположений», а не объект с `false`, который обещал бы отсутствие отмены.",
        "nullable": true,
        "properties": {
          "note": {
            "nullable": true,
            "type": "string"
          },
          "requires_cancel_first": {
            "description": "ТЕКУЩИЙ тариф отменяется до добавления нового: этот поставщик не складывает тарифы. Сообщите клиенту ДО пополнения новым тарифом.",
            "type": "boolean"
          },
          "stacking": {
            "description": "Добавляются ли срок и лимит нового тарифа к текущему.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "PlanOptionsResponse": {
        "properties": {
          "data": {
            "description": "Тарифы пополнения ЭТОЙ eSIM, уже отфильтрованные по её поставщику. Каждый элемент — полный `Package`, как в каталоге, без второй схемы. `policy` относится к поставщику, СЕЙЧАС обслуживающему eSIM. `null` — политика не проверена: не делайте предположений, это НЕ обещание отсутствия отмены.",
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/Package"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "type": "integer"
              },
              "policy": {
                "$ref": "#/components/schemas/PlanChangePolicy"
              },
              "total": {
                "description": "Общее число тарифов по фильтрам. `null` при дорогом подсчёте (международная система или без `market`). Подсчёт идёт ДО ограничений каталога ключа и наличия цены организации: это число совпадений в каталоге, а не доступных вам покупок.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "PlanView": {
        "description": "Текущий тариф этой eSIM.",
        "nullable": true,
        "properties": {
          "current_code": {
            "type": "string"
          },
          "expires_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "started_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "ResendResponse": {
        "properties": {
          "data": {
            "properties": {
              "id": {
                "description": "ID заказа, данные которого только что отправлены повторно.",
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "resent_at": {
                "format": "date-time",
                "type": "string"
              },
              "resent_to": {
                "description": "Адрес получателя, ЧАСТИЧНО СКРЫТЫЙ: партнёрский интерфейс не возвращает полный email клиента.",
                "example": "ab***@x.com",
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "SimulateRequest": {
        "properties": {
          "data": {
            "description": "Частичное переопределение поля `data` тестового содержимого.",
            "type": "object"
          }
        },
        "type": "object"
      },
      "SimulateResponse": {
        "properties": {
          "data": {
            "properties": {
              "delivery_id": {
                "format": "uuid",
                "type": "string"
              },
              "event_id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeEsimState": {
        "properties": {
          "data": {
            "properties": {
              "cancellable": {
                "$ref": "#/components/schemas/Cancellable"
              },
              "external_ref": {
                "description": "Ваша ссылка заказа `external_ref`, переданная при покупке, для связи eSIM с вашей системой. `null`, если не указана.",
                "nullable": true,
                "type": "string"
              },
              "iccid": {
                "example": "8984012345678901234",
                "nullable": true,
                "type": "string"
              },
              "id": {
                "description": "ID eSIM для всех путей `/v1/esims/{id}/…`, он же `order_item_id` вебхуков. Если известен только ICCID, получите `id` через GET /v1/esims?iccid=….",
                "format": "uuid",
                "type": "string"
              },
              "install": {
                "$ref": "#/components/schemas/Install"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "msisdn": {
                "nullable": true,
                "type": "string"
              },
              "order_id": {
                "format": "uuid",
                "type": "string"
              },
              "package_code": {
                "description": "КОД тарифа из каталога для связи eSIM с вашим каталогом. `null` только если исходный тариф удалён из каталога.",
                "nullable": true,
                "type": "string"
              },
              "package_name": {
                "description": "Отображаемое НАЗВАНИЕ может меняться. Не используйте его как ключ сверки.",
                "type": "string"
              },
              "plan": {
                "$ref": "#/components/schemas/PlanView"
              },
              "simulated": {
                "description": "Состояние ПОСЛЕ применения сценария.",
                "properties": {
                  "esim_state": {
                    "description": "ТЕХНИЧЕСКИЙ цикл тестовой eSIM. У рабочей eSIM он берётся из `smdp_status`, но у тестовой нет профиля SM-DP+, поэтому поле хранится среди тестовых данных.",
                    "enum": [
                      "released",
                      "installed",
                      "enabled",
                      "disabled"
                    ],
                    "type": "string"
                  },
                  "last_via": {
                    "description": "Процесс, ПОСЛЕДНИМ ИЗМЕНИВШИЙ её.",
                    "enum": [
                      "open_api",
                      "simulate",
                      "seed"
                    ],
                    "type": "string"
                  },
                  "via": {
                    "description": "Процесс, СОЗДАВШИЙ тестовую eSIM.",
                    "enum": [
                      "open_api",
                      "simulate",
                      "seed"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "smdp_status": {
                "example": "released",
                "nullable": true,
                "type": "string"
              },
              "status": {
                "example": "delivered",
                "type": "string"
              },
              "updated_at": {
                "format": "date-time",
                "type": "string"
              },
              "usage": {
                "$ref": "#/components/schemas/Usage"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeFailNextRequest": {
        "properties": {
          "count": {
            "default": 1,
            "maximum": 5,
            "minimum": 1,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "TestModeFailNextResponse": {
        "properties": {
          "data": {
            "properties": {
              "endpoint_id": {
                "format": "uuid",
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "testmode_fail_next": {
                "type": "integer"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeReset": {
        "properties": {
          "data": {
            "properties": {
              "esim_states_deleted": {
                "format": "int64",
                "type": "integer"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "order_items_deleted": {
                "format": "int64",
                "type": "integer"
              },
              "orders_deleted": {
                "format": "int64",
                "type": "integer"
              },
              "wallet_balance": {
                "description": "Баланс тестового кошелька ПОСЛЕ сброса, всегда 0. Реестр НЕ удаляется: обнуление выполняется компенсирующей проводкой.",
                "format": "int64",
                "type": "integer"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeResetInput": {
        "properties": {
          "reason": {
            "example": "Reset test data",
            "maxLength": 1000,
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      },
      "TestModeSeed": {
        "properties": {
          "data": {
            "properties": {
              "already_seeded": {
                "type": "boolean"
              },
              "esims_created": {
                "type": "integer"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "orders_created": {
                "type": "integer"
              },
              "seeded": {
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeSimulateRequest": {
        "description": "Сценарий симуляции. Все поля необязательны, но требуется хотя бы одно. Пустое тело даёт `422 testmode.invalid_scenario` вместо ложного успеха.",
        "properties": {
          "data_used_mb": {
            "description": "УЖЕ ИСПОЛЬЗОВАННЫЕ данные в МБ (двоичные единицы 1 MiB). Значение выше лимита ограничивается лимитом: это сценарий исчерпания данных, а не ошибка.",
            "example": 4096,
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "expire_at": {
            "description": "Задать точное время истечения срока (ISO-8601 UTC).",
            "format": "date-time",
            "type": "string"
          },
          "expire_now": {
            "description": "`true` — немедленно завершить срок тарифа (`esim_status = expired`).",
            "type": "boolean"
          },
          "provider_reject": {
            "description": "Симулировать отказ поставщика при следующем пополнении/отмене.",
            "type": "boolean"
          },
          "status": {
            "description": "ТЕХНИЧЕСКИЙ жизненный цикл профиля eSIM по терминологии поставщика, ОТЛИЧНЫЙ от коммерческого `esim_status` в методах eSIM.",
            "enum": [
              "released",
              "installed",
              "enabled",
              "disabled"
            ],
            "example": "enabled",
            "type": "string"
          },
          "throttled": {
            "description": "`true` — скорость ограничена после скоростного порога безлимитного тарифа.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "TestModeStatus": {
        "properties": {
          "data": {
            "properties": {
              "base_url_testing": {
                "description": "Хост тестового режима. Используйте только ключи tke_test_ или tke_member_test_; обращение к рабочему хосту возвращает 403 partner.wrong_host.",
                "type": "string"
              },
              "capabilities": {
                "properties": {
                  "bulk_orders": {
                    "type": "boolean"
                  },
                  "cancel_refund": {
                    "type": "boolean"
                  },
                  "refund_requests": {
                    "type": "boolean"
                  },
                  "webhooks": {
                    "type": "boolean"
                  }
                },
                "type": "object"
              },
              "checklist": {
                "description": "Этапы интеграции определяются по реальным вызовам API того же владельца в тестовом режиме. Проверка вебхуков применяется только к организациям.",
                "items": {
                  "properties": {
                    "done": {
                      "type": "boolean"
                    },
                    "label": {
                      "type": "string"
                    },
                    "last_at": {
                      "format": "date-time",
                      "nullable": true,
                      "type": "string"
                    },
                    "step": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              },
              "drift": {
                "description": "Цикл имитации расхода: включён ли он, интервал и последний запуск. Вебхуки порогов отправляются только организациям с поддержкой вебхуков.",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "interval_secs": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "last_run_at": {
                    "format": "date-time",
                    "nullable": true,
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "ready": {
                "description": "Выполнены ли владельцем ключа все поддерживаемые пункты проверки. Участникам не требуется проверка вебхуков.",
                "type": "boolean"
              },
              "sample_counts": {
                "properties": {
                  "test_esims": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "test_orders": {
                    "format": "int64",
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "seeded": {
                "description": "Есть ли у владельца ключа образцы тестовых заказов и eSIM.",
                "type": "boolean"
              },
              "test_key_count": {
                "format": "int64",
                "type": "integer"
              },
              "wallet_balance": {
                "description": "Баланс тестового кошелька владельца ключа в виртуальных VND, изолированный от рабочего кошелька.",
                "format": "int64",
                "type": "integer"
              },
              "webhook": {
                "properties": {
                  "endpoint_url": {
                    "nullable": true,
                    "type": "string"
                  },
                  "fail_next": {
                    "type": "integer"
                  },
                  "status": {
                    "nullable": true,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "TestModeWebhookFireRequest": {
        "properties": {
          "data": {
            "description": "Частичное переопределение поля `data` тестового содержимого.",
            "type": "object"
          },
          "event_type": {
            "description": "Тип тестового события вебхука.",
            "enum": [
              "order.completed",
              "order.failed",
              "esim.delivered",
              "esim.activated",
              "esim.usage_threshold",
              "esim.expiring",
              "wallet.low_balance",
              "catalog.updated"
            ],
            "type": "string"
          }
        },
        "required": [
          "event_type"
        ],
        "type": "object"
      },
      "Usage": {
        "description": "Статистика использованных данных eSIM. `updated_at = null`, если опроса ещё не было.",
        "nullable": true,
        "properties": {
          "expires_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "remaining_bytes": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "source": {
            "enum": [
              "poll",
              "webhook"
            ],
            "nullable": true,
            "type": "string"
          },
          "total_bytes": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "used_bytes": {
            "format": "int64",
            "nullable": true,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "WalletBalance": {
        "properties": {
          "data": {
            "properties": {
              "available": {
                "$ref": "#/components/schemas/Money"
              },
              "balance": {
                "$ref": "#/components/schemas/Money"
              },
              "credit_limit": {
                "$ref": "#/components/schemas/Money"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "WebhookConfig": {
        "properties": {
          "data": {
            "properties": {
              "active": {
                "description": "`false` — обработчик перестал получать новые события после паузы в панели или отзыва API-ключа (канал закрывается той же транзакцией). Успешная CHECK_HEALTH при PUT /v1/webhooks/{id} включает его снова.",
                "type": "boolean"
              },
              "created_at": {
                "format": "date-time",
                "type": "string"
              },
              "events": {
                "description": "Пусто — получать все события.",
                "items": {
                  "enum": [
                    "order.completed",
                    "order.failed",
                    "esim.delivered",
                    "esim.activated",
                    "esim.usage_threshold",
                    "esim.expiring",
                    "wallet.low_balance",
                    "catalog.updated"
                  ],
                  "type": "string"
                },
                "type": "array"
              },
              "id": {
                "description": "ID обработчика для `/v1/webhooks/{id}`. При каждом создании выдаётся НОВЫЙ: удаление и повторное создание не восстанавливают старый обработчик.",
                "format": "uuid",
                "type": "string"
              },
              "last_delivery_at": {
                "description": "Последнее время УСПЕШНОЙ ДОСТАВКИ обработчику. `null` — доставок не было, а не ошибка доставки. Проверьте первым при жалобе на отсутствие вебхуков.",
                "format": "date-time",
                "nullable": true,
                "type": "string"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "secret_last4": {
                "description": "Последние четыре символа секрета вебхука для проверки соответствия без раскрытия секрета. Полный секрет показывается ОДИН РАЗ при создании.",
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "WebhookEndpoint": {
        "properties": {
          "active": {
            "description": "`false` — обработчик перестал получать новые события после паузы в панели или отзыва API-ключа (канал закрывается той же транзакцией). Успешная CHECK_HEALTH при PUT /v1/webhooks/{id} включает его снова.",
            "type": "boolean"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "events": {
            "description": "Пусто — получать все события.",
            "items": {
              "enum": [
                "order.completed",
                "order.failed",
                "esim.delivered",
                "esim.activated",
                "esim.usage_threshold",
                "esim.expiring",
                "wallet.low_balance",
                "catalog.updated"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "id": {
            "description": "ID обработчика для `/v1/webhooks/{id}`. При каждом создании выдаётся НОВЫЙ: удаление и повторное создание не восстанавливают старый обработчик.",
            "format": "uuid",
            "type": "string"
          },
          "last_delivery_at": {
            "description": "Последнее время УСПЕШНОЙ ДОСТАВКИ обработчику. `null` — доставок не было, а не ошибка доставки. Проверьте первым при жалобе на отсутствие вебхуков.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "secret_last4": {
            "description": "Последние четыре символа секрета вебхука для проверки соответствия без раскрытия секрета. Полный секрет показывается ОДИН РАЗ при создании.",
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "WebhookListResponse": {
        "properties": {
          "data": {
            "properties": {
              "items": {
                "items": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                },
                "type": "array"
              },
              "mode": {
                "$ref": "#/components/schemas/ModeEcho"
              },
              "next_cursor": {
                "description": "Передайте БЕЗ ИЗМЕНЕНИЙ для следующей страницы. `null` — БОЛЬШЕ ДАННЫХ НЕТ, единственный сигнал остановки: за страницей короче `page_size` могут оставаться другие.",
                "nullable": true,
                "type": "string"
              },
              "page_size": {
                "description": "МАКСИМАЛЬНОЕ число записей, использованное сервером для страницы с учётом ограничения, а не фактическая длина `items`.",
                "nullable": true,
                "type": "integer"
              },
              "total": {
                "description": "Число строк по фильтру. `null`, если подсчёт слишком дорог. Конец списка определяйте по `next_cursor`, а не по этому полю.",
                "format": "int64",
                "nullable": true,
                "type": "integer"
              },
              "warnings": {
                "description": "ПРИЧИНЫ состава списка. Пусто — особенностей нет. `code` — ЗАКРЫТЫЙ набор: `filtered_by_key_package_filters` (ограничения каталога ключа), `filtered_by_provider_scope` (поставщики организации), `no_price_for_org` (нет цены), `price_filter_removed_rows` (фильтр цены), `provider_disabled` (нет доступного поставщика), `capability_missing` (не заявлены действия после продажи). `count` — число затронутых строк или `null`, если не выразимо числом.",
                "example": [],
                "items": {
                  "$ref": "#/components/schemas/ListWarning"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ok": {
            "enum": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "ok",
          "data"
        ],
        "type": "object"
      },
      "WebhookRequest": {
        "properties": {
          "events": {
            "description": "Пусто — получать все события. Неизвестное значение: 400 `internal.validation_failed` (поле `events`).",
            "items": {
              "enum": [
                "order.completed",
                "order.failed",
                "esim.delivered",
                "esim.activated",
                "esim.usage_threshold",
                "esim.expiring",
                "wallet.low_balance",
                "catalog.updated"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "url": {
            "example": "https://partner.example.com/hooks/tke",
            "format": "uri",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "TkeHmac": {
        "description": "Аутентификация HMAC-SHA256 (§4). Передайте 4 заголовка: `X-TKE-Key` (публичный key_id), `X-TKE-Timestamp` (мс Unix), `X-TKE-Nonce` (UUID на запрос), `X-TKE-Signature` (hex в нижнем регистре). signing_string = method\\npath\\ntimestamp\\nnonce\\nbody_hash; body_hash = SHA256(raw_body) hex. Сравнение за постоянное время. path ВКЛЮЧАЕТ строку запроса.",
        "in": "header",
        "name": "X-TKE-Signature",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "Open API для партнёров с интеграцией продаж eSIM. Все `/v1/*` требуют **HMAC-SHA256** с 4 заголовками `X-TKE-*`. POST с деньгами и заказами требует `Idempotency-Key`. Ключ `tke_test_` работает на тестовом хосте с виртуальными кошельком, запасом и выдачей. REST — источник состояния (сверка через `updated_since` и курсор); вебхуки — дополнительный канал. Первичные ключи всегда `id`, внешние — с префиксом, например `order_id`.",
    "title": "Tổng Kho eSIM — Open API đối tác",
    "version": "2.4.0"
  },
  "openapi": "3.0.3",
  "paths": {
    "/v1/catalog/packages": {
      "get": {
        "description": "Требуемая область доступа: `catalog:read`.\n\nКаталог организации: ЕДИНЫЙ список для двух систем поставки с фильтром `?market=`. Возвращаются только реально доступные для ПОКУПКИ тарифы: опубликованные, поставляемые, разрешённые ключу и с ценой организации. **Курсорная пагинация**: первый запрос без `cursor`, затем передавайте `next_cursor` до `null`. Короткая страница НЕ означает конец. `capabilities` берётся из РЕАЛЬНОЙ декларации тарифа; при отсутствии декларации все флаги `false`, чтобы не обещать вызов с неизбежным 422. В каталоге НЕТ данных о запасе. Если поставщик не может выдать тариф, POST /v1/orders вернёт явную ошибку `esim.out_of_stock` и подобную при заказе.",
        "operationId": "get_catalog_packages",
        "parameters": [
          {
            "description": "Записей на странице. По умолчанию 50, максимум 100. Большее значение ограничивается 100, это НЕ ошибка.",
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Система поставки: `domestic` | `international`. Значение вне списка даёт `internal.invalid_filter` (400), а не весь каталог: опечатка не должна отключать фильтр.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Код страны ISO-3166 alpha-2, например `VN`. Только тарифы с покрытием этой страны.",
            "in": "query",
            "name": "country",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Код региона, например `chau-a`. Тарифы с покрытием хотя бы одной страны региона и все глобальные тарифы.",
            "in": "query",
            "name": "region",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Поиск по публичному коду и названию тарифа: частичное совпадение без учёта регистра.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Фильтр по ОДНОЙ коммерческой метке. Нормализация как при сохранении: лишние пробелы удаляются, нижний регистр, дефисы; `Ban Le` и `ban-le` — одна метка.",
            "in": "query",
            "name": "tag",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Модель данных: `daily` | `fixed` | `unlimited`. ЗАМЕНЯЕТ старое `supports_topup`. Неизвестное значение: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "data_model",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Минимальный лимит в **БАЙТАХ**. Дневные тарифы сравниваются по ДНЕВНОМУ лимиту; безлимитные ВСЕГДА проходят нижнюю границу.",
            "in": "query",
            "name": "data_min_bytes",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Максимальный лимит в **БАЙТАХ**. Безлимитные тарифы ИСКЛЮЧАЮТСЯ: верхняя граница данных к ним неприменима и не должна выдавать безлимит ищущему малый пакет.",
            "in": "query",
            "name": "data_max_bytes",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Минимальный срок в днях.",
            "in": "query",
            "name": "days_min",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Максимальный срок в днях.",
            "in": "query",
            "name": "days_max",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Минимальная цена VND по цене ВАШЕЙ ОРГАНИЗАЦИИ. Фильтр применяется ПОСЛЕ формирования страницы, поэтому короткая страница не означает конец данных.",
            "in": "query",
            "name": "price_min",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Максимальная цена VND, правила как у `price_min`.",
            "in": "query",
            "name": "price_max",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Только тарифы с поддержкой поколения сети `2g` | `3g` | `4g` | `5g`. Неизвестное значение: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "network_gen",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`true` — только тарифы с ЗАЯВЛЕННОЙ раздачей Wi-Fi; `false` — с ЗАЯВЛЕННЫМ запретом. Без декларации (`features.hotspot = null`) тариф не проходит НИ ОДИН вариант. Допустимы только строки `true`/`false`.",
            "in": "query",
            "name": "hotspot",
            "required": false,
            "schema": {
              "enum": [
                "true",
                "false"
              ],
              "type": "string"
            }
          },
          {
            "description": "Только тарифы с ЗАЯВЛЕННОЙ поддержкой приложения хотя бы на одной ОС (`app=tiktok`). Отсутствие сведений не означает поддержку. Пока принимается только `tiktok`; другой код: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "app",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`true` — только тарифы с ЗАЯВЛЕННЫМ голосом; `false` — с ЗАЯВЛЕННЫМ отсутствием. Без декларации тариф не проходит ни один вариант. Допустимы только строки `true`/`false`.",
            "in": "query",
            "name": "voice",
            "required": false,
            "schema": {
              "enum": [
                "true",
                "false"
              ],
              "type": "string"
            }
          },
          {
            "description": "Передайте `next_cursor` предыдущей страницы БЕЗ ИЗМЕНЕНИЙ. **Остановитесь при `next_cursor = null`, а НЕ при короткой странице.** Ограничения каталога ключа, наличие цены организации и фильтр цены применяются ПОСЛЕ разбиения: за страницей из 3 элементов могут оставаться тысячи тарифов. Курсор содержит ОТПЕЧАТОК фильтров. Другие фильтры или повреждённый курсор дают `catalog.cursor_mismatch` (400), чтобы не смешивать результаты разных запросов.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`, `catalog.cursor_mismatch`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Список тарифов",
        "tags": [
          "catalog"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/catalog/packages/{code}": {
      "get": {
        "description": "Требуемая область доступа: `catalog:read`.\n\nДетали ОДНОГО тарифа по публичному коду. `data` содержит ТЕ ЖЕ ПОЛЯ, что элемент GET /v1/catalog/packages, плюс `mode`. Для `Package` достаточно одного типа. Недоступный код даёт `partner.package_not_visible` (404). Один код ошибки для отсутствующего, запрещённого ключу, не имеющего цены организации или потерявшего поставщика тарифа: различение позволило бы постороннему перечислить весь каталог.",
        "operationId": "get_catalog_packages__code_",
        "parameters": [
          {
            "description": "Код тарифа из каталога — `code` (`public_sku`). НЕИЗМЕНЯЕМ при смене поставщика, подходит для сверки. Запрещённый ключу или не имеющий цены организации код даёт `404 partner.package_not_visible`, как несуществующий.",
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageDetail"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.package_not_visible`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Получить один тариф",
        "tags": [
          "catalog"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.",
        "operationId": "get_esims",
        "parameters": [
          {
            "description": "Записей на странице. По умолчанию 50, максимум 200. Большее значение ограничивается 200, это НЕ ошибка.",
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Фильтр по `esim_status`. Значение вне списка даёт `internal.invalid_filter` (400), а не пустой список: опечатка вроде `canceled` без второго `l` не должна выглядеть как отсутствие eSIM в этом состоянии.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "pending",
                "available",
                "reserved",
                "sold",
                "delivered",
                "in_use",
                "used_up",
                "expired",
                "suspended",
                "cancelled",
                "provider_failed"
              ],
              "type": "string"
            }
          },
          {
            "description": "Только eSIM одного заказа.",
            "in": "query",
            "name": "order_id",
            "required": false,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "description": "Фильтр по ICCID (строка, точное совпадение).",
            "in": "query",
            "name": "iccid",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Все eSIM заказов с вашей ссылкой заказа (`external_ref`, переданной при покупке, точное совпадение).",
            "in": "query",
            "name": "external_ref",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO-8601 UTC. Записи с `updated_at >= updated_since` по возрастанию — стандартная СВЕРКА ЗАПРОСАМИ (§8.5), позволяющая восстановить пропущенный вебхук по состоянию. Неверный формат: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Курсор следующей страницы: передайте `next_cursor` предыдущей страницы БЕЗ ИЗМЕНЕНИЙ. ВНИМАНИЕ: неверный курсор не вызывает ошибку, сервер снова читает НАЧАЛО списка для совместимости при смене кодирования. Поэтому перед повтором проверяйте, что `next_cursor` отличается от отправленного курсора, иначе цикл будет бесконечно читать первую страницу.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Дополнительные блоки через запятую. `lpa` возвращает `install` с кодом активации; `qr` добавляет `install.qr_code_base64` только в детальном ответе. **ВОЗВРАТ КОДА СЧИТАЕТСЯ РАСКРЫТИЕМ.** `lpa` НАВСЕГДА закрывает отмену всех eSIM ответа (`cancellable.allowed = false`, `reason = code_disclosed`): выданный код нельзя отозвать. Запрашивайте при передаче клиенту; при покупке заранее не запрашивайте, чтобы сохранить отмену. Неизвестное значение: `internal.invalid_filter` (400, `field: \"include\"`).",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "example": "lpa",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EsimListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Список eSIM (сверка запросами)",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims/{id}": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.",
        "operationId": "get_esims__id_",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Дополнительные блоки через запятую. `lpa` возвращает `install` с кодом активации; `qr` добавляет `install.qr_code_base64` только в детальном ответе. **ВОЗВРАТ КОДА СЧИТАЕТСЯ РАСКРЫТИЕМ.** `lpa` НАВСЕГДА закрывает отмену всех eSIM ответа (`cancellable.allowed = false`, `reason = code_disclosed`): выданный код нельзя отозвать. Запрашивайте при передаче клиенту; при покупке заранее не запрашивайте, чтобы сохранить отмену. Неизвестное значение: `internal.invalid_filter` (400, `field: \"include\"`).",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "example": "lpa",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Esim"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Получить одну eSIM",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims/{id}/cancel": {
      "post": {
        "description": "Требуемая область доступа: `esims:write`.",
        "operationId": "post_esims__id__cancel",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — `api_key_id` (§11): разные ключи означают разные команды.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `esim.not_cancellable`, `idempotency.conflict`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `capability.not_supported`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Отменить неиспользованную eSIM",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims/{id}/change-plan": {
      "post": {
        "description": "Требуемая область доступа: `esims:write`.",
        "operationId": "post_esims__id__change-plan",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — `api_key_id` (§11): разные ключи означают разные команды.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlanRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangePlanResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `wallet.insufficient_balance`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.package_not_visible`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `esim.topup_not_supported`, `esim.topup_provider_mismatch`, `esim.not_eligible`, `idempotency.conflict`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `capability.not_supported`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Пополнить eSIM",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims/{id}/plan-options": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.\n\nДоступные тарифы пополнения **ИМЕННО ЭТОЙ eSIM**. Сервер находит её поставщика по `id` и возвращает только его тарифы. `/v1` не раскрывает `provider_id`, поэтому фильтрация исключает выбор другого поставщика. Прямой POST /v1/esims/{id}/change-plan с тарифом вне списка даёт `409 esim.topup_provider_mismatch`. Без связанного поставщика (импортированная запись или отсутствующие исходные данные) возвращается ПУСТОЙ список `total: 0`; это корректный ответ.",
        "operationId": "get_esims__id__plan-options",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Записей на странице. По умолчанию 50, максимум 200. Большее значение ограничивается 200, это НЕ ошибка.",
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Курсор следующей страницы: передайте `next_cursor` предыдущей страницы БЕЗ ИЗМЕНЕНИЙ. ВНИМАНИЕ: неверный курсор не вызывает ошибку, сервер снова читает НАЧАЛО списка для совместимости при смене кодирования. Поэтому перед повтором проверяйте, что `next_cursor` отличается от отправленного курсора, иначе цикл будет бесконечно читать первую страницу.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanOptionsResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Доступные тарифы пополнения этой eSIM",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/esims/{id}/refund-requests": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.\n\nТолько разрешённые рабочие ключи участников. Возвращает до 50 последних заявок по eSIM участника, начиная с новых; next_cursor и total равны null. has_open_request указывает на ожидание проверки. Ключи организаций и тестовые ключи получают capability.not_supported.",
        "operationId": "get_esims__id__refund-requests",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberRefundRequestListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `capability.not_supported`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "История заявок на возврат eSIM (только участники)",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live"
        ],
        "x-tke-owner-types": [
          "member"
        ]
      },
      "post": {
        "description": "Требуемая область доступа: `esims:write`.\n\nТолько разрешённые рабочие ключи участников. Заявка на возврат за собственную eSIM требует Idempotency-Key; средства не переводятся до одобрения администратора. Ключи организаций и тестовые ключи получают capability.not_supported. Для проверки виртуального возврата в тестовом режиме отмените eSIM.",
        "operationId": "post_esims__id__refund-requests",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — `api_key_id` (§11): разные ключи означают разные команды.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberRefundRequestInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberRefundRequestResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `esim.refund_not_eligible`, `esim.refund_request_pending`, `idempotency.conflict`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `capability.not_supported`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Создать заявку на возврат eSIM (только участники)",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live"
        ],
        "x-tke-owner-types": [
          "member"
        ]
      }
    },
    "/v1/esims/{id}/usage": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.\n\nИспользованные и оставшиеся данные eSIM с `updated_at`, показывающим фактическую свежесть. Для поставщиков с опросом по запросу (сейчас SkyFi) вызов ставит опрос в очередь и ЖДЁТ до 15 секунд. Успешный ответ содержит свежий результат. При ошибке, интервале менее 15 секунд между опросами одной eSIM или тайм-ауте ошибки НЕТ: возвращаются последние сохранённые данные, проверяйте `updated_at`. Другие поставщики возвращают данные периодического обновления.",
        "operationId": "get_esims__id__usage",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EsimUsage"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `capability.not_supported`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Использованные данные",
        "tags": [
          "esims"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/orders": {
      "get": {
        "description": "Требуемая область доступа: `orders:read`.",
        "operationId": "get_orders",
        "parameters": [
          {
            "description": "Записей на странице. По умолчанию 50, максимум 200. Большее значение ограничивается 200, это НЕ ошибка.",
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Фильтр по статусу заказа. Значение вне списка: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "completed",
                "pending_provider",
                "provider_failed",
                "cancelled"
              ],
              "type": "string"
            }
          },
          {
            "description": "Фильтр по вашей ссылке, переданной при оформлении (ТОЧНОЕ совпадение).",
            "in": "query",
            "name": "external_ref",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO-8601 UTC. Записи с `updated_at >= updated_since` по возрастанию — стандартная СВЕРКА ЗАПРОСАМИ (§8.5), позволяющая восстановить пропущенный вебхук по состоянию. Неверный формат: `internal.invalid_filter` (400).",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Курсор следующей страницы: передайте `next_cursor` предыдущей страницы БЕЗ ИЗМЕНЕНИЙ. ВНИМАНИЕ: неверный курсор не вызывает ошибку, сервер снова читает НАЧАЛО списка для совместимости при смене кодирования. Поэтому перед повтором проверяйте, что `next_cursor` отличается от отправленного курсора, иначе цикл будет бесконечно читать первую страницу.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Список заказов (сверка запросами)",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      },
      "post": {
        "description": "Требуемая область доступа: `orders:write`.",
        "operationId": "post_orders",
        "parameters": [
          {
            "description": "Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — `api_key_id` (§11): разные ключи означают разные команды.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "Повтор ранее выполненной команды: те же `Idempotency-Key` и тело за 24 часа. Тело ответа ИДЕНТИЧНО первому, повторного списания НЕТ, добавляется `Idempotent-Replayed: true`. НОВАЯ операция возвращает `201`; не определяйте успех только по этому статусу."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `wallet.insufficient_balance`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.package_not_visible`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `esim.out_of_stock`, `idempotency.conflict`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `invoice.buyer_invalid`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Создать заказ (прямая покупка)",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/orders/bulk": {
      "post": {
        "description": "Требуемая область доступа: `orders:write`.\n\nСоздать **пакет из нескольких строк**: строка создаёт ОДИН независимый заказ тем же путём quote→commit, что POST /v1/orders. **ЧАСТИЧНЫЙ УСПЕХ**: ошибки не блокируют другие строки, списание только за успешные. Ошибки запаса, баланса, недоступности и лимитов — в `lines[].error` без смены HTTP-статуса. При нехватке баланса последующие более дешёвые строки всё равно проверяются. Статус всегда `200`: ответ содержит результаты строк, не один ресурс и не отложенный процесс. **Повтор после прерывания**: ТЕ ЖЕ `Idempotency-Key` и тело загружают старый пакет, сохраняют завершённые результаты и выполняют только `pending` без двойного списания. Если строк не выполнялось, добавляется `Idempotent-Replayed: true`. Другое тело с тем же ключом: `idempotency.conflict`. **Та же корзина за 10 минут** в одной организации считается случайным дублем даже с разными ключами. Возвращается старый пакет с `Idempotent-Replayed: true` без списания. Для намеренной повторной покупки другому клиенту **смените `external_ref`**: он входит в подписанное тело, различает команды и помогает сверке. Полностью неуспешный пакет не блокируется; после 10 минут новый заказ разрешён. Ссылки строк возвращаются в `lines[].external_ref`, пакета — в корне. LPA/QR отсутствуют: получите eSIM через GET /v1/orders/{order_id} для каждого заказа.",
        "operationId": "post_orders_bulk",
        "parameters": [
          {
            "description": "Строка клиента: одинаковые ключ и тело выполняются ровно один раз; повтор возвращает исходный результат. Область действия — `api_key_id` (§11): разные ключи означают разные команды.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkBatchResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.package_not_visible`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `idempotency.conflict`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.limit_exceeded`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Создать пакет из нескольких строк (заказ на строку)",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/orders/bulk/{id}": {
      "get": {
        "description": "Требуемая область доступа: `orders:read`.\n\nПовторное чтение результатов строк ранее созданного пакета при потере исходного ответа без повторной отправки тела. Пакет другой организации или режима (рабочий ⇄ тестовый) даёт `404`.",
        "operationId": "get_orders_bulk__id_",
        "parameters": [
          {
            "description": "ID пакета UUID, возвращённый POST /v1/orders/bulk.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkBatchResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Результат пакета заказов",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/orders/{id}": {
      "get": {
        "description": "Требуемая область доступа: `orders:read`.",
        "operationId": "get_orders__id_",
        "parameters": [
          {
            "description": "ID заказа UUID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Дополнительные блоки через запятую. `lpa` возвращает `install` с кодом активации; `qr` добавляет `install.qr_code_base64` только в детальном ответе. **ВОЗВРАТ КОДА СЧИТАЕТСЯ РАСКРЫТИЕМ.** `lpa` НАВСЕГДА закрывает отмену всех eSIM ответа (`cancellable.allowed = false`, `reason = code_disclosed`): выданный код нельзя отозвать. Запрашивайте при передаче клиенту; при покупке заранее не запрашивайте, чтобы сохранить отмену. Неизвестное значение: `internal.invalid_filter` (400, `field: \"include\"`).",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "example": "lpa",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.invalid_filter`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Детали заказа и eSIM",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/orders/{id}/resend": {
      "post": {
        "description": "Требуемая область доступа: `orders:write`.",
        "operationId": "post_orders__id__resend",
        "parameters": [
          {
            "description": "ID заказа UUID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResendResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `order.not_deliverable`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Повторно отправить письмо/QR заказа",
        "tags": [
          "orders"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/testmode/esims/{id}/simulate": {
      "post": {
        "description": "Требуемая область доступа: `esims:write`.\n\nТолько тестовые ключи tke_test_ или tke_member_test_. Задайте сценарий для тестовой eSIM владельца: расход, установку, истечение срока, ограничение скорости или отказ поставщика при следующей операции. В теле требуется хотя бы одно поле; пустое тело возвращает 422 testmode.invalid_scenario. Результат читается через GET /v1/esims/{id} и /usage, как в рабочем режиме. Правила смены плана и отмены общие; реальный поставщик не вызывается.",
        "operationId": "post_testmode_esims__id__simulate",
        "parameters": [
          {
            "description": "Постоянный ID проданной eSIM, НЕ ICCID, который может повторно использоваться.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestModeSimulateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestModeEsimState"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `testmode.invalid_scenario`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Симулировать жизненный цикл тестовой eSIM (только тестовые ключи)",
        "tags": [
          "testmode"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/testmode/reset": {
      "post": {
        "description": "Требуемая область доступа: `orders:write`.",
        "operationId": "post_testmode_reset",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestModeResetInput"
              }
            }
          },
          "required": false
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestModeReset"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Сбросить тестовые данные (только тестовые ключи)",
        "tags": [
          "testmode"
        ],
        "x-tke-idempotency-owner-types": [
          "member"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ],
        "x-tke-required-body-owner-types": [
          "member"
        ]
      }
    },
    "/v1/testmode/seed": {
      "post": {
        "description": "Требуемая область доступа: `orders:write`.",
        "operationId": "post_testmode_seed",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestModeSeed"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `testmode.no_sellable_package`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Создать примеры тестовых данных (только тестовые ключи)",
        "tags": [
          "testmode"
        ],
        "x-tke-idempotency-owner-types": [
          "member"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/testmode/status": {
      "get": {
        "description": "Требуемая область доступа: `esims:read`.",
        "operationId": "get_testmode_status",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestModeStatus"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Обзор тестового режима (только тестовые ключи)",
        "tags": [
          "testmode"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/testmode/webhooks/fail-next": {
      "post": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "post_testmode_webhooks_fail-next",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestModeFailNextRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestModeFailNextResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`, `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Симулировать следующую ошибку вебхука (только тестовые ключи)",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/testmode/webhooks/fire": {
      "post": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "post_testmode_webhooks_fire",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestModeWebhookFireRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulateResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`, `testmode.live_key_forbidden`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.not_configured`, `internal.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Отправить тестовое событие вебхука (только тестовые ключи)",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/wallet/balance": {
      "get": {
        "description": "Требуемая область доступа: `wallet:read`.",
        "operationId": "get_wallet_balance",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletBalance"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Баланс кошелька",
        "tags": [
          "wallet"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization",
          "member"
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "description": "Требуемая область доступа: `webhook:manage`.\n\nОбработчики вебхуков текущего API-ключа. Ключ НИКОГДА не видит обработчики другого, даже в одной организации (§5.11, привязка к `api_key_id`; тестовый и рабочий ключи разделены). Если настройка ещё не создана, возвращается `200` с ПУСТЫМ массивом, не 404.",
        "operationId": "get_webhooks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Список обработчиков вебхуков",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      },
      "post": {
        "description": "Требуемая область доступа: `webhook:manage`.\n\nСоздать обработчик вебхука для текущего API-ключа. До сохранения сервер **отправляет подписанный `ping`** на указанный URL (CHECK_HEALTH). Без 2xx ничего не сохраняется: `422 webhook.health_check_failed`. URL — публичный `https`; внутренний или metadata IP даёт `422 webhook.url_not_allowed`. Ответ показывает `webhook_secret` **ровно один раз**, прочитать его снова нельзя. При потере смените секрет в панели; старый действует ещё 24 часа (§8.4). Если у ключа уже есть обработчик, даже приостановленный (`is_active: false`), возвращается `409 webhook.already_configured`: URL, секрет и журнал сохраняются. Чтобы начать заново, вызовите DELETE /v1/webhooks/{id} и создайте новый.",
        "operationId": "post_webhooks",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateWebhookResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.already_configured`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.health_check_failed`, `webhook.url_not_allowed`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Создать обработчик вебхука",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/webhooks/deliveries": {
      "get": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "get_webhooks_deliveries",
        "parameters": [
          {
            "description": "Номер страницы с 1. За концом списка возвращаются `items: []` и реальный `total` (200, не 404).",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Записей на странице. По умолчанию 50, максимум 200. Большее значение ограничивается 200, это НЕ ошибка.",
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Фильтр по типу события (см. каталог вебхуков).",
            "in": "query",
            "name": "event_type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Фильтр по статусу доставки. `?status=failed` используется для сверки вебхуков запросами (§13). Неизвестное значение не вызывает ошибку: фильтр ИГНОРИРУЕТСЯ, возвращается полный журнал.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "pending",
                "delivered",
                "failed"
              ],
              "type": "string"
            }
          },
          {
            "description": "Все попытки доставки ОДНОГО события, включая переотправки.",
            "in": "query",
            "name": "event_id",
            "required": false,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryListResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.not_configured`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Журнал доставок вебхуков",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/webhooks/deliveries/{id}/replay": {
      "post": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "post_webhooks_deliveries__id__replay",
        "parameters": [
          {
            "description": "ID одной доставки вебхука (`items[].id` из GET /v1/webhooks/deliveries).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryReplayResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.delivery_not_found`, `webhook.not_configured`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Повторно отправить вебхук",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "description": "Требуемая область доступа: `webhook:manage`.\n\nУдалить обработчик и прекратить новые события текущего API-ключа. **Теряется** `webhook_secret`: повторный POST /v1/webhooks создаёт НОВЫЕ `id` и секрет, проверку подписи нужно обновить. Для временной остановки с сохранением секрета используйте кнопку паузы в панели. **Сохраняется** журнал для сверки, но переотправлять доставки удалённого обработчика нельзя. Ожидающие `pending` доставки останавливаются с `endpoint_disabled` и остаются в журнале (§8.5). Чужой или уже удалённый `id` даёт `404 webhook.not_found`, не 200.",
        "operationId": "delete_webhooks__id_",
        "parameters": [
          {
            "description": "ID обработчика вебхука: `id` из POST /v1/webhooks или GET /v1/webhooks.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteWebhookResponse"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Удалить обработчик вебхука (прекратить новые события)",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      },
      "get": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "get_webhooks__id_",
        "parameters": [
          {
            "description": "ID обработчика вебхука: `id` из POST /v1/webhooks или GET /v1/webhooks.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.not_found`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Получить один обработчик вебхука",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      },
      "put": {
        "description": "Требуемая область доступа: `webhook:manage`.",
        "operationId": "put_webhooks__id_",
        "parameters": [
          {
            "description": "ID обработчика вебхука: `id` из POST /v1/webhooks или GET /v1/webhooks.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                }
              }
            },
            "description": "Успешно"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `internal.validation_failed`"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.invalid_key`, `partner.invalid_signature`, `partner.timestamp_expired`, `partner.nonce_reused`"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.ip_not_allowed`, `partner.scope_denied`, `partner.key_suspended`, `partner.key_revoked`, `org.suspended`"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.not_found`"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `webhook.health_check_failed`, `webhook.url_not_allowed`"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.rate_limited`"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Ошибка: `partner.endpoint_disabled`, `internal.service_unavailable`"
          }
        },
        "summary": "Обновить обработчик вебхука",
        "tags": [
          "webhook"
        ],
        "x-tke-modes": [
          "live",
          "test"
        ],
        "x-tke-owner-types": [
          "organization"
        ]
      }
    }
  },
  "security": [
    {
      "TkeHmac": []
    }
  ],
  "servers": [
    {
      "description": "Live",
      "url": "https://api.tongkhoesim.com"
    },
    {
      "description": "Тестовый режим",
      "url": "https://api-testing.tongkhoesim.com"
    }
  ],
  "tags": [
    {
      "description": "Каталог тарифов: ЕДИНЫЙ список для двух систем поставки. Система — поле `market` (`domestic` | `international`) и фильтр `?market=`, а не отдельные пути. Данных о запасе НЕТ: ни числа, ни уровней `available`/`low`/`out_of_stock`. Если поставщик не может выдать тариф, POST /v1/orders вернёт явную ошибку `esim.out_of_stock` и подобную. Единая курсорная пагинация. `total` заполняется при дешёвом подсчёте (внутренняя система), иначе `null`.",
      "name": "catalog"
    },
    {
      "description": "Создание заказов и сверка",
      "name": "orders"
    },
    {
      "description": "eSIM: записи, расход, пополнение и отмена",
      "name": "esims"
    },
    {
      "description": "Баланс кошелька",
      "name": "wallet"
    },
    {
      "description": "Настройки вебхуков, журнал доставок и симулятор",
      "name": "webhook"
    },
    {
      "description": "Используйте только тестовые ключи tke_test_ или tke_member_test_ на хосте api-testing. Моделируются тестовые eSIM и данные владельца без реальных средств и поставщиков. Для участников не поддерживаются вебхуки, пакетные заказы и заявки на ручное рассмотрение возврата.",
      "name": "testmode"
    }
  ]
}
