{"openapi":"3.0.3","info":{"title":"FlashProxy Reseller API","version":"2.1.0","description":"# FlashProxy Reseller API - Complete Documentation\n\nThis is the complete API documentation for the FlashProxy Reseller API. Use this specification to build proxy reselling platforms, automate proxy management, or integrate FlashProxy services into your applications.\n\n## Base URL\n- **Production**: `https://rapi.flashproxy.com/api/v1`\n- **Development**: `http://localhost:3000/api/v1`\n- **Sandbox**: `https://rapi.flashproxy.com/sandbox/api/v1`\n\n## Authentication\nAll API requests require authentication via Bearer token. Include your API key in the `Authorization` header:\n```\nAuthorization: Bearer fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nAPI keys start with `fp_live_` for production or `fp_test_` for sandbox mode.\n\n### Optional HMAC Signature\nFor enhanced security, you can enable HMAC request signing:\n- `X-Signature`: HMAC-SHA256 signature of the request body\n- `X-Timestamp`: Unix timestamp of the request (must be within 5 minutes)\n\n## Rate Limiting\n- Default: 100 requests per minute per API key\n- Burst: Up to 20 concurrent requests\n- Rate limit headers are included in responses\n\n## Idempotency Keys\n\nFor critical operations that modify data (creating plans, extending, upgrading),\nyou can use idempotency keys to safely retry requests without risking duplicate charges.\n\n### How It Works\n1. Generate a unique key (UUID recommended) for each distinct operation\n2. Include it in the `X-Idempotency-Key` header\n3. If you retry with the same key within 24 hours, you'll get the cached response\n\n### Example\n```bash\ncurl -X POST \"https://rapi.flashproxy.com/api/v1/plans\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_API_KEY\" \\\n  -H \"X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000\" \\\n  -d '{\"product\": \"residential-lite\", \"bandwidth_gb\": 10}'\n```\n\n### Supported Endpoints\n| Endpoint | Method |\n|----------|--------|\n| `/plans` | POST |\n| `/plans/{id}/extend` | POST |\n| `/plans/{id}/upgrade` | POST |\n\n### Key Requirements\n- 8-64 characters long\n- Alphanumeric, hyphens, and underscores only\n- Must be unique per distinct operation\n\n### Error Response\nIf you reuse a key with a different request body:\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"IDEMPOTENCY_KEY_CONFLICT\",\n    \"message\": \"This idempotency key was already used with different request parameters.\"\n  }\n}\n```\n\n---\n\n## Error Handling\nAll errors follow a consistent format:\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ERROR_CODE\",\n    \"message\": \"Human readable message\",\n    \"details\": {} // Optional additional context\n  }\n}\n```\n\n### Common Error Codes\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `VALIDATION_ERROR` | 400 | Invalid request parameters |\n| `UNAUTHORIZED` | 401 | Invalid or missing API key |\n| `INSUFFICIENT_BALANCE` | 402 | Not enough balance for operation |\n| `FORBIDDEN` | 403 | Account suspended or lacking permission |\n| `NOT_FOUND` | 404 | Resource not found |\n| `OUT_OF_STOCK` | 409 | Product out of stock |\n| `RATE_LIMITED` | 429 | Too many requests |\n| `INTERNAL_ERROR` | 500 | Server error |\n| `IDEMPOTENCY_KEY_CONFLICT` | 409 | Idempotency key reused with different payload |\n| `ACCOUNT_NOT_ACTIVE` | 403 | Reseller account is pending or suspended |\n| `ALREADY_CANCELLED` | 400 | Plan was already cancelled |\n| `PLAN_NOT_ACTIVE` | 400 | Cannot extend/upgrade inactive plan |\n| `NO_PROVIDER_ID` | 400 | Plan missing provider reference |\n| `IP_NOT_FOUND` | 404 | Server still provisioning |\n| `SERVER_NOT_FOUND` | 404 | Server not in provider system |\n| `UPDATE_FAILED` | 400 | Password or plan update failed |\n| `UPGRADE_FAILED` | 400 | Plan upgrade failed |\n\n---\n\n## Products Overview\n\nFlashProxy offers 15 proxy product types:\n\n| Product | Billing | Use Case |\n|---------|---------|----------|\n| `residential-lite` | Per GB | High-volume scraping, basic tasks |\n| `residential` | Per GB | Premium scraping, ad verification |\n| `mobile` | Per GB | Mobile-specific targets, social media |\n| `mobile_usa` | Per GB | Mobile USA-only proxies (no geo targeting) |\n| `datacenter` | Per GB or Time | High-speed tasks, non-geo-sensitive |\n| `shared_isp` | Per GB or Time | ISP-grade IPs, streaming |\n| `isp_eu` | Per GB or Time | European ISP IPs (Netherlands now, more coming soon) |\n| `ipv6-residential` | Per GB or Time | IPv6-specific targets |\n| `ipv6-datacenter` | Per GB or Time | IPv6 datacenter tasks |\n| `pool1` | Per GB | Residential Pool 1 |\n| `pool2` | Per GB | Residential Pool 2 |\n| `pool3` | Per GB | Residential Pool 3 |\n| `pool4` | Per GB | Residential Pool 4 |\n| `pool5` | Per GB | Residential Pool 5 |\n| `unlimited_residential` | Per Time | Unlimited bandwidth residential proxies |\n\n> **Product Type Format:** Product types use hyphenated format (e.g., `residential-lite`,\n> `ipv6-residential`, `ipv6-datacenter`). The API also accepts underscore format\n> (`residential_lite`) for backwards compatibility, but hyphenated format is recommended.\n\n---\n\n## Complete Proxy Connection Reference\n\n| Product | Hostname | HTTP Port | SOCKS5 Port |\n|---------|----------|-----------|-------------|\n| Residential | `geo.proxyserver.bot` | 8080 | 1080 |\n| Residential Lite | `lite.proxyserver.bot` | 6969 | 9696 |\n| Datacenter | `v3-dc.proxyserver.bot` | 777 | 666 |\n| Mobile | `geo.proxyserver.bot` | 8080 | 1080 |\n| Mobile USA | `v3-resi-us.proxyserver.bot` | 10000 | 11000 |\n| Shared ISP | `v3-isp.proxyserver.bot` | 30 | 31 |\n| Shared ISP EU | `eu-isp.proxyserver.bot` | 30 | 31 |\n| IPv6 Residential | `v3-v6-resi.proxyserver.bot` | 30 | 31 |\n| IPv6 Datacenter | `v3-v6-dc.proxyserver.bot` | 50 | 51 |\n| Residential Pool 1–5 | `v3-resi-us.proxyserver.bot` | 10000–10009 | 11000–11009 |\n| Dedicated ISP | *(varies per IP)* | - | - |\n| Unlimited Residential | `unlim.proxyserver.bot` | 10507 | 10507 |\n\n### Connection Format Examples\n\n**Residential / Mobile:**\n```\nUSERNAME:PASSWORD@geo.proxyserver.bot:8080\n```\n\n**Residential Lite:**\n```\nUSERNAME:PASSWORD@lite.proxyserver.bot:6969\n```\n\n**Datacenter:**\n```\nUSERNAME:PASSWORD@v3-dc.proxyserver.bot:777\n```\n\n**Shared ISP:**\n```\nUSERNAME:PASSWORD@v3-isp.proxyserver.bot:30\n```\n\n**Shared ISP EU:**\n```\nUSERNAME:PASSWORD@eu-isp.proxyserver.bot:30\n```\n\n**IPv6 Residential:**\n```\nUSERNAME:PASSWORD@v3-v6-resi.proxyserver.bot:30\n```\n\n**IPv6 Datacenter:**\n```\nUSERNAME:PASSWORD@v3-v6-dc.proxyserver.bot:50\n```\n\n**Residential Pool 1–5:**\n```\nUSERNAME:PASSWORD@v3-resi-us.proxyserver.bot:10000\n```\nMultiple ports (10000–10009 HTTP, 11000–11009 SOCKS5) are available for load distribution — all are identical.\n\n### Residential Pool Targeting\n\nEach pool has different geo-targeting options. Targeting is appended directly to the username using `-key-value` pairs.\n\n**Pool username format:**\n```\n{username}-country-{CC}-state-{STATE}-city-{CITY}-session-{ID}-time-{DURATION}\n```\n\n#### Per-Pool Targeting Features\n\n| Feature | Pool 1 | Pool 2 | Pool 3 | Pool 4 | Pool 5 |\n|---------|:------:|:------:|:------:|:------:|:------:|\n| Country | Yes | Yes | Yes | Yes | Yes |\n| State | US (full name) | Full name | `us_` prefix | 2-letter | US (full name) |\n| City | US (needs state) | Yes | Yes | Yes | Non-US direct; US needs state |\n| ASN | Yes | No | Yes | Yes | No |\n| ZIP | No | No | US only | No | No |\n| Session | Yes | Yes | Yes | Yes | Yes |\n| Max session | 24h (long) | 7 days | 24h | ~10 min | 2h |\n\n#### Pool 1 Session Behavior\n\nPool 1 uses `-time-short` or `-time-long` instead of seconds:\n- **`-time-short`**: Random device from the **entire pool** — good for IP diversity, session may not last long\n- **`-time-long`**: Selects a **reliable device** optimized for stable sticky sessions up to 24 hours\n- Default (no `-time-`): short behavior\n\n```\nuser-country-us-session-abc123-time-short   # random device\nuser-country-us-session-abc123-time-long    # reliable device, up to 24h\n```\n\n#### Pools 2, 3, 5 Session Duration\n\nUse `-time-<seconds>` to set session duration. Default is 1 hour if omitted.\n```\nuser-country-us-session-abc123-time-600     # 10 minutes\nuser-country-us-session-abc123-time-1800    # 30 minutes\n```\n\n#### Pool 4 Sessions\n\nPool 4 sessions last approximately 10 minutes. No duration control available.\n\n#### Pool Examples\n\n| Pool | Example Username |\n|------|-----------------|\n| Pool 1 (US, long session) | `user-country-us-session-abc-time-long` |\n| Pool 2 (DE, Berlin) | `user-country-de-city-berlin` |\n| Pool 3 (US, ZIP) | `user-country-us-zip-10001` |\n| Pool 4 (US, state CA) | `user-country-us-state-ca` |\n| Pool 5 (GB, London) | `user-country-gb-city-london` |\n\n---\n\n## Geo Targeting\n\nFor rotating proxies (residential, mobile, datacenter), use username parameters:\n\n### Username Format\n```\n{base_username}-country-{CC}-state-{STATE}-city-{CITY}-session-{SESSION}\n```\n\n### Examples\n| Target | Username | Notes |\n|--------|----------|-------|\n| United States | `user123-country-us` | All products |\n| California, US | `user123-country-us-state-california` | Full state name (residential, mobile). Pool 4 uses 2-letter: `-state-ca`. Pool 3 uses `us_` prefix: `-state-us_california` |\n| Los Angeles | `user123-country-us-state-california-city-losangeles` | State format varies by pool (see pool docs) |\n| Sticky session | `user123-country-us-session-abc123` | All products |\n\n> **Important:** State format varies by product pool. The examples above use full state names which work for residential, mobile, and pools 1/2/5. Pool 3 requires `us_` prefix (`-state-us_california`), and Pool 4 requires 2-letter abbreviations (`-state-ca`). See per-pool targeting docs above.\n\n---\n\n## Quickstart Guide\n\n### Step 1: Check Your Balance\n```bash\ncurl -X GET https://rapi.flashproxy.com/api/v1/balance \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n### Step 2: Create a Plan\n```bash\ncurl -X POST https://rapi.flashproxy.com/api/v1/plans \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"product\": \"residential-lite\", \"bandwidth_gb\": 10}'\n```\n\n### Step 3: Use Your Proxy\n```bash\ncurl -x http://USERNAME:PASSWORD@lite.proxyserver.bot:6969 https://api.ipify.org\n```\n\n---\n\n## SDK Support\n\nOfficial SDKs coming soon. For now, use standard HTTP libraries:\n- **Python**: `requests`, `httpx`\n- **JavaScript**: `fetch`, `axios`\n- **PHP**: `curl`, `Guzzle`\n- **Go**: `net/http`\n","contact":{"name":"FlashProxy Support","email":"support@flashproxy.io","url":"https://flashproxy.io"},"license":{"name":"Proprietary","url":"https://flashproxy.io/terms"}},"servers":[{"url":"https://rapi.flashproxy.com/api/v1","description":"Production Server"},{"url":"http://localhost:3000/api/v1","description":"Development Server"},{"url":"https://rapi.flashproxy.com/sandbox/api/v1","description":"Sandbox Server (for testing)"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Balance","description":"Manage your account balance, view transactions, and initiate top-ups.\n\n**Key Concepts:**\n- Balance is stored in cents (1 dollar = 100 cents)\n- Allocations are pre-paid bandwidth pools for specific products\n- Transactions include purchases, top-ups, and refunds\n"},{"name":"Plans","description":"Create, manage, and extend proxy plans.\n\n**Key Concepts:**\n- Plans have either bandwidth billing (pay per GB) or time billing (pay per day)\n- Each plan gets unique proxy credentials\n- Plans can be extended but not modified after creation\n"},{"name":"Dedicated ISP","description":"## Static ISP Proxy IPs\n\nDedicated ISP provides **static, exclusive ISP IP addresses** assigned to you for 30-day periods.\nUnlike rotating proxies, these IPs remain constant and are exclusively yours.\n\n---\n\n### Quick Start\n\n**Step 1: Check Available Pools**\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/proxies/pools\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n**Step 2: Create a Plan**\n```bash\ncurl -X POST \"https://rapi.flashproxy.com/api/v1/plans\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"product\": \"dedicated_isp\", \"quantity\": 5, \"pool\": \"ISP_US_SNEAKERS\"}'\n```\n\n**Step 3: Use Your Proxies**\nThe response includes a `proxy_list` array with your static IPs.\nEach proxy format: `host:port:username:password`\n\n---\n\n### Pool Types\n\nPools are organized by **type**, **country**, and **use case**:\n\n| Pool Name | Country | Use Case |\n|-----------|---------|----------|\n| `ISP_US_SNEAKERS` | USA | Sneaker sites |\n| `ISP_US_TICKETS` | USA | Ticketing |\n| `ISP_UK_SNEAKERS` | UK | Sneaker sites |\n| `ISP_DE_RETAILPLUS` | Germany | Retail |\n| `SN_US_SNEAKERS` | USA | Sneaker (subnet) |\n\n**Naming Convention:** `{TYPE}_{COUNTRY}_{USE_CASE}`\n- `ISP_` = Standard ISP proxies\n- `SN_` = Subnet proxies (/24 blocks)\n\n---\n\n### Pricing\n\nBilled **per IP, per 30-day period**. Check your pricing at `GET /balance/pricing`.\n\n---\n\n### Key Endpoints\n\n| Endpoint | Purpose |\n|----------|---------|\n| `GET /proxies/pools` | List available pools and stock |\n| `POST /plans` | Purchase dedicated ISP proxies |\n| `GET /plans/{id}/proxies` | Get your proxy list |\n| `POST /plans/{id}/extend` | Extend by 30 days |\n"},{"name":"Stock","description":"Check product availability before purchasing.\n\n**Important:** Always check stock for dedicated products (unlimited_residential trial) before purchasing.\n"},{"name":"Servers","description":"Server management for dedicated products.\n\n**Applies to:**\n- `unlimited_residential`: Get server IP, restart, view stats\n"},{"name":"Geo","description":"Get available geo-targeting options.\n\n**Products supporting geo:**\n- All rotating products (residential, mobile, datacenter, etc.)\n- Not applicable to dedicated products\n"},{"name":"Usage","description":"Track bandwidth usage across plans.\n\n**Key Metrics:**\n- `bytes_used`: Total bytes consumed\n- `bytes_remaining`: Available bandwidth (for bandwidth plans)\n- `usage_percent`: Percentage of allocation used\n"},{"name":"Plan Metrics","description":"Per-plan ClickHouse-backed monitoring metrics — throughput, latency,\nerrors, status codes, top destinations, hourly bandwidth, and sampled\nerror messages — over a window of up to 168 hours (7 days).\n\n**Supported products:** `datacenter`, `shared_isp`, `isp_eu`, `ipv6_residential`,\n`ipv6_datacenter`. Other products return `400 METRICS_NOT_SUPPORTED`.\n\n**Endpoints:**\n\n| Endpoint | Purpose |\n|----------|---------|\n| `GET /plans/{planId}/metrics/summary` | Aggregate totals (bytes, connections, success rate, peak Mbps) |\n| `GET /plans/{planId}/metrics/throughput` | Mbps time series with plan rate cap |\n| `GET /plans/{planId}/metrics/latency` | Connection-duration p50/p95/p99 |\n| `GET /plans/{planId}/metrics/errors` | Per-bucket error counts by typed category |\n| `GET /plans/{planId}/metrics/status-codes` | Upstream HTTP 2xx/3xx/4xx/5xx counts (plain HTTP only) |\n| `GET /plans/{planId}/metrics/destinations` | Top destinations by traffic |\n| `GET /plans/{planId}/metrics/hourly-usage` | GB per hour |\n| `GET /plans/{planId}/metrics/error-messages` | Aggregated recent error messages |\n\nAll endpoints accept `hours` (1–168, default 24) and are cached\nserver-side for 60 seconds. See [PLAN_METRICS.md](./PLAN_METRICS.md)\nfor response shapes and example payloads.\n"},{"name":"Proxies","description":"Additional proxy utilities and configuration.\n\n**Note:** For Dedicated ISP pools and proxy lists, see the **Dedicated ISP** section.\n"},{"name":"Investigations","description":"AI-powered proxy diagnostics. Submit a customer complaint and get an automated\ninvestigation that queries real-time monitoring data and returns a structured diagnosis.\n\n**Cost:** $0.50 per investigation, deducted from your balance. Refunded automatically on failure.\n\n**Supported products:** Datacenter (IPv4/IPv6), Shared ISP, Shared ISP EU, IPv6 Residential.\n\n**Rate limit:** 10 investigations per hour.\n\n**Flow:** POST to start -> poll GET every 10-15s -> receive diagnosis when complete (typically 60-180s).\n"},{"name":"Sub-Users","description":"Create and manage sub-users for your reseller account.\n\nSub-users can have their own proxy plans and credentials but operate under your account balance.\n"}],"paths":{"/balance":{"get":{"operationId":"getBalance","tags":["Balance"],"summary":"Get current balance","description":"Returns your account's current balance, any pre-paid bandwidth allocations, and total spending statistics.\n\n**Use this to:**\n- Check if you have sufficient funds before creating plans\n- Monitor your spending\n- View pre-paid allocations\n","responses":{"200":{"description":"Balance retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"},"examples":{"with_balance":{"summary":"Account with balance","value":{"success":true,"data":{"balance_cents":500000,"balance_formatted":"$5,000.00","allocations":{"residential-lite":{"gb_remaining":50,"bytes_remaining":50000000000}},"total_spent_cents":150000,"total_spent_formatted":"$1,500.00"}}},"new_account":{"summary":"New account (no balance)","value":{"success":true,"data":{"balance_cents":0,"balance_formatted":"$0.00","allocations":{},"total_spent_cents":0,"total_spent_formatted":"$0.00"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/balance/transactions":{"get":{"operationId":"getTransactions","tags":["Balance"],"summary":"Get transaction history","description":"Returns paginated list of all balance transactions including:\n- Top-ups (credit card, crypto)\n- Plan purchases\n- Plan extensions\n- Refunds\n- Manual adjustments\n","parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1},"description":"Page number for pagination"},{"name":"per_page","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Number of items per page (max 100)"},{"name":"type","in":"query","schema":{"type":"string","enum":["topup","purchase","extend","refund","adjustment","all"],"default":"all"},"description":"Filter by transaction type"}],"responses":{"200":{"description":"Transactions retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionsResponse"},"example":{"success":true,"data":{"items":[{"id":"txn_abc123","type":"topup","amount_cents":100000,"amount_formatted":"$1,000.00","description":"Paddle top-up","balance_after_cents":500000,"created_at":"2025-01-15T10:30:00.000Z"},{"id":"txn_def456","type":"purchase","amount_cents":-5000,"amount_formatted":"-$50.00","description":"residential-lite - 10GB","plan_id":"plan_xyz789","balance_after_cents":495000,"created_at":"2025-01-15T11:00:00.000Z"}],"pagination":{"page":1,"per_page":20,"total":2,"total_pages":1}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/balance/pricing":{"get":{"operationId":"getPricing","tags":["Balance"],"summary":"Get your pricing","description":"Returns the pricing configured for your reseller account.\n\n**Pricing can be:**\n- Per GB (for bandwidth products)\n- Per day (for time products)\n- Fixed price (for specific products)\n\nPricing may vary based on your reseller tier and negotiated rates.\n","responses":{"200":{"description":"Pricing retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"},"example":{"success":true,"data":{"residential-lite":{"billing":"bandwidth","price_per_gb":50,"price_per_gb_formatted":"$0.50"},"residential":{"billing":"bandwidth","price_per_gb":300,"price_per_gb_formatted":"$3.00"},"mobile":{"billing":"bandwidth","price_per_gb":500,"price_per_gb_formatted":"$5.00"},"datacenter":{"billing":"hybrid","price_per_gb":100,"price_per_gb_formatted":"$1.00","price_per_day_cents":200,"price_per_day_formatted":"$2.00"},"unlimited_residential":{"billing":"time","trial_price_cents":2000,"trial_price_formatted":"$20.00","pricing_tiers":[{"bandwidth_mbps":500,"price_per_day_cents":15000}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/balance/topup/crypto":{"post":{"operationId":"createCryptoTopup","tags":["Balance"],"summary":"Get a crypto deposit address","description":"Returns a **permanent** crypto deposit `address` for the requesting reseller, scoped to\nthe chosen `currency` + `network`, plus a `tracking_id` you can poll on\n`GET /balance/verify-payment/{tracking_id}`.\n\n**How it works:**\n1. You send the USD amount and the cryptocurrency + network you want to receive in.\n2. We return a deposit `address`, an FX-derived `amount_crypto` (guideline only), and a `tracking_id`.\n3. Your end user sends crypto to that address — any amount, any number of times.\n4. Each inbound payment automatically credits the reseller's balance once confirmed on-chain. No extra call required.\n\n**Supported coin / network codes** (uppercase):\n- `USDT` on `TRON`, `ETHEREUM`, `POLYGON`, `BSC`\n- `USDC` on `TRON`, `ETHEREUM`, `POLYGON`, `BSC`\n- `BTC` on `BITCOIN`\n- `ETH` on `ETHEREUM`\n- `LTC` on `LITECOIN`\n- `TRX` on `TRON`\n- `BNB` on `BSC`\n- `TON` on `TON`\n\nSending on a different network than the one shown will lose the funds.\n\n**Important behavioural notes:**\n- The deposit `address` is **permanent and reused** for the same reseller + coin/network on every call. Calling this endpoint twice with the same `currency`/`network` returns the same address and the same `tracking_id`.\n- `tracking_id` is the wallet ID — stable per coin/network, **not** per request.\n- `amount_crypto` is a **guideline** based on the current FX rate. The user can pay any amount; the actual credit equals the fiat value Thedex reports for the inbound payment.\n- `expires_at` is `null` — static deposit addresses do not expire.\n- `pay_url` is `null` — no hosted payment page in this flow; show the address yourself.\n- Minimum top-up amount: $5.00 (informational; the address itself accepts any amount).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CryptoTopupRequest"},"examples":{"usdt_tron":{"summary":"USDT on Tron","value":{"amount_cents":5000,"currency":"USDT","network":"TRON"}},"btc":{"summary":"Native BTC","value":{"amount_cents":25000,"currency":"BTC","network":"BITCOIN"}}}}}},"responses":{"200":{"description":"Deposit address returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CryptoTopupResponse"},"example":{"success":true,"data":{"tracking_id":"WAL_abc123def456","address":"TXyz9ABCdefGHIjklMNOpqrsTUVwxYZ","amount_crypto":"50.12345678","currency":"USDT","network":"TRON","amount_usd_cents":5000,"fiat_currency":"USD"}}}}},"400":{"description":"Validation error or amount below minimum","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"description":"Failed to provision the deposit address (e.g. unsupported currency/network combination)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/balance/verify-payment/{tracking_id}":{"get":{"operationId":"verifyPayment","tags":["Balance"],"summary":"Verify a top-up payment","description":"Poll the status of a top-up created via `POST /balance/topup/crypto`.\n\nFor crypto top-ups, `tracking_id` is the wallet ID. The endpoint returns the\n**most recent** payment that landed on that wallet (or a `pending` placeholder\nwith the wallet's address if no payment has landed yet).\n\n**Status values:**\n- `pending` — no payment has landed for this tracking ID yet.\n- `completed` — payment confirmed, balance credited.\n- `expired` — only applicable to legacy hosted-page invoices.\n- `failed` — payment cancelled or rejected by the processor.\n\nWebhooks are the source of truth — this endpoint exists as a backup\npolling channel.\n","parameters":[{"name":"tracking_id","in":"path","required":true,"schema":{"type":"string"},"description":"The `tracking_id` returned from `POST /balance/topup/crypto`."}],"responses":{"200":{"description":"Payment status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPaymentResponse"},"examples":{"pending":{"summary":"No payment yet","value":{"transaction_id":"WAL_abc123def456","status":"pending","amount_cents":0,"currency":"USD","address":"TXyz9ABCdefGHIjklMNOpqrsTUVwxYZ","pay_currency":"USDT_TRON"}},"completed":{"summary":"Latest payment to this wallet","value":{"transaction_id":"WAL_abc123def456","status":"completed","amount_cents":5000,"currency":"USD","completed_at":"2026-04-24T12:30:12.000Z"}}}}}},"400":{"description":"Invalid tracking ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Tracking ID not found for this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/plans/check-price":{"post":{"operationId":"checkPlanPrice","tags":["Plans"],"summary":"Check the price of a plan","description":"Calculate the cost of a plan without creating it. Accepts the **exact same request body** as `POST /plans`.\n\nUse this to display pricing to your end users before they commit to a purchase.\n\n**Response includes:**\n- `cost_cents` — total cost in cents\n- `cost_usd` — total cost formatted as USD string\n- `mode` — billing mode used (`price`, `allocation`, `price_only`)\n- For allocation mode: `gb_required` and `allocation_available`\n- For unlimited residential trials: `trial_info` with tiered pricing details\n- For coupon previews: a `coupon` object (see below)\n\n**Coupons (preview only):** Supply an optional `coupon_code` to preview a discount — it is never reserved or redeemed here. When present, `data.coupon` reflects the outcome: `{ applied: true, code, discount_cents, final_cost_cents, final_cost_usd }` when the coupon applies, or `{ applied: false, code, reason }` (reason `coupon_not_applicable` or `coupon_requires_price_mode`) when it does not. `cost_cents` stays UNDISCOUNTED; the discounted total is `coupon.final_cost_cents`.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlanRequest"},"examples":{"residential-lite":{"summary":"Check price for 10GB Residential Lite","value":{"product":"residential-lite","bandwidth_gb":10}},"datacenter_time":{"summary":"Check price for Datacenter 100Mbps, 7 days","value":{"product":"datacenter","billing_type":"time","duration":"7_days","mbps":100}},"unlimited_residential":{"summary":"Check price for Unlimited Residential 500Mbps, 30 days","value":{"product":"unlimited_residential","duration":"30_days","bandwidth_mbps":500}},"pool1":{"summary":"Check price for 5GB Pool 1","value":{"product":"pool1","bandwidth_gb":5}},"dedicated_isp":{"summary":"Check price for 5 Dedicated ISP IPs","value":{"product":"dedicated_isp","quantity":5,"pool":"ISP_US_SNEAKERS"}}}}}},"responses":{"200":{"description":"Price calculated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"cost_cents":{"type":"integer","description":"Total cost in cents","example":500},"cost_usd":{"type":"string","description":"Total cost formatted as USD","example":"5.00"},"mode":{"type":"string","enum":["price","allocation","price_only"],"description":"Billing mode used for this calculation","example":"price"},"gb_required":{"type":"number","description":"GB required (allocation mode only)"},"allocation_available":{"type":"number","description":"GB available in allocation pool (allocation mode only)"},"trial_info":{"type":"object","description":"Trial pricing details (unlimited residential trials only)","properties":{"trials_used_today":{"type":"integer"},"discounted_trials_remaining":{"type":"integer"},"price_applied":{"type":"string","enum":["discounted","full"]},"discounted_price_cents":{"type":"integer"},"full_price_cents":{"type":"integer"},"daily_discount_limit":{"type":"integer"}}},"coupon":{"type":"object","description":"Present only when `coupon_code` was supplied in the request. `data.cost_cents` is always the UNDISCOUNTED total; the discounted total is `coupon.final_cost_cents`. Two shapes: applied (`applied: true`) carries the discount; not-applied (`applied: false`) carries a `reason` (`coupon_not_applicable` or `coupon_requires_price_mode`).","properties":{"applied":{"type":"boolean","description":"Whether the coupon was applied to this quote"},"code":{"type":"string","description":"The coupon code that was evaluated"},"discount_cents":{"type":"integer","description":"Discount amount in cents (applied only)"},"final_cost_cents":{"type":"integer","description":"Discounted total in cents (applied only)"},"final_cost_usd":{"type":"string","description":"Discounted total formatted as USD (applied only)"},"reason":{"type":"string","enum":["coupon_not_applicable","coupon_requires_price_mode"],"description":"Why the coupon was not applied (not-applied only)"}}}}}}},"examples":{"price_mode":{"summary":"Price mode result","value":{"success":true,"data":{"cost_cents":500,"cost_usd":"5.00","mode":"price"}}},"allocation_mode":{"summary":"Allocation mode result","value":{"success":true,"data":{"cost_cents":0,"cost_usd":"0.00","mode":"allocation","gb_required":10,"allocation_available":95.5}}},"trial":{"summary":"Unlimited residential trial","value":{"success":true,"data":{"cost_cents":50,"cost_usd":"0.50","mode":"price_only","trial_info":{"trials_used_today":3,"discounted_trials_remaining":7,"price_applied":"discounted","discounted_price_cents":50,"full_price_cents":150,"daily_discount_limit":10}}}}}}}},"400":{"description":"Validation or pricing error","content":{"application/json":{"example":{"success":false,"error":{"code":"PRICING_ERROR","message":"Unable to calculate price"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/plans":{"get":{"operationId":"listPlans","tags":["Plans"],"summary":"List all plans","description":"Returns a paginated list of all your proxy plans.\n\n**Filter options:**\n- By status: active, expired, cancelled\n- By product type: residential-lite, residential, etc.\n\n**Sorting:** Use `sort` and `order` parameters to control sorting.\nDefault: sorted by `created_at` descending (newest first).\n\n**Search:** Use the `search` parameter to search across plan_id, proxy_username, and end_user_reference fields.\nSearch is case-insensitive and matches partial strings.\n","parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1},"description":"Page number"},{"name":"per_page","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Items per page (max 100)"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","expired","cancelled","all"],"default":"all"},"description":"Filter by plan status"},{"name":"product","in":"query","schema":{"type":"string","enum":["residential-lite","residential","mobile","mobile_usa","datacenter","shared_isp","isp_eu","ipv6-residential","ipv6-datacenter","pool1","pool2","pool3","pool4","pool5","unlimited_residential","dedicated_isp"]},"description":"Filter by product type"},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","expires_at","updated_at"],"default":"created_at"},"description":"Field to sort by"},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Sort order (ascending or descending)"},{"name":"search","in":"query","schema":{"type":"string","maxLength":100},"description":"Search term to filter plans by plan_id, proxy_username, or end_user_reference (case-insensitive, partial match)"}],"responses":{"200":{"description":"Plans retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansListResponse"},"example":{"success":true,"data":{"items":[{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","product":"residential-lite","billing_type":"bandwidth","proxy_username":"xaGBMTIV","proxy_password":"HoLJlh55","connection":{"hostname":"lite.proxyserver.bot","port_http":6969,"port_socks":9696,"format":"xaGBMTIV:HoLJlh55@lite.proxyserver.bot:6969"},"limits":{"max_gb":10,"max_bytes":10000000000,"bytes_used":2500000000},"expires_at":"2025-02-28T00:00:00.000Z","status":"active","created_at":"2025-01-15T10:00:00.000Z"}],"pagination":{"page":1,"per_page":20,"total":1,"total_pages":1}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"operationId":"createPlan","tags":["Plans"],"summary":"Create a new plan","description":"Create a new proxy plan. The required parameters vary by product type.\n\n## Product-Specific Requirements\n\n### Bandwidth Products (residential-lite, residential, mobile, pool1–pool5)\n- **Required**: `product`, `bandwidth_gb`\n- **Optional**: `duration` (default: no expiry until bandwidth used)\n- Pool products require a minimum of 1 GB\n\n### Hybrid Products (datacenter, shared_isp, isp_eu, ipv6-residential, ipv6-datacenter)\n- **Required**: `product`, `billing_type`\n- If `billing_type: \"bandwidth\"`: requires `bandwidth_gb`\n- If `billing_type: \"time\"`: requires `duration`, `mbps`\n\n### Unlimited Residential\n- **For trial**: `product`, `duration: \"trial\"` (1 hour, 200 Mbps)\n- **For full plan**: `product`, `duration`, `bandwidth_mbps`\n\n## Idempotency\nInclude `X-Idempotency-Key` header to prevent duplicate charges on retries.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlanRequest"},"examples":{"residential-lite":{"summary":"Residential Lite - 10GB","description":"Purchase 10GB of residential lite bandwidth. No expiry date - valid until bandwidth is used.","value":{"product":"residential-lite","bandwidth_gb":10}},"residential-lite_with_duration":{"summary":"Residential Lite - 10GB for 30 days","description":"Purchase 10GB with 30-day expiry","value":{"product":"residential-lite","bandwidth_gb":10,"duration":"30_days"}},"residential":{"summary":"Residential - 5GB","description":"Premium rotating residential proxies","value":{"product":"residential","bandwidth_gb":5}},"mobile":{"summary":"Mobile - 2GB","description":"Rotating mobile proxies","value":{"product":"mobile","bandwidth_gb":2}},"datacenter_bandwidth":{"summary":"Datacenter - 10GB bandwidth","description":"Datacenter proxies billed per GB","value":{"product":"datacenter","billing_type":"bandwidth","bandwidth_gb":10}},"datacenter_time":{"summary":"Datacenter - 100Mbps for 7 days","description":"Datacenter proxies billed per time","value":{"product":"datacenter","billing_type":"time","duration":"7_days","mbps":100}},"shared_isp_bandwidth":{"summary":"Shared ISP - 5GB","value":{"product":"shared_isp","billing_type":"bandwidth","bandwidth_gb":5}},"isp_eu_bandwidth":{"summary":"Shared ISP EU - 5GB","value":{"product":"isp_eu","billing_type":"bandwidth","bandwidth_gb":5}},"ipv6-residential":{"summary":"IPv6 Residential - 10GB","value":{"product":"ipv6-residential","billing_type":"bandwidth","bandwidth_gb":10}},"ipv6-datacenter":{"summary":"IPv6 Datacenter - 20GB","value":{"product":"ipv6-datacenter","billing_type":"bandwidth","bandwidth_gb":20}},"unlimited_residential_trial":{"summary":"Unlimited Residential - 30 min Trial","description":"30-minute trial of unlimited residential server.\n\n**Tiered Pricing (resets daily at midnight UTC):**\n- First 10 trials/day: $0.50 each\n- Additional trials: $1.50 each\n\n**Limitations:**\n- 200 Mbps bandwidth cap\n- 1 hour duration\n","value":{"product":"unlimited_residential","duration":"trial"}},"unlimited_residential_full":{"summary":"Unlimited Residential - 500Mbps, 30 days","description":"Full unlimited residential plan with country targeting and sticky sessions","value":{"product":"unlimited_residential","duration":"30_days","bandwidth_mbps":500}},"pool1":{"summary":"Residential Pool 1 - 5GB","description":"Residential pool proxies billed per GB. 90-day expiry, 1 GB minimum.\n\n**Connection:** `user:pass@v3-resi-us.proxyserver.bot:10000` (HTTP ports 10000–10009, SOCKS5 ports 11000–11009)\n\n**Pool 1 targeting:** country, state (US full name), city (US, requires state), ASN\n**Pool 1 sessions:** `-time-short` (random device) or `-time-long` (reliable device, up to 24h)\n\nSee Residential Pool documentation for full per-pool targeting details.\n","value":{"product":"pool1","bandwidth_gb":5}},"pool2":{"summary":"Residential Pool 2 - 5GB","value":{"product":"pool2","bandwidth_gb":5}},"pool3":{"summary":"Residential Pool 3 - 5GB","value":{"product":"pool3","bandwidth_gb":5}},"pool4":{"summary":"Residential Pool 4 - 5GB","value":{"product":"pool4","bandwidth_gb":5}},"pool5":{"summary":"Residential Pool 5 - 5GB","value":{"product":"pool5","bandwidth_gb":5}},"dedicated_isp":{"summary":"Dedicated ISP - 5 IPs from US Sneakers pool","description":"Purchase static ISP proxy IPs.\n\n**Prerequisites:**\n1. Get pool names from `GET /proxies/pools`\n2. Verify pool has sufficient stock\n\n**Pool Naming Convention:**\n- `ISP_` prefix = ISP proxies\n- `SN_` prefix = Subnet proxies\n- Format: `{TYPE}_{COUNTRY}_{USE_CASE}`\n","value":{"product":"dedicated_isp","quantity":5,"pool":"ISP_US_SNEAKERS"}},"with_reference":{"summary":"Plan with end-user reference","description":"Include your own reference ID for tracking","value":{"product":"residential-lite","bandwidth_gb":10,"end_user_reference":"customer_12345"}}}}}},"responses":{"201":{"description":"Plan created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"},"examples":{"residential-lite":{"summary":"Residential Lite plan created","value":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","product":"residential-lite","billing_type":"bandwidth","proxy_username":"xaGBMTIV","proxy_password":"HoLJlh55","connection":{"hostname":"lite.proxyserver.bot","port_http":6969,"port_socks":9696,"format":"xaGBMTIV:HoLJlh55@lite.proxyserver.bot:6969"},"limits":{"max_gb":10,"max_bytes":10000000000,"bytes_used":0},"expires_at":"2025-02-28T00:00:00.000Z","status":"active","created_at":"2025-01-15T10:00:00.000Z","billing":{"mode":"price","price_per_gb":50,"gb_purchased":10,"cost_cents":500,"cost_formatted":"$5.00"}}}},"unlimited_trial":{"summary":"Unlimited Residential Trial created","value":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","product":"unlimited_residential","billing_type":"time","proxy_username":"fp1234567890@flashproxy.io","proxy_password":"abc123def456","connection":{"hostname":"unlim.proxyserver.bot","port_http":10507,"format":"fp1234567890@flashproxy.io:abc123def456@unlim.proxyserver.bot:10507"},"limits":{"bytes_used":0,"max_mbps":200},"expires_at":"2025-01-15T11:00:00.000Z","status":"active","created_at":"2025-01-15T10:00:00.000Z","billing":{"mode":"price_only","cost_cents":50,"cost_formatted":"$0.50","trial_info":{"trials_used_today":3,"discounted_trials_remaining":7,"price_applied":"discounted","discounted_price_cents":50,"full_price_cents":150,"daily_discount_limit":10}}},"note":"Unlimited residential plans connect via unlim.proxyserver.bot:10507. No server provisioning required."}},"dedicated_isp":{"summary":"Dedicated ISP created","value":{"success":true,"data":{"plan_id":"ca8f4359-16d1-4aec-bd7f-8349f028e914","product":"dedicated_isp","billing_type":"per_ip","pool":"ISP_US_SNEAKERS","quantity":5,"proxy_username":"user_4f8071c5e93f","proxy_password":"L68LsMrv","connection":{"hostname":"159.197.238.218","port_http":61234,"format":"user_4f8071c5e93f:L68LsMrv@159.197.238.218:61234"},"proxy_list":[{"host":"159.197.238.218","port":61234,"username":"user_4f8071c5e93f","password":"L68LsMrv","full":"159.197.238.218:61234:user_4f8071c5e93f:L68LsMrv"},{"host":"159.197.238.219","port":61234,"username":"user_4f8071c5e93f","password":"L68LsMrv","full":"159.197.238.219:61234:user_4f8071c5e93f:L68LsMrv"}],"limits":{"bytes_used":0},"expires_at":"2026-03-02T15:29:14.000Z","status":"active","provider_user_id":"TL-9SB8KEEQQV","created_at":"2026-01-31T15:29:15.402Z","billing":{"mode":"price_only","cost_cents":7500,"cost_formatted":"$75.00"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"examples":{"missing_product":{"summary":"Missing required field","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid request parameters","details":{"product":["Required"]}}}},"invalid_product":{"summary":"Invalid product type","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid request parameters","details":{"product":["Invalid enum value. Expected 'residential-lite' | 'residential' | 'mobile' | 'mobile_usa' | 'datacenter' | 'shared_isp' | 'isp_eu' | 'ipv6-residential' | 'ipv6-datacenter' | 'pool1' | 'pool2' | 'pool3' | 'pool4' | 'pool5' | 'unlimited_residential'"]}}}},"missing_bandwidth":{"summary":"Missing bandwidth for bandwidth product","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"bandwidth_gb is required for bandwidth-billed products"}}},"invalid_billing_type":{"summary":"Missing billing_type for hybrid product","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"billing_type is required for datacenter/shared_isp/isp_eu/ipv6 products"}}},"invalid_pool":{"summary":"Invalid pool for dedicated ISP","value":{"success":false,"error":{"code":"INVALID_POOL","message":"Invalid pool 'INVALID_POOL'. Valid pools include: ISP_US_SNEAKERS, ISP_US_TICKETS (+20 more). Use GET /proxies/pools for full list."}}},"pool_out_of_stock":{"summary":"Pool out of stock for dedicated ISP","value":{"success":false,"error":{"code":"POOL_OUT_OF_STOCK","message":"Pool 'ISP_US_SNEAKERS' has insufficient stock. Available: 5, Requested: 10"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Insufficient balance","content":{"application/json":{"example":{"success":false,"error":{"code":"INSUFFICIENT_BALANCE","message":"Insufficient balance. Required: $500.00, Available: $100.00","required_cents":50000,"available_cents":10000}}}}},"409":{"description":"Out of stock","content":{"application/json":{"example":{"success":false,"error":{"code":"OUT_OF_STOCK","message":"product is out of stock"}}}}}}}},"/plans/{planId}":{"get":{"operationId":"getPlan","tags":["Plans"],"summary":"Get a specific plan","description":"Get full details of a specific plan including:\n- Proxy credentials\n- Connection details\n- Current usage\n- Billing information\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The plan ID (UUID format)","example":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164"}],"responses":{"200":{"description":"Plan retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Plan not found","content":{"application/json":{"example":{"success":false,"error":{"code":"NOT_FOUND","message":"Plan not found"}}}}}}},"delete":{"operationId":"cancelPlan","tags":["Plans"],"summary":"Cancel a plan","description":"Cancel an active plan immediately.\n\n**Important:**\n- No refund will be issued\n- The plan becomes unusable immediately\n- This action cannot be undone\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The plan ID to cancel"}],"responses":{"200":{"description":"Plan cancelled successfully","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","status":"cancelled","message":"Plan cancelled successfully. No refund will be issued.","cancelled_at":"2025-01-15T12:00:00.000Z"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/extend":{"post":{"operationId":"extendPlan","tags":["Plans"],"summary":"Extend a plan","description":"Add more bandwidth or time to an existing plan. The required parameter depends on the product type.\n\n## Bandwidth-Only Products\nUse `add_bandwidth_gb` to add more GB:\n- **residential-lite, residential, mobile, pool1–pool5**: Only `add_bandwidth_gb` accepted\n\n## Hybrid Products (bandwidth + time)\nUse `add_bandwidth_gb`, `add_days`, or both:\n- **datacenter, shared_isp, isp_eu, ipv6-residential, ipv6-datacenter**\n- Bandwidth-billed plans: use `add_bandwidth_gb`\n- Time-billed plans: use `add_days` (any positive integer)\n- Both can be provided in a single call\n\n## Dedicated ISP\nUse `extend_30_days: true` (always extends by exactly 30 days):\n- **dedicated_isp**: Cost is per-IP × price_per_ip_30_days\n\n## Not Extendable\n- **unlimited_residential**: extension is not supported for this product. The upstream provider issues immutable fixed-duration plans, so to give a customer more time on this product you must create a new plan. Calls return 400 `EXTENSION_NOT_SUPPORTED`.\n\n## Idempotency\nInclude `X-Idempotency-Key` header to prevent duplicate charges.\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The plan ID to extend"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendPlanRequest"},"examples":{"add_bandwidth":{"summary":"Add 5GB (residential, mobile, residential-lite)","value":{"add_bandwidth_gb":5}},"extend_dedicated_isp":{"summary":"Extend dedicated ISP by 30 days","value":{"extend_30_days":true}},"hybrid_both":{"summary":"Add bandwidth + time to hybrid product (datacenter, shared_isp, isp_eu, ipv6)","value":{"add_bandwidth_gb":10,"add_days":30}}}}}},"responses":{"200":{"description":"Plan extended successfully","content":{"application/json":{"examples":{"bandwidth_extended":{"summary":"Bandwidth added","value":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","cost_cents":250,"cost_formatted":"$2.50","gb_added":5,"new_max_gb":15,"new_max_bytes":15000000000}}},"days_extended":{"summary":"Days added","value":{"success":true,"data":{"plan_id":"b146c7ec-7e38-4e17-b526-09ba9f757e6e","cost_cents":70000,"cost_formatted":"$700.00","days_added":7,"new_expires_at":"2025-01-29T10:00:00.000Z"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"examples":{"wrong_type":{"summary":"Wrong extension type for plan","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Cannot add bandwidth to a time-billed plan. Use add_days instead."}}},"plan_expired":{"summary":"Cannot extend expired plan","value":{"success":false,"error":{"code":"PLAN_EXPIRED","message":"Cannot extend an expired plan"}}},"extension_not_supported":{"summary":"Product does not support extension (unlimited_residential)","value":{"success":false,"error":{"code":"EXTENSION_NOT_SUPPORTED","message":"Plan extension is not supported for this product. Please create a new plan instead."}}}}}}},"402":{"$ref":"#/components/responses/InsufficientBalance"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/upgrade":{"post":{"operationId":"upgradePlan","tags":["Plans"],"summary":"Upgrade a plan (unlimited_residential only)","description":"Upgrade an unlimited_residential plan to higher specs.\n\n**Note:** Upgrade is not currently supported for new unlimited residential plans. Purchase a new plan instead.\n\n**Upgradeable parameters (legacy plans only):**\n- `bandwidth_mbps`: Increase bandwidth cap\n\n**Important:**\n- Only applies to unlimited_residential plans\n- Prorated charges apply for remaining time\n- Downgrade is not supported\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bandwidth_mbps":{"type":"integer","description":"New bandwidth cap in Mbps (200–3000)"}}},"example":{"bandwidth_mbps":1000}}}},"responses":{"200":{"description":"Plan upgraded successfully","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","cost_cents":50000,"cost_formatted":"$500.00","new_bandwidth_mbps":1000,"message":"Plan upgraded."}}}}},"400":{"description":"Invalid upgrade request or not supported for this plan type"},"402":{"$ref":"#/components/responses/InsufficientBalance"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/password":{"put":{"operationId":"updatePlanPassword","tags":["Plans"],"summary":"Update plan password","description":"Change the proxy password for a plan.\n\n**Use cases:**\n- Security rotation\n- Compromised credentials\n- Team member changes\n\n**Note:** The new password takes effect immediately.\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["new_password"],"properties":{"new_password":{"type":"string","minLength":6,"maxLength":32,"pattern":"^[a-zA-Z0-9]+$","description":"New password (alphanumeric only, 6-32 characters)"}}},"example":{"new_password":"MyNewPass123"}}}},"responses":{"200":{"description":"Password updated successfully","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","proxy_username":"xaGBMTIV","proxy_password":"MyNewPass123","message":"Password updated successfully"}}}}},"400":{"description":"Invalid password format"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/allowed-ips":{"put":{"operationId":"updatePlanAllowedIps","tags":["Plans"],"summary":"Set plan IP allowlist","description":"Replace the plan's IP allowlist (max 10 entries). When non-empty, only\nthose source IPs can authenticate to the proxy with this plan's\ncredentials. Pass an empty array to clear the allowlist.\n\n**Notes:**\n- Each entry must be a valid IPv4 or IPv6 address. CIDR ranges are not supported.\n- Duplicates and IPv4-mapped IPv6 addresses (`::ffff:1.2.3.4`) are folded server-side.\n- The list completely replaces any prior allowlist on the plan.\n- Empty list means no IP restriction (creds are sufficient).\n- Idempotency keys are supported via the `X-Idempotency-Key` header.\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAllowedIpsRequest"},"example":{"allowed_ips":["203.0.113.5","198.51.100.42"]}}}},"responses":{"200":{"description":"IP allowlist updated","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","allowed_ips":["203.0.113.5","198.51.100.42"],"updated_at":"2026-04-29T12:34:56.789Z"}}}}},"400":{"description":"Invalid IP list (too many entries, malformed IP, or non-array body)"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/usage":{"get":{"operationId":"getPlanUsage","tags":["Plans"],"summary":"Get plan usage statistics","description":"Get detailed usage statistics for a specific plan.\n\n**Includes:**\n- Total bytes used\n- Bytes remaining (for bandwidth plans)\n- Usage percentage\n- Daily/hourly breakdown (if available)\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Usage retrieved successfully","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","product":"residential-lite","billing_type":"bandwidth","usage":{"bytes_used":2500000000,"bytes_used_formatted":"2.5 GB","bytes_remaining":7500000000,"bytes_remaining_formatted":"7.5 GB","max_bytes":10000000000,"usage_percent":25},"period":{"start":"2025-01-01T00:00:00.000Z","end":"2025-01-31T23:59:59.999Z"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/summary":{"get":{"operationId":"getPlanMetricsSummary","tags":["Plan Metrics"],"summary":"Aggregate metrics totals for a plan","description":"Aggregate totals over the requested window: bytes transferred\n(total + upload/download split), connections, success rate, peak\nper-user concurrency, and throughput.\n\n**Traffic & throughput are payload _goodput_** (application bytes the\nproxy forwarded at the relay boundary), not wire bytes — so they read\n~10% under NIC counters and are correct regardless of shaping. Fields:\n- `avg_mbps` — byte-weighted sustained average over the window.\n- `peak_mbps` — the busiest minute's mean rate (trustworthy peak).\n- `burst_mbps` — peak 1-second sample; upper-biased, use as a burstiness\n  indicator only, not a hard number.\n- `samples` — count of 1-second samples (~60/min when fully active).\n\n**Supported products only:** `datacenter`, `shared_isp`, `isp_eu`,\n`ipv6_residential`, `ipv6_datacenter`. Others return\n`400 METRICS_NOT_SUPPORTED`.\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/summary?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"Plan id owned by the calling reseller"},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24},"description":"Lookback window in hours (1–168)"}],"responses":{"200":{"description":"Aggregate totals","content":{"application/json":{"examples":{"active_plan":{"summary":"Plan with real traffic in the window","value":{"success":true,"data":{"hours":24,"total_bytes":1425000000,"total_mb":1425,"total_up_bytes":95000000,"total_down_bytes":1330000000,"up_mb":95,"down_mb":1330,"total_connections":31,"total_successes":30,"total_errors":1,"success_rate_pct":96.77,"peak_concurrent":5,"avg_mbps":0.31,"peak_mbps":7.11,"burst_mbps":11.4,"samples":1380}}},"idle_plan":{"summary":"Plan with no traffic in the window","value":{"success":true,"data":{"hours":24,"total_bytes":0,"total_mb":0,"total_up_bytes":0,"total_down_bytes":0,"up_mb":0,"down_mb":0,"total_connections":0,"total_successes":0,"total_errors":0,"success_rate_pct":null,"peak_concurrent":0,"avg_mbps":0,"peak_mbps":0,"burst_mbps":0,"samples":0}}}}}}},"400":{"description":"Bad request (invalid hours, unsupported product, or missing proxy username)","content":{"application/json":{"examples":{"unsupported_product":{"summary":"Plan's product type is not metrics-eligible","value":{"success":false,"error":{"code":"METRICS_NOT_SUPPORTED","message":"Metrics are not available for product \"residential_lite\""}}},"invalid_hours":{"summary":"hours out of range","value":{"success":false,"error":{"code":"INVALID_HOURS","message":"hours must be an integer in [1, 168]"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"description":"Metrics backend unavailable","content":{"application/json":{"example":{"success":false,"error":{"code":"METRICS_BACKEND_UNAVAILABLE","message":"Metrics backend is unreachable"}}}}}}}},"/plans/{planId}/metrics/throughput":{"get":{"operationId":"getPlanMetricsThroughput","tags":["Plan Metrics"],"summary":"Throughput (Mbps) time series with plan cap","description":"Per-bucket throughput over the requested window. The series is\nbucketed to roughly 60 points regardless of `hours`; the returned\n`bucket_minutes` reflects the actual interval. Per point:\n- `mbps` — byte-weighted mean throughput over the bucket.\n- `peak_mbps` — busiest minute's mean rate within the bucket (trustworthy).\n- `burst_mbps` — peak 1-second sample; upper-biased, indicator only.\n- `rate_cap_mbps` — configured cap from the BPF policer; `0` when the\n  user has no policer class (isp/dc only) or the cap is unknown.\n- `samples` — count of 1-second samples in the bucket.\n\nSource: `user_traffic_1m`, the canonical relay-boundary meter — payload\ngoodput (application bytes forwarded), throttling-mode-independent.\n\n### Example\n```bash\n# Last 6 hours of throughput\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/throughput?hours=6\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n\n# Last 7 days (max window)\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/throughput?hours=168\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"Throughput time series","content":{"application/json":{"example":{"success":true,"data":{"hours":24,"bucket_minutes":24,"series":[{"bucket":"2026-05-13 20:00:00","mbps":7.11,"peak_mbps":9.84,"burst_mbps":12.6,"rate_cap_mbps":3000,"samples":1380},{"bucket":"2026-05-13 20:24:00","mbps":6.62,"peak_mbps":8.9,"burst_mbps":11.2,"rate_cap_mbps":3000,"samples":1440}]}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/latency":{"get":{"operationId":"getPlanMetricsLatency","tags":["Plan Metrics"],"summary":"Connection-duration percentile time series","description":"Per-bucket p50 / p95 / p99 of connection lifetime in milliseconds.\n\nNote: each bucket reflects connections that **started** in that\nminute. Long-running connections that started in an earlier minute\nbut closed later will surface as percentile spikes in their start\nbucket.\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/latency?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"Latency percentile time series","content":{"application/json":{"example":{"success":true,"data":{"hours":24,"bucket_minutes":24,"series":[{"bucket":"2026-05-13 20:00:00","p50":124,"p95":1032,"p99":1042}]}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/errors":{"get":{"operationId":"getPlanMetricsErrors","tags":["Plan Metrics"],"summary":"Error counts by typed category over time","description":"Per-bucket failed-connection counts, broken out by typed error\ncategory. Categories: `dns`, `tcp`, `tls`, `timeout`, `auth`,\n`upstream_4xx`, `upstream_5xx`, `zero_byte`, `proxy_internal`,\n`client_disconnect`, `socks5_protocol`, `bad_request`,\n`conn_limit`, `bandwidth_quota`, `blacklisted`, `upstream_select`.\n\nEach failed connection contributes to exactly one category.\n`proxy_internal` is the default catch-all when no other rule matches.\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/errors?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"Error counts time series","content":{"application/json":{"examples":{"with_errors":{"summary":"A bucket with several failed connections","value":{"success":true,"data":{"hours":24,"bucket_minutes":24,"series":[{"bucket":"2026-05-13 20:00:00","dns":0,"tcp":1,"tls":0,"timeout":0,"auth":0,"upstream_4xx":0,"upstream_5xx":0,"zero_byte":5,"proxy_internal":0,"client_disconnect":0,"socks5_protocol":0,"bad_request":0,"conn_limit":0,"bandwidth_quota":0,"blacklisted":0,"upstream_select":0}]}}},"all_clean":{"summary":"All zero — plan had no failures in the window","value":{"success":true,"data":{"hours":24,"bucket_minutes":24,"series":[{"bucket":"2026-05-13 20:00:00","dns":0,"tcp":0,"tls":0,"timeout":0,"auth":0,"upstream_4xx":0,"upstream_5xx":0,"zero_byte":0,"proxy_internal":0,"client_disconnect":0,"socks5_protocol":0,"bad_request":0,"conn_limit":0,"bandwidth_quota":0,"blacklisted":0,"upstream_select":0}]}}}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/status-codes":{"get":{"operationId":"getPlanMetricsStatusCodes","tags":["Plan Metrics"],"summary":"Upstream HTTP status code time series","description":"Per-bucket counts of upstream HTTP responses by class\n(`s2xx` / `s3xx` / `s4xx` / `s5xx`).\n\nOnly populated for **plain-HTTP** proxy traffic. CONNECT tunnels\nand SOCKS5 carry encrypted payloads and report 0 for every class.\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/status-codes?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"HTTP status-code time series","content":{"application/json":{"example":{"success":true,"data":{"hours":24,"bucket_minutes":24,"series":[{"bucket":"2026-05-13 20:00:00","s2xx":14,"s3xx":0,"s4xx":1,"s5xx":0}]}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/destinations":{"get":{"operationId":"getPlanMetricsDestinations","tags":["Plan Metrics"],"summary":"Top destinations by traffic","description":"Top target hosts the plan connected to, ranked by connection count.\nReturned fields cover counts (`connections` / `successes` / `errors`),\ntraffic (`mb_received` / `mb_sent`), and worst-case `p95_ms`.\n\n`mb_received` is target → proxy → client (download direction);\n`mb_sent` is client → proxy → target (upload direction).\n\n### Example\n```bash\n# Default (top 30 destinations over last 24h)\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/destinations?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n\n# Top 10 over the last week\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/destinations?hours=168&limit=10\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":30},"description":"Maximum number of destinations to return"}],"responses":{"200":{"description":"Top destinations","content":{"application/json":{"examples":{"with_destinations":{"summary":"Active plan with several distinct targets","value":{"success":true,"data":{"hours":24,"destinations":[{"destination":"proof.ovh.net:443","connections":7,"successes":7,"errors":0,"mb_received":30.25,"mb_sent":0.01,"p95_ms":31701},{"destination":"api.example.com:443","connections":4,"successes":4,"errors":0,"mb_received":18.4,"mb_sent":0,"p95_ms":22000}]}}},"empty":{"summary":"No destination data in the window","value":{"success":true,"data":{"hours":24,"destinations":[]}}}}}}},"400":{"description":"Bad request (invalid hours, invalid limit, or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/hourly-usage":{"get":{"operationId":"getPlanMetricsHourlyUsage","tags":["Plan Metrics"],"summary":"GB per wall-clock hour","description":"Bandwidth transferred (up+down payload goodput) per wall-clock hour\nover the requested window, plus a `total_gb` rollup. Useful for daily /\nweekly usage charts.\n\nSource: `user_traffic_1m` `bytes_total` (same canonical meter as the\nsummary and throughput series).\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/hourly-usage?hours=168\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"Hourly usage breakdown","content":{"application/json":{"example":{"success":true,"data":{"hours":24,"total_gb":0.41,"hourly":[{"hour":"2026-05-13 16:00:00","gb":0.165},{"hour":"2026-05-13 20:00:00","gb":0.245}]}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/metrics/error-messages":{"get":{"operationId":"getPlanMetricsErrorMessages","tags":["Plan Metrics"],"summary":"Aggregated recent error messages","description":"Top 30 error messages observed for this plan in the window,\naggregated by `(error_type, message)`. Internal hostnames,\ninfrastructure names, and IP literals are scrubbed to `[redacted]`\nin the `message` field before return.\n\nUseful for diagnosing why connections are failing without\nsampling individual events.\n\n### Example\n```bash\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/plans/{planId}/metrics/error-messages?hours=24\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":168,"default":24}}],"responses":{"200":{"description":"Aggregated error messages","content":{"application/json":{"examples":{"with_samples":{"summary":"Plan with error samples in the window","value":{"success":true,"data":{"hours":24,"messages":[{"error_type":"tcp_connect","message":"dial tcp [redacted]: connect: connection refused","count":42,"last_seen":"2026-05-13 20:34:12","sample_destination":"api.example.com:443"},{"error_type":"timeout","message":"read tcp [redacted]: i/o timeout","count":7,"last_seen":"2026-05-13 20:31:55","sample_destination":"example.org:443"}]}}},"empty":{"summary":"No errors sampled in the window","value":{"success":true,"data":{"hours":24,"messages":[]}}}}}}},"400":{"description":"Bad request (invalid hours or unsupported product)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/plans/{planId}/proxies":{"get":{"operationId":"getPlanProxies","tags":["Dedicated ISP"],"summary":"Get proxy list for a Dedicated ISP plan","description":"## Retrieve Your Dedicated ISP Proxy List\n\nGet the complete list of static proxy IPs assigned to your dedicated ISP plan.\n\n**⚠️ EXCLUSIVE TO: `dedicated_isp` product**\n\n---\n\n### What This Returns\n\nEach proxy in your list includes:\n- **host**: The static IP address\n- **port**: Connection port\n- **username**: Your unique proxy username\n- **password**: Your proxy password\n- **full**: Complete connection string (`host:port:username:password`)\n\n---\n\n### Data Source\n\n| Source | Description |\n|--------|-------------|\n| `provider` | Fresh data fetched from upstream provider |\n| `cached` | Stored data (when provider is temporarily unavailable) |\n\n---\n\n### Connection Examples\n\n**cURL (HTTP proxy):**\n```bash\ncurl -x \"http://username:password@host:port\" https://httpbin.org/ip\n```\n\n**Python (requests):**\n```python\nproxies = {\n    \"http\": \"http://username:password@host:port\",\n    \"https\": \"http://username:password@host:port\"\n}\nresponse = requests.get(\"https://httpbin.org/ip\", proxies=proxies)\n```\n\n**Node.js (axios):**\n```javascript\nconst proxy = {\n    host: 'host',\n    port: port,\n    auth: { username: 'username', password: 'password' }\n};\nconst response = await axios.get('https://httpbin.org/ip', { proxy });\n```\n\n---\n\n### When to Use This Endpoint\n\n- After creating a dedicated ISP plan to get connection details\n- To refresh proxy list (data may update if IPs change)\n- To verify proxy credentials for troubleshooting\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Proxy list retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyListResponse"},"examples":{"from_provider":{"summary":"Fresh data from provider","value":{"success":true,"data":{"plan_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","count":5,"proxies":[{"host":"159.197.238.218","port":61234,"username":"user_4f8071c5e93f","password":"L68LsMrv","full":"159.197.238.218:61234:user_4f8071c5e93f:L68LsMrv"},{"host":"159.197.238.219","port":61234,"username":"user_4f8071c5e93f","password":"L68LsMrv","full":"159.197.238.219:61234:user_4f8071c5e93f:L68LsMrv"}],"pool":"ISP_US_SNEAKERS","expires_at":"2026-03-02T15:29:14.000Z","source":"provider"}}},"from_cache":{"summary":"Cached data (provider unavailable)","value":{"success":true,"data":{"plan_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","count":5,"proxies":[{"host":"159.197.238.218","port":61234,"username":"user_4f8071c5e93f","password":"L68LsMrv","full":"159.197.238.218:61234:user_4f8071c5e93f:L68LsMrv"}],"pool":"ISP_US_SNEAKERS","expires_at":"2026-03-02T15:29:14.000Z","source":"cached"}}}}}}},"400":{"description":"Not applicable to this product type","content":{"application/json":{"example":{"success":false,"error":{"code":"NOT_SUPPORTED","message":"This endpoint is only for Dedicated ISP plans"}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/investigate/{planId}":{"post":{"operationId":"startInvestigation","tags":["Investigations"],"summary":"Start an AI-powered proxy investigation","description":"## AI Proxy Investigation\n\nRun an automated AI investigation on a proxy plan to diagnose performance issues,\nconnection failures, or other problems reported by your end user.\n\nThe investigation queries real-time monitoring data across the proxy infrastructure\nand returns a structured diagnosis with evidence, root cause analysis, and\nactionable recommendations.\n\n**Cost:** $0.50 per investigation (deducted from your balance).\n\n**Supported products:** Datacenter (IPv4/IPv6), Shared ISP, Shared ISP EU, and IPv6 Residential only.\n\n**Rate limit:** 10 investigations per hour per reseller.\n\n**How it works:**\n1. Submit a POST with the plan ID and a short description of the complaint\n2. Receive an `investigation_id` and a `poll_url`\n3. Poll the status endpoint every 10-15 seconds until `status` is `complete` or `error`\n4. On `error`, the $0.50 charge is automatically refunded\n\n**Typical runtime:** 60-180 seconds.\n\n### Example\n```bash\n# Step 1: Start investigation\ncurl -X POST \"https://rapi.flashproxy.com/api/v1/investigate/{planId}\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"complaint\": \"Customer reports 403 errors on target site\"}'\n\n# Step 2: Poll for result (repeat every 10s)\ncurl \"https://rapi.flashproxy.com/api/v1/investigate/{planId}/{investigation_id}\" \\\n  -H \"Authorization: Bearer fp_live_YOUR_KEY\"\n```\n","security":[{"BearerAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"The plan ID to investigate"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["complaint"],"properties":{"complaint":{"type":"string","minLength":1,"maxLength":400,"description":"Short description of the issue (max 400 chars)","example":"Customer reports 403 errors when hitting target site xyz.com"}}},"examples":{"slow_speeds":{"summary":"Slow speed complaint","value":{"complaint":"End user reports very slow speeds, requests timing out after 10+ seconds"}},"blocked_target":{"summary":"Target blocking complaint","value":{"complaint":"Customer getting 403 errors on all requests to example.com"}},"auth_errors":{"summary":"Authentication errors","value":{"complaint":"User cannot connect at all, getting connection refused errors"}}}}}},"responses":{"202":{"description":"Investigation started","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"investigation_id":{"type":"string","format":"uuid","description":"Unique ID for this investigation"},"status":{"type":"string","enum":["running"]},"estimated_seconds":{"type":"integer","example":120},"poll_url":{"type":"string","description":"URL to poll for status","example":"/api/v1/investigate/{planId}/{investigation_id}"}}}}}}}},"400":{"description":"Invalid input or unsupported product type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"unsupported":{"value":{"success":false,"error":{"code":"UNSUPPORTED_PRODUCT","message":"Investigations are only available for Datacenter, Shared ISP, Shared ISP EU, and IPv6 Residential plans"}}},"too_long":{"value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Complaint too long (max 400 chars)"}}}}}}},"402":{"description":"Insufficient balance (requires $0.50)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"INSUFFICIENT_BALANCE","message":"Insufficient balance for investigation","details":{"required_cents":50,"available_cents":25,"required_formatted":"$0.50","available_formatted":"$0.25"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"description":"Rate limit exceeded (10/hour)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"RATE_LIMIT","message":"Maximum 10 investigations per hour"}}}}}}},"get":{"operationId":"listInvestigations","tags":["Investigations"],"summary":"List past investigations for a plan","description":"Returns the 50 most recent investigations for this plan, newest first.\nIncludes status, severity, headline, cost, and whether a refund was issued.\n","security":[{"BearerAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"},"description":"The plan ID"}],"responses":{"200":{"description":"Investigation history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"plan_id":{"type":"string"},"investigations":{"type":"array","items":{"type":"object","properties":{"investigation_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","running","complete","error"]},"severity":{"type":"string","enum":["info","warning","critical"],"nullable":true},"headline":{"type":"string","nullable":true},"cost":{"type":"string","example":"$0.50"},"refunded":{"type":"boolean"},"elapsed_seconds":{"type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time","nullable":true}}}}}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/investigate/{planId}/{investigationId}":{"get":{"operationId":"getInvestigation","tags":["Investigations"],"summary":"Poll investigation status or get result","description":"Poll this endpoint every 10-15 seconds after starting an investigation.\n\n**Status values:**\n- `pending` — queued, not yet started\n- `running` — investigation in progress (typically 60-180s)\n- `complete` — diagnosis available in the `diagnosis` field\n- `error` — investigation failed (charge is automatically refunded)\n\nWhen `status` is `complete`, the response includes a full `diagnosis` object with:\n- `severity` — `info`, `warning`, or `critical`\n- `headline` — one-sentence summary\n- `root_cause` — detailed explanation with specific numbers\n- `evidence` — array of metrics that support the diagnosis\n- `recommendation_to_customer` — text you can paste directly to the end user\n- `recommendation_to_staff` — internal notes for your team\n","security":[{"BearerAuth":[]}],"parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string"}},{"name":"investigationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Investigation status or result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"investigation_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","running","complete","error"]},"elapsed_seconds":{"type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time","nullable":true},"cost":{"type":"string","example":"$0.50"},"refunded":{"type":"boolean"},"diagnosis":{"type":"object","nullable":true,"description":"Present only when status is `complete`","properties":{"severity":{"type":"string","enum":["info","warning","critical"]},"headline":{"type":"string","description":"One-sentence summary of the diagnosis"},"root_cause":{"type":"string","description":"Detailed explanation with specific numbers"},"evidence":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"string"},"context":{"type":"string"}}}},"recommendation_to_customer":{"type":"string","description":"Text you can paste directly to the end user"},"recommendation_to_staff":{"type":"string","description":"Internal notes for your support team"}}}}}}},"examples":{"running":{"summary":"Investigation in progress","value":{"success":true,"data":{"investigation_id":"ad2d27b5-cfad-4183-a0fb-bfca97d4f4f5","status":"running","elapsed_seconds":45}}},"complete":{"summary":"Investigation complete","value":{"success":true,"data":{"investigation_id":"ad2d27b5-cfad-4183-a0fb-bfca97d4f4f5","status":"complete","elapsed_seconds":92,"created_at":"2026-04-08T10:00:00Z","completed_at":"2026-04-08T10:01:32Z","cost":"$0.50","refunded":false,"diagnosis":{"severity":"warning","headline":"Target site is blocking datacenter IPs at the ASN level.","root_cause":"Near-100% of connections to example.com are failing with TCP connect timeouts (7s SYN blackhole). This is consistent with ASN-level blocking by the target. The customer's other destinations work normally.","evidence":[{"metric":"error_rate_example_com","value":"98% failure","context":"487 out of 496 connections failed in the last 30 minutes"},{"metric":"connect_latency","value":"7000ms","context":"Consistent with SYN blackhole (no response from target)"}],"recommendation_to_customer":"The site you're trying to reach is blocking the datacenter IP range we use. This is common with sites that have strict anti-proxy measures. To access this target reliably, you'd need to switch to a Residential proxy product which uses a much larger and different type of IP pool.","recommendation_to_staff":"Classic Pattern B ASN block. Customer is on datacenter product targeting a site with aggressive proxy detection. Recommend upgrade to Residential or Mobile."}}}},"error":{"summary":"Investigation failed (refunded)","value":{"success":true,"data":{"investigation_id":"ad2d27b5-cfad-4183-a0fb-bfca97d4f4f5","status":"error","error":"Investigation timed out","refunded":true}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/servers/{planId}/ip":{"get":{"operationId":"getServerIp","tags":["Servers"],"summary":"Get server IP (unlimited_residential only)","description":"Get the actual IP address of an unlimited_residential server.\n\n**Important:**\n- Server needs ~30-60 seconds to provision after purchase\n- If called too early, will return 404\n- Retry after 30 seconds if server is still provisioning\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Server IP retrieved","content":{"application/json":{"examples":{"unlimited_residential":{"summary":"Unlimited residential plan","value":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","hostname":"unlim.proxyserver.bot","port":10507}}},"legacy":{"summary":"Legacy dedicated server plan","value":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","real_ip":"43.153.88.155","port":9999,"hostname":"43.153.88.155"}}}}}}},"404":{"description":"Plan not found","content":{"application/json":{"examples":{"provisioning":{"summary":"Server still provisioning","value":{"success":false,"error":{"code":"SERVER_PROVISIONING","message":"Server is still provisioning. Please try again in 30 seconds."}}},"not_found":{"summary":"Plan not found","value":{"success":false,"error":{"code":"NOT_FOUND","message":"Plan not found"}}}}}}}}}},"/servers/{planId}/stats":{"get":{"operationId":"getServerStats","tags":["Servers"],"summary":"Get server statistics","description":"Get real-time statistics for unlimited_residential servers.\n\n**Includes:**\n- CPU usage\n- Memory usage\n- Network throughput\n- Uptime\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Server stats retrieved","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","server":{"status":"running","uptime_seconds":86400,"uptime_formatted":"1 day"},"resources":{"cpu_percent":25.5,"memory_used_mb":4096,"memory_total_mb":32768,"memory_percent":12.5},"network":{"bytes_in":1500000000,"bytes_out":500000000,"current_mbps":150},"updated_at":"2025-01-15T12:00:00.000Z"}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/servers/{planId}/monitoring":{"get":{"operationId":"getServerMonitoring","tags":["Servers"],"summary":"Get server monitoring details","description":"Get monitoring information for unlimited_residential servers.\n\n**Includes:**\n- Instance ID\n- Region/datacenter\n- Health status\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Monitoring info retrieved","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","ins_id":"ins-abc123","region":"us-west-1","provider":"FlashProxy","health":{"status":"healthy","last_check":"2025-01-15T12:00:00.000Z","response_time_ms":45}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/servers/{planId}/restart":{"post":{"operationId":"restartServer","tags":["Servers"],"summary":"Restart a server","description":"Restart the server for unlimited_residential plans.\n\n**Use cases:**\n- Connection issues\n- After upgrade\n- Performance problems\n\n**Note:** Server will be unavailable for 1-3 minutes during restart.\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Restart initiated","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"c54334e0-c431-435b-98a9-dee196887cde","message":"Server restart initiated. This may take 1-3 minutes.","estimated_downtime_seconds":120}}}}},"400":{"description":"Server already restarting","content":{"application/json":{"example":{"success":false,"error":{"code":"SERVER_BUSY","message":"Server is already restarting. Please wait."}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/usage/summary":{"get":{"operationId":"getUsageSummary","tags":["Usage"],"summary":"Get usage summary across all plans","description":"Get aggregated usage statistics across all your active plans.\n\n**Includes:**\n- Total bandwidth used\n- Breakdown by product type\n- Daily trends\n","parameters":[{"name":"period","in":"query","schema":{"type":"string","enum":["today","week","month","all"],"default":"month"},"description":"Time period for summary"}],"responses":{"200":{"description":"Usage summary retrieved","content":{"application/json":{"example":{"success":true,"data":{"period":"month","total_bytes_used":50000000000,"total_bytes_formatted":"50 GB","by_product":{"residential-lite":{"bytes_used":30000000000,"bytes_formatted":"30 GB","plans_count":5},"residential":{"bytes_used":15000000000,"bytes_formatted":"15 GB","plans_count":2},"mobile":{"bytes_used":5000000000,"bytes_formatted":"5 GB","plans_count":1}},"daily_breakdown":[{"date":"2025-01-15","bytes_used":2000000000},{"date":"2025-01-14","bytes_used":1800000000}]}}}}}}}},"/usage/plans/{planId}":{"get":{"operationId":"getPlanUsageDetailed","tags":["Usage"],"summary":"Get detailed usage for a plan","description":"Get detailed usage statistics for a specific plan with historical breakdown.\n","parameters":[{"name":"planId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"granularity","in":"query","schema":{"type":"string","enum":["hourly","daily","weekly"],"default":"daily"},"description":"Data granularity"}],"responses":{"200":{"description":"Detailed usage retrieved","content":{"application/json":{"example":{"success":true,"data":{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","product":"residential-lite","granularity":"daily","current":{"bytes_used":2500000000,"bytes_remaining":7500000000,"usage_percent":25},"history":[{"timestamp":"2025-01-15T00:00:00.000Z","bytes_used":500000000},{"timestamp":"2025-01-14T00:00:00.000Z","bytes_used":750000000}]}}}}}}}},"/usage/realtime":{"get":{"operationId":"getRealtimeUsage","tags":["Usage"],"summary":"Get real-time usage","description":"Get near real-time usage data (updated every minute).\n\nUseful for monitoring active sessions and preventing overages.\n","responses":{"200":{"description":"Real-time usage retrieved","content":{"application/json":{"example":{"success":true,"data":{"updated_at":"2025-01-15T12:00:45.000Z","active_plans":[{"plan_id":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164","product":"residential-lite","current_session_bytes":15000000,"total_bytes_used":2500000000,"bytes_remaining":7500000000}],"total_active_sessions":1}}}}}}}},"/proxies/stock":{"get":{"operationId":"getProxyStock","tags":["Proxies"],"summary":"Get proxy pool statistics","description":"Get statistics about available proxy pools for rotating products.\n\n**Includes:**\n- Total IPs available\n- IPs by country\n- Pool health metrics\n","responses":{"200":{"description":"Stock information retrieved","content":{"application/json":{"example":{"success":true,"data":{"residential":{"total_ips":5000000,"countries":195,"status":"healthy"},"residential-lite":{"total_ips":3000000,"countries":195,"status":"healthy"},"mobile":{"total_ips":500000,"countries":45,"status":"healthy"}}}}}}}}},"/proxies/connection-info":{"get":{"operationId":"getConnectionInfo","tags":["Proxies"],"summary":"Get connection information","description":"Get proxy connection details for all product types.\n\nUseful for building connection strings and configuring clients.\n","responses":{"200":{"description":"Connection info retrieved","content":{"application/json":{"example":{"success":true,"data":{"residential-lite":{"hostname":"lite.proxyserver.bot","port_http":6969,"port_socks":9696,"format":"USERNAME:PASSWORD@lite.proxyserver.bot:6969"},"residential":{"hostname":"geo.proxyserver.bot","port_http":8080,"port_socks":1080,"format":"USERNAME:PASSWORD@geo.proxyserver.bot:8080"},"datacenter":{"hostname":"v3-dc.proxyserver.bot","port_http":777,"port_socks":666,"format":"USERNAME:PASSWORD@v3-dc.proxyserver.bot:777"},"mobile":{"hostname":"geo.proxyserver.bot","port_http":8080,"port_socks":1080,"format":"USERNAME:PASSWORD@geo.proxyserver.bot:8080"},"shared_isp":{"hostname":"v3-isp.proxyserver.bot","port_http":30,"port_socks":31,"format":"USERNAME:PASSWORD@v3-isp.proxyserver.bot:30"},"isp_eu":{"hostname":"eu-isp.proxyserver.bot","port_http":30,"port_socks":31,"format":"USERNAME:PASSWORD@eu-isp.proxyserver.bot:30"},"ipv6-residential":{"hostname":"v3-v6-resi.proxyserver.bot","port_http":30,"port_socks":31,"format":"USERNAME:PASSWORD@v3-v6-resi.proxyserver.bot:30"},"ipv6-datacenter":{"hostname":"v3-v6-dc.proxyserver.bot","port_http":50,"port_socks":51,"format":"USERNAME:PASSWORD@v3-v6-dc.proxyserver.bot:50"},"format":"USERNAME:PASSWORD@v3-v6-dc.proxyserver.bot:50","unlimited_residential":{"hostname":"unlim.proxyserver.bot","port_http":10507,"port_socks":10507,"format":"USERNAME:PASSWORD@unlim.proxyserver.bot:10507","targeting":"Append -region-{CC} for country, -session-{ID}-sessTime-{MIN}-sessAuto-1 for sticky"}}}}}}}}},"/proxies/pools":{"get":{"operationId":"getIspPools","tags":["Dedicated ISP"],"summary":"List available ISP pools and stock","description":"## Get Available Dedicated ISP Pools\n\nReturns all available pool types for the **Dedicated ISP** product with real-time stock information.\n\n**⚠️ IMPORTANT: This endpoint is exclusive to the `dedicated_isp` product.**\n\n---\n\n### Why Use This Endpoint?\n\nBefore purchasing dedicated ISP proxies, you should:\n1. Check which pools are available in your target country\n2. Verify the pool has sufficient stock for your order\n3. Get the exact pool name to use in your `POST /plans` request\n\n---\n\n### Pool Naming Convention\n\nPool names follow the format: `{TYPE}_{COUNTRY}_{USE_CASE}`\n\n| Prefix | Description |\n|--------|-------------|\n| `ISP_` | Standard ISP proxies - individual static IPs |\n| `SN_` | Subnet proxies - IPs from /24 blocks |\n\n---\n\n### Available Countries\n\n| Code | Country |\n|------|---------|\n| `US` | United States |\n| `UK` | United Kingdom |\n| `DE` | Germany |\n| `CA` | Canada |\n| `AU` | Australia |\n| `EU` | European Union (mixed) |\n\n---\n\n### Example Usage\n\n```bash\n# Get all pools\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/proxies/pools\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n\n# Filter by country\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/proxies/pools?country=US\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n\n# Filter by type\ncurl -X GET \"https://rapi.flashproxy.com/api/v1/proxies/pools?type=isp\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n---\n\n### Response Fields\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `pool` | string | Pool identifier to use in `POST /plans` |\n| `inStock` | boolean | Whether pool has available IPs |\n| `stock` | number | Number of available IPs |\n| `title` | string | Human-readable pool name |\n| `provider` | string | Pool type (ISP or Subnet) |\n| `isSubnet` | boolean | True for subnet pools |\n\n---\n\n### Next Steps\n\nAfter finding your desired pool:\n```bash\ncurl -X POST \"https://rapi.flashproxy.com/api/v1/plans\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"product\": \"dedicated_isp\", \"quantity\": 5, \"pool\": \"ISP_US_SNEAKERS\"}'\n```\n","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["isp","subnet"]},"description":"Filter by pool type:\n- `isp`: Standard ISP pools\n- `subnet`: Subnet pools\n"},{"name":"country","in":"query","schema":{"type":"string"},"description":"Filter by country code (e.g., US, UK, DE, CA, AU, EU)\n"}],"responses":{"200":{"description":"Pools retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolListResponse"},"examples":{"all_pools":{"summary":"All available pools","value":{"success":true,"data":{"pools":[{"pool":"ISP_US_SNEAKERS","inStock":true,"stock":150,"title":"USA Sneaker Proxies (ISP)","provider":"ISP","isSubnet":false},{"pool":"ISP_US_TICKETS","inStock":true,"stock":80,"title":"USA Ticket Proxies (ISP)","provider":"ISP","isSubnet":false},{"pool":"ISP_UK_SNEAKERS","inStock":true,"stock":45,"title":"United Kingdom Sneaker Proxies (ISP)","provider":"ISP","isSubnet":false}],"count":3,"note":"This endpoint is exclusive to Dedicated ISP product. Use the pool value when creating a dedicated_isp plan."}}},"us_only":{"summary":"US pools filtered","value":{"success":true,"data":{"pools":[{"pool":"ISP_US_SNEAKERS","inStock":true,"stock":150,"title":"USA Sneaker Proxies (ISP)","provider":"ISP","isSubnet":false}],"count":1,"note":"This endpoint is exclusive to Dedicated ISP product. Use the pool value when creating a dedicated_isp plan."}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Dedicated ISP product not enabled","content":{"application/json":{"example":{"success":false,"error":{"code":"PRODUCT_DISABLED","message":"Dedicated ISP is not enabled for your account. This endpoint is exclusive to the dedicated_isp product."}}}}}}}},"/sub-users":{"get":{"operationId":"listSubUsers","tags":["Sub-Users"],"summary":"List all sub-users","description":"Get a list of all sub-users created under your reseller account.\n","parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","suspended","all"],"default":"all"}}],"responses":{"200":{"description":"Sub-users retrieved","content":{"application/json":{"example":{"success":true,"data":{"items":[{"id":"sub_abc123","email":"customer@example.com","name":"John Doe","status":"active","balance_cents":10000,"plans_count":3,"created_at":"2025-01-01T00:00:00.000Z"}],"pagination":{"page":1,"per_page":20,"total":1,"total_pages":1}}}}}}}},"post":{"operationId":"createSubUser","tags":["Sub-Users"],"summary":"Create a sub-user","description":"Create a new sub-user under your reseller account.\n\nSub-users can:\n- Purchase plans using allocated balance\n- Manage their own plans\n- View their usage\n\nSub-users cannot:\n- Access your main account\n- View other sub-users\n- Change pricing\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","name"],"properties":{"email":{"type":"string","format":"email","description":"Sub-user email address"},"name":{"type":"string","description":"Sub-user display name"},"initial_balance_cents":{"type":"integer","minimum":0,"description":"Initial balance to allocate (from your balance)"}}},"example":{"email":"customer@example.com","name":"John Doe","initial_balance_cents":10000}}}},"responses":{"201":{"description":"Sub-user created","content":{"application/json":{"example":{"success":true,"data":{"id":"sub_abc123","email":"customer@example.com","name":"John Doe","status":"active","balance_cents":10000,"api_key":"fp_sub_xxxxxxxxxxxx","created_at":"2025-01-15T12:00:00.000Z"}}}}},"400":{"description":"Validation error"},"402":{"$ref":"#/components/responses/InsufficientBalance"}}}},"/sub-users/{id}":{"get":{"operationId":"getSubUser","tags":["Sub-Users"],"summary":"Get sub-user details","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sub-user retrieved"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"operationId":"updateSubUser","tags":["Sub-Users"],"summary":"Update sub-user","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["active","suspended"]},"add_balance_cents":{"type":"integer","description":"Amount to add to sub-user balance"}}}}}},"responses":{"200":{"description":"Sub-user updated"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/geo/catalog":{"get":{"tags":["Geo"],"summary":"Get a product targeting catalog","description":"Returns one product's targeting catalog (countries, states, cities, ASNs, ZIPs). Issue one request per product — `product` is required and singular. Aliases (residential to pool1, shared_isp to isp, mobile_usa to mobile-usa, plus the underscored forms of the hyphenated names) resolve to canonical keys; the response always echoes the canonical key. `isp_eu` is also valid (NL only, no state/city sub-country targeting).\n\nDedicated ISP is excluded — that product is stock-based (no geo targeting). Use `GET /proxies/pools` for its stock listing.\n","operationId":"getTargetingCatalog","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Targeting catalog","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"product":{"type":"string","example":"pool1"},"supported":{"type":"object","properties":{"country":{"type":"array","items":{"type":"string"}},"state":{"type":"array","items":{"type":"string"}},"city":{"type":"array","items":{"type":"object","properties":{"city":{"type":"string"},"country":{"type":"string"}}}},"state_city":{"type":"array","items":{"type":"object","properties":{"state":{"type":"string"},"city":{"type":"string"}}}},"asn":{"type":"array","items":{"type":"integer"}},"zip":{"type":"array","items":{"type":"string"}}}},"capabilities":{"type":"object","properties":{"country":{"type":"boolean"},"state":{"type":"boolean"},"city":{"type":"boolean"},"state_city":{"type":"boolean"},"asn":{"type":"boolean"},"zip":{"type":"boolean"},"session":{"type":"boolean"}}},"asn_by_country":{"type":"object","description":"Mobile catalog only: country code to list of ASN integers.","additionalProperties":{"type":"array","items":{"type":"integer"}}},"generated_at":{"type":"string","format":"date-time"},"source":{"type":"string","example":"discovery"}}}}}}}},"400":{"description":"`product` missing, unknown, out of catalog scope, or comma-separated.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_PARAM","INVALID_PRODUCT"]},"message":{"type":"string"}}}}},"examples":{"missing":{"summary":"Missing product","value":{"success":false,"error":{"code":"MISSING_PARAM","message":"product query parameter is required (e.g. ?product=pool1)"}}},"listForm":{"summary":"List form rejected","value":{"success":false,"error":{"code":"INVALID_PRODUCT","message":"product must be a single key, not a comma-separated list. Issue one request per product."}}},"unknown":{"summary":"Unknown key","value":{"success":false,"error":{"code":"INVALID_PRODUCT","message":"Unknown product type: dedicated-isp"}}}}}}},"401":{"description":"Missing or invalid API key"},"429":{"description":"Rate limit exceeded"}},"parameters":[{"name":"product","in":"query","required":true,"description":"Canonical product key or alias. Comma-separated lists are rejected; issue one request per product.","schema":{"type":"string"},"examples":{"pool1":{"value":"pool1","summary":"Residential Pool 1"},"pool2":{"value":"pool2","summary":"Residential Pool 2"},"pool3":{"value":"pool3","summary":"Residential Pool 3"},"pool4":{"value":"pool4","summary":"Residential Pool 4"},"pool5":{"value":"pool5","summary":"Residential Pool 5"},"mobile":{"value":"mobile","summary":"Mobile"},"mobile_usa":{"value":"mobile-usa","summary":"Mobile USA"},"residential_lite":{"value":"residential-lite","summary":"Residential Lite"},"unlimited_residential":{"value":"unlimited-residential","summary":"Unlimited Residential"},"datacenter":{"value":"datacenter","summary":"Datacenter"},"isp":{"value":"isp","summary":"Shared ISP (alias: shared_isp)"},"isp_eu":{"value":"isp_eu","summary":"Shared ISP EU (NL only, no sub-country targeting)"},"ipv6_residential":{"value":"ipv6-residential","summary":"IPv6 Residential"},"ipv6_datacenter":{"value":"ipv6-datacenter","summary":"IPv6 Datacenter"}}}]}},"/coupons/validate":{"post":{"operationId":"validateCoupon","tags":["Plans"],"summary":"Validate a coupon (preview)","description":"Preview a coupon discount against a cart total **without reserving or redeeming it**.\n\nThis is a **preview only** — no redemption is created and no redemption id is returned. The actual reserve + consume happens at purchase time when you pass `coupon_code` to `POST /plans`.\n\nResponses are constant-time (250 ms floor) and protected by per-reseller and per-IP rate limits to resist enumeration. Over-limit requests and unknown codes return the same `{ \"ok\": false, \"error\": \"coupon_not_applicable\" }` shape as a genuinely inapplicable coupon, so you cannot distinguish them.\n\nRequires the `MANAGE_PLANS` permission.\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","cart_total_cents","proxy_type"],"properties":{"code":{"type":"string","description":"Coupon code to preview"},"cart_total_cents":{"type":"integer","minimum":1,"description":"Cart total in cents the discount is evaluated against (must be greater than 0)"},"proxy_type":{"type":"string","description":"Product the discount applies to (e.g. `shared_isp`, `isp_eu`, `datacenter`)","example":"shared_isp"}}},"examples":{"shared_isp":{"summary":"Preview a coupon for a Shared ISP cart","value":{"code":"SAVE10","cart_total_cents":5000,"proxy_type":"shared_isp"}}}}}},"responses":{"200":{"description":"Preview result. Two shapes: applicable (`ok: true`) carries the discount; not-applicable, invalid, or rate-limited (`ok: false`) carries a generic `coupon_not_applicable` error.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","description":"Whether the coupon applies to this cart"},"discount_cents":{"type":"integer","description":"Discount amount in cents (applicable only)"},"final_cents":{"type":"integer","description":"Discounted cart total in cents (applicable only)"},"error":{"type":"string","enum":["coupon_not_applicable"],"description":"Generic error returned for inapplicable, invalid, unknown, or rate-limited codes (not-applicable only)"}}},"examples":{"applicable":{"summary":"Coupon applies","value":{"ok":true,"discount_cents":500,"final_cents":4500}},"not_applicable":{"summary":"Coupon does not apply (or invalid/rate-limited)","value":{"ok":false,"error":"coupon_not_applicable"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API_KEY","description":"API key authentication. Include your API key in the Authorization header:\n```\nAuthorization: Bearer fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nAPI keys start with:\n- `fp_live_` - Production keys\n- `fp_test_` - Sandbox/test keys\n"}},"responses":{"Unauthorized":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"example":{"success":false,"error":{"code":"UNAUTHORIZED","message":"Invalid or missing API key"}}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"example":{"success":false,"error":{"code":"NOT_FOUND","message":"Resource not found"}}}}},"InsufficientBalance":{"description":"Insufficient balance","content":{"application/json":{"example":{"success":false,"error":{"code":"INSUFFICIENT_BALANCE","message":"Insufficient balance","required_cents":50000,"available_cents":10000}}}}},"ValidationError":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Invalid request parameters","details":{"field_name":["Error message"]}}}}}}},"schemas":{"SuccessResponse":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","example":true}}},"ErrorResponse":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code for programmatic handling","example":"VALIDATION_ERROR"},"message":{"type":"string","description":"Human-readable error message","example":"Invalid request parameters"},"details":{"type":"object","description":"Additional error context","additionalProperties":true}}}}},"TargetingCatalogResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["product","supported","capabilities","generated_at","source"],"properties":{"product":{"type":"string","description":"Pool identifier this catalog applies to (always normalized — `residential` aliases to `pool1`).","example":"pool1"},"supported":{"type":"object","description":"Sets of values empirically validated against the upstream pool. Empty arrays mean the dimension is either unsupported by this pool or not yet discovered.","properties":{"country":{"type":"array","description":"ISO-3166-1 alpha-2 country codes (lowercase).","items":{"type":"string","example":"us"}},"state":{"type":"array","description":"Normalized state names — lowercase, no spaces (e.g. `newyork`).","items":{"type":"string","example":"california"}},"city":{"type":"array","description":"City + country pairs supported as a city-only target (no state).","items":{"type":"object","required":["city","country"],"properties":{"city":{"type":"string","example":"berlin"},"country":{"type":"string","example":"de"}}}},"state_city":{"type":"array","description":"State + city pairs supported as a combined target. Required when the pool only accepts city when scoped by state.","items":{"type":"object","required":["state","city"],"properties":{"state":{"type":"string","example":"newyork"},"city":{"type":"string","example":"newyork"}}}},"asn":{"type":"array","description":"Autonomous System Numbers supported as a target.","items":{"type":"integer","example":7922}},"zip":{"type":"array","description":"ZIP / postal codes supported as a target.","items":{"type":"string","example":"10001"}}}},"capabilities":{"type":"object","description":"Per-dimension capability flags. `true` means the pool accepts this dimension as a targeting parameter; `false` means requests using that dimension will be rejected upstream of routing.","properties":{"country":{"type":"boolean"},"state":{"type":"boolean"},"city":{"type":"boolean"},"state_city":{"type":"boolean"},"asn":{"type":"boolean"},"zip":{"type":"boolean"},"session":{"type":"boolean","description":"True when the pool supports sticky sessions (`-session-` parameter)."}}},"generated_at":{"type":"string","format":"date-time","description":"When the catalog was last refreshed by discovery."},"source":{"type":"string","description":"Provenance of the catalog — `discovery` (empirically discovered) or `manual` (operator-curated seed).","example":"discovery"}}}}},"BalanceResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"balance_cents":{"type":"integer","description":"Current balance in cents","example":500000},"balance_formatted":{"type":"string","description":"Formatted balance string","example":"$5,000.00"},"allocations":{"type":"object","description":"Pre-paid bandwidth allocations by product","properties":{"residential":{"$ref":"#/components/schemas/Allocation"},"residential-lite":{"$ref":"#/components/schemas/Allocation"},"mobile":{"$ref":"#/components/schemas/Allocation"}}},"total_spent_cents":{"type":"integer","description":"Total amount spent historically","example":150000},"total_spent_formatted":{"type":"string","example":"$1,500.00"}}}}}]},"Allocation":{"type":"object","nullable":true,"properties":{"allocated_gb":{"type":"number","nullable":true,"description":"Total GB allocated","example":100},"used_gb":{"type":"number","nullable":true,"description":"GB consumed so far","example":50},"remaining_gb":{"type":"number","nullable":true,"description":"GB remaining in allocation","example":50}}},"TransactionsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}]},"Transaction":{"type":"object","properties":{"id":{"type":"string","description":"Transaction ID","example":"txn_abc123"},"type":{"type":"string","enum":["topup","purchase","extend","refund","adjustment","allocation_usage","manual_refund","plan_creation","plan_extension","admin_credit","admin_debit","admin_adjustment"],"description":"Transaction type"},"amount_cents":{"type":"integer","description":"Amount in cents (negative for charges)","example":-5000},"amount_formatted":{"type":"string","example":"-$50.00"},"description":{"type":"string","description":"Human-readable description","example":"residential-lite - 10GB"},"plan_id":{"type":"string","nullable":true,"description":"Associated plan ID (if applicable)"},"balance_after_cents":{"type":"integer","description":"Balance after this transaction"},"created_at":{"type":"string","format":"date-time"}}},"PricingResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","additionalProperties":{"type":"object","properties":{"billing":{"type":"string","enum":["bandwidth","time","hybrid"]},"price_per_gb":{"type":"integer"},"price_per_day_cents":{"type":"integer"}}}}}}]},"CryptoTopupRequest":{"type":"object","required":["amount_cents","currency","network"],"properties":{"amount_cents":{"type":"integer","minimum":500,"maximum":100000000,"description":"Top-up amount in USD cents. Minimum $5.00 (500 cents), maximum $1,000,000 (100,000,000 cents).","example":5000},"currency":{"type":"string","minLength":2,"maxLength":20,"pattern":"^[A-Z0-9]+$","description":"Cryptocurrency coin code (uppercase). Example values, `USDT`, `USDC`, `BTC`, `ETH`, `LTC`, `TRX`, `BNB`, `TON`.","example":"USDT"},"network":{"type":"string","minLength":2,"maxLength":20,"pattern":"^[A-Z0-9]+$","description":"Blockchain network (uppercase). Example values, `TRON`, `ETHEREUM`, `POLYGON`, `BSC`, `BITCOIN`, `LITECOIN`, `TON`. Must be a valid network for the chosen `currency`.","example":"TRON"},"fiat_currency":{"type":"string","minLength":3,"maxLength":3,"default":"USD","description":"Fiat currency the top-up is denominated in. Defaults to `USD`.","example":"USD"}}},"CryptoTopupResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"tracking_id":{"type":"string","description":"Wallet ID. Stable per (reseller, currency, network); calling the endpoint again with the same coin/network returns the same value. Pass to `GET /balance/verify-payment/{tracking_id}`."},"address":{"type":"string","description":"Permanent crypto deposit address. Send funds to this address on the `network` shown."},"amount_crypto":{"type":"string","nullable":true,"description":"FX-derived guideline for how much crypto to send to credit `amount_usd_cents`. Actual credit equals whatever fiat value the inbound payment converts to. May be `null` if the FX rate fetch failed."},"currency":{"type":"string","description":"Echo of the requested cryptocurrency."},"network":{"type":"string","description":"Echo of the requested network. **Sending on a different network will lose the funds.**"},"amount_usd_cents":{"type":"integer","description":"USD value used to compute the `amount_crypto` guideline."},"fiat_currency":{"type":"string","description":"Fiat currency used as the basis for `amount_crypto`."},"expires_at":{"type":"string","format":"date-time","nullable":true,"description":"Always `null` — the deposit address is permanent."},"pay_url":{"type":"string","nullable":true,"description":"Always `null` — no hosted payment page in this flow. Display the address yourself."}}}}}]},"VerifyPaymentResponse":{"type":"object","properties":{"transaction_id":{"type":"string","description":"Echo of the `tracking_id` you queried."},"status":{"type":"string","enum":["pending","completed","expired","failed"],"description":"Current state. `pending` means no payment has landed on this wallet yet."},"amount_cents":{"type":"integer","description":"Most recent payment's fiat value in cents (`0` if no payment yet)."},"currency":{"type":"string","description":"Fiat currency the payment was credited as."},"completed_at":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp the most recent payment was credited. `null` until first payment."},"address":{"type":"string","nullable":true,"description":"Permanent deposit address (present when no payment has landed yet to help redisplay)."},"amount_crypto":{"type":"string","nullable":true,"description":"Always `null` here — actual crypto-amount details live in `/balance/transactions`."},"pay_currency":{"type":"string","nullable":true,"description":"Combined `COIN_NETWORK` code for this wallet."},"expires_at":{"type":"string","format":"date-time","nullable":true,"description":"Always `null` for crypto top-ups (static deposit addresses do not expire)."}}},"PlansListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}]},"PlanResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Plan"}}}]},"Plan":{"type":"object","properties":{"plan_id":{"type":"string","format":"uuid","description":"Unique plan identifier","example":"3cd1f4b9-efc3-4252-b9f7-9cebc5236164"},"product":{"type":"string","enum":["residential-lite","residential","mobile","mobile_usa","datacenter","shared_isp","isp_eu","ipv6-residential","ipv6-datacenter","pool1","pool2","pool3","pool4","pool5","unlimited_residential","dedicated_isp"],"description":"Product type"},"billing_type":{"type":"string","enum":["bandwidth","time","per_ip"],"description":"How this plan is billed"},"proxy_username":{"type":"string","description":"Proxy authentication username","example":"xaGBMTIV"},"proxy_password":{"type":"string","description":"Proxy authentication password","example":"HoLJlh55"},"connection":{"$ref":"#/components/schemas/ConnectionInfo"},"limits":{"$ref":"#/components/schemas/PlanLimits"},"location":{"type":"string","nullable":true,"description":"Location code","example":"NL"},"expires_at":{"type":"string","format":"date-time","nullable":true,"description":"Plan expiration date"},"status":{"type":"string","enum":["pending","provisioning","active","inactive","expired","cancelled","failed"],"description":"Current plan status"},"created_at":{"type":"string","format":"date-time","description":"Plan creation timestamp"},"updated_at":{"type":"string","format":"date-time","nullable":true,"description":"Last update timestamp"},"activated_at":{"type":"string","format":"date-time","nullable":true,"description":"When the plan became active"},"purchase_price_cents":{"type":"integer","nullable":true,"description":"Original purchase cost in cents"},"billing":{"$ref":"#/components/schemas/BillingInfo"},"end_user_reference":{"type":"string","nullable":true,"description":"Your custom reference for this plan"},"allowed_ips":{"type":"array","maxItems":10,"items":{"type":"string","description":"IPv4 or IPv6 address"},"description":"IP allowlist for this plan (max 10). When non-empty, only these\nsource IPs can authenticate to the proxy with this plan's\ncredentials. Empty array means no IP restriction.\n"},"pool":{"type":"string","nullable":true,"description":"IP pool name (dedicated_isp only)"},"quantity":{"type":"integer","nullable":true,"description":"Number of IPs purchased (dedicated_isp only)"},"proxy_list":{"type":"array","nullable":true,"description":"List of proxy IPs (dedicated_isp and some other products)","items":{"type":"object","properties":{"host":{"type":"string"},"port":{"type":"integer"},"username":{"type":"string"},"password":{"type":"string"},"full":{"type":"string","description":"host:port:username:password format"}}}}}},"ConnectionInfo":{"type":"object","description":"Proxy connection details","properties":{"hostname":{"type":"string","description":"Proxy server hostname or IP","example":"lite.proxyserver.bot"},"port_http":{"type":"integer","description":"HTTP proxy port","example":6969},"port_socks":{"type":"integer","nullable":true,"description":"SOCKS5 proxy port (null if not available)","example":9696},"format":{"type":"string","description":"Ready-to-use connection string","example":"xaGBMTIV:HoLJlh55@lite.proxyserver.bot:6969"}}},"PlanLimits":{"type":"object","description":"Plan usage limits","properties":{"max_gb":{"type":"number","nullable":true,"description":"Maximum GB allowed (null for unlimited)","example":10},"max_bytes":{"type":"integer","format":"int64","nullable":true,"description":"Maximum bytes allowed","example":10000000000},"bytes_used":{"type":"integer","format":"int64","description":"Bytes consumed so far","example":2500000000},"max_mbps":{"type":"integer","nullable":true,"description":"Bandwidth cap in Mbps (for time-billed plans)","example":500}}},"BillingInfo":{"type":"object","description":"Billing details for the plan","properties":{"mode":{"type":"string","enum":["price","allocation","price_only"],"description":"Billing mode used"},"price_per_gb":{"type":"number","nullable":true,"description":"Price per GB in USD"},"gb_purchased":{"type":"number","nullable":true,"description":"GB purchased"},"cost_cents":{"type":"integer","description":"Total cost in cents","example":500},"cost_formatted":{"type":"string","description":"Formatted cost string","example":"$5.00"},"balance_before":{"type":"integer","nullable":true,"description":"Balance in cents before this charge (price mode only)"},"balance_after":{"type":"integer","nullable":true,"description":"Balance in cents after this charge (price mode only)"},"allocation_before":{"type":"number","nullable":true,"description":"Allocation GB remaining before this charge (allocation mode only)"},"allocation_after":{"type":"number","nullable":true,"description":"Allocation GB remaining after this charge (allocation mode only)"},"trial_info":{"type":"object","nullable":true,"description":"Trial pricing details (unlimited residential trials only)","properties":{"trials_used_today":{"type":"integer"},"discounted_trials_remaining":{"type":"integer"},"price_applied":{"type":"string","enum":["discounted","full"]},"discounted_price_cents":{"type":"integer"},"full_price_cents":{"type":"integer"},"daily_discount_limit":{"type":"integer"}}}}},"CreatePlanRequest":{"type":"object","required":["product"],"properties":{"product":{"type":"string","enum":["residential-lite","residential","mobile","mobile_usa","datacenter","shared_isp","isp_eu","ipv6-residential","ipv6-datacenter","pool1","pool2","pool3","pool4","pool5","unlimited_residential","dedicated_isp"],"description":"Product type to purchase.\n\n**Bandwidth products** (pay per GB):\n- residential-lite, residential, mobile, mobile_usa, pool1, pool2, pool3, pool4, pool5\n\n**Hybrid products** (bandwidth OR time):\n- datacenter, shared_isp, isp_eu, ipv6-residential, ipv6-datacenter\n\n**Time products** (pay per day):\n- unlimited_residential\n"},"bandwidth_gb":{"type":"number","minimum":0.1,"description":"GB to purchase. Required for:\n- residential-lite, residential, mobile, pool1–pool5 (always)\n- datacenter, shared_isp, isp_eu, ipv6_* (when billing_type is \"bandwidth\")\n- Pool products require a minimum of 1 GB\n"},"duration":{"type":"string","enum":["trial","1_hour","1_day","7_days","14_days","30_days","60_days","90_days"],"description":"Plan duration. Required for:\n- unlimited_residential (always)\n- datacenter, shared_isp, isp_eu, ipv6_* (when billing_type is \"time\")\n- Optional for bandwidth products (sets expiry date)\n\n**Note:** \"trial\" is only valid for unlimited_residential (30 minutes).\n**Note:** \"1_hour\" is only valid for datacenter, shared_isp, isp_eu, ipv6-residential, ipv6-datacenter (priced at 1/8 of daily rate).\n"},"billing_type":{"type":"string","enum":["bandwidth","time"],"description":"Billing type for hybrid products. Required for:\n- datacenter, shared_isp, isp_eu, ipv6-residential, ipv6-datacenter\n"},"mbps":{"type":"integer","minimum":10,"maximum":10000,"description":"Bandwidth in Mbps. Required for time-billed hybrid products.\nValid range: 10-10000 Mbps\n"},"bandwidth_mbps":{"type":"integer","minimum":200,"maximum":3000,"description":"Bandwidth cap in Mbps for unlimited_residential (non-trial only).\nRange: 200–3000. Hourly plans capped at 200 Mbps.\nHigher bandwidth = higher price.\n"},"location":{"type":"string","enum":["NL","UK"],"description":""},"quantity":{"type":"integer","minimum":1,"description":"Number of proxies to purchase. Required for:\n- dedicated_isp\n\n**Check pool stock first!** Use GET /proxies/pools\n"},"pool":{"type":"string","description":"Pool name from /proxies/pools endpoint. Required for:\n- dedicated_isp\n\nExample: \"ISP_US_SNEAKERS\", \"ISP_UK_TICKETS\"\n\n**Important:** Use GET /proxies/pools to see valid pool names and stock.\n"},"end_user_reference":{"type":"string","maxLength":100,"description":"Your reference ID for this plan.\nUseful for tracking which customer/order this plan belongs to.\n"},"allowed_ips":{"type":"array","maxItems":10,"items":{"type":"string","description":"IPv4 or IPv6 address"},"description":"Optional IP allowlist for this plan (max 10). When non-empty, only\nthese source IPs can authenticate to the proxy with the plan's\ncredentials. Can be edited later via PUT /plans/{planId}/allowed-ips.\nOmit or pass [] for no restriction.\n"},"coupon_code":{"type":"string","minLength":1,"maxLength":64,"description":"Discount code applied at purchase against the cash price; balance is checked against the discounted price. Ignored for allocation-mode (pre-paid quota) purchases."}}},"UpdateAllowedIpsRequest":{"type":"object","required":["allowed_ips"],"properties":{"allowed_ips":{"type":"array","maxItems":10,"items":{"type":"string","description":"IPv4 or IPv6 address"},"description":"Replacement IP allowlist for this plan (max 10). Pass [] to clear.\nCIDR ranges are not supported.\n"}}},"ExtendPlanRequest":{"type":"object","description":"Extend a plan by adding bandwidth, time, or both (for hybrid products).\nThe accepted parameters depend on the product type:\n\n| Product | Accepted Parameters |\n|---------|-------------------|\n| residential, mobile, residential-lite, pool1–pool5 | `add_bandwidth_gb` only |\n| datacenter, shared_isp, ipv6-residential, ipv6-datacenter | `add_bandwidth_gb` and/or `add_days` |\n| isp_eu | `add_bandwidth_gb` and/or `add_days` |\n| dedicated_isp | `extend_30_days` only |\n| unlimited_residential | **not extendable** — create a new plan |\n","properties":{"add_bandwidth_gb":{"type":"number","minimum":0.1,"maximum":10000,"description":"GB to add to the plan (max 10,000 GB per extension).\nUse for: residential-lite, residential, mobile, pool1–pool5, and\nbandwidth-billed datacenter/shared_isp/isp_eu/ipv6\n"},"add_days":{"type":"integer","minimum":1,"maximum":365,"description":"Days to add to the plan expiration.\nFor hybrid products (datacenter, shared_isp, isp_eu, ipv6): any positive integer.\nNot accepted for unlimited_residential (product is not extendable).\n"},"extend_30_days":{"type":"boolean","description":"Set to true to extend a dedicated_isp plan by exactly 30 days.\nCost is calculated as: number_of_IPs × price_per_ip_30_days.\nOnly valid for dedicated_isp plans.\n"},"coupon_code":{"type":"string","minLength":1,"maxLength":64,"description":"Discounts the extension price."}}},"LocationStock":{"type":"object","properties":{"available":{"type":"integer","description":"Number of devices available","example":19},"in_stock":{"type":"boolean","description":"Whether any devices are available","example":true},"price_per_day_cents":{"type":"integer","description":"Price per day in cents","example":10000}}},"CountriesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"product_type":{"type":"string"},"total":{"type":"integer"},"countries":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","example":"United States"},"iso_code":{"type":"string","example":"US"},"flag":{"type":"string","example":"��🇸"}}}}}}}}]},"Pool":{"type":"object","description":"ISP pool information","properties":{"pool":{"type":"string","description":"Pool identifier to use when creating a plan","example":"ISP_US_SNEAKERS"},"inStock":{"type":"boolean","description":"Whether proxies are available in this pool","example":true},"stock":{"type":"integer","description":"Number of available proxies","example":150},"title":{"type":"string","description":"Human-readable pool name","example":"USA Sneaker Proxies (ISP)"},"provider":{"type":"string","enum":["ISP","SN"],"description":"Pool provider type (ISP or Subnet)","example":"ISP"},"isSubnet":{"type":"boolean","description":"Whether this is a subnet pool","example":false}}},"ProxyItem":{"type":"object","description":"Individual proxy details from a Dedicated ISP plan","properties":{"host":{"type":"string","description":"Proxy IP address","example":"192.168.1.10"},"port":{"type":"integer","description":"Proxy port","example":8080},"username":{"type":"string","description":"Authentication username","example":"flash_abc123"},"password":{"type":"string","description":"Authentication password","example":"xyz789"},"full":{"type":"string","description":"Full proxy string in ip:port:user:pass format","example":"192.168.1.10:8080:flash_abc123:xyz789"}}},"PoolListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"pools":{"type":"array","items":{"$ref":"#/components/schemas/Pool"},"description":"List of available pools"},"count":{"type":"integer","description":"Total number of pools returned","example":15},"note":{"type":"string","description":"Usage note","example":"This endpoint is exclusive to Dedicated ISP product. Use the pool value when creating a dedicated_isp plan."}}}}}]},"ProxyListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"plan_id":{"type":"string","format":"uuid","description":"Plan identifier","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},"count":{"type":"integer","description":"Number of proxies in the list","example":5},"proxies":{"type":"array","items":{"$ref":"#/components/schemas/ProxyItem"},"description":"List of proxy details"},"pool":{"type":"string","nullable":true,"description":"Pool name (for dedicated ISP plans)","example":"ISP_US_SNEAKERS"},"expires_at":{"type":"string","format":"date-time","description":"When the proxies expire","example":"2025-03-01T00:00:00.000Z"},"source":{"type":"string","enum":["provider","cached"],"description":"Whether data came fresh from provider or from cache","example":"provider"}}}}}]},"Pagination":{"type":"object","description":"Pagination metadata","properties":{"page":{"type":"integer","description":"Current page number","example":1},"per_page":{"type":"integer","description":"Items per page","example":20},"total":{"type":"integer","description":"Total number of items","example":100},"total_pages":{"type":"integer","description":"Total number of pages","example":5}}}}}}