{
  "openapi": "3.0.3",
  "info": {
    "title": "GIGABIT Partner API",
    "version": "1.0.0",
    "description": "API do integracji proxy mobilnych: zamawianie i przedłużanie portów, zarządzanie dostępem i rozliczenia.\n\nDłuższa operacja zwraca HTTP 202 i id utworzony przez serwer. Status i wynik są dostępne przez GET /operations/{id}. Sprawdzenie statusu nie tworzy nowej operacji."
  },
  "servers": [
    {
      "url": "https://api.gigabit.ltd/api/partner/v1"
    }
  ],
  "security": [
    {
      "PartnerToken": []
    }
  ],
  "tags": [
    {
      "name": "operations",
      "description": "Operacje"
    },
    {
      "name": "funds",
      "description": "Saldo i rozliczenia"
    },
    {
      "name": "orders",
      "description": "Katalog i zamówienia"
    },
    {
      "name": "access",
      "description": "Dostęp i zmiana IP"
    },
    {
      "name": "profile",
      "description": "Profil partnera"
    }
  ],
  "paths": {
    "/orders/{id}/rotation-token": {
      "post": {
        "operationId": "rotation-token",
        "tags": [
          "access"
        ],
        "summary": "Reset tokenu zmiany IP",
        "description": "Tworzy nowy token zmiany IP i zwraca gotowy link. Poprzedni token i wszystkie linki z nim natychmiast przestają działać. Hasło proxy i timer pozostają bez zmian.\n\nOdpowiedź jest zwracana od razu, bez operacji w tle. Nowy link jest również dostępny w polu rotation_url danych portu.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "rotation_token": {
                          "type": "string"
                        },
                        "rotation_url": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Nowy link",
                    "value": {
                      "success": true,
                      "data": {
                        "rotation_token": "0123456789abcdef0123456789abcdef",
                        "rotation_url": "https://api.gigabit.ltd/change_ip?token=0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID zamówienia z pola id na liście portów."
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "examples": {
                "0": {
                  "summary": "Nowy link",
                  "value": {}
                }
              }
            }
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "balance",
        "tags": [
          "funds"
        ],
        "summary": "Saldo",
        "description": "Bieżące saldo, limit kredytowy, dostępne środki, rabat i ceny partnera.\n\n",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "currency": {
                          "type": "string"
                        },
                        "balance_cents": {
                          "type": "integer"
                        },
                        "reserved_cents": {
                          "type": "integer"
                        },
                        "credit_limit_cents": {
                          "type": "integer"
                        },
                        "debt_cents": {
                          "type": "integer"
                        },
                        "available_cents": {
                          "type": "integer"
                        },
                        "withdrawable_cents": {
                          "type": "integer"
                        },
                        "discount_percent": {
                          "type": "integer"
                        },
                        "prefix": {
                          "type": "string"
                        },
                        "api_token_hint": {
                          "type": "string"
                        },
                        "monthly_net_cents": {
                          "type": "integer"
                        },
                        "payment_method": {
                          "type": "string"
                        },
                        "connection_domains": {
                          "type": "object",
                          "properties": {
                            "host": {
                              "type": "string"
                            },
                            "api": {
                              "type": "string"
                            }
                          }
                        },
                        "paid_in_cents": {
                          "type": "integer"
                        },
                        "prices": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "currency": {
                                "type": "string"
                              },
                              "base_net_cents": {
                                "type": "integer"
                              },
                              "net_cents": {
                                "type": "integer"
                              },
                              "vat_cents": {
                                "type": "integer"
                              },
                              "total_cents": {
                                "type": "integer"
                              },
                              "tax_at_topup": {
                                "type": "boolean"
                              },
                              "discount_percent": {
                                "type": "integer"
                              },
                              "months": {
                                "type": "integer"
                              },
                              "days": {
                                "type": "integer"
                              },
                              "pricing_version": {
                                "type": "integer"
                              },
                              "tax": {
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "type": "string"
                                  },
                                  "rate_percent": {
                                    "type": "integer"
                                  },
                                  "vat_code": {
                                    "type": "string"
                                  },
                                  "reverse_charge": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "topup_tax": {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string"
                            },
                            "rate_percent": {
                              "type": "integer"
                            },
                            "vat_code": {
                              "type": "string"
                            },
                            "reverse_charge": {
                              "type": "boolean"
                            }
                          }
                        },
                        "can_order_new_ports": {
                          "type": "boolean"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Saldo",
                    "value": {
                      "success": true,
                      "data": {
                        "currency": "EUR",
                        "balance_cents": 10000,
                        "reserved_cents": 0,
                        "credit_limit_cents": 10000,
                        "debt_cents": 0,
                        "available_cents": 20000,
                        "withdrawable_cents": 10000,
                        "discount_percent": 10,
                        "prefix": "astra",
                        "api_token_hint": "demo12",
                        "monthly_net_cents": 4500,
                        "payment_method": "card",
                        "connection_domains": {
                          "host": "",
                          "api": ""
                        },
                        "paid_in_cents": 10000,
                        "prices": [
                          {
                            "currency": "EUR",
                            "base_net_cents": 4500,
                            "net_cents": 4050,
                            "vat_cents": 0,
                            "total_cents": 4050,
                            "tax_at_topup": true,
                            "discount_percent": 10,
                            "months": 1,
                            "days": 30,
                            "pricing_version": 1,
                            "tax": {
                              "mode": "vat",
                              "rate_percent": 23,
                              "vat_code": "23",
                              "reverse_charge": false
                            }
                          }
                        ],
                        "topup_tax": {
                          "mode": "vat",
                          "rate_percent": 23,
                          "vat_code": "23",
                          "reverse_charge": false
                        },
                        "can_order_new_ports": true
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/catalog": {
      "get": {
        "operationId": "catalog",
        "tags": [
          "orders"
        ],
        "summary": "Dostępne porty",
        "description": "Dostępne numery portów pogrupowane według operatora i lokalizacji.\n\nDostępność jest sprawdzana podczas składania zamówienia. Wyświetlenie katalogu nie rezerwuje portów.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "operator": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              },
                              "location": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              },
                              "ports": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "string"
                                    },
                                    "number": {
                                      "type": "integer"
                                    }
                                  }
                                }
                              },
                              "available": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "prices": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "currency": {
                                "type": "string"
                              },
                              "base_net_cents": {
                                "type": "integer"
                              },
                              "net_cents": {
                                "type": "integer"
                              },
                              "vat_cents": {
                                "type": "integer"
                              },
                              "total_cents": {
                                "type": "integer"
                              },
                              "tax_at_topup": {
                                "type": "boolean"
                              },
                              "discount_percent": {
                                "type": "integer"
                              },
                              "months": {
                                "type": "integer"
                              },
                              "days": {
                                "type": "integer"
                              },
                              "pricing_version": {
                                "type": "integer"
                              },
                              "tax": {
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "type": "string"
                                  },
                                  "rate_percent": {
                                    "type": "integer"
                                  },
                                  "vat_code": {
                                    "type": "string"
                                  },
                                  "reverse_charge": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Dostępność",
                    "value": {
                      "success": true,
                      "data": {
                        "items": [
                          {
                            "operator": {
                              "id": "operator-orange",
                              "name": "Orange"
                            },
                            "location": {
                              "id": "location-warsaw",
                              "name": "Warsaw"
                            },
                            "ports": [
                              {
                                "id": "b1c2d3e4f5a60123456789abcdef0123",
                                "number": 10001
                              },
                              {
                                "id": "b2c3d4e5f6a70123456789abcdef0123",
                                "number": 10002
                              }
                            ],
                            "available": 2
                          }
                        ],
                        "prices": [
                          {
                            "currency": "EUR",
                            "base_net_cents": 4500,
                            "net_cents": 4050,
                            "vat_cents": 0,
                            "total_cents": 4050,
                            "tax_at_topup": true,
                            "discount_percent": 10,
                            "months": 1,
                            "days": 30,
                            "pricing_version": 1,
                            "tax": {
                              "mode": "vat",
                              "rate_percent": 23,
                              "vat_code": "23",
                              "reverse_charge": false
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "operationId": "create-order",
        "tags": [
          "orders"
        ],
        "summary": "Zamówienie portu",
        "description": "Zamówienie jednego dostępnego portu na 30 dni według numeru lub ID z katalogu. Koszt jest pobierany z salda.\n\nDłuższa operacja zwraca HTTP 202 i id utworzony przez serwer. Status i wynik są dostępne przez GET /operations/{id}. Sprawdzenie statusu nie tworzy nowej operacji.",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Według numeru",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "1": {
                    "summary": "Według ID",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "port_number": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 65535,
                    "description": "Numer portu z katalogu. Wymagane jest jedno z pól: port_number lub port_id."
                  },
                  "port_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "ID portu z katalogu, zamiast port_number."
                  }
                },
                "additionalProperties": false,
                "oneOf": [
                  {
                    "required": [
                      "port_number"
                    ]
                  },
                  {
                    "required": [
                      "port_id"
                    ]
                  }
                ]
              },
              "examples": {
                "0": {
                  "summary": "Według numeru",
                  "value": {
                    "port_number": 10001
                  }
                },
                "1": {
                  "summary": "Według ID",
                  "value": {
                    "port_id": "b1c2d3e4f5a60123456789abcdef0123"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "orders",
        "tags": [
          "orders"
        ],
        "summary": "Lista portów",
        "description": "Bieżące porty konta: termin wynajmu, dane połączenia, IP i timer zmiany IP.\n\nZmiana IP odbywa się przez zapytanie GET pod pełny adres rotation_url z danych portu. Nagłówek Authorization nie jest wymagany. Link zawiera już token portu.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "port_id": {
                                "type": "string"
                              },
                              "number": {
                                "type": "integer"
                              },
                              "host": {
                                "type": "string"
                              },
                              "username": {
                                "type": "string"
                              },
                              "proxy_password": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string"
                              },
                              "expires": {
                                "type": "string"
                              },
                              "operator": {
                                "type": "string"
                              },
                              "cityName": {
                                "type": "string"
                              },
                              "ip": {
                                "type": "string"
                              },
                              "rotation_url": {
                                "type": "string"
                              },
                              "rotation": {
                                "type": "boolean"
                              },
                              "rotation_seconds": {
                                "type": "integer"
                              },
                              "connection_options": {
                                "type": "object",
                                "properties": {
                                  "custom": {
                                    "type": "object",
                                    "properties": {
                                      "host": {
                                        "type": "string"
                                      },
                                      "rotation_url": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Porty",
                    "value": {
                      "success": true,
                      "data": {
                        "items": [
                          {
                            "id": "a1b2c3d4e5f60123456789abcdef0123",
                            "port_id": "b1c2d3e4f5a60123456789abcdef0123",
                            "number": 10001,
                            "host": "l1.gigabit.ltd",
                            "username": "astra_a1b2c3d4e5f",
                            "proxy_password": "EXAMPLE_ONLY_22_CHARS_x",
                            "status": "active",
                            "expires": "2026-12-09T22:59:59+00:00",
                            "operator": "Orange",
                            "cityName": "Warsaw",
                            "ip": "198.51.100.42",
                            "rotation_url": "https://api.gigabit.ltd/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME",
                            "rotation": true,
                            "rotation_seconds": 120,
                            "connection_options": {
                              "custom": {
                                "host": "proxy.example.com",
                                "rotation_url": "https://api.example.com/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/operations/{id}": {
      "get": {
        "operationId": "operation-status",
        "tags": [
          "operations"
        ],
        "summary": "Status operacji",
        "description": "Zwraca status i wynik operacji konta. Szybkie sprawdzenie bez ponownego wykonania.\n\n",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "state": {
                                  "type": "string"
                                },
                                "error": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "order_ids": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "amount_cents": {
                                  "type": "integer"
                                },
                                "currency": {
                                  "type": "string"
                                },
                                "price": {
                                  "type": "object",
                                  "properties": {
                                    "currency": {
                                      "type": "string"
                                    },
                                    "base_net_cents": {
                                      "type": "integer"
                                    },
                                    "net_cents": {
                                      "type": "integer"
                                    },
                                    "vat_cents": {
                                      "type": "integer"
                                    },
                                    "total_cents": {
                                      "type": "integer"
                                    },
                                    "tax_at_topup": {
                                      "type": "boolean"
                                    },
                                    "discount_percent": {
                                      "type": "integer"
                                    },
                                    "months": {
                                      "type": "integer"
                                    },
                                    "days": {
                                      "type": "integer"
                                    },
                                    "pricing_version": {
                                      "type": "integer"
                                    },
                                    "tax": {
                                      "type": "object",
                                      "properties": {
                                        "mode": {
                                          "type": "string"
                                        },
                                        "rate_percent": {
                                          "type": "integer"
                                        },
                                        "vat_code": {
                                          "type": "string"
                                        },
                                        "reverse_charge": {
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string"
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "W kolejce",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "1": {
                    "summary": "Zakończona",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "ready",
                        "error": null,
                        "result": {
                          "id": "partner_0123456789abcdef0123456789abcdef",
                          "state": "ready",
                          "error": null,
                          "order_ids": [
                            "a1b2c3d4e5f60123456789abcdef0123"
                          ],
                          "amount_cents": 4050,
                          "currency": "EUR",
                          "price": {
                            "currency": "EUR",
                            "base_net_cents": 4500,
                            "net_cents": 4050,
                            "vat_cents": 0,
                            "total_cents": 4050,
                            "tax_at_topup": true,
                            "discount_percent": 10,
                            "months": 1,
                            "days": 30,
                            "pricing_version": 1,
                            "tax": {
                              "mode": "vat",
                              "rate_percent": 23,
                              "vat_code": "23",
                              "reverse_charge": false
                            }
                          }
                        },
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "2": {
                    "summary": "Błąd",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "failed",
                        "error": "insufficient_partner_balance",
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID operacji z odpowiedzi HTTP 202."
            }
          }
        ]
      }
    },
    "/orders/{id}": {
      "get": {
        "operationId": "order",
        "tags": [
          "orders"
        ],
        "summary": "Dane portu",
        "description": "Dane zamówienia przypisanego do konta. Niedostępne lub nieistniejące zamówienie zwraca 404.\n\nZmiana IP odbywa się przez zapytanie GET pod pełny adres rotation_url z danych portu. Nagłówek Authorization nie jest wymagany. Link zawiera już token portu.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "port_id": {
                          "type": "string"
                        },
                        "number": {
                          "type": "integer"
                        },
                        "host": {
                          "type": "string"
                        },
                        "username": {
                          "type": "string"
                        },
                        "proxy_password": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "expires": {
                          "type": "string"
                        },
                        "operator": {
                          "type": "string"
                        },
                        "cityName": {
                          "type": "string"
                        },
                        "ip": {
                          "type": "string"
                        },
                        "rotation_url": {
                          "type": "string"
                        },
                        "rotation": {
                          "type": "boolean"
                        },
                        "rotation_seconds": {
                          "type": "integer"
                        },
                        "connection_options": {
                          "type": "object",
                          "properties": {
                            "custom": {
                              "type": "object",
                              "properties": {
                                "host": {
                                  "type": "string"
                                },
                                "rotation_url": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Port",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "a1b2c3d4e5f60123456789abcdef0123",
                        "port_id": "b1c2d3e4f5a60123456789abcdef0123",
                        "number": 10001,
                        "host": "l1.gigabit.ltd",
                        "username": "astra_a1b2c3d4e5f",
                        "proxy_password": "EXAMPLE_ONLY_22_CHARS_x",
                        "status": "active",
                        "expires": "2026-12-09T22:59:59+00:00",
                        "operator": "Orange",
                        "cityName": "Warsaw",
                        "ip": "198.51.100.42",
                        "rotation_url": "https://api.gigabit.ltd/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME",
                        "rotation": true,
                        "rotation_seconds": 120,
                        "connection_options": {
                          "custom": {
                            "host": "proxy.example.com",
                            "rotation_url": "https://api.example.com/change_ip?token=EXAMPLE_ROTATION_TOKEN_REPLACE_ME"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID zamówienia (id) lub portu (port_id) z listy portów."
            }
          }
        ]
      }
    },
    "/orders/{id}/renew": {
      "post": {
        "operationId": "renew",
        "tags": [
          "orders"
        ],
        "summary": "Przedłużenie portu",
        "description": "Przedłuża wynajem jednego portu o 30 dni z płatnością z salda. Wymagany jest tylko numer lub ID portu w adresie.\n\nDłuższa operacja zwraca HTTP 202 i id utworzony przez serwer. Status i wynik są dostępne przez GET /operations/{id}. Sprawdzenie statusu nie tworzy nowej operacji.",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Według numeru",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "1": {
                    "summary": "Według ID",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Numer lub ID portu. Akceptowany jest też id zamówienia z GET /orders."
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "examples": {
                "0": {
                  "summary": "Według numeru",
                  "value": {}
                },
                "1": {
                  "summary": "Według ID",
                  "value": {}
                }
              }
            }
          }
        }
      }
    },
    "/orders/{id}/password": {
      "post": {
        "operationId": "password",
        "tags": [
          "access"
        ],
        "summary": "Zmiana danych dostępu według ID",
        "description": "Serwer generuje nowe hasło. Przy change_login=true generuje też nowy login z bieżącym prefiksem partnera. Dostępne wyłącznie dla aktywnego wynajmu.\n\nNowe dane są dostępne w result po zastosowaniu. Błąd operation_superseded oznacza, że nowsze polecenie zmieniło dane dostępu.",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Login i hasło",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "1": {
                    "summary": "Tylko hasło",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID zamówienia (id) lub portu (port_id) z listy portów."
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "change_login": {
                    "type": "boolean",
                    "default": false,
                    "description": "true - nowy login z bieżącym prefiksem i nowe hasło. false - tylko hasło. Starszy wspólny dostęp otrzymuje osobne dane także bez tej flagi."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "0": {
                  "summary": "Login i hasło",
                  "value": {
                    "change_login": true
                  }
                },
                "1": {
                  "summary": "Tylko hasło",
                  "value": {
                    "change_login": false
                  }
                }
              }
            }
          }
        }
      }
    },
    "/orders/{id}/rotation": {
      "get": {
        "operationId": "rotation-get",
        "tags": [
          "access"
        ],
        "summary": "Timer zmiany IP",
        "description": "Bieżący stan timera. Przy rotation=true zwracane jest rotation_seconds. Gdy timer jest wyłączony, zwracane jest tylko rotation=false.\n\n",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "rotation": {
                              "type": "boolean"
                            },
                            "rotation_seconds": {
                              "type": "integer"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "rotation": {
                              "type": "boolean"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Włączony",
                    "value": {
                      "success": true,
                      "data": {
                        "rotation": true,
                        "rotation_seconds": 120
                      }
                    }
                  },
                  "1": {
                    "summary": "Wyłączony",
                    "value": {
                      "success": true,
                      "data": {
                        "rotation": false
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID zamówienia (id) lub portu (port_id) z listy portów."
            }
          }
        ]
      },
      "put": {
        "operationId": "rotation-set",
        "tags": [
          "access"
        ],
        "summary": "Ustawienia timera",
        "description": "Włączenie wymaga rotation=true oraz rotation_seconds, liczby całkowitej od 20 do 86400 sekund. Wartość poniżej 20 zwraca błąd rotation_interval_too_short. Wyłączenie wymaga tylko rotation=false.\n\nOperacja pozostaje processing do potwierdzenia zastosowania timera.",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "state": {
                              "type": "string"
                            },
                            "error": {
                              "type": "string",
                              "nullable": true
                            },
                            "result": {
                              "type": "object",
                              "nullable": true
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "status_url": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "success",
                        "data"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Co 120 sekund",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  },
                  "1": {
                    "summary": "Wyłącz",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID zamówienia (id) lub portu (port_id) z listy portów."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rotation": {
                    "type": "boolean",
                    "description": "true włącza timer; false wyłącza."
                  },
                  "rotation_seconds": {
                    "type": "integer",
                    "minimum": 20,
                    "maximum": 86400,
                    "description": "Wymagane przy rotation=true. Przy rotation=false pole należy pominąć."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "rotation"
                ],
                "oneOf": [
                  {
                    "properties": {
                      "rotation": {
                        "enum": [
                          true
                        ]
                      }
                    },
                    "required": [
                      "rotation_seconds"
                    ]
                  },
                  {
                    "properties": {
                      "rotation": {
                        "enum": [
                          false
                        ]
                      }
                    },
                    "not": {
                      "required": [
                        "rotation_seconds"
                      ]
                    }
                  }
                ]
              },
              "examples": {
                "0": {
                  "summary": "Co 120 sekund",
                  "value": {
                    "rotation": true,
                    "rotation_seconds": 120
                  }
                },
                "1": {
                  "summary": "Wyłącz",
                  "value": {
                    "rotation": false
                  }
                }
              }
            }
          }
        }
      }
    },
    "/topups": {
      "post": {
        "operationId": "topup",
        "tags": [
          "funds"
        ],
        "summary": "Doładowanie salda",
        "description": "Tworzy link do płatności przez Stripe. amount_cents to kwota zasilenia salda w eurocentach; total_cents to kwota do zapłaty z uwzględnieniem należnego VAT.\n\n",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "result": {
                          "type": "object",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Karta / Stripe",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount_cents": {
                    "type": "integer",
                    "minimum": 100,
                    "maximum": 10000000,
                    "description": "Od 1 do 100 000 EUR w całkowitych eurocentach."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "amount_cents"
                ]
              },
              "examples": {
                "0": {
                  "summary": "Karta / Stripe",
                  "value": {
                    "amount_cents": 10000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/topups/{id}": {
      "get": {
        "operationId": "topup-status",
        "tags": [
          "funds"
        ],
        "summary": "Status doładowania",
        "description": "Zwraca status doładowania konta. paid potwierdza zaksięgowanie środków. Sam powrót ze strony Stripe nie potwierdza płatności.\n\nStatusy: creating, pending, paid, expired, failed.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "amount_cents": {
                          "type": "integer"
                        },
                        "vat_cents": {
                          "type": "integer"
                        },
                        "total_cents": {
                          "type": "integer"
                        },
                        "currency": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Stripe",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "ptop_0123456789abcdef0123456789abcdef",
                        "state": "pending",
                        "url": "https://checkout.stripe.com/c/pay/EXAMPLE_SESSION",
                        "amount_cents": 10000,
                        "vat_cents": 2300,
                        "total_cents": 12300,
                        "currency": "EUR"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID doładowania z POST /topups."
            }
          }
        ]
      }
    },
    "/transactions": {
      "get": {
        "operationId": "transactions",
        "tags": [
          "funds"
        ],
        "summary": "Historia transakcji",
        "description": "Operacje od najnowszych do najstarszych, źródła, komentarze, kwoty i saldo po każdej operacji. Techniczne rezerwacje zakupu są domyślnie ukryte.\n\n",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "created_at": {
                                "type": "string"
                              },
                              "currency": {
                                "type": "string"
                              },
                              "operation": {
                                "type": "string"
                              },
                              "amount_cents": {
                                "type": "integer"
                              },
                              "reserved_delta_cents": {
                                "type": "integer"
                              },
                              "source": {
                                "type": "string"
                              },
                              "comment": {
                                "type": "string"
                              },
                              "reference": {
                                "type": "string"
                              },
                              "balance_after_cents": {
                                "type": "integer"
                              },
                              "reserved_after_cents": {
                                "type": "integer"
                              },
                              "sequence": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        },
                        "offset": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Pierwsza strona",
                    "value": {
                      "success": true,
                      "data": {
                        "items": [
                          {
                            "id": "ptop_0123456789abcdef0123456789abcdef:credit",
                            "created_at": "2026-11-09T12:05:00+00:00",
                            "currency": "EUR",
                            "operation": "topup",
                            "amount_cents": 10000,
                            "reserved_delta_cents": 0,
                            "source": "stripe",
                            "comment": "",
                            "reference": "ptop_0123456789abcdef0123456789abcdef",
                            "balance_after_cents": 10000,
                            "reserved_after_cents": 0,
                            "sequence": 1
                          }
                        ],
                        "total": 1,
                        "offset": 0,
                        "limit": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0,
              "description": "Liczba pomijanych wpisów."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30,
              "description": "Rozmiar strony: 1-100."
            }
          },
          {
            "name": "include_reservations",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ],
              "description": "1 uwzględnia purchase_reserve i purchase_release."
            }
          }
        ]
      }
    },
    "/withdrawals": {
      "post": {
        "operationId": "withdrawal",
        "tags": [
          "funds"
        ],
        "summary": "Wniosek o zwrot środków",
        "description": "Tworzy wniosek i rezerwuje kwotę do jego rozpatrzenia. Kwota dostępna do wypłaty jest podana w withdrawable_cents; nie obejmuje limitu kredytowego ani bezzwrotnych rekompensat.\n\nPo przetworzeniu wniosku result.state=requested oznacza oczekiwanie na decyzję. Operacja pozostaje processing do potwierdzenia wypłaty lub odrzucenia.",
        "responses": {
          "202": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "result": {
                          "type": "object",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Wniosek",
                    "value": {
                      "success": true,
                      "data": {
                        "id": "op_0123456789abcdef0123456789abcdef",
                        "state": "queued",
                        "error": null,
                        "result": null,
                        "created_at": "2026-11-10T12:00:00+00:00",
                        "status_url": "/api/partner/v1/operations/op_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount_cents": {
                    "type": "integer",
                    "minimum": 100,
                    "maximum": 100000000,
                    "description": "Kwota EUR w centach, nie większa niż dostępna do wypłaty."
                  },
                  "comment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Dane do wypłaty lub wyjaśnienie. Niepusty tekst po usunięciu skrajnych spacji."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "amount_cents",
                  "comment"
                ]
              },
              "examples": {
                "0": {
                  "summary": "Wniosek",
                  "value": {
                    "amount_cents": 5000,
                    "comment": "Please contact me to confirm payment details."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profile": {
      "put": {
        "operationId": "profile",
        "tags": [
          "profile"
        ],
        "summary": "Prefiks loginów",
        "description": "Prefiks to początek loginów portów, np. nazwa marki. Loginy są generowane w formacie prefix_random: przy prefix=astra nowy port otrzyma login taki jak astra_a1b2c3d4e5f. Losowa część jest tworzona osobno dla każdego portu.\n\nZmiana prefiksu nie zmienia już wydanych loginów. Nowe porty oraz zmiana loginu przez change_login=true używają bieżącego prefiksu. Prefiks musi być unikalny; zajęty zwraca 409 partner_prefix_taken.",
        "responses": {
          "200": {
            "description": "Przykład odpowiedzi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "prefix": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                },
                "examples": {
                  "0": {
                    "summary": "Prefiks",
                    "value": {
                      "success": true,
                      "data": {
                        "prefix": "astra"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Błędy",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prefix": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 24,
                    "pattern": "^[a-z][a-z0-9-]{1,23}$",
                    "description": "2-24 znaki: litery łacińskie, cyfry i myślnik; pierwszy znak to litera. Normalizowany do małych liter. proxy i gigabit są zastrzeżone."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "prefix"
                ]
              },
              "examples": {
                "0": {
                  "summary": "Prefiks",
                  "value": {
                    "prefix": "astra"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "PartnerToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gbp_…"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string"
          },
          "retry_after": {
            "type": "integer"
          }
        }
      }
    }
  }
}
