{
  "openapi": "3.1.0",
  "info": {
    "title": "KILLA PROXY & VPN",
    "version": "v1",
    "description": "Один API для VPN-подписок, серверных и резидентных прокси: узнать цену, купить, продлить и управлять — из своего бота или панели.\n\nТокен передаётся в заголовке `Authorization: Bearer <token>`.\n\nОтвет всегда JSON с полем `ok`. Всегда проверяй поле `ok`. При `ok: false` логику строй на `error.code`, а `error.message` показывай человеку как текст.\n\nДокументация: https://proxy-docs.killa.cc — вся одним текстом: https://proxy-docs.killa.cc/llms-full.txt",
    "contact": {
      "url": "https://t.me/KillaSupport_Bot"
    }
  },
  "servers": [
    {
      "url": "https://proxy.killa.cc/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "VPN",
      "description": "Подписки и устройства клиентов. Продавай VPN-подписки под своим брендом: клиент получает ссылку, добавляет её в приложение — и подключается."
    },
    {
      "name": "Серверные прокси",
      "description": "Выделенные и общие IPv4, IPv6. Прокси с фиксированным IP: выбираешь страну, тип адреса и срок — получаешь готовые данные для подключения."
    },
    {
      "name": "Резидентные прокси",
      "description": "Трафик, локации, прокси-листы. Продаёшь трафик в гигабайтах, а клиент сам собирает прокси-лист под нужные страны, города и провайдеров."
    },
    {
      "name": "Аккаунт",
      "description": "Баланс и расходы. Всё, что касается самого аккаунта: сколько денег на балансе и сколько ушло через API."
    }
  ],
  "paths": {
    "/vpn/quote": {
      "get": {
        "operationId": "vpn_quote",
        "summary": "Цены на VPN",
        "description": "Возвращает цены на месячные тарифы и условия платного пробного тарифа.\n\n**Когда нужен.** Чтобы показать клиенту цены и передать в покупку только допустимый период.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "1": {
                          "type": "number",
                          "description": "Цена за период: ключ — число месяцев, значение — цена, ₽. Только эти периоды принимают покупка и продление."
                        },
                        "trial": {
                          "type": "object",
                          "description": "Платный пробный тариф.",
                          "properties": {
                            "price_rub": {
                              "type": "number",
                              "description": "Цена пробного тарифа, ₽."
                            },
                            "days": {
                              "type": "integer",
                              "description": "Срок пробного тарифа, дней."
                            },
                            "traffic_limit_gb": {
                              "type": "integer",
                              "description": "Лимит трафика пробного тарифа, ГБ."
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "1": 200,
                    "3": 500,
                    "6": 900,
                    "12": 1500,
                    "trial": {
                      "price_rub": 5,
                      "days": 3,
                      "traffic_limit_gb": 5
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "цена",
          "цены",
          "стоимость",
          "тарифы",
          "прайс",
          "сколько стоит",
          "пробный",
          "trial",
          "quote"
        ],
        "x-effect": "read"
      }
    },
    "/vpn/buy": {
      "post": {
        "operationId": "vpn_buy",
        "summary": "Купить подписку",
        "description": "Создаёт новую подписку и списывает её цену с баланса. В ответе — `uuid` и ссылка подписки для клиента.\n\n**Когда нужен.** Когда клиент оплатил VPN у тебя и ему нужна новая подписка.\n\n**Важно.** Передай **одно** из двух полей — `period_months` или `plan`. Оба сразу нельзя. Старые интеграции с `period_months` работают без изменений.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "description": "Какой тариф куплен: `months` — месячный."
                        },
                        "period_months": {
                          "type": "integer",
                          "description": "Период в месяцах."
                        },
                        "traffic_limit_gb": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Лимит трафика, ГБ. `null` — без лимита."
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "uuid": {
                          "type": "string",
                          "description": "Идентификатор подписки. **Сохрани его** — все дальнейшие действия только по нему."
                        },
                        "subscriptionUrl": {
                          "type": "string",
                          "description": "Ссылка подписки — её получает клиент."
                        },
                        "expireAt": {
                          "type": "string",
                          "description": "Дата окончания в UTC, формат ISO 8601."
                        },
                        "expireAt_date": {
                          "type": "string",
                          "description": "Та же дата в виде ДД.ММ.ГГГГ — удобно показать клиенту."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "plan": "months",
                    "period_months": 1,
                    "traffic_limit_gb": null,
                    "price_rub": 200,
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "subscriptionUrl": "https://vpn.tunnelgate.org/xxxxxxxxxxxxxxxx",
                    "expireAt": "2026-03-25T10:00:00.000Z",
                    "expireAt_date": "25.03.2026"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "купить",
          "покупка",
          "оформить",
          "создать подписку",
          "новая подписка",
          "пробный",
          "trial",
          "buy"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "period_months": {
                    "type": "integer",
                    "description": "Период в месяцах. Только значения из `/vpn/quote`."
                  },
                  "plan": {
                    "type": "string",
                    "description": "Платный пробный тариф — значение `\"trial\"`. Срок и лимит трафика — в `/vpn/quote`."
                  }
                }
              },
              "example": {
                "period_months": 1
              }
            }
          }
        }
      }
    },
    "/vpn/info": {
      "get": {
        "operationId": "vpn_info",
        "summary": "Информация о подписке",
        "description": "Показывает статус, срок, ссылку, лимит трафика и лимит устройств подписки.\n\n**Когда нужен.** Чтобы показать клиенту состояние подписки или проверить, прошло ли продление после сетевого сбоя.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "VPN"
        ],
        "parameters": [
          {
            "name": "uuid",
            "in": "query",
            "required": true,
            "description": "UUID подписки.",
            "schema": {
              "type": "string",
              "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "`ACTIVE` — активна, `DISABLED` — отключена, `LIMITED` — ограничена, `EXPIRED` — истекла."
                        },
                        "expireAt": {
                          "type": "string",
                          "description": "Дата окончания в UTC, формат ISO 8601."
                        },
                        "expireAt_date": {
                          "type": "string",
                          "description": "Та же дата в виде ДД.ММ.ГГГГ."
                        },
                        "subscriptionUrl": {
                          "type": "string",
                          "description": "Ссылка подписки."
                        },
                        "trafficLimitBytes": {
                          "type": "integer",
                          "description": "Лимит трафика в байтах. `0` — без лимита."
                        },
                        "hwidDeviceLimit": {
                          "type": "integer",
                          "description": "Сколько устройств можно подключить."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "status": "ACTIVE",
                    "expireAt": "2026-06-25T10:00:00.000Z",
                    "expireAt_date": "25.06.2026",
                    "subscriptionUrl": "https://vpn.tunnelgate.org/xxxxxxxxxxxxxxxx",
                    "trafficLimitBytes": 0,
                    "hwidDeviceLimit": 5
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "информация",
          "инфо",
          "статус",
          "срок",
          "проверить",
          "ссылка подписки",
          "когда заканчивается",
          "info"
        ],
        "x-effect": "read"
      }
    },
    "/vpn/renew": {
      "post": {
        "operationId": "vpn_renew",
        "summary": "Продлить подписку",
        "description": "Продлевает подписку на выбранный период и списывает его цену с баланса.\n\n**Когда нужен.** Когда клиент оплатил продление.\n\n**Важно.** Если подписка ещё действует, период добавляется к дате окончания. Если уже истекла — отсчёт идёт от текущего дня.\n\n**Совет.** Пробную подписку продлевают обычным месячным периодом — она становится полноценной. Значение `\"trial\"` здесь не принимается.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "period_months": {
                          "type": "integer",
                          "description": "На сколько месяцев продлено."
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "subscriptionUrl": {
                          "type": "string",
                          "description": "Ссылка подписки."
                        },
                        "expireAt": {
                          "type": "string",
                          "description": "Новая дата окончания в UTC, формат ISO 8601."
                        },
                        "expireAt_date": {
                          "type": "string",
                          "description": "Та же дата в виде ДД.ММ.ГГГГ."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "period_months": 3,
                    "price_rub": 500,
                    "subscriptionUrl": "https://vpn.tunnelgate.org/xxxxxxxxxxxxxxxx",
                    "expireAt": "2026-06-25T10:00:00.000Z",
                    "expireAt_date": "25.06.2026"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "продлить",
          "продление",
          "продлевать",
          "срок",
          "renew"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "description": "UUID подписки.",
                    "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  },
                  "period_months": {
                    "type": "integer",
                    "enum": [
                      1,
                      3,
                      6,
                      12
                    ],
                    "description": "Период в месяцах. Только значения из `/vpn/quote`.",
                    "example": 3
                  }
                },
                "required": [
                  "uuid",
                  "period_months"
                ]
              },
              "example": {
                "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "period_months": 3
              }
            }
          }
        }
      }
    },
    "/vpn/hwid/devices": {
      "get": {
        "operationId": "vpn_hwid_devices",
        "summary": "Список устройств",
        "description": "Показывает подключённые устройства и лимит подписки.\n\n**Когда нужен.** Когда клиент пишет, что не может подключить новое устройство, — проверить, не занят ли лимит.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "VPN"
        ],
        "parameters": [
          {
            "name": "uuid",
            "in": "query",
            "required": true,
            "description": "UUID подписки.",
            "schema": {
              "type": "string",
              "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "device_limit": {
                          "type": "integer",
                          "description": "Лимит устройств."
                        },
                        "connected": {
                          "type": "integer",
                          "description": "Сколько устройств привязано к подписке."
                        },
                        "devices": {
                          "type": "array",
                          "description": "Список устройств.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "hwid": {
                                "type": "string",
                                "description": "Идентификатор устройства — нужен для сброса."
                              },
                              "platform": {
                                "type": "string",
                                "description": "Платформа: Windows, Android, iOS и т. д."
                              },
                              "osVersion": {
                                "type": "string",
                                "description": "Версия системы."
                              },
                              "deviceModel": {
                                "type": "string",
                                "description": "Модель устройства."
                              },
                              "userAgent": {
                                "type": "string",
                                "description": "Приложение и его версия."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "Когда устройство появилось в подписке, UTC."
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "Когда запись об устройстве обновлялась в последний раз, UTC."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "device_limit": 5,
                    "connected": 1,
                    "devices": [
                      {
                        "hwid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                        "userUuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                        "platform": "Windows",
                        "osVersion": "10.0.19045",
                        "deviceModel": "Home-PC_x86_64",
                        "userAgent": "Happ/1.5.2/Windows",
                        "createdAt": "2026-01-21T14:42:27.559Z",
                        "updatedAt": "2026-01-21T14:42:27.558Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "устройства",
          "девайсы",
          "телефоны",
          "подключения",
          "hwid",
          "лимит устройств",
          "devices"
        ],
        "x-effect": "read"
      }
    },
    "/vpn/hwid/reset": {
      "post": {
        "operationId": "vpn_hwid_reset",
        "summary": "Сбросить одно устройство",
        "description": "Отвязывает одно устройство от подписки и освобождает место под новое.\n\n**Когда нужен.** Клиент сменил телефон или компьютер, и лимит устройств занят.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "hwid": {
                          "type": "string",
                          "description": "Какое устройство отвязано."
                        },
                        "deleted": {
                          "type": "boolean",
                          "description": "`true` — устройство отвязано."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "hwid": "abcdef123456",
                    "deleted": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "сбросить устройство",
          "отвязать",
          "освободить место",
          "удалить устройство",
          "hwid reset"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "description": "UUID подписки.",
                    "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  },
                  "hwid": {
                    "type": "string",
                    "description": "HWID устройства из списка устройств.",
                    "example": "abcdef123456"
                  }
                },
                "required": [
                  "uuid",
                  "hwid"
                ]
              },
              "example": {
                "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "hwid": "abcdef123456"
              }
            }
          }
        }
      }
    },
    "/vpn/hwid/reset-all": {
      "post": {
        "operationId": "vpn_hwid_reset_all",
        "summary": "Сбросить все устройства",
        "description": "Отвязывает от подписки все устройства сразу.\n\n**Когда нужен.** Когда проще начать с чистого листа: клиент сменил устройства и не помнит, какие из старых ещё заняты.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted_all": {
                          "type": "boolean",
                          "description": "`true` — все устройства отвязаны."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "deleted_all": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "сбросить все",
          "отвязать все",
          "очистить устройства",
          "reset all"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "description": "UUID подписки.",
                    "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  }
                },
                "required": [
                  "uuid"
                ]
              },
              "example": {
                "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
              }
            }
          }
        }
      }
    },
    "/vpn/hwid/quote": {
      "get": {
        "operationId": "vpn_hwid_quote",
        "summary": "Цены на увеличение лимита",
        "description": "Возвращает, на сколько устройств можно увеличить лимит и сколько это стоит.\n\n**Когда нужен.** Чтобы показать клиенту варианты перед увеличением лимита.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "1": {
                          "type": "number",
                          "description": "Ключ — на сколько устройств увеличить лимит, значение — цена, ₽."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "1": 200,
                    "2": 350,
                    "3": 500,
                    "5": 750,
                    "10": 1300
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "лимит устройств",
          "цена устройств",
          "больше устройств",
          "hwid quote"
        ],
        "x-effect": "read"
      }
    },
    "/vpn/hwid/increase": {
      "post": {
        "operationId": "vpn_hwid_increase",
        "summary": "Увеличить лимит устройств",
        "description": "Увеличивает лимит устройств подписки и списывает цену с баланса.\n\n**Когда нужен.** Клиенту нужно подключить больше устройств, чем позволяет лимит.\n\n**Важно.** Оплата разовая: лимит увеличивается навсегда и сохраняется при продлениях.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current_limit": {
                          "type": "integer",
                          "description": "Лимит до увеличения."
                        },
                        "delta": {
                          "type": "integer",
                          "description": "На сколько увеличен."
                        },
                        "target_limit": {
                          "type": "integer",
                          "description": "Новый лимит."
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "current_limit": 5,
                    "delta": 2,
                    "target_limit": 7,
                    "price_rub": 350
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "увеличить лимит",
          "больше устройств",
          "добавить устройства",
          "hwid increase"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "description": "UUID подписки.",
                    "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  },
                  "delta": {
                    "type": "integer",
                    "enum": [
                      1,
                      2,
                      3,
                      5,
                      10
                    ],
                    "description": "На сколько увеличить лимит. Только значения из `/vpn/hwid/quote`.",
                    "example": 2
                  }
                },
                "required": [
                  "uuid",
                  "delta"
                ]
              },
              "example": {
                "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "delta": 2
              }
            }
          }
        }
      }
    },
    "/vpn/delete": {
      "post": {
        "operationId": "vpn_delete",
        "summary": "Удалить подписку",
        "description": "Удаляет подписку. Клиент теряет доступ, вернуть подписку нельзя.\n\n**Когда нужен.** Только если подписка больше не нужна совсем. Чтобы отвязать устройства, удалять её не нужно — для этого есть сброс устройств.\n\n**Стоимость вызова:** необратимо.",
        "tags": [
          "VPN"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "`true` — подписка удалена."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "удалить",
          "удаление",
          "удалить подписку",
          "delete"
        ],
        "x-effect": "destructive",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "description": "UUID подписки.",
                    "example": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                  }
                },
                "required": [
                  "uuid"
                ]
              },
              "example": {
                "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
              }
            }
          }
        }
      }
    },
    "/dedicated/quote": {
      "get": {
        "operationId": "dedicated_quote",
        "summary": "Посчитать стоимость",
        "description": "Считает цену покупки: за всё количество и за одну прокси.\n\n**Когда нужен.** Перед покупкой — показать цену и проверить, хватит ли баланса.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [
          {
            "name": "ipv",
            "in": "query",
            "required": true,
            "description": "Тип адреса. Значения: `3` — IPv4 Shared, `4` — IPv4 Private, `6` — IPv6.",
            "schema": {
              "type": "integer",
              "enum": [
                3,
                4,
                6
              ],
              "example": 4
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "description": "Срок в днях. Единица: дн. Допустимые значения зависят от `ipv`: при `ipv = 3` → `7`, `14`, `30`, `60`, `90`; при `ipv = 4` → `7`, `14`, `30`, `60`, `90`; при `ipv = 6` → `3`, `7`, `14`, `30`, `60`, `90`.",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                14,
                30,
                60,
                90,
                3
              ],
              "example": 30
            }
          },
          {
            "name": "count",
            "in": "query",
            "required": true,
            "description": "Количество прокси.",
            "schema": {
              "type": "integer",
              "example": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "price": {
                          "type": "number",
                          "description": "Цена за всё количество, ₽."
                        },
                        "price_single": {
                          "type": "number",
                          "description": "Цена за одну прокси, ₽."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "period": 30,
                    "count": 10,
                    "ipv": 4,
                    "price": 1800,
                    "price_single": 180
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "цена",
          "стоимость",
          "сколько стоит",
          "расчёт",
          "прокси",
          "quote"
        ],
        "x-effect": "read"
      }
    },
    "/dedicated/country": {
      "get": {
        "operationId": "dedicated_country",
        "summary": "Список стран",
        "description": "Возвращает страны, в которых можно купить прокси выбранного типа.\n\n**Когда нужен.** Чтобы показать клиенту выбор страны и взять `country_code` для покупки.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [
          {
            "name": "ipv",
            "in": "query",
            "required": true,
            "description": "Тип адреса. Значения: `3` — IPv4 Shared, `4` — IPv4 Private, `6` — IPv6.",
            "schema": {
              "type": "integer",
              "enum": [
                3,
                4,
                6
              ],
              "example": 4
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "description": "Доступные страны.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "country_code": {
                                "type": "string",
                                "description": "Код страны — передаётся в покупку и в `/dedicated/count`."
                              },
                              "title": {
                                "type": "string",
                                "description": "Название с флагом — можно показать клиенту как есть."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "ipv": 4,
                    "countries": [
                      {
                        "country_code": "ua",
                        "title": "🇺🇦 Украина"
                      },
                      {
                        "country_code": "us",
                        "title": "🇺🇸 США"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "страны",
          "страна",
          "локации",
          "country",
          "где купить"
        ],
        "x-effect": "read"
      }
    },
    "/dedicated/count": {
      "get": {
        "operationId": "dedicated_count",
        "summary": "Сколько прокси доступно",
        "description": "Показывает, сколько прокси выбранного типа есть в стране прямо сейчас.\n\n**Когда нужен.** Перед крупной покупкой — убедиться, что нужное количество есть в наличии.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [
          {
            "name": "country_code",
            "in": "query",
            "required": true,
            "description": "Код страны из `/dedicated/country`.",
            "schema": {
              "type": "string",
              "example": "ru"
            }
          },
          {
            "name": "ipv",
            "in": "query",
            "required": true,
            "description": "Тип адреса. Значения: `3` — IPv4 Shared, `4` — IPv4 Private, `6` — IPv6.",
            "schema": {
              "type": "integer",
              "enum": [
                3,
                4,
                6
              ],
              "example": 4
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer",
                          "description": "Сколько прокси доступно."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "country_code": "ru",
                    "ipv": 4,
                    "count": 1233
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "наличие",
          "сколько доступно",
          "количество",
          "остаток прокси",
          "count"
        ],
        "x-effect": "read"
      }
    },
    "/dedicated/buy": {
      "post": {
        "operationId": "dedicated_buy",
        "summary": "Купить прокси",
        "description": "Покупает прокси и списывает их цену с баланса. В ответе — готовые данные для подключения.\n\n**Когда нужен.** Когда клиент оплатил прокси у тебя.\n\n**Важно.** `port_type: auto` — прокси понимают HTTP(S) и SOCKS5 одновременно. Переключать ничего не нужно: протокол выбирается на стороне клиента.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "check_id": {
                          "type": "string",
                          "description": "Номер покупки."
                        },
                        "order_id": {
                          "type": "integer",
                          "description": "Номер заказа."
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "port_type": {
                          "type": "string",
                          "description": "`auto` — HTTP(S) и SOCKS5 одновременно."
                        },
                        "proxies": {
                          "type": "array",
                          "description": "Купленные прокси.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ids": {
                                "type": "integer",
                                "description": "ID прокси — нужен для продления."
                              },
                              "ip": {
                                "type": "string",
                                "description": "IP-адрес."
                              },
                              "port": {
                                "type": "string",
                                "description": "Порт."
                              },
                              "username": {
                                "type": "string",
                                "description": "Логин."
                              },
                              "password": {
                                "type": "string",
                                "description": "Пароль."
                              },
                              "date_end": {
                                "type": "string",
                                "description": "Дата окончания, формат ГГГГ-ММ-ДД чч:мм:сс."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "check_id": "b_8300069",
                    "order_id": 13765429,
                    "price_rub": 180,
                    "port_type": "auto",
                    "proxies": [
                      {
                        "ids": 36400089,
                        "ip": "203.0.113.24",
                        "port": "10900",
                        "username": "username",
                        "password": "password",
                        "date_end": "2026-01-16 05:42:18"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "купить",
          "покупка",
          "купить прокси",
          "серверные",
          "buy"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "country_code": {
                    "type": "string",
                    "description": "Код страны из `/dedicated/country`.",
                    "example": "ru"
                  },
                  "ipv": {
                    "type": "integer",
                    "enum": [
                      3,
                      4,
                      6
                    ],
                    "description": "Тип адреса.",
                    "example": 4
                  },
                  "period": {
                    "type": "integer",
                    "enum": [
                      7,
                      14,
                      30,
                      60,
                      90,
                      3
                    ],
                    "description": "Срок в днях.",
                    "example": 30
                  },
                  "count": {
                    "type": "integer",
                    "description": "Количество прокси.",
                    "example": 1
                  }
                },
                "required": [
                  "country_code",
                  "ipv",
                  "period",
                  "count"
                ]
              },
              "example": {
                "country_code": "ru",
                "ipv": 4,
                "period": 30,
                "count": 1
              }
            }
          }
        }
      }
    },
    "/dedicated/prolong/quote": {
      "get": {
        "operationId": "dedicated_prolong_quote",
        "summary": "Стоимость продления",
        "description": "Считает цену продления для списка прокси: общую и по каждой.\n\n**Когда нужен.** Перед продлением — показать цену клиенту.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "required": true,
            "description": "ID прокси из ответа на покупку, через запятую.",
            "schema": {
              "type": "array",
              "items": {
                "type": "integer"
              },
              "example": [
                36400089,
                36400090
              ]
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "description": "Срок продления в днях. Единица: дн.",
            "schema": {
              "type": "integer",
              "enum": [
                3,
                7,
                14,
                30,
                60,
                90
              ],
              "example": 3
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "total_price_rub": {
                          "type": "number",
                          "description": "Цена продления всех прокси, ₽."
                        },
                        "items": {
                          "type": "array",
                          "description": "Цена по каждой прокси.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ids": {
                                "type": "integer",
                                "description": "ID прокси."
                              },
                              "ipv": {
                                "type": "integer",
                                "description": "Тип адреса."
                              },
                              "price_rub": {
                                "type": "number",
                                "description": "Цена продления этой прокси, ₽."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "period": 3,
                    "total_price_rub": 8.9,
                    "items": [
                      {
                        "ids": 36400089,
                        "ipv": 6,
                        "price_rub": 4.45
                      },
                      {
                        "ids": 36400090,
                        "ipv": 6,
                        "price_rub": 4.45
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "продление цена",
          "сколько стоит продлить",
          "стоимость продления",
          "prolong quote"
        ],
        "x-effect": "read"
      }
    },
    "/dedicated/prolong": {
      "post": {
        "operationId": "dedicated_prolong",
        "summary": "Продлить прокси",
        "description": "Продлевает прокси на выбранный срок и списывает цену с баланса.\n\n**Когда нужен.** Когда клиент оплатил продление.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "Серверные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "total_price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ids": {
                                "type": "integer",
                                "description": "ID прокси."
                              },
                              "date_end": {
                                "type": "string",
                                "description": "Новая дата окончания."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "period": 3,
                    "total_price_rub": 8.9,
                    "items": [
                      {
                        "ids": 36400089,
                        "date_end": "2026-01-19 05:42:18"
                      },
                      {
                        "ids": 36400090,
                        "date_end": "2026-01-19 05:42:18"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "продлить",
          "продление",
          "продлить прокси",
          "prolong"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Список ID прокси из ответа на покупку. В поле ниже — через запятую.",
                    "example": [
                      36400089,
                      36400090
                    ]
                  },
                  "period": {
                    "type": "integer",
                    "enum": [
                      3,
                      7,
                      14,
                      30,
                      60,
                      90
                    ],
                    "description": "Срок продления в днях.",
                    "example": 3
                  }
                },
                "required": [
                  "ids",
                  "period"
                ]
              },
              "example": {
                "ids": [
                  36400089,
                  36400090
                ],
                "period": 3
              }
            }
          }
        }
      }
    },
    "/residential/traffic/quote": {
      "get": {
        "operationId": "residential_traffic_quote",
        "summary": "Посчитать стоимость трафика",
        "description": "Считает цену трафика с учётом скидки.\n\n**Когда нужен.** Перед покупкой или пополнением — показать цену клиенту.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [
          {
            "name": "pool_type",
            "in": "query",
            "required": true,
            "description": "Тип пула. Значения: `residential` — Резидентные, `datacenter` — Датацентр, `mobile` — Мобильные, `residential_premium` — Премиум.",
            "schema": {
              "type": "string",
              "enum": [
                "residential",
                "datacenter",
                "mobile",
                "residential_premium"
              ],
              "example": "residential"
            }
          },
          {
            "name": "gb",
            "in": "query",
            "required": true,
            "description": "Объём, ГБ.",
            "schema": {
              "type": "integer",
              "example": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "price_per_gb_rub": {
                          "type": "number",
                          "description": "Цена за 1 ГБ, ₽."
                        },
                        "subtotal_rub": {
                          "type": "number",
                          "description": "Цена без скидки, ₽."
                        },
                        "discount_percent": {
                          "type": "integer",
                          "description": "Скидка, %."
                        },
                        "discount_rub": {
                          "type": "number",
                          "description": "Скидка, ₽."
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Итоговая цена, ₽."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "pool_type": "residential",
                    "gb": 100,
                    "price_per_gb_rub": 99,
                    "subtotal_rub": 9900,
                    "discount_percent": 5,
                    "discount_rub": 495,
                    "price_rub": 9405
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "цена трафика",
          "стоимость",
          "гигабайты",
          "гб",
          "скидка",
          "traffic quote"
        ],
        "x-effect": "read"
      }
    },
    "/residential/traffic/buy": {
      "post": {
        "operationId": "residential_traffic_buy",
        "summary": "Купить трафик",
        "description": "Создаёт подписку клиента на пул и начисляет трафик. В ответе — `subuser_id`, логин и пароль.\n\n**Когда нужен.** Первая покупка клиента в этом пуле. Дальше пополняй через `/residential/traffic/add`.\n\n**Внимание.** Для пары `telegram_id` + `pool_type` подписка создаётся один раз. Повторная покупка вернёт `409 already_exists` — для пополнения есть `/residential/traffic/add`.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "subuser": {
                          "type": "object",
                          "properties": {
                            "subuser_id": {
                              "type": "integer",
                              "description": "Идентификатор клиента. **Сохрани его** — дальше все методы работают только с ним."
                            },
                            "login": {
                              "type": "string",
                              "description": "Логин для прокси."
                            },
                            "password": {
                              "type": "string",
                              "description": "Пароль для прокси."
                            }
                          }
                        },
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "traffic_added_gb": {
                          "type": "integer",
                          "description": "Сколько трафика начислено, ГБ."
                        },
                        "traffic_balance_gb": {
                          "type": "number",
                          "description": "Остаток трафика после покупки, ГБ."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential",
                      "login": "user_login",
                      "password": "user_password"
                    },
                    "price_rub": 9405,
                    "price_per_gb_rub": 99,
                    "subtotal_rub": 9900,
                    "discount_percent": 5,
                    "discount_rub": 495,
                    "traffic_added_gb": 100,
                    "traffic_balance_gb": 100
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "409": {
            "description": "`already_exists` — Уже существует",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "already_exists",
                    "message": "Уже существует",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "купить трафик",
          "покупка",
          "резидентные",
          "subuser",
          "telegram_id",
          "buy"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pool_type": {
                    "type": "string",
                    "enum": [
                      "residential",
                      "datacenter",
                      "mobile",
                      "residential_premium"
                    ],
                    "description": "Тип пула.",
                    "example": "residential"
                  },
                  "gb": {
                    "type": "integer",
                    "description": "Объём, ГБ.",
                    "example": 100
                  },
                  "telegram_id": {
                    "type": "integer",
                    "description": "Telegram ID конечного клиента.",
                    "example": 123456789
                  }
                },
                "required": [
                  "pool_type",
                  "gb",
                  "telegram_id"
                ]
              },
              "example": {
                "pool_type": "residential",
                "gb": 100,
                "telegram_id": 123456789
              }
            }
          }
        }
      }
    },
    "/residential/traffic/add": {
      "post": {
        "operationId": "residential_traffic_add",
        "summary": "Пополнить трафик",
        "description": "Начисляет клиенту дополнительный трафик и списывает цену с баланса.\n\n**Когда нужен.** Трафик заканчивается или клиент докупает объём.\n\n**Стоимость вызова:** спишет деньги с баланса.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "price_rub": {
                          "type": "number",
                          "description": "Списано с баланса, ₽."
                        },
                        "traffic_added_gb": {
                          "type": "integer",
                          "description": "Сколько трафика начислено, ГБ."
                        },
                        "traffic_balance_gb": {
                          "type": "number",
                          "description": "Остаток трафика после пополнения, ГБ."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "price_rub": 9405,
                    "price_per_gb_rub": 99,
                    "subtotal_rub": 9900,
                    "discount_percent": 5,
                    "discount_rub": 495,
                    "traffic_added_gb": 100,
                    "traffic_balance_gb": 200
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "пополнить",
          "докупить",
          "добавить трафик",
          "увеличить трафик",
          "traffic add"
        ],
        "x-effect": "paid",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  },
                  "gb": {
                    "type": "integer",
                    "description": "Объём, ГБ.",
                    "example": 100
                  }
                },
                "required": [
                  "subuser_id",
                  "gb"
                ]
              },
              "example": {
                "subuser_id": 12345,
                "gb": 100
              }
            }
          }
        }
      }
    },
    "/residential/traffic/balance": {
      "get": {
        "operationId": "residential_traffic_balance",
        "summary": "Остаток трафика",
        "description": "Показывает, сколько трафика осталось у клиента.\n\n**Когда нужен.** Чтобы вовремя предложить клиенту пополнение.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [
          {
            "name": "subuser_id",
            "in": "query",
            "required": true,
            "description": "Идентификатор клиента.",
            "schema": {
              "type": "integer",
              "example": 12345
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "subuser": {
                          "type": "object",
                          "description": "Клиент: `subuser_id`, `telegram_id`, `pool_type`."
                        },
                        "traffic_gb": {
                          "type": "number",
                          "description": "Остаток трафика, ГБ."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "traffic_gb": 8.5
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "остаток",
          "баланс трафика",
          "сколько осталось",
          "гб",
          "traffic balance"
        ],
        "x-effect": "read"
      }
    },
    "/residential/locations/{level}": {
      "post": {
        "operationId": "residential_locations",
        "summary": "Локации",
        "description": "Возвращает доступные страны, регионы, города, почтовые индексы или провайдеров (ASN) — для фильтров прокси-листа.\n\n**Когда нужен.** Чтобы клиент выбрал, откуда нужны адреса, перед генерацией прокси-листа.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [
          {
            "name": "level",
            "in": "path",
            "required": true,
            "description": "Что получить Значения: `countries` — Страны, `states` — Регионы, `cities` — Города, `zipcodes` — Индексы, `asns` — ASN.",
            "schema": {
              "type": "string",
              "enum": [
                "countries",
                "states",
                "cities",
                "zipcodes",
                "asns"
              ],
              "example": "cities"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "description": "Какие страны применены как фильтр."
                        },
                        "states": {
                          "type": "array",
                          "description": "Какие регионы применены как фильтр."
                        },
                        "items": {
                          "type": "array",
                          "description": "Найденные локации. Формат один для всех уровней.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string",
                                "description": "Код — его передают в генерацию прокси-листа."
                              },
                              "name": {
                                "type": "string",
                                "description": "Название для показа клиенту."
                              },
                              "count": {
                                "type": "integer",
                                "description": "Количество доступных адресов в локации."
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "pool_type": "residential",
                    "countries": [
                      "us"
                    ],
                    "states": [
                      "california"
                    ],
                    "items": [
                      {
                        "code": "alameda",
                        "name": "Alameda",
                        "count": 16
                      },
                      {
                        "code": "alhambra",
                        "name": "Alhambra",
                        "count": 9
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "локации",
          "страны",
          "регионы",
          "штаты",
          "города",
          "индексы",
          "zip",
          "asn",
          "провайдеры",
          "locations",
          "countries",
          "states",
          "cities",
          "zipcodes",
          "asns"
        ],
        "x-effect": "read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pool_type": {
                    "type": "string",
                    "enum": [
                      "residential",
                      "datacenter",
                      "mobile",
                      "residential_premium"
                    ],
                    "description": "Тип пула.",
                    "example": "residential"
                  },
                  "countries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Список стран. В поле ниже — через запятую.",
                    "example": [
                      "US"
                    ]
                  },
                  "states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по штатам и регионам — список. В поле ниже — через запятую.",
                    "example": [
                      "California"
                    ]
                  },
                  "cities": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по городам — список. В поле ниже — через запятую."
                  }
                },
                "required": [
                  "pool_type",
                  "countries"
                ]
              },
              "example": {
                "pool_type": "residential",
                "countries": [
                  "US"
                ]
              }
            }
          }
        }
      }
    },
    "/residential/proxies/generate": {
      "post": {
        "operationId": "residential_proxies_generate",
        "summary": "Сгенерировать прокси-лист",
        "description": "Собирает прокси-лист клиента: адреса через домен и через IP в выбранном формате.\n\n**Когда нужен.** Когда клиенту нужны строки для подключения. Генерация бесплатна — трафик расходуется, когда клиент работает через прокси.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "params": {
                          "type": "object",
                          "description": "С какими параметрами собран лист — значения строками."
                        },
                        "domain": {
                          "type": "string",
                          "description": "Прокси-лист с адресом через домен. Строки разделены пустой строкой."
                        },
                        "ip": {
                          "type": "string",
                          "description": "Тот же лист с адресом через IP."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "params": {
                      "countries": "ru",
                      "cities": "",
                      "states": "",
                      "zipcodes": "",
                      "asns": "",
                      "anonymous": "0",
                      "type": "sticky",
                      "protocol": "http",
                      "format": "hostname:port:login:password",
                      "quantity": "2",
                      "session_ttl": "10"
                    },
                    "domain": "gw.tunnelgate.org:10000:login:password\n\ngw.tunnelgate.org:10001:login:password",
                    "ip": "74.81.81.81:10000:login:password\n\n74.81.81.81:10001:login:password"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "сгенерировать",
          "генерация",
          "прокси-лист",
          "список прокси",
          "строки",
          "generate",
          "sticky",
          "rotating"
        ],
        "x-effect": "read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  },
                  "countries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Список стран. В поле ниже — через запятую.",
                    "example": [
                      "ru"
                    ]
                  },
                  "protocol": {
                    "type": "string",
                    "enum": [
                      "http",
                      "socks5"
                    ],
                    "description": "Протокол. По умолчанию `http`."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "sticky",
                      "rotating"
                    ],
                    "description": "`sticky` — IP держится `session_ttl` минут, `rotating` — новый IP на каждый запрос."
                  },
                  "session_ttl": {
                    "type": "integer",
                    "description": "Время жизни сессии в минутах. Только для `type = sticky`."
                  },
                  "anonymous": {
                    "type": "boolean",
                    "enum": [
                      true,
                      false
                    ],
                    "description": "Анонимность."
                  },
                  "quantity": {
                    "type": "integer",
                    "description": "Сколько строк сгенерировать. По умолчанию `1`.",
                    "example": 2
                  },
                  "format_id": {
                    "type": "integer",
                    "enum": [
                      1,
                      2,
                      3
                    ],
                    "description": "Формат строк: `1` — `hostname:port:login:password`, `2` — `login:password@hostname:port`, `3` — `hostname:port`."
                  },
                  "states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по штатам и регионам."
                  },
                  "cities": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по городам."
                  },
                  "zipcodes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по почтовым индексам."
                  },
                  "asns": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Фильтр по провайдерам (ASN)."
                  }
                },
                "required": [
                  "subuser_id",
                  "countries"
                ]
              },
              "example": {
                "subuser_id": 12345,
                "countries": [
                  "ru"
                ]
              }
            }
          }
        }
      }
    },
    "/residential/proxies/rotate-ip": {
      "post": {
        "operationId": "residential_proxies_rotate_ip",
        "summary": "Сменить IP",
        "description": "Меняет IP у sticky-сессий клиента.\n\n**Когда нужен.** IP в sticky-сессии перестал подходить и нужен новый, не дожидаясь `session_ttl`.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "rotated": {
                          "type": "boolean",
                          "description": "`true` — IP сменён."
                        },
                        "result": {
                          "type": "object",
                          "description": "Ответ поставщика: логин, статус, сообщение, время выполнения."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "rotated": true,
                    "result": {
                      "login": "examplelogin",
                      "status": "ok",
                      "message": "ok",
                      "elapsed": "00:00:00.0018686"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "сменить ip",
          "ротация",
          "новый ip",
          "поменять адрес",
          "rotate"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  }
                },
                "required": [
                  "subuser_id"
                ]
              },
              "example": {
                "subuser_id": 12345
              }
            }
          }
        }
      }
    },
    "/residential/whitelist": {
      "get": {
        "operationId": "residential_whitelist",
        "summary": "Разрешённые IP",
        "description": "Показывает IP-адреса, с которых клиент подключается к прокси без логина и пароля.\n\n**Когда нужен.** Чтобы проверить, какие адреса уже добавлены.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [
          {
            "name": "subuser_id",
            "in": "query",
            "required": true,
            "description": "Идентификатор клиента.",
            "schema": {
              "type": "integer",
              "example": 12345
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "allowed_ips": {
                          "type": "array",
                          "description": "Разрешённые IP-адреса."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "allowed_ips": [
                      "1.2.3.4",
                      "5.6.7.8"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "whitelist",
          "белый список ip",
          "разрешённые ip",
          "доступ по ip"
        ],
        "x-effect": "read"
      }
    },
    "/residential/whitelist/add": {
      "post": {
        "operationId": "residential_whitelist_add",
        "summary": "Добавить IP",
        "description": "Разрешает подключаться к прокси с этого IP без логина и пароля.\n\n**Когда нужен.** Клиенту удобнее доступ по IP — например, для формата строк `hostname:port`.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ip": {
                          "type": "string",
                          "description": "Добавленный IP."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "ip": "1.2.3.4"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "добавить ip",
          "разрешить ip",
          "whitelist add"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  },
                  "ip": {
                    "type": "string",
                    "description": "IP-адрес.",
                    "example": "1.2.3.4"
                  }
                },
                "required": [
                  "subuser_id",
                  "ip"
                ]
              },
              "example": {
                "subuser_id": 12345,
                "ip": "1.2.3.4"
              }
            }
          }
        }
      }
    },
    "/residential/whitelist/remove": {
      "post": {
        "operationId": "residential_whitelist_remove",
        "summary": "Убрать IP",
        "description": "Запрещает подключение без пароля с этого IP.\n\n**Когда нужен.** Клиент сменил адрес или доступ по IP больше не нужен.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ip": {
                          "type": "string",
                          "description": "Убранный IP."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "ip": "1.2.3.4"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — Неверный запрос",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_request",
                    "message": "Неверный запрос",
                    "details": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "убрать ip",
          "удалить ip",
          "whitelist remove"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  },
                  "ip": {
                    "type": "string",
                    "description": "IP-адрес.",
                    "example": "1.2.3.4"
                  }
                },
                "required": [
                  "subuser_id",
                  "ip"
                ]
              },
              "example": {
                "subuser_id": 12345,
                "ip": "1.2.3.4"
              }
            }
          }
        }
      }
    },
    "/residential/password": {
      "get": {
        "operationId": "residential_password",
        "summary": "Текущий пароль",
        "description": "Возвращает логин и текущий пароль клиента для прокси.\n\n**Когда нужен.** Клиент потерял данные для подключения.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [
          {
            "name": "subuser_id",
            "in": "query",
            "required": true,
            "description": "Идентификатор клиента.",
            "schema": {
              "type": "integer",
              "example": 12345
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "login": {
                          "type": "string",
                          "description": "Логин."
                        },
                        "password": {
                          "type": "string",
                          "description": "Текущий пароль."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "login": "login",
                    "password": "current_password"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "пароль",
          "логин",
          "данные доступа",
          "password"
        ],
        "x-effect": "read"
      }
    },
    "/residential/password/reset": {
      "post": {
        "operationId": "residential_password_reset",
        "summary": "Сбросить пароль",
        "description": "Выдаёт клиенту новый пароль для прокси.\n\n**Когда нужен.** Пароль мог утечь. После сброса обнови пароль у клиента.\n\n**Стоимость вызова:** меняет состояние, денег не спишет.",
        "tags": [
          "Резидентные прокси"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "login": {
                          "type": "string",
                          "description": "Логин."
                        },
                        "password": {
                          "type": "string",
                          "description": "Новый пароль."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "subuser": {
                      "subuser_id": 12345,
                      "telegram_id": 123456789,
                      "pool_type": "residential"
                    },
                    "login": "login",
                    "password": "new_password"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found` — Не найдено",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "not_found",
                    "message": "Не найдено",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "сбросить пароль",
          "новый пароль",
          "сменить пароль",
          "password reset"
        ],
        "x-effect": "change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subuser_id": {
                    "type": "integer",
                    "description": "Идентификатор клиента.",
                    "example": 12345
                  }
                },
                "required": [
                  "subuser_id"
                ]
              },
              "example": {
                "subuser_id": 12345
              }
            }
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "account_balance",
        "summary": "Баланс",
        "description": "Показывает, сколько денег на балансе и сколько всего потрачено через API.\n\n**Когда нужен.** Перед покупкой — убедиться, что денег хватит. После сетевого сбоя — проверить, прошло ли списание.\n\n**Стоимость вызова:** бесплатно, ничего не меняет.",
        "tags": [
          "Аккаунт"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Успех. Поле `ok` равно `true`. Полезные поля лежат внутри `data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "balance_rub": {
                          "type": "number",
                          "description": "Баланс, ₽."
                        },
                        "api_spent_rub": {
                          "type": "number",
                          "description": "Сколько всего потрачено через API, ₽."
                        }
                      }
                    }
                  },
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true,
                  "data": {
                    "balance_rub": 1234.56,
                    "api_spent_rub": 1234.56
                  }
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token` — Токен не принят",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_token",
                    "message": "Токен не принят",
                    "details": null
                  }
                }
              }
            }
          }
        },
        "x-keywords": [
          "баланс",
          "деньги",
          "счёт",
          "остаток",
          "расход",
          "потрачено",
          "balance"
        ],
        "x-effect": "read"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Токен из бота: Профиль → API."
      }
    },
    "schemas": {
      "Ok": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "data": {
            "type": "object"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Код ошибки — на нём строй логику.",
                "enum": [
                  "invalid_token",
                  "invalid_request",
                  "not_found",
                  "already_exists",
                  "insufficient_funds",
                  "plan_unavailable",
                  "provider_error",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Текст для показа человеку."
              },
              "details": {
                "description": "Подробности или null: поле в ответе есть всегда."
              }
            }
          }
        }
      }
    }
  }
}
