{
  "info": {
    "name": "GIGABIT Partner API · RU",
    "description": "API доступен после активации партнёрского аккаунта. Создание и отзыв токена доступны только в кабинете GIGABIT. Новый токен заменяет предыдущий и отображается один раз.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{partner_token}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.gigabit.ltd/api/partner/v1"
    },
    {
      "key": "partner_token",
      "value": ""
    },
    {
      "key": "order_id",
      "value": "a1b2c3d4e5f60123456789abcdef0123"
    },
    {
      "key": "operation_id",
      "value": "REPLACE_WITH_RESPONSE_ID"
    },
    {
      "key": "topup_id",
      "value": "ptop_REPLACE_WITH_RESPONSE_ID"
    }
  ],
  "item": [
    {
      "name": "Операции",
      "item": [
        {
          "name": "Статус операции · В очереди",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/operations/{{operation_id}}",
            "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
          },
          "response": [
            {
              "name": "В очереди",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/operations/{{operation_id}}",
                "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Статус операции · Выполнено",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/operations/{{operation_id}}",
            "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
          },
          "response": [
            {
              "name": "Выполнено",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/operations/{{operation_id}}",
                "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"ready\",\n    \"error\": null,\n    \"result\": {\n      \"id\": \"partner_0123456789abcdef0123456789abcdef\",\n      \"state\": \"ready\",\n      \"error\": null,\n      \"order_ids\": [\n        \"a1b2c3d4e5f60123456789abcdef0123\"\n      ],\n      \"amount_cents\": 4050,\n      \"currency\": \"EUR\",\n      \"price\": {\n        \"currency\": \"EUR\",\n        \"base_net_cents\": 4500,\n        \"net_cents\": 4050,\n        \"vat_cents\": 0,\n        \"total_cents\": 4050,\n        \"tax_at_topup\": true,\n        \"discount_percent\": 10,\n        \"months\": 1,\n        \"days\": 30,\n        \"pricing_version\": 1,\n        \"tax\": {\n          \"mode\": \"vat\",\n          \"rate_percent\": 23,\n          \"vat_code\": \"23\",\n          \"reverse_charge\": false\n        }\n      }\n    },\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Статус операции · Ошибка",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/operations/{{operation_id}}",
            "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
          },
          "response": [
            {
              "name": "Ошибка",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/operations/{{operation_id}}",
                "description": "Возвращает состояние и результат операции аккаунта. Быстрая проверка, без повторного выполнения.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"failed\",\n    \"error\": \"insufficient_partner_balance\",\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Баланс и расчёты",
      "item": [
        {
          "name": "Баланс · Баланс",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/balance",
            "description": "Текущий баланс, кредитный лимит, доступные средства, скидка и цены партнёра.\n\n"
          },
          "response": [
            {
              "name": "Баланс",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/balance",
                "description": "Текущий баланс, кредитный лимит, доступные средства, скидка и цены партнёра.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"currency\": \"EUR\",\n    \"balance_cents\": 10000,\n    \"reserved_cents\": 0,\n    \"credit_limit_cents\": 10000,\n    \"debt_cents\": 0,\n    \"available_cents\": 20000,\n    \"withdrawable_cents\": 10000,\n    \"discount_percent\": 10,\n    \"prefix\": \"astra\",\n    \"api_token_hint\": \"demo12\",\n    \"monthly_net_cents\": 4500,\n    \"payment_method\": \"card\",\n    \"connection_domains\": {\n      \"host\": \"\",\n      \"api\": \"\"\n    },\n    \"paid_in_cents\": 10000,\n    \"prices\": [\n      {\n        \"currency\": \"EUR\",\n        \"base_net_cents\": 4500,\n        \"net_cents\": 4050,\n        \"vat_cents\": 0,\n        \"total_cents\": 4050,\n        \"tax_at_topup\": true,\n        \"discount_percent\": 10,\n        \"months\": 1,\n        \"days\": 30,\n        \"pricing_version\": 1,\n        \"tax\": {\n          \"mode\": \"vat\",\n          \"rate_percent\": 23,\n          \"vat_code\": \"23\",\n          \"reverse_charge\": false\n        }\n      }\n    ],\n    \"topup_tax\": {\n      \"mode\": \"vat\",\n      \"rate_percent\": 23,\n      \"vat_code\": \"23\",\n      \"reverse_charge\": false\n    },\n    \"can_order_new_ports\": true\n  }\n}"
            }
          ]
        },
        {
          "name": "Пополнение баланса · Карта / Stripe",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/topups",
            "description": "Создаёт ссылку на оплату через Stripe. amount_cents - сумма зачисления на баланс в евроцентах; total_cents - сумма оплаты с учётом применимого VAT.\n\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount_cents\": 10000\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Карта / Stripe",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/topups",
                "description": "Создаёт ссылку на оплату через Stripe. amount_cents - сумма зачисления на баланс в евроцентах; total_cents - сумма оплаты с учётом применимого VAT.\n\n",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"amount_cents\": 10000\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Статус пополнения · Stripe",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/topups/{{topup_id}}",
            "description": "Возвращает статус пополнения аккаунта. paid подтверждает зачисление средств. Возврат со страницы Stripe сам по себе не подтверждает оплату.\n\nСостояния: creating, pending, paid, expired, failed."
          },
          "response": [
            {
              "name": "Stripe",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/topups/{{topup_id}}",
                "description": "Возвращает статус пополнения аккаунта. paid подтверждает зачисление средств. Возврат со страницы Stripe сам по себе не подтверждает оплату.\n\nСостояния: creating, pending, paid, expired, failed."
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"ptop_0123456789abcdef0123456789abcdef\",\n    \"state\": \"pending\",\n    \"url\": \"https://checkout.stripe.com/c/pay/EXAMPLE_SESSION\",\n    \"amount_cents\": 10000,\n    \"vat_cents\": 2300,\n    \"total_cents\": 12300,\n    \"currency\": \"EUR\"\n  }\n}"
            }
          ]
        },
        {
          "name": "История транзакций · Первая страница",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/transactions?offset=0&limit=30",
            "description": "Операции от новых к старым, источники и комментарии, суммы и остаток после каждой операции. Технические резервы покупки скрыты по умолчанию.\n\n"
          },
          "response": [
            {
              "name": "Первая страница",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/transactions?offset=0&limit=30",
                "description": "Операции от новых к старым, источники и комментарии, суммы и остаток после каждой операции. Технические резервы покупки скрыты по умолчанию.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"ptop_0123456789abcdef0123456789abcdef:credit\",\n        \"created_at\": \"2026-11-09T12:05:00+00:00\",\n        \"currency\": \"EUR\",\n        \"operation\": \"topup\",\n        \"amount_cents\": 10000,\n        \"reserved_delta_cents\": 0,\n        \"source\": \"stripe\",\n        \"comment\": \"\",\n        \"reference\": \"ptop_0123456789abcdef0123456789abcdef\",\n        \"balance_after_cents\": 10000,\n        \"reserved_after_cents\": 0,\n        \"sequence\": 1\n      }\n    ],\n    \"total\": 1,\n    \"offset\": 0,\n    \"limit\": 30\n  }\n}"
            }
          ]
        },
        {
          "name": "Заявка на вывод средств · Заявка",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/withdrawals",
            "description": "Создаёт заявку и резервирует сумму до её рассмотрения. Доступная для вывода сумма указана в withdrawable_cents; кредитный лимит и невозвратные компенсации в неё не входят.\n\nПосле обработки заявки result.state=requested означает ожидание решения. Операция остаётся processing до подтверждения выплаты или отклонения.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount_cents\": 5000,\n  \"comment\": \"Please contact me to confirm payment details.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Заявка",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/withdrawals",
                "description": "Создаёт заявку и резервирует сумму до её рассмотрения. Доступная для вывода сумма указана в withdrawable_cents; кредитный лимит и невозвратные компенсации в неё не входят.\n\nПосле обработки заявки result.state=requested означает ожидание решения. Операция остаётся processing до подтверждения выплаты или отклонения.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"amount_cents\": 5000,\n  \"comment\": \"Please contact me to confirm payment details.\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Каталог и заказы",
      "item": [
        {
          "name": "Доступные порты · Наличие",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/catalog",
            "description": "Доступные номера портов, сгруппированные по оператору и локации.\n\nНаличие проверяется при оформлении заказа. Просмотр каталога не резервирует порты."
          },
          "response": [
            {
              "name": "Наличие",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/catalog",
                "description": "Доступные номера портов, сгруппированные по оператору и локации.\n\nНаличие проверяется при оформлении заказа. Просмотр каталога не резервирует порты."
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"items\": [\n      {\n        \"operator\": {\n          \"id\": \"operator-orange\",\n          \"name\": \"Orange\"\n        },\n        \"location\": {\n          \"id\": \"location-warsaw\",\n          \"name\": \"Warsaw\"\n        },\n        \"ports\": [\n          {\n            \"id\": \"b1c2d3e4f5a60123456789abcdef0123\",\n            \"number\": 10001\n          },\n          {\n            \"id\": \"b2c3d4e5f6a70123456789abcdef0123\",\n            \"number\": 10002\n          }\n        ],\n        \"available\": 2\n      }\n    ],\n    \"prices\": [\n      {\n        \"currency\": \"EUR\",\n        \"base_net_cents\": 4500,\n        \"net_cents\": 4050,\n        \"vat_cents\": 0,\n        \"total_cents\": 4050,\n        \"tax_at_topup\": true,\n        \"discount_percent\": 10,\n        \"months\": 1,\n        \"days\": 30,\n        \"pricing_version\": 1,\n        \"tax\": {\n          \"mode\": \"vat\",\n          \"rate_percent\": 23,\n          \"vat_code\": \"23\",\n          \"reverse_charge\": false\n        }\n      }\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Заказ порта · По номеру",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders",
            "description": "Заказ одного доступного порта на 30 дней по номеру или ID из каталога. Стоимость списывается с баланса.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"port_number\": 10001\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "По номеру",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders",
                "description": "Заказ одного доступного порта на 30 дней по номеру или ID из каталога. Стоимость списывается с баланса.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"port_number\": 10001\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Заказ порта · По ID",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders",
            "description": "Заказ одного доступного порта на 30 дней по номеру или ID из каталога. Стоимость списывается с баланса.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"port_id\": \"b1c2d3e4f5a60123456789abcdef0123\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "По ID",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders",
                "description": "Заказ одного доступного порта на 30 дней по номеру или ID из каталога. Стоимость списывается с баланса.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"port_id\": \"b1c2d3e4f5a60123456789abcdef0123\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Список портов · Порты",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/orders",
            "description": "Текущие порты аккаунта: срок аренды, данные подключения, IP и таймер смены IP.\n\nДля смены IP выполняется GET-запрос по полной ссылке rotation_url из данных порта. Заголовок Authorization не требуется. Ссылка уже содержит токен порта."
          },
          "response": [
            {
              "name": "Порты",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/orders",
                "description": "Текущие порты аккаунта: срок аренды, данные подключения, IP и таймер смены IP.\n\nДля смены IP выполняется GET-запрос по полной ссылке rotation_url из данных порта. Заголовок Authorization не требуется. Ссылка уже содержит токен порта."
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"a1b2c3d4e5f60123456789abcdef0123\",\n        \"port_id\": \"b1c2d3e4f5a60123456789abcdef0123\",\n        \"number\": 10001,\n        \"host\": \"l1.gigabit.ltd\",\n        \"username\": \"astra_a1b2c3d4e5f\",\n        \"proxy_password\": \"EXAMPLE_ONLY_22_CHARS_x\",\n        \"status\": \"active\",\n        \"expires\": \"2026-12-09T22:59:59+00:00\",\n        \"operator\": \"Orange\",\n        \"cityName\": \"Warsaw\",\n        \"ip\": \"198.51.100.42\",\n        \"rotation_url\": \"https://api.gigabit.ltd/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME\",\n        \"rotation\": true,\n        \"rotation_seconds\": 120,\n        \"connection_options\": {\n          \"custom\": {\n            \"host\": \"proxy.example.com\",\n            \"rotation_url\": \"https://api.example.com/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME\"\n          }\n        }\n      }\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Данные порта · Порт",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/orders/{{order_id}}",
            "description": "Данные заказа, принадлежащего аккаунту. Недоступный или несуществующий заказ возвращает 404.\n\nДля смены IP выполняется GET-запрос по полной ссылке rotation_url из данных порта. Заголовок Authorization не требуется. Ссылка уже содержит токен порта."
          },
          "response": [
            {
              "name": "Порт",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/orders/{{order_id}}",
                "description": "Данные заказа, принадлежащего аккаунту. Недоступный или несуществующий заказ возвращает 404.\n\nДля смены IP выполняется GET-запрос по полной ссылке rotation_url из данных порта. Заголовок Authorization не требуется. Ссылка уже содержит токен порта."
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"a1b2c3d4e5f60123456789abcdef0123\",\n    \"port_id\": \"b1c2d3e4f5a60123456789abcdef0123\",\n    \"number\": 10001,\n    \"host\": \"l1.gigabit.ltd\",\n    \"username\": \"astra_a1b2c3d4e5f\",\n    \"proxy_password\": \"EXAMPLE_ONLY_22_CHARS_x\",\n    \"status\": \"active\",\n    \"expires\": \"2026-12-09T22:59:59+00:00\",\n    \"operator\": \"Orange\",\n    \"cityName\": \"Warsaw\",\n    \"ip\": \"198.51.100.42\",\n    \"rotation_url\": \"https://api.gigabit.ltd/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME\",\n    \"rotation\": true,\n    \"rotation_seconds\": 120,\n    \"connection_options\": {\n      \"custom\": {\n        \"host\": \"proxy.example.com\",\n        \"rotation_url\": \"https://api.example.com/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME\"\n      }\n    }\n  }\n}"
            }
          ]
        },
        {
          "name": "Продление порта · По номеру",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/10001/renew",
            "description": "Добавляет 30 дней к аренде одного порта с оплатой с баланса. В запросе нужен только номер порта или его ID в адресе.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "По номеру",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/10001/renew",
                "description": "Добавляет 30 дней к аренде одного порта с оплатой с баланса. В запросе нужен только номер порта или его ID в адресе.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Продление порта · По ID",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/b1c2d3e4f5a60123456789abcdef0123/renew",
            "description": "Добавляет 30 дней к аренде одного порта с оплатой с баланса. В запросе нужен только номер порта или его ID в адресе.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "По ID",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/b1c2d3e4f5a60123456789abcdef0123/renew",
                "description": "Добавляет 30 дней к аренде одного порта с оплатой с баланса. В запросе нужен только номер порта или его ID в адресе.\n\nДлительная операция возвращает HTTP 202 и созданный сервером id. Статус и результат доступны через GET /operations/{id}. Проверка статуса не создаёт новую операцию.",
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Доступы и смена IP",
      "item": [
        {
          "name": "Сброс токена смены IP · Новая ссылка",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/{{order_id}}/rotation-token",
            "description": "Создаёт новый токен смены IP и возвращает готовую ссылку. Старый токен и все ссылки с ним сразу перестают работать. Пароль прокси и таймер не меняются.\n\nОтвет возвращается сразу, без фоновой операции. Новая ссылка также доступна в поле rotation_url данных порта.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Новая ссылка",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/{{order_id}}/rotation-token",
                "description": "Создаёт новый токен смены IP и возвращает готовую ссылку. Старый токен и все ссылки с ним сразу перестают работать. Пароль прокси и таймер не меняются.\n\nОтвет возвращается сразу, без фоновой операции. Новая ссылка также доступна в поле rotation_url данных порта.",
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"rotation_token\": \"0123456789abcdef0123456789abcdef\",\n    \"rotation_url\": \"https://api.gigabit.ltd/change_ip?token=0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Смена доступов по ID · Логин и пароль",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/{{order_id}}/password",
            "description": "Сервер генерирует новый пароль. При change_login=true одновременно генерируется новый логин с актуальным префиксом партнёра. Работает только для активной аренды.\n\nНовые данные доступны в result после применения. При ошибке operation_superseded более новая команда уже изменила доступы.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"change_login\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Логин и пароль",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/{{order_id}}/password",
                "description": "Сервер генерирует новый пароль. При change_login=true одновременно генерируется новый логин с актуальным префиксом партнёра. Работает только для активной аренды.\n\nНовые данные доступны в result после применения. При ошибке operation_superseded более новая команда уже изменила доступы.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"change_login\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Смена доступов по ID · Только пароль",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/{{order_id}}/password",
            "description": "Сервер генерирует новый пароль. При change_login=true одновременно генерируется новый логин с актуальным префиксом партнёра. Работает только для активной аренды.\n\nНовые данные доступны в result после применения. При ошибке operation_superseded более новая команда уже изменила доступы.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"change_login\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Только пароль",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/{{order_id}}/password",
                "description": "Сервер генерирует новый пароль. При change_login=true одновременно генерируется новый логин с актуальным префиксом партнёра. Работает только для активной аренды.\n\nНовые данные доступны в result после применения. При ошибке operation_superseded более новая команда уже изменила доступы.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"change_login\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Таймер смены IP · Включён",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/orders/{{order_id}}/rotation",
            "description": "Текущее состояние таймера. При rotation=true возвращается rotation_seconds. При выключенном таймере возвращается только rotation=false.\n\n"
          },
          "response": [
            {
              "name": "Включён",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/orders/{{order_id}}/rotation",
                "description": "Текущее состояние таймера. При rotation=true возвращается rotation_seconds. При выключенном таймере возвращается только rotation=false.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"rotation\": true,\n    \"rotation_seconds\": 120\n  }\n}"
            }
          ]
        },
        {
          "name": "Таймер смены IP · Выключен",
          "request": {
            "method": "GET",
            "header": [],
            "url": "{{base_url}}/orders/{{order_id}}/rotation",
            "description": "Текущее состояние таймера. При rotation=true возвращается rotation_seconds. При выключенном таймере возвращается только rotation=false.\n\n"
          },
          "response": [
            {
              "name": "Выключен",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": "{{base_url}}/orders/{{order_id}}/rotation",
                "description": "Текущее состояние таймера. При rotation=true возвращается rotation_seconds. При выключенном таймере возвращается только rotation=false.\n\n"
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"rotation\": false\n  }\n}"
            }
          ]
        },
        {
          "name": "Настройка таймера · Каждые 120 секунд",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/{{order_id}}/rotation",
            "description": "Для включения передаются rotation=true и rotation_seconds, целое число от 20 до 86400 секунд. Значение меньше 20 возвращает ошибку rotation_interval_too_short. Для отключения передаётся только rotation=false.\n\nОперация остаётся processing до подтверждения применения таймера.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"rotation\": true,\n  \"rotation_seconds\": 120\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Каждые 120 секунд",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/{{order_id}}/rotation",
                "description": "Для включения передаются rotation=true и rotation_seconds, целое число от 20 до 86400 секунд. Значение меньше 20 возвращает ошибку rotation_interval_too_short. Для отключения передаётся только rotation=false.\n\nОперация остаётся processing до подтверждения применения таймера.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"rotation\": true,\n  \"rotation_seconds\": 120\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Настройка таймера · Отключить",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/orders/{{order_id}}/rotation",
            "description": "Для включения передаются rotation=true и rotation_seconds, целое число от 20 до 86400 секунд. Значение меньше 20 возвращает ошибку rotation_interval_too_short. Для отключения передаётся только rotation=false.\n\nОперация остаётся processing до подтверждения применения таймера.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"rotation\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Отключить",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/orders/{{order_id}}/rotation",
                "description": "Для включения передаются rotation=true и rotation_seconds, целое число от 20 до 86400 секунд. Значение меньше 20 возвращает ошибку rotation_interval_too_short. Для отключения передаётся только rotation=false.\n\nОперация остаётся processing до подтверждения применения таймера.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"rotation\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 202,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"op_0123456789abcdef0123456789abcdef\",\n    \"state\": \"queued\",\n    \"error\": null,\n    \"result\": null,\n    \"created_at\": \"2026-11-10T12:00:00+00:00\",\n    \"status_url\": \"/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Профиль партнёра",
      "item": [
        {
          "name": "Префикс логинов · Префикс",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": "{{base_url}}/profile",
            "description": "Префикс - начало логинов портов, например название бренда. Логины генерируются в формате prefix_random: при prefix=astra новый порт получит логин вида astra_a1b2c3d4e5f. Случайная часть создаётся отдельно для каждого порта.\n\nИзменение префикса не меняет уже выданные логины. Новые порты и смена логина через change_login=true используют текущий префикс. Префикс должен быть уникальным; занятый возвращает 409 partner_prefix_taken.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"prefix\": \"astra\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "Префикс",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": "{{base_url}}/profile",
                "description": "Префикс - начало логинов портов, например название бренда. Логины генерируются в формате prefix_random: при prefix=astra новый порт получит логин вида astra_a1b2c3d4e5f. Случайная часть создаётся отдельно для каждого порта.\n\nИзменение префикса не меняет уже выданные логины. Новые порты и смена логина через change_login=true используют текущий префикс. Префикс должен быть уникальным; занятый возвращает 409 partner_prefix_taken.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"prefix\": \"astra\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"prefix\": \"astra\"\n  }\n}"
            }
          ]
        }
      ]
    }
  ],
  "event": [
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "if (pm.response.code >= 200 && pm.response.code < 300) {",
          "  const data = pm.response.json().data;",
          "  if (data && data.status_url) pm.collectionVariables.set(\"operation_id\", data.id);",
          "  const result = data && data.result;",
          "  if (result && result.order_ids && result.order_ids.length) pm.collectionVariables.set(\"order_id\", result.order_ids[0]);",
          "  if (result && result.id && result.id.startsWith(\"ptop_\")) pm.collectionVariables.set(\"topup_id\", result.id);",
          "}"
        ]
      }
    }
  ]
}
