{"openapi":"3.1.0","info":{"title":"ClickIP API","version":"1.0.0","summary":"Buy, manage, rotate and track proxies programmatically.","description":"The **ClickIP API** is a JSON-over-HTTPS REST API. Everything you can do in the\ndashboard — browse the catalog, buy mobile / residential / IPv4 / IPv6 / ISP\nproxies, fetch credentials, rotate IPs, track residential traffic, and top up your\nbalance — you can also do from your own code. It is built for **automation** and for\n**resellers** who provision and manage proxies on behalf of their own users.\n\n### Base URL\n```\nhttps://api.click-ip.com/v1\n```\n\n### Authentication\nEvery request (except the public `Catalog` endpoints and the service ping) is\nauthenticated with a secret API key sent as a Bearer token:\n```\nAuthorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\nCreate and revoke keys in the dashboard under **Settings → API keys**. The full key is\nshown **once** at creation — copy it and store it securely; ClickIP only keeps a hash.\nKeys carry **scopes** (least-privilege); a request outside a key’s scopes returns\n`403 insufficient_scope`. `ck_live_` keys act on live data and balance; `ck_test_` keys\nrun against the sandbox. Never expose a key in client-side code or a public repo.\n\n### Response envelope\nEvery response is wrapped consistently.\n```json\n// success\n{ \"success\": true, \"data\": { \"...\": \"...\" }, \"meta\": { \"next_cursor\": null } }\n\n// error\n{ \"success\": false,\n  \"error\": { \"code\": \"insufficient_balance\",\n             \"message\": \"Your balance ($3.10) is lower than the order total ($8.00).\",\n             \"details\": { \"balance\": 3.10, \"required\": 8.00 } } }\n```\n\n### Error codes\n| HTTP | `code` | Meaning |\n|---|---|---|\n| 400 | `validation_error` | Malformed/invalid parameters (`details` lists fields). |\n| 401 | `unauthorized` | Missing / invalid / revoked API key. |\n| 402 | `insufficient_balance` | Not enough balance to complete a purchase. |\n| 403 | `forbidden` | Authenticated but not allowed (e.g. not your proxy). |\n| 403 | `insufficient_scope` | Key lacks the required scope. |\n| 404 | `not_found` | Resource does not exist or isn’t yours. |\n| 409 | `idempotency_conflict` | Reused idempotency key with a different payload. |\n| 429 | `rate_limited` | Per-key rate limit hit. See `Retry-After`. |\n| 503 | `service_unavailable` | Service temporarily busy/unavailable; retry later. |\n| 500 | `internal_error` | Unexpected server error (`request_id` in `details`). |\n\n### Pagination\nList endpoints are cursor-paginated: `?limit=50&cursor=…`. `meta.next_cursor` is\n`null` on the last page. `limit` max **100** (default 50).\n\n### Idempotency\nFor any request that spends money (`POST /proxies`, `/balance/deposits`,\n`/proxies/{id}/extend`) send an `Idempotency-Key` header (any unique string, e.g. a\nUUID). Retrying with the same key returns the original result instead of charging\ntwice. Keys are remembered for 24 hours.\n\n### Rate limits\nPer-key sliding window (default **120 requests/min**; purchase endpoints **10/min**).\nResponses include `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`. On\n`429`, honor `Retry-After` (seconds). Cache catalog data and poll proxy state sparingly.\n\n### Versioning\nThe API is versioned in the path (`/v1`). Additive changes (new fields/endpoints) ship\nwithin `v1`; breaking changes get a new version. Treat unknown fields as\nforward-compatible.\n\n### Reselling with ClickIP\nResellers buy on their prepaid balance, expose their own pricing to their users, and\nlist/rotate proxies programmatically. Use a separate scoped key per environment and\nnever surface your ClickIP key to end users — front it with your own service.\n\n> **Teams** (`teams:read` / `teams:write`) and **Webhooks** (`proxy.provisioned`,\n> `proxy.expired`, `order.failed`, `deposit.completed`) are planned for v1.1.","contact":{"name":"ClickIP Support","url":"https://click-ip.com/#support"},"license":{"name":"ClickIP API Terms","url":"https://click-ip.com/legal/terms"}},"servers":[{"url":"https://api.click-ip.com/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Service","description":"Health / ping. No key required."},{"name":"Catalog","description":"Public reference data — no API key required. Cache these; they change rarely. Proxy `type` is one of `ipv4`, `ipv6`, `isp`, `mobile`, `resident`. For a per-type walkthrough, see the guide on `POST /v1/proxies` (**Buy proxies**)."},{"name":"Account & Balance","description":"Profile, balances, transaction history and top-ups."},{"name":"Proxies","description":"Buy, list, rotate, extend, auto-renew and annotate proxies."},{"name":"Residential endpoints","description":"Prepaid residential GB pool: usage and IP lists."}],"x-tagGroups":[{"name":"API reference","tags":["Service","Catalog","Account & Balance","Proxies","Residential endpoints"]}],"paths":{"/":{"get":{"tags":["Service"],"summary":"Service ping","operationId":"ping","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"Unauthenticated health/version probe — handy for smoke tests and uptime checks.\n\n> **Status: Live.**","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"name":{"type":"string","example":"ClickIP API"},"version":{"type":"string","example":"v1"},"docs":{"type":"string","example":"https://api.click-ip.com/v1/docs"}}}}}}}}}}},"/catalog/pricing":{"get":{"tags":["Catalog"],"summary":"Pricing overview","operationId":"getCatalogPricing","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"“From” prices for every proxy type. Internals (COGS/margin) are never returned.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","responses":{"200":{"description":"A price overview per proxy type.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PricingItem"}}}}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/catalog/countries/{type}":{"get":{"tags":["Catalog"],"summary":"Countries for a type","operationId":"getCatalogCountries","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"Available countries for the given proxy `type`.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","parameters":[{"$ref":"#/components/parameters/ProxyTypePath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Country"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"}}}},"/catalog/periods/{type}":{"get":{"tags":["Catalog"],"summary":"Rental periods for a type","operationId":"getCatalogPeriods","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"Rental periods (and their multipliers) for the given proxy `type`.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","parameters":[{"$ref":"#/components/parameters/ProxyTypePath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Period"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"}}}},"/catalog/tarifs/{type}":{"get":{"tags":["Catalog"],"summary":"GB tiers for a type","operationId":"getCatalogTarifs","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"GB volume tiers for the volume-priced `resident` type.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","parameters":[{"$ref":"#/components/parameters/ProxyTypePath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Tarif"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"}}}},"/catalog/residential/geo":{"get":{"tags":["Catalog"],"summary":"Residential geo tree","operationId":"getResidentialGeo","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"The residential targeting tree: country → city → ASN.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/GeoNode"}}}}}}}}}},"/catalog/operators/{countryId}/{serviceType}":{"get":{"tags":["Catalog"],"summary":"Mobile carriers","operationId":"getCatalogOperators","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"Mobile carriers available in a country for a given mobile service type.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","parameters":[{"name":"countryId","in":"path","required":true,"schema":{"type":"integer"},"example":616},{"name":"serviceType","in":"path","required":true,"schema":{"type":"string","enum":["dedicated","shared"]},"example":"shared"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Operator"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"}}}},"/catalog/calculate":{"post":{"tags":["Catalog"],"summary":"Price an order","operationId":"calculateOrder","security":[],"x-badges":[{"name":"Live","position":"after"}],"description":"Compute the exact total for an order before buying. Never returns COGS/margin.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalculateRequest"},"example":{"type":"ipv4","countryId":840,"periodId":1,"quantity":5}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/CalculateResult"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST https://api.click-ip.com/v1/catalog/calculate \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":5}'"},{"lang":"javascript","label":"Node.js","source":"const res = await fetch('https://api.click-ip.com/v1/catalog/calculate', {\n  method: 'POST',\n  headers: {\n      'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"type\": \"ipv4\",\n    \"countryId\": 840,\n    \"periodId\": 1,\n    \"quantity\": 5\n  }),\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nresp = requests.post(\n    \"https://api.click-ip.com/v1/catalog/calculate\",\n    json={\n      \"type\": \"ipv4\",\n      \"countryId\": 840,\n      \"periodId\": 1,\n      \"quantity\": 5\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\nfunc main() {\n\tbody := []byte(`{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":5}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.click-ip.com/v1/catalog/calculate\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/catalog/calculate');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Content-Type: application/json',\n  ],\n  CURLOPT_POSTFIELDS => '{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":5}',\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]}},"/account":{"get":{"tags":["Account & Balance"],"summary":"Get account","operationId":"getAccount","security":[{"bearerAuth":["account:read"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"Your profile summary: id, email, balance, referral code and earnings.\n\nRequires scope `account:read`.\n\n> **Status: Live.**","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Account"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET https://api.click-ip.com/v1/account \\\n  -H \"Authorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\""},{"lang":"javascript","label":"Node.js","source":"const res = await fetch('https://api.click-ip.com/v1/account', {\n  method: 'GET',\n  headers: {\n      Authorization: 'Bearer ' + process.env.CLICKIP_API_KEY,\n  },\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nresp = requests.get(\n    \"https://api.click-ip.com/v1/account\",\n    headers={\n    \"Authorization\": f\"Bearer {os.environ['CLICKIP_API_KEY']}\",\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.click-ip.com/v1/account\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"CLICKIP_API_KEY\"))\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/account');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Authorization: Bearer ' . getenv('CLICKIP_API_KEY'),\n  ],\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]}},"/balance":{"get":{"tags":["Account & Balance"],"summary":"Get balance","operationId":"getBalance","security":[{"bearerAuth":["balance:read"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"Your prepaid balance and referral balance. Requires scope `balance:read`.\n\n> **Status: Live.**","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Balance"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET https://api.click-ip.com/v1/balance \\\n  -H \"Authorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\""},{"lang":"javascript","label":"Node.js","source":"const res = await fetch('https://api.click-ip.com/v1/balance', {\n  method: 'GET',\n  headers: {\n      Authorization: 'Bearer ' + process.env.CLICKIP_API_KEY,\n  },\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nresp = requests.get(\n    \"https://api.click-ip.com/v1/balance\",\n    headers={\n    \"Authorization\": f\"Bearer {os.environ['CLICKIP_API_KEY']}\",\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.click-ip.com/v1/balance\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"CLICKIP_API_KEY\"))\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/balance');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Authorization: Bearer ' . getenv('CLICKIP_API_KEY'),\n  ],\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]}},"/transactions":{"get":{"tags":["Account & Balance"],"summary":"List transactions","operationId":"listTransactions","security":[{"bearerAuth":["balance:read"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"Your ledger, newest first. Cursor-paginated. Requires scope `balance:read`.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.","parameters":[{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/CursorParam"},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["deposit","worldwide_proxy_purchase","worldwide_proxy_renewal","withdrawal","referral_commission","team_transfer_out"]},"description":"Filter by transaction type."},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/balance/deposits":{"post":{"tags":["Account & Balance"],"summary":"Create a top-up invoice","operationId":"createDeposit","security":[{"bearerAuth":["billing:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Create a crypto (USDT) top-up invoice and receive a hosted `payment_url`. Payment completes **asynchronously** — poll the balance or subscribe to the `deposit.completed` webhook. Requires scope `billing:write` and an `Idempotency-Key`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"$ref":"#/components/parameters/IdempotencyKeyHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number","minimum":5,"example":50}}},"example":{"amount":50}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/DepositInvoice"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"409":{"$ref":"#/components/responses/IdempotencyConflict"}}}},"/proxies":{"get":{"tags":["Proxies"],"summary":"List proxies","operationId":"listProxies","security":[{"bearerAuth":["proxies:read"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"List your active proxies with full connection details. Served from ClickIP state (cheap, served directly from ClickIP). Cursor-paginated. Requires scope `proxies:read`.\n\n> **Status: Live.**","parameters":[{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/CursorParam"},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["ipv4","ipv6","isp","mobile","resident"]},"description":"Filter by proxy type."},{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"Country name or alpha-3."},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","expired","all"],"default":"active"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"},"description":"Match ip / note / tags."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Proxy"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET https://api.click-ip.com/v1/proxies?limit=50 \\\n  -H \"Authorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\""},{"lang":"javascript","label":"Node.js","source":"const res = await fetch('https://api.click-ip.com/v1/proxies?limit=50', {\n  method: 'GET',\n  headers: {\n      Authorization: 'Bearer ' + process.env.CLICKIP_API_KEY,\n  },\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nresp = requests.get(\n    \"https://api.click-ip.com/v1/proxies?limit=50\",\n    headers={\n    \"Authorization\": f\"Bearer {os.environ['CLICKIP_API_KEY']}\",\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.click-ip.com/v1/proxies?limit=50\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"CLICKIP_API_KEY\"))\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/proxies?limit=50');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Authorization: Bearer ' . getenv('CLICKIP_API_KEY'),\n  ],\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]},"post":{"tags":["Proxies"],"summary":"Buy proxies","operationId":"buyProxies","security":[{"bearerAuth":["proxies:write"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"Buy one or more proxies, debited from your prepaid balance. Some types provision **asynchronously** — the response returns `pending` order(s) you poll via `GET /orders/pending`. Send an `Idempotency-Key`. Requires scope `proxies:write`.\n\n**Never** send `userId`, `price`, `balance` or `status` — they are derived/ignored.\n\n> **Status: Live.** With a `ck_test_` (sandbox) key this returns representative mock data.\n\n---\n\nBuy any proxy type through **one endpoint** — `POST /v1/proxies` — with the proxy\n`type` as a field in the body. The generic flow is the same for every type:\n\n1. **Browse the catalog** (public, no key) to get the ids you need — `countryId`,\n   `periodId`, `operatorId`, or `tarifId` depending on the type.\n2. **Price it** with `POST /v1/catalog/calculate`.\n3. **Buy it** with `POST /v1/proxies` (debited from your prepaid balance; send an\n   `Idempotency-Key`).\n\nEach proxy type below shows the exact catalog calls and the exact request body.\n\n## IPv4\n\nDedicated datacenter **IPv4** proxies — a private, stable IP over HTTP(S) and SOCKS5. Best for account management, SEO tooling, retail/sneaker, and anything that needs one clean, consistent IP.\n\n| | |\n|---|---|\n| **Pricing** | from **$1.20 / proxy / month**. |\n| **Billing** | Per **proxy**, per rental period |\n| **Rotation** | — |\n| **Type value** | `\"ipv4\"` |\n\n#### 1 · Browse the catalog\n_Public — no API key required. Cache it; it changes rarely._\n\n- `GET /v1/catalog/countries/ipv4` — countries currently in stock.\n- `GET /v1/catalog/periods/ipv4` — rental periods and their `periodId`s.\n\n#### 2 · Price the order\nGet the exact total with `POST /v1/catalog/calculate` (never returns cost/margin):\n```json\n{\n  \"type\": \"ipv4\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 5\n}\n```\n\n#### 3 · Buy it\nPlace the order with `POST /v1/proxies` — debited from your prepaid balance. Send an `Idempotency-Key` so a retry never double-charges:\n```json\n{\n  \"type\": \"ipv4\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 5,\n  \"protocol\": \"http\"\n}\n```\n\nThen list what you own with `GET /v1/proxies?type=ipv4` and fetch one with `GET /v1/proxies/{id}`.\n\n## IPv6\n\nDatacenter **IPv6** proxies — an enormous address space at the lowest per-IP price. Best for high-volume scraping and testing against IPv6-ready targets.\n\n| | |\n|---|---|\n| **Pricing** | from **$0.15 / proxy / month** (minimum **10** per order). |\n| **Billing** | Per **proxy**, per rental period |\n| **Rotation** | — |\n| **Type value** | `\"ipv6\"` |\n\n#### 1 · Browse the catalog\n_Public — no API key required. Cache it; it changes rarely._\n\n- `GET /v1/catalog/countries/ipv6` — countries currently in stock.\n- `GET /v1/catalog/periods/ipv6` — rental periods and their `periodId`s.\n\n#### 2 · Price the order\nGet the exact total with `POST /v1/catalog/calculate` (never returns cost/margin):\n```json\n{\n  \"type\": \"ipv6\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 10\n}\n```\n\n#### 3 · Buy it\nPlace the order with `POST /v1/proxies` — debited from your prepaid balance. Send an `Idempotency-Key` so a retry never double-charges:\n```json\n{\n  \"type\": \"ipv6\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 10,\n  \"protocol\": \"http\"\n}\n```\n\nThen list what you own with `GET /v1/proxies?type=ipv6` and fetch one with `GET /v1/proxies/{id}`.\n\n> **Minimum order:** IPv6 is sold in batches of **10** (`quantity ≥ 10`).\n\n## ISP\n\n**ISP** (static residential) proxies — datacenter speed on IPs registered to real ISPs, so they read as residential. Best for long-lived sessions on strict targets that block plain datacenter ranges.\n\n| | |\n|---|---|\n| **Pricing** | from **$2.00 / proxy / month**. |\n| **Billing** | Per **proxy**, per rental period |\n| **Rotation** | — |\n| **Type value** | `\"isp\"` |\n\n#### 1 · Browse the catalog\n_Public — no API key required. Cache it; it changes rarely._\n\n- `GET /v1/catalog/countries/isp` — countries currently in stock.\n- `GET /v1/catalog/periods/isp` — rental periods and their `periodId`s.\n\n#### 2 · Price the order\nGet the exact total with `POST /v1/catalog/calculate` (never returns cost/margin):\n```json\n{\n  \"type\": \"isp\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 3\n}\n```\n\n#### 3 · Buy it\nPlace the order with `POST /v1/proxies` — debited from your prepaid balance. Send an `Idempotency-Key` so a retry never double-charges:\n```json\n{\n  \"type\": \"isp\",\n  \"countryId\": 840,\n  \"periodId\": 1,\n  \"quantity\": 3,\n  \"protocol\": \"http\"\n}\n```\n\nThen list what you own with `GET /v1/proxies?type=isp` and fetch one with `GET /v1/proxies/{id}`.\n\n## Mobile\n\n**Mobile** (4G/LTE) proxies on real carrier IPs — the hardest to detect and shared across thousands of real subscribers. Best for social-media automation, ad verification, and mobile-first targets.\n\n| | |\n|---|---|\n| **Pricing** | from **$45.00 / proxy / month**. |\n| **Billing** | Per **proxy**, per rental period |\n| **Rotation** | On demand — `POST /v1/proxies/{id}/rotate` |\n| **Type value** | `\"mobile\"` |\n\n#### 1 · Browse the catalog\n_Public — no API key required. Cache it; it changes rarely._\n\n- `GET /v1/catalog/countries/mobile` — countries with mobile coverage.\n- `GET /v1/catalog/operators/{countryId}/{serviceType}` — carriers for a country, e.g. `GET /v1/catalog/operators/616/shared` (Poland, shared). `serviceType` is `dedicated` or `shared`.\n- `GET /v1/catalog/periods/mobile` — rental periods and their `periodId`s.\n\n#### 2 · Price the order\nGet the exact total with `POST /v1/catalog/calculate` (never returns cost/margin):\n```json\n{\n  \"type\": \"mobile\",\n  \"countryId\": 616,\n  \"periodId\": 1,\n  \"quantity\": 1\n}\n```\n\n#### 3 · Buy it\nPlace the order with `POST /v1/proxies` — debited from your prepaid balance. Send an `Idempotency-Key` so a retry never double-charges:\n```json\n{\n  \"type\": \"mobile\",\n  \"countryId\": 616,\n  \"periodId\": 1,\n  \"quantity\": 1,\n  \"operatorId\": 3,\n  \"rotationId\": 0,\n  \"mobileServiceType\": \"shared\"\n}\n```\n\nThen list what you own with `GET /v1/proxies?type=mobile` and fetch one with `GET /v1/proxies/{id}`.\n\n> **Mobile requires** `operatorId` (from `GET /v1/catalog/operators/…`) and `mobileServiceType` (`dedicated` or `shared`). `rotationId` is the rotation mode (`0` = by-link only, or a minutes interval offered by the operator).\n> **Rotate on demand:** change the exit IP any time with `POST /v1/proxies/{id}/rotate`. For mobile this triggers a modem reboot and is rate-limited to once every 2 minutes per proxy (a `429 rate_limited` with `Retry-After` means you are inside the cooldown).\n\n## Residential\n\nRotating **residential** proxies billed from a prepaid **GB pool** — millions of real-user IPs with country / city / ASN targeting. Best for large-scale scraping where you pay for traffic, not for individual IPs.\n\n| | |\n|---|---|\n| **Pricing** | **$2.00 / GB**, drawn from your prepaid residential pool. |\n| **Billing** | Prepaid **GB pool** (pay for traffic) |\n| **Rotation** | On demand — `POST /v1/proxies/{id}/rotate` |\n| **Type value** | `\"resident\"` |\n\n#### 1 · Browse the catalog\n_Public — no API key required. Cache it; it changes rarely._\n\n- `GET /v1/catalog/tarifs/resident` — GB volume tiers (`tarifId`) and per-GB pricing.\n- `GET /v1/catalog/residential/geo` — the targeting tree: country → city → ASN.\n\n#### 2 · Price the order\nGet the exact total with `POST /v1/catalog/calculate` (never returns cost/margin):\n```json\n{\n  \"type\": \"resident\",\n  \"tarifId\": 4,\n  \"gb\": 10\n}\n```\n\n#### 3 · Buy it\nPlace the order with `POST /v1/proxies` — debited from your prepaid balance. Send an `Idempotency-Key` so a retry never double-charges:\n```json\n{\n  \"type\": \"resident\",\n  \"tarifId\": 4,\n  \"gb\": 10\n}\n```\n\nThen list what you own with `GET /v1/proxies?type=resident` and fetch one with `GET /v1/proxies/{id}`.\n\n> **GB pool, not per-IP:** a purchase tops up your shared residential balance rather than handing you fixed IPs. Carve targeted, rotating IP lists out of the pool with `POST /v1/residential/lists`, watch consumption with `GET /v1/residential/usage`, and rotate a list’s current IP with `POST /v1/proxies/{id}/rotate`. See the **Residential endpoints** section for the full pool/list API.","parameters":[{"$ref":"#/components/parameters/IdempotencyKeyHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyProxyRequest"},"examples":{"ipv4":{"summary":"IPv4, USA, 2 units","value":{"type":"ipv4","countryId":840,"periodId":1,"quantity":2}},"mobile":{"summary":"Mobile, Poland, shared operator","value":{"type":"mobile","countryId":616,"periodId":1,"quantity":1,"operatorId":3,"rotationId":0,"mobileServiceType":"shared"}},"resident":{"summary":"Residential, 10 GB","value":{"type":"resident","tarifId":4,"gb":10}}}}}},"responses":{"200":{"description":"Purchase settled (or queued if async).","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/BuyProxyResult"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientBalance"},"403":{"$ref":"#/components/responses/InsufficientScope"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST https://api.click-ip.com/v1/proxies \\\n  -H \"Authorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":2}'"},{"lang":"javascript","label":"Node.js","source":"import { randomUUID } from 'node:crypto';\n\nconst res = await fetch('https://api.click-ip.com/v1/proxies', {\n  method: 'POST',\n  headers: {\n      Authorization: 'Bearer ' + process.env.CLICKIP_API_KEY,\n      'Idempotency-Key': randomUUID(),\n      'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"type\": \"ipv4\",\n    \"countryId\": 840,\n    \"periodId\": 1,\n    \"quantity\": 2\n  }),\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nimport uuid\nresp = requests.post(\n    \"https://api.click-ip.com/v1/proxies\",\n    headers={\n    \"Authorization\": f\"Bearer {os.environ['CLICKIP_API_KEY']}\",\n    \"Idempotency-Key\": str(uuid.uuid4()),\n    },\n    json={\n      \"type\": \"ipv4\",\n      \"countryId\": 840,\n      \"periodId\": 1,\n      \"quantity\": 2\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/google/uuid\"\n)\nfunc main() {\n\tbody := []byte(`{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":2}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.click-ip.com/v1/proxies\", bytes.NewReader(body))\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"CLICKIP_API_KEY\"))\n\treq.Header.Set(\"Idempotency-Key\", uuid.NewString())\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/proxies');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Authorization: Bearer ' . getenv('CLICKIP_API_KEY'),\n    'Idempotency-Key: ' . bin2hex(random_bytes(16)),\n    'Content-Type: application/json',\n  ],\n  CURLOPT_POSTFIELDS => '{\"type\":\"ipv4\",\"countryId\":840,\"periodId\":1,\"quantity\":2}',\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]}},"/proxies/{id}":{"get":{"tags":["Proxies"],"summary":"Get a proxy","operationId":"getProxy","security":[{"bearerAuth":["proxies:read"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"A single proxy you own, with full connection details. Requires scope `proxies:read`.\n\n> **Status: Live.**","parameters":[{"$ref":"#/components/parameters/ProxyIdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Proxy"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Proxies"],"summary":"Update proxy metadata","operationId":"updateProxy","security":[{"bearerAuth":["proxies:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Set your own `note` and `tags` on a proxy. Requires scope `proxies:write`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"$ref":"#/components/parameters/ProxyIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","nullable":true,"example":"eu-residential"},"tags":{"type":"array","items":{"type":"string"},"example":["prod","eu"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Proxy"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/proxies/{id}/rotate":{"post":{"tags":["Proxies"],"summary":"Rotate / change IP","operationId":"rotateProxy","security":[{"bearerAuth":["proxies:write"]}],"x-badges":[{"name":"Live","position":"after"}],"description":"Rotate the proxy’s IP. For **mobile**, triggers a modem reboot (rate-limited to once per 2 minutes per proxy). Returns `429 rate_limited` with `Retry-After` if called within the cooldown. Non-mobile types return `400 validation_error`. Requires scope `proxies:write`. _(Residential list rotation ships with the residential endpoints.)_\n\n> **Status: Live.**","parameters":[{"$ref":"#/components/parameters/ProxyIdPath"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"integer","example":14226},"rotated":{"type":"boolean","example":true},"cooldown_seconds":{"type":"integer","example":120}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST https://api.click-ip.com/v1/proxies/14226/rotate \\\n  -H \"Authorization: Bearer ck_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\""},{"lang":"javascript","label":"Node.js","source":"const res = await fetch('https://api.click-ip.com/v1/proxies/14226/rotate', {\n  method: 'POST',\n  headers: {\n      Authorization: 'Bearer ' + process.env.CLICKIP_API_KEY,\n  },\n});\nconst payload = await res.json();\nif (!payload.success) throw new Error(payload.error.code + ': ' + payload.error.message);\nconsole.log(payload.data);"},{"lang":"python","label":"Python","source":"import os\nimport requests\nresp = requests.post(\n    \"https://api.click-ip.com/v1/proxies/14226/rotate\",\n    headers={\n    \"Authorization\": f\"Bearer {os.environ['CLICKIP_API_KEY']}\",\n    },\n)\npayload = resp.json()\nif not payload[\"success\"]:\n    raise RuntimeError(payload[\"error\"][\"code\"] + \": \" + payload[\"error\"][\"message\"])\nprint(payload[\"data\"])"},{"lang":"go","label":"Go","source":"package main\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\nfunc main() {\n\treq, _ := http.NewRequest(\"POST\", \"https://api.click-ip.com/v1/proxies/14226/rotate\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"CLICKIP_API_KEY\"))\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tos.Stdout.Write(out)\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init('https://api.click-ip.com/v1/proxies/14226/rotate');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => [\n    'Authorization: Bearer ' . getenv('CLICKIP_API_KEY'),\n  ],\n]);\n$payload = json_decode(curl_exec($ch), true);\nif (!$payload['success']) {\n  throw new RuntimeException($payload['error']['code'] . ': ' . $payload['error']['message']);\n}\nprint_r($payload['data']);"}]}},"/proxies/{id}/extend":{"post":{"tags":["Proxies"],"summary":"Extend a proxy","operationId":"extendProxy","security":[{"bearerAuth":["proxies:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Prolong a proxy for another period. Debits balance — send an `Idempotency-Key`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"$ref":"#/components/parameters/ProxyIdPath"},{"$ref":"#/components/parameters/IdempotencyKeyHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["periodId"],"properties":{"periodId":{"type":"integer","example":1}}},"example":{"periodId":1}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Proxy"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientBalance"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/IdempotencyConflict"}}}},"/proxies/{id}/auto-renew":{"post":{"tags":["Proxies"],"summary":"Toggle auto-renew","operationId":"setAutoRenew","security":[{"bearerAuth":["proxies:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Enable or disable automatic renewal for a proxy. Requires scope `proxies:write`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"$ref":"#/components/parameters/ProxyIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean","example":true},"periodId":{"type":"integer","example":1,"description":"Period to renew into (defaults to the current one)."}}},"example":{"enabled":true,"periodId":1}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Proxy"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/orders/pending":{"get":{"tags":["Proxies"],"summary":"List pending orders","operationId":"listPendingOrders","security":[{"bearerAuth":["proxies:read"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Orders still being provisioned. Poll this after an async purchase.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PendingOrder"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/residential/usage":{"get":{"tags":["Residential endpoints"],"summary":"Residential usage","operationId":"getResidentialUsage","security":[{"bearerAuth":["residential:read"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Your residential GB pool: limit, used and left, plus per-list usage. Served from daily snapshots; pass `?fresh=true` for a live read (heavily rate-limited). Scope `residential:read`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/ResidentialUsage"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/residential/lists":{"get":{"tags":["Residential endpoints"],"summary":"List residential IP lists","operationId":"listResidentialLists","security":[{"bearerAuth":["residential:read"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Your residential IP lists (login/password, geo, rotation). Scope `residential:read`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/ResidentialList"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}},"post":{"tags":["Residential endpoints"],"summary":"Create a residential IP list","operationId":"createResidentialList","security":[{"bearerAuth":["residential:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Create an IP list that draws from your GB pool. Scope `residential:write`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string","example":"eu-rotating"},"geo":{"type":"object","properties":{"country":{"type":"string","example":"DE"},"city":{"type":"string","example":"Berlin"},"asn":{"type":"string","nullable":true}}},"rotation":{"type":"string","enum":["per_request","sticky"],"example":"per_request"},"protocol":{"type":"string","enum":["http","socks5"],"example":"http"}}},"example":{"title":"eu-rotating","geo":{"country":"DE","city":"Berlin"},"rotation":"per_request","protocol":"http"}}}},"responses":{"201":{"description":"List created.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/ResidentialList"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/residential/lists/{id}":{"delete":{"tags":["Residential endpoints"],"summary":"Delete a residential IP list","operationId":"deleteResidentialList","security":[{"bearerAuth":["residential:write"]}],"x-badges":[{"name":"Planned","position":"after"}],"description":"Delete one of your residential IP lists. Scope `residential:write`.\n\n> **Status: Planned.** The contract below is stable, but this operation is not live yet. Follow the changelog or your dashboard for availability.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":991}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"integer","example":991},"deleted":{"type":"boolean","example":true}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"$ref":"#/components/responses/NotFound"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"ck_live_… (API key)","description":"Send your secret API key as a Bearer token: `Authorization: Bearer ck_live_…`. Create keys in the dashboard under **Settings → API keys**. Scopes are enforced (`403 insufficient_scope`). Available scopes: `account:read`, `balance:read`, `billing:write`, `proxies:read`, `proxies:write`, `residential:read`, `residential:write`, `teams:read`, `teams:write`."}},"parameters":{"LimitParam":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Page size (max 100)."},"CursorParam":{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from a previous response’s `meta.next_cursor`."},"IdempotencyKeyHeader":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Unique key (e.g. a UUID) that makes this money-spending request safe to retry. Reusing a key returns the original result; reusing it with a different payload returns `409 idempotency_conflict`. Remembered for 24 hours."},"ProxyTypePath":{"name":"type","in":"path","required":true,"schema":{"type":"string","enum":["ipv4","ipv6","isp","mobile","resident"]},"example":"ipv4"},"ProxyIdPath":{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":14226,"description":"ClickIP proxy id."}},"schemas":{"Meta":{"type":"object","description":"Pagination metadata. `next_cursor` is `null` on the last page.","properties":{"next_cursor":{"type":"string","nullable":true,"example":"90180"}}},"Error":{"type":"object","description":"The standard error envelope returned on any non-2xx response.","required":["success","error"],"properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["validation_error","unauthorized","insufficient_balance","forbidden","insufficient_scope","not_found","idempotency_conflict","rate_limited","service_unavailable","internal_error"]},"message":{"type":"string","example":"Your balance ($3.10) is lower than the order total ($8.00)."},"details":{"type":"object","additionalProperties":true,"nullable":true,"description":"Optional machine-readable context (offending fields, balances, request_id …)."}}}}},"Proxy":{"type":"object","description":"A worldwide proxy you own. Cost/margin and internal URLs are never exposed.","properties":{"id":{"type":"integer","example":14226},"type":{"type":"string","enum":["ipv4","ipv6","isp","mobile","resident"],"example":"mobile"},"country":{"type":"string","example":"Poland"},"country_alpha3":{"type":"string","example":"POL"},"ip":{"type":"string","example":"57.128.233.26"},"port_http":{"type":"integer","example":44411},"port_socks":{"type":"integer","example":54411},"login":{"type":"string","example":"u_7GQDBigI"},"password":{"type":"string","example":"0JE6I3rPK9"},"expires_at":{"type":"string","format":"date-time","example":"2026-09-04T23:59:59Z"},"status":{"type":"string","enum":["active","expired"],"example":"active"},"auto_renew":{"type":"boolean","example":false},"rotate_url":{"type":"string","nullable":true,"example":"https://api.click-ip.com/v1/proxies/14226/rotate","description":"Convenience URL for `POST .../rotate` (mobile / residential only; else `null`)."},"note":{"type":"string","nullable":true,"example":null},"tags":{"type":"array","items":{"type":"string"},"example":[]},"created_at":{"type":"string","format":"date-time","example":"2026-08-05T13:49:01Z"}}},"Account":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"14fa9d49-ed48-4129-ae79-7195b510d8bc"},"email":{"type":"string","format":"email","nullable":true,"example":"you@example.com"},"balance":{"type":"number","example":128.4},"currency":{"type":"string","example":"USD"},"referral_code":{"type":"string","nullable":true,"example":"IZY-4K2"},"referral_earnings":{"type":"number","example":12.5},"created_at":{"type":"string","format":"date-time","example":"2026-07-02T06:59:43Z"}}},"Balance":{"type":"object","properties":{"balance":{"type":"number","example":128.4},"referral_balance":{"type":"number","example":12.5},"currency":{"type":"string","example":"USD"}}},"Transaction":{"type":"object","properties":{"id":{"type":"integer","example":90211},"type":{"type":"string","example":"worldwide_proxy_purchase"},"amount":{"type":"number","description":"Signed amount (negative = debit).","example":-8},"balance_after":{"type":"number","example":128.4},"description":{"type":"string","example":"Mobile × 1 (Poland)"},"created_at":{"type":"string","format":"date-time","example":"2026-08-05T13:49:01Z"}}},"DepositInvoice":{"type":"object","properties":{"invoice_id":{"type":"string","example":"inv_9f3a2b1c"},"amount":{"type":"number","example":50},"currency":{"type":"string","example":"USDT"},"payment_url":{"type":"string","format":"uri","example":"https://pay.anymoney.io/inv_9f3a2b1c"},"status":{"type":"string","enum":["pending","completed","failed"],"example":"pending"},"expires_at":{"type":"string","format":"date-time","example":"2026-08-08T01:30:00Z"}}},"ResidentialUsage":{"type":"object","properties":{"traffic_limit_gb":{"type":"number","example":100},"traffic_used_gb":{"type":"number","example":16},"traffic_left_gb":{"type":"number","example":84},"lists":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","example":991},"login":{"type":"string","example":"res_ab12"},"used_gb":{"type":"number","example":4.2}}}}}},"ResidentialList":{"type":"object","properties":{"id":{"type":"integer","example":991},"title":{"type":"string","example":"eu-rotating"},"login":{"type":"string","example":"res_ab12"},"password":{"type":"string","example":"Zx8h2Kd0"},"geo":{"type":"object","properties":{"country":{"type":"string","example":"DE"},"city":{"type":"string","nullable":true,"example":"Berlin"},"asn":{"type":"string","nullable":true,"example":null}}},"rotation":{"type":"string","enum":["per_request","sticky"],"example":"per_request"},"protocol":{"type":"string","enum":["http","socks5"],"example":"http"},"used_gb":{"type":"number","example":4.2},"created_at":{"type":"string","format":"date-time","example":"2026-08-01T09:00:00Z"}}},"PendingOrder":{"type":"object","properties":{"order_id":{"type":"integer","example":5078487},"type":{"type":"string","example":"mobile"},"quantity":{"type":"integer","example":1},"status":{"type":"string","enum":["provisioning","failed"],"example":"provisioning"},"created_at":{"type":"string","format":"date-time","example":"2026-08-05T13:49:01Z"}}},"BuyProxyRequest":{"type":"object","required":["type"],"description":"Order payload. Type-specific fields apply per `type` (see below).","properties":{"type":{"type":"string","enum":["ipv4","ipv6","isp","mobile","resident"],"description":"Proxy type to buy."},"countryId":{"type":"integer","example":840,"description":"Numeric country id (from the catalog)."},"periodId":{"type":"integer","example":1,"description":"Rental period id (from the catalog)."},"quantity":{"type":"integer","minimum":1,"maximum":100,"example":2},"protocol":{"type":"string","enum":["http","socks5"],"description":"Preferred protocol, when applicable."},"operatorId":{"type":"integer","description":"Mobile carrier id (mobile only)."},"rotationId":{"type":"integer","description":"Rotation mode (mobile only)."},"mobileServiceType":{"type":"string","enum":["dedicated","shared"],"description":"Mobile service type (required for mobile)."},"tarifId":{"type":"integer","description":"GB tier id (resident)."},"gb":{"type":"number","description":"GB to buy (resident).","example":10},"promoCode":{"type":"string","nullable":true,"description":"Optional promo code."}}},"BuyProxyResult":{"type":"object","properties":{"proxies":{"type":"array","items":{"$ref":"#/components/schemas/Proxy"},"description":"Provisioned proxies (empty when the order is async)."},"pending":{"type":"array","items":{"$ref":"#/components/schemas/PendingOrder"},"description":"Orders still being provisioned (poll `GET /orders/pending`)."},"balance_after":{"type":"number","example":120.4}}},"CalculateRequest":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["ipv4","ipv6","isp","mobile","resident"]},"countryId":{"type":"integer","example":840},"periodId":{"type":"integer","example":1},"quantity":{"type":"integer","example":5},"tarifId":{"type":"integer"},"gb":{"type":"number"},"promoCode":{"type":"string","nullable":true}}},"CalculateResult":{"type":"object","properties":{"currency":{"type":"string","example":"USD"},"total":{"type":"number","example":6},"unit_price":{"type":"number","example":1.2},"quantity":{"type":"integer","example":5}}},"PricingItem":{"type":"object","properties":{"type":{"type":"string","example":"ipv4"},"label":{"type":"string","example":"IPv4"},"from_price":{"type":"number","example":1.2},"currency":{"type":"string","example":"USD"},"unit":{"type":"string","enum":["per_proxy","per_gb"],"example":"per_proxy"}}},"Country":{"type":"object","properties":{"id":{"type":"integer","example":840},"name":{"type":"string","example":"United States"},"alpha3":{"type":"string","example":"USA"},"available":{"type":"boolean","example":true}}},"Period":{"type":"object","properties":{"id":{"type":"integer","example":1},"label":{"type":"string","example":"30 days"},"days":{"type":"integer","example":30}}},"Tarif":{"type":"object","properties":{"id":{"type":"integer","example":4},"gb":{"type":"number","example":10},"price_per_gb":{"type":"number","example":0.45},"currency":{"type":"string","example":"USD"}}},"Operator":{"type":"object","properties":{"id":{"type":"integer","example":3},"name":{"type":"string","example":"Orange"},"available":{"type":"boolean","example":true}}},"GeoNode":{"type":"object","properties":{"country":{"type":"string","example":"DE"},"country_name":{"type":"string","example":"Germany"},"cities":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","example":"Berlin"},"asns":{"type":"array","items":{"type":"string"},"example":["AS3320"]}}}}}}},"responses":{"ValidationError":{"description":"`400` — malformed or invalid parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"validation_error","message":"quantity must be between 1 and 100.","details":{"field":"quantity"}}}}}},"Unauthorized":{"description":"`401` — missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"InsufficientBalance":{"description":"`402` — not enough balance to complete the purchase.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"insufficient_balance","message":"Your balance ($3.10) is lower than the order total ($8.00).","details":{"balance":3.1,"required":8}}}}}},"Forbidden":{"description":"`403` — authenticated but not allowed (e.g. not your resource).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"forbidden","message":"You do not have access to this resource."}}}}},"InsufficientScope":{"description":"`403` — the API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"insufficient_scope","message":"This key is missing the required scope: proxies:write."}}}}},"NotFound":{"description":"`404` — resource does not exist or isn’t yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"not_found","message":"Proxy not found."}}}}},"IdempotencyConflict":{"description":"`409` — the idempotency key was reused with a different payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"idempotency_conflict","message":"This Idempotency-Key was already used with a different request."}}}}},"RateLimited":{"description":"`429` — per-key rate limit hit. Honor `Retry-After`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"rate_limited","message":"Rate limit exceeded. Retry after 30s.","details":{"retry_after":30}}}}}},"ServiceUnavailable":{"description":"`503` — the service is temporarily busy/unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"service_unavailable","message":"The service is temporarily busy. Retry shortly."}}}}},"InternalError":{"description":"`500` — unexpected server error (`request_id` in `details`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"internal_error","message":"Something went wrong.","details":{"request_id":"req_a1b2c3"}}}}}}}}}