{"openapi":"3.1.0","info":{"title":"Getwebup Cloud API","version":"1.17.0","description":"Manage your Getwebup Cloud servers from code. Production keys (cx_live_…) act on your real account; sandbox keys (cx_test_…) on a simulated copy where nothing is built or billed. Full guide: https://cloud.getwebup.in/docs/api"},"servers":[{"url":"https://cloud.getwebup.in/api","description":"Production and sandbox — the key decides which"}],"security":[{"apiKey":[]}],"tags":[{"name":"Authentication"},{"name":"Request log"},{"name":"Sandbox reset"},{"name":"Account"},{"name":"Catalogue"},{"name":"Servers"},{"name":"Server access"},{"name":"Server tools"},{"name":"Upgrades"},{"name":"Apps on servers"},{"name":"Alerts"},{"name":"Add-ons"},{"name":"Backups"},{"name":"Firewall"},{"name":"Security groups"},{"name":"Disks"},{"name":"IP addresses"},{"name":"Billing"},{"name":"Support"},{"name":"SSH keys"},{"name":"Tunnels"}],"paths":{"/v1/key":{"get":{"operationId":"key","summary":"The key you are using","description":"Who the key belongs to, whether it is a production or a sandbox key, its scopes, IP allowlist, expiry and rate limit. Needs no scope — handy to check a key works. API 1.12.0: connects_tunnels — whether the getwebup tunnel agent can sign in with it: a production key with tunnels:connect, or a full-access key from before Tunnels (which can't show that permission).\n\nNeeds a valid key; no particular permission.","tags":["Authentication"],"x-scope":null,"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"Deploy bot","mode":"production","scopes":["servers:read","servers:power"],"ip_allowlist":["203.0.113.5"],"expires_at":null,"rate_limit_per_minute":120,"account":{"id":42,"email":"asha@example.com"},"connects_tunnels":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/requests":{"get":{"operationId":"listRequests","summary":"Your API calls","description":"The request log the panel shows under API → Request log, newest first (API 1.9.0): every call made with the account's keys — answered, refused or failed — with the key, when, the caller's address and user agent, the endpoint (route) and the permission it needs, the status and error code, how long it took and the Idempotency-Key (replayed: answered from an earlier call). A production key sees the calls of every key of the account, production and sandbox; a sandbox key only the sandbox's (mode=production gives it none). Calls with a key that isn't yours, or none, aren't here. Kept as long as the request log keeps calls (see Request log above); this call is in it from the next one.\n\nRequires the `account:read` permission.","tags":["Request log"],"x-scope":"account:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"key","in":"query","required":false,"description":"Only this key's calls, by its id (GET /v1/key gives the id of the one you are using).","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"production or sandbox: only the calls made with that kind of key.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"2xx (answered), 4xx (refused) or 5xx (failed) — or one status, like 404.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Part of the path (/v1/servers), a request id (req_…) or an error code (insufficient_scope).","schema":{"type":"string"}},{"name":"ip","in":"query","required":false,"description":"Only the calls from this address.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"req_3f9a…","method":"POST","path":"/api/v1/servers","route":"POST /v1/servers","scope":"servers:write","status":201,"error_code":null,"duration_ms":840,"ip":"203.0.113.5","user_agent":"deploy-bot/2.1","key":{"id":"01a1…","name":"Deploy bot","prefix":"cx_live_Ab12Cd"},"mode":"production","idempotency_key":"b7c1…","replayed":false,"created_at":"2026-10-06T07:49:12Z"}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sandbox/reset":{"post":{"operationId":"resetSandbox","summary":"Reset the sandbox","description":"What the panel's Reset sandbox does (API 1.9.0): everything made in the sandbox is wiped — servers, disks, addresses, SSH keys, security groups, invoices, payments, tickets and the account settings changed there — and its make-believe wallet is full again. wiped: how many servers (not counting destroyed ones), SSH keys, invoices and tickets went. Your keys, the request log and your real account are never touched. With a sandbox key only: a production key gets 403 sandbox_only.\n\nRequires the `account:write` permission.","tags":["Sandbox reset"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"reset":true,"wiped":{"servers":2,"ssh_keys":1,"invoices":5,"tickets":1},"balance":1000000,"balance_display":"₹10,000.00","currency":"INR"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/account":{"get":{"operationId":"account","summary":"Your account","description":"Profile, the group the account is in, its limits and how much of them is used — and what it takes to move up a group. team: true for a Team account (API 1.8.0) — nothing it orders is invoiced or charged, so orders and purchases come back with payment.required false, and renewing answers 409 team_not_billed. API 1.9.0: email_verified; last_sign_in_at — the last sign-in to the panel (API calls don't count); identity_verification — status none, pending, review (with our team), verified or failed, how and when it was verified, and whether the account must verify (required) and before what (required_for: orders, or panel — using the panel at all; verifying is done in the panel); tax — how its invoices are taxed: type registered (a GSTIN, or a tax ID at home), unregistered or export (billed abroad), the place of supply, the taxes with their rates, whether it is exempt or reverse-charged, the note printed on its invoices, and whether prices include tax; null until a billing address is added. In the sandbox, verification and sign-in are the real account's; tax follows the sandbox's own billing address once one is set there (its invoices still carry no tax).\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":42,"email":"asha@example.com","name":"Asha Verma","phone":"+919820000000","phone_verified":true,"group":{"name":"Advanced","server_limit":8,"ipv4_limit":5},"team":false,"email_verified":true,"last_sign_in_at":"2026-10-12T08:30:05Z","identity_verification":{"status":"verified","verified":true,"verified_at":"2026-10-01T09:40:12Z","method":"digilocker","verified_name":"ASHA VERMA","required":false,"required_for":null},"created_at":"2026-10-01T09:12:44Z","tax":{"type":"registered","country":"IN","place_of_supply":"Maharashtra (27)","taxes":[{"name":"IGST","percent":18.0}],"label":"IGST 18%","percent":18.0,"exempt":false,"reverse_charge":false,"note":null,"prices_include_tax":false},"limits":{"servers":3,"server_limit":8,"ipv4":4,"ipv4_limit":5,"next_group":{"name":"Pro","top_up_needed":800000,"server_limit":20,"ipv4_limit":15}},"mode":"production"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateAccount","summary":"Change your name or phone","description":"Your name, and your phone number while it isn't confirmed (one confirmed with a code at sign-up stays). Fields left out stay as they are. The e-mail address and password are changed in the panel. The answer is the profile as GET /v1/account gives it, without limits and tax.\n\nRequires the `account:write` permission.","tags":["Account"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":42,"email":"asha@example.com","name":"Asha Verma","phone":"+919820000000"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Your name.","example":"Asha Verma"},"phone":{"type":"string","description":"International format.","example":"+919820000000"}}}}}}}},"/v1/account/billing-address":{"get":{"operationId":"billingAddress","summary":"Your billing address","description":"The address and tax number printed on your invoices. null until one is added — every order needs one.\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"name":"Asha Verma","company":"Verma Labs Pvt Ltd","line1":"12 MG Road","line2":null,"city":"Pune","state":"Maharashtra","postal_code":"411001","country":"IN","phone":null,"tax_id":"27AAPFU0939F1ZV","tax_exempt":false,"updated_at":"2026-10-01T09:20:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"saveBillingAddress","summary":"Set your billing address","description":"New invoices use it; ones already issued keep the address they were made with. In India: a 6-digit PIN, your state, and a GSTIN registered in that state (optional).\n\nRequires the `account:write` permission.","tags":["Account"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"name":"Asha Verma","company":"Verma Labs Pvt Ltd","line1":"12 MG Road","line2":null,"city":"Pune","state":"Maharashtra","postal_code":"411001","country":"IN","phone":null,"tax_id":"27AAPFU0939F1ZV","tax_exempt":false,"updated_at":"2026-10-01T09:20:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name to bill.","example":"Asha Verma"},"company":{"type":"string","description":"Company name.","example":"Verma Labs Pvt Ltd"},"line1":{"type":"string","description":"Street address.","example":"12 MG Road"},"line2":{"type":"string","description":"More of the address."},"city":{"type":"string","description":"City.","example":"Pune"},"state":{"type":"string","description":"State or union territory (or region).","example":"Maharashtra"},"postal_code":{"type":"string","description":"PIN or postal code.","example":"411001"},"country":{"type":"string","description":"Two-letter country code.","example":"IN"},"phone":{"type":"string","description":"A phone number for the invoice."},"tax_id":{"type":"string","description":"GSTIN (India) or VAT number.","example":"27AAPFU0939F1ZV"}},"required":["name","line1","city","state","postal_code","country"]}}}}}},"/v1/account/renewals":{"get":{"operationId":"renewalPreferences","summary":"Auto-renew for new servers","description":"Whether a new server starts with auto-renew on (its renewals paid from the wallet by themselves) or off.\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"auto_renew":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"saveRenewalPreferences","summary":"Set auto-renew for new servers","description":"What servers ordered from now on start with. Servers you have keep theirs: PUT /v1/subscriptions/{id}/auto-renew.\n\nRequires the `account:write` permission.","tags":["Account"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"auto_renew":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"auto_renew":{"type":"boolean","description":"true or false.","example":false}},"required":["auto_renew"]}}}}}},"/v1/account/alerts":{"get":{"operationId":"alertDefaults","summary":"Alerts for new servers","description":"The free e-mail alerts a new server starts with: when it goes down or comes back (email_alerts), and when CPU, memory or network stay high (usage_alerts).\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"email_alerts":true,"usage_alerts":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"saveAlertDefaults","summary":"Set alerts for new servers","description":"What servers ordered from now on start with; only the fields you give change. With apply_to_servers, every server you have now takes them too (applied: how many). One server on its own: PATCH /v1/servers/{id}/alerts.\n\nRequires the `account:write` permission.","tags":["Account"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"email_alerts":true,"usage_alerts":false,"applied":3}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"email_alerts":{"type":"boolean","description":"E-mail when a server goes down and comes back.","example":true},"usage_alerts":{"type":"boolean","description":"E-mail when CPU, memory or network stay at 85 % or more.","example":false},"apply_to_servers":{"type":"boolean","description":"Set them on every server you have now as well.","example":true}}}}}}}},"/v1/account/email-preferences":{"get":{"operationId":"emailPreferences","summary":"E-mail preferences","description":"Whether you get product updates and offers. Notices about your own servers (maintenance, bills, alerts) always come.\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"updates":true,"offers":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"saveEmailPreferences","summary":"Set e-mail preferences","description":"Product updates and offers, on or off. Fields left out stay as they are.\n\nRequires the `account:write` permission.","tags":["Account"],"x-scope":"account:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"updates":true,"offers":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"updates":{"type":"boolean","description":"Product updates.","example":true},"offers":{"type":"boolean","description":"Offers.","example":false}}}}}}}},"/v1/account/emails":{"get":{"operationId":"listEmails","summary":"E-mails we sent you","description":"Every e-mail sent to the account, newest first — or sorted (API 1.9.0) by date (when it went, or was queued), subject or status, as the panel's E-mails page sorts them.\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"sort","in":"query","required":false,"description":"Sort by (API 1.9.0): date (when it was sent, else queued); subject (A → Z); status (by its status). Left out: the usual order. Another word: 422.","schema":{"type":"string"}},{"name":"dir","in":"query","required":false,"description":"asc (default) or desc. Empty values come last either way; equal ones newest first.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","to":"asha@example.com","subject":"web-01.example.com is ready","status":"sent","private":false,"created_at":"2026-10-06T07:51:00Z","sent_at":"2026-10-06T07:51:02Z"}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/account/emails/{id}":{"get":{"operationId":"getEmail","summary":"One e-mail","description":"With its HTML and text. Ones that carried a one-time link or code (a sign-up or sign-in code, an address confirmation, a password reset) show a plain subject such as \"Your sign-in code\" and no body: private is true.\n\nRequires the `account:read` permission.","tags":["Account"],"x-scope":"account:read","parameters":[{"name":"id","in":"path","required":true,"description":"The e-mail's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","to":"asha@example.com","subject":"web-01.example.com is ready","status":"sent","private":false,"created_at":"2026-10-06T07:51:00Z","sent_at":"2026-10-06T07:51:02Z","html":"<!doctype html>…","text":"Your server web-01 is ready…"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/catalog":{"get":{"operationId":"catalog","summary":"Locations, images, apps, types and prices","description":"Everything a server can be made of: server types, the price of each resource (vCPU, memory, storage), locations, operating-system images, one-click apps and control panels (each with the images it installs on and the size it needs), presets and add-ons — and what is on offer where right now (availability). Amounts are in minor units (paise). API 1.11.0: tunnel_plans — the Getwebup Tunnels plans, cheapest first (free ones too): slug, name, description, price_cents (for 30 days, in minor units — paise; 0: free) with price_display, currency, is_default (the plan an account starts on) and limits — max_tunnels open at once; max_tcp_tunnels, max_reserved_subdomains, max_reserved_tcp_ports and max_custom_domains (0: not in the plan); bandwidth_monthly_bytes (traffic a calendar month), bandwidth_rate_bps (bytes a second), requests_per_minute and max_conns_per_tunnel (0: no limit). Left out when the plans can't be read right now. API 1.12.0: what your account can do with each plan, and its price with your tax — GET /v1/tunnels/plans. API 1.13.0: min_cpu on each app — the fewest CPU cores it is sold with (vCPU on a VPS, host cores on a VDS; 1 for most; a quote or a rebuild with fewer is refused).\n\nRequires the `catalog:read` permission.","tags":["Catalogue"],"x-scope":"catalog:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"currency":"INR","types":{"vps":{"code":"vps","name":"VPS"}},"locations":[{"code":"in-bom-1","name":"Mumbai"}],"images":[{"code":"ubuntu-24.04","label":"Ubuntu 24.04 LTS","family":"linux"}],"apps":[{"code":"wordpress","kind":"app","name":"WordPress","images":["ubuntu-24.04","debian-12"],"min_cpu":1,"min_ram_gb":1,"min_disk_gb":10,"minutes":5}],"availability":{"in-bom-1":{"ready":true,"images":["ubuntu-24.04","debian-12"],"backups":true,"ipv6":true}},"resources":["…"],"addons":["…"],"presets":["…"],"tunnel_plans":[{"slug":"pro","name":"Pro","description":"For everyday development","currency":"INR","price_cents":29900,"price_display":"₹299.00","is_default":false,"limits":{"max_tunnels":10,"max_tcp_tunnels":2,"max_reserved_subdomains":5,"max_reserved_tcp_ports":2,"max_custom_domains":2,"bandwidth_monthly_bytes":107374182400,"bandwidth_rate_bps":12500000,"requests_per_minute":0,"max_conns_per_tunnel":0}}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/quotes":{"post":{"operationId":"quote","summary":"Price a server","description":"What a server of this size costs for 30 days, line by line, before tax — with an app and add-ons if you give them. Nothing is ordered. API 1.9.0: with your tax, as its invoice would charge it and the panel shows it — tax, taxes (each at its rate: CGST and SGST, or IGST…), monthly_with_tax, tax_label (null: no tax for you, like an export), tax_mode (inclusive: the prices have the tax in them), tax_note, and on each line whether it is taxed. For a Team account free and team are true and there is no tax: nothing is invoiced, and monthly stays the list price. The sandbox charges no tax (tax_label \"No tax (sandbox)\").\n\nRequires the `catalog:read` permission.","tags":["Catalogue"],"x-scope":"catalog:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"currency":"INR","monthly":59000,"monthly_display":"₹590.00","lines":[{"label":"2 vCPU","quantity":2,"amount":30000,"included":false,"taxed":true}],"port_label":"100 Mbit/s","tax":10620,"taxes":[{"name":"IGST","rate":"18%","rate_bp":1800,"amount":10620,"amount_display":"₹106.20","compound":false}],"monthly_with_tax":69620,"monthly_with_tax_display":"₹696.20","tax_label":"IGST 18%","tax_mode":"exclusive","tax_note":null,"free":false,"team":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location":{"type":"string","description":"A location code from the catalogue.","example":"in-bom-1"},"image":{"type":"string","description":"An operating-system image code from the catalogue.","example":"ubuntu-24.04"},"cpu":{"type":"integer","description":"vCPUs.","example":2},"ram_gb":{"type":"integer","description":"Memory in GB.","example":4},"disk_gb":{"type":"integer","description":"NVMe storage in GB.","example":60},"type":{"type":"string","description":"Server type code (default vps).","example":"vps"},"app":{"type":"string","description":"A one-click app or control panel code from the catalogue.","example":"wordpress"},"addons":{"type":"object","description":"Add-on codes and how many: {\"backups\": 1, \"bandwidth\": 2}.","example":{"backups":1}}},"required":["location","image","cpu","ram_gb","disk_gb"]}}}}}},"/v1/coupons/check":{"post":{"operationId":"checkCoupon","summary":"Check a coupon","description":"Whether a coupon works for you, and — with an amount (before tax) — the discount it would give. The order checks it again. A coupon given with an order is on its first invoice — so is one given with an upgrade, an add-on or a disk grown (they count as orders); one that works on renewals goes on a renewal invoice with POST /v1/invoices/{id}/coupon, or with POST /v1/servers/{id}/renew. API 1.10.0: applies_to says what it works on — all (orders and renewals), orders (new orders and moves), renewals, or moves (only a move of a server or a disk, or a rebuild in another location: for move); max_discount is the most its discount comes to (null: no cap); type none gives no discount, only offers. perks: what it gives besides its discount, on a new server only (for server — given with POST /v1/servers; refused with any other order and on an invoice): add-ons free with it (addons, each by type — its add-on code — with quantity: bandwidth's TB free, 1 for the others) and extra vCPU, memory and storage at no charge (resources), both for free_periods periods of 30 days — the order's own the first; null: for good — and then at the normal price; and the server's first renewals.count renewals renewals.percent % off (100: free). They come with the order by themselves; label says it all in words. null: no offers.\n\nRequires the `catalog:read` permission.","tags":["Catalogue"],"x-scope":"catalog:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"code":"WELCOME10","label":"10% off (up to ₹500.00)","description":"For new customers","type":"percent","discount":5900,"discount_display":"₹59.00","min_amount":null,"max_amount":null,"expires_at":"2026-12-31T18:29:59Z","applies_to":"orders","max_discount":50000,"perks":{"addons":[{"type":"backups","name":"Automatic backups","quantity":1,"pricing":"per_disk"}],"resources":{"cpu":1,"ram_gb":2,"disk_gb":20},"free_periods":3,"renewals":{"count":2,"percent":50},"label":"Free backups for 3 × 30 days · +1 vCPU, +2 GB RAM, +20 GB disk · first 2 renewals 50% off"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"The coupon code.","example":"WELCOME10"},"for":{"type":"string","description":"What it would go on: an order (default — an address or a disk of its own, an upgrade, an add-on, a disk grown), a renewal invoice, a move (API 1.10.0: of a server or a disk, or a rebuild in another location) or a new server (API 1.10.0: where its free offers work).","enum":["order","renewal","move","server"]},"amount":{"type":"integer","description":"An order's amount for 30 days in minor units, to work the discount out. For a new server with offers: what it costs without them.","example":59000}},"required":["code"]}}}}}},"/v1/servers":{"get":{"operationId":"listServers","summary":"List servers","description":"Your servers, newest first. Destroyed ones are left out unless you ask for status=terminated. API 1.9.0: search them with q and sort them (sort, dir) as the panel's servers list does; serial is the server's SN as the panel shows it.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"Only these statuses, comma separated: provisioning, active, suspended, awaiting_payment, failed, upgrading, rebuilding, migrating, terminated.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Search (API 1.9.0): part of a name, an IPv4 or IPv6 address, the operating system or the location; the SN (F55C-DBE0, or part of it); or a server's id.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Sort by (API 1.9.0): name (the hostname, A → Z); created (when it was ordered); status (its status); location (the location's name); ipv4 (its main IPv4, as numbers); size (vCPU, then memory, then storage); bandwidth (data transferred this month); uptime (how long it has been up (running servers only)); expires (when its paid time ends). Left out: the usual order. Another word: 422.","schema":{"type":"string"}},{"name":"dir","in":"query","required":false,"description":"asc (default) or desc. Empty values come last either way; equal ones newest first.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a10eff-7046-7490-84f7-6318061bb37d","hostname":"web-01.example.com","status":"active","power":"running","serial":"061B-B37D","type":"vps","location":"in-bom-1","location_name":"Mumbai","image":"ubuntu-24.04","image_label":"Ubuntu 24.04 LTS","os_family":"linux","cpu":2,"ram_gb":4,"disk_gb":60,"port_mbps":100,"ipv4":"203.0.113.16","ipv6":"2001:db8:100::16","network":{"ipv4":{"address":"203.0.113.16","prefix":24,"gateway":"203.0.113.1","netmask":"255.255.255.0","dns":["203.0.113.2","203.0.113.3"]},"ipv6":{"address":"2001:db8:100::16","prefix":64,"gateway":"2001:db8:100::1","subnet":null,"dns":["2001:db8:100::2"]},"ipv4_extra":[{"address":"203.0.113.40","prefix":24,"gateway":"203.0.113.1","inside":true}],"setup":{"state":"done","message":"Set up inside the server."}},"app":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null},"backups_enabled":true,"firewall_enabled":true,"call_alerting":false,"uptime_seconds":86400,"bandwidth":{"used_bytes":26843545600,"allowance_bytes":1099511627776,"percent":2.4,"limited":null,"limited_mbps":null,"resets_on":"2026-11-01"},"licence":null,"upgrade":null,"failure_reason":null,"created_at":"2026-10-06T07:49:12Z","sandbox":false}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createServer","summary":"Create a server","description":"Orders a server — with an app, add-ons and extra IPv4 addresses if you like — and pays from the wallet; it is then built (status provisioning → active, usually in a minute or two; an app installs after). If the wallet can't cover it, the server waits with status awaiting_payment and payment.required = true: pay with POST /v1/invoices/{id}/pay, or top up the wallet, and it is built automatically. Extra IPv4 addresses are subscriptions of their own, each with its own invoice (payment.invoice_ids). Send an Idempotency-Key so a retry never orders twice. API 1.10.0: a coupon with free offers (POST /v1/coupons/check with for server: perks) brings them by itself — its add-ons are switched on and its extra vCPU, memory and storage built on top of the size you give (cpu, ram_gb and disk_gb in the answer are what is built; they count toward your limits and need room in the location like any server). The first invoice has each at its normal price with a line taking it off (perk: true), then the coupon's discount on what is left; they stay free for the coupon's free periods of 30 days (the order's own the first) and its free renewals come off this server's renewals — GET /v1/subscriptions (perks) shows what is left. coupon: the coupon as it went on the first invoice — code, discount (0 for one that only gives offers) and its offers (perks, as POST /v1/coupons/check shows them) — or null. A Team account takes no coupon, so none is checked or added. The sandbox does the same with make-believe money (a Team account's too).\n\nRequires the `servers:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Servers"],"x-scope":"servers:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a10eff-7046-7490-84f7-6318061bb37d","hostname":"web-01.example.com","status":"active","power":"running","serial":"061B-B37D","type":"vps","location":"in-bom-1","location_name":"Mumbai","image":"ubuntu-24.04","image_label":"Ubuntu 24.04 LTS","os_family":"linux","cpu":2,"ram_gb":4,"disk_gb":60,"port_mbps":100,"ipv4":"203.0.113.16","ipv6":"2001:db8:100::16","network":{"ipv4":{"address":"203.0.113.16","prefix":24,"gateway":"203.0.113.1","netmask":"255.255.255.0","dns":["203.0.113.2","203.0.113.3"]},"ipv6":{"address":"2001:db8:100::16","prefix":64,"gateway":"2001:db8:100::1","subnet":null,"dns":["2001:db8:100::2"]},"ipv4_extra":[{"address":"203.0.113.40","prefix":24,"gateway":"203.0.113.1","inside":true}],"setup":{"state":"done","message":"Set up inside the server."}},"app":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null},"backups_enabled":true,"firewall_enabled":true,"call_alerting":false,"uptime_seconds":86400,"bandwidth":{"used_bytes":26843545600,"allowance_bytes":1099511627776,"percent":2.4,"limited":null,"limited_mbps":null,"resets_on":"2026-11-01"},"licence":null,"upgrade":null,"failure_reason":null,"created_at":"2026-10-06T07:49:12Z","sandbox":false,"payment":{"required":false,"invoice_id":"01a1…","invoice_ids":["01a1…"],"total":62658,"total_display":"₹626.58","amount_due":0},"coupon":{"code":"WELCOME10","discount":5900,"discount_display":"₹59.00","perks":{"addons":[{"type":"backups","name":"Automatic backups","quantity":1,"pricing":"per_disk"}],"resources":{"cpu":1,"ram_gb":2,"disk_gb":20},"free_periods":3,"renewals":{"count":2,"percent":50},"label":"Free backups for 3 × 30 days · +1 vCPU, +2 GB RAM, +20 GB disk · first 2 renewals 50% off"}}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"string","description":"A hostname (letters, digits, dots, dashes). Left out: one is made up.","example":"web-01.example.com"},"location":{"type":"string","description":"A location code from the catalogue.","example":"in-bom-1"},"image":{"type":"string","description":"An operating-system image code from the catalogue.","example":"ubuntu-24.04"},"cpu":{"type":"integer","description":"vCPUs.","example":2},"ram_gb":{"type":"integer","description":"Memory in GB.","example":4},"disk_gb":{"type":"integer","description":"NVMe storage in GB.","example":60},"type":{"type":"string","description":"Server type code (default vps).","example":"vps"},"app":{"type":"string","description":"A one-click app or control panel from the catalogue, installed on the fresh system (free).","example":"wordpress"},"addons":{"type":"object","description":"Add-ons and how many: backups, alerting (call alerting), managed, bandwidth (TB a month).","example":{"backups":1}},"alert_phone":{"type":"string","description":"With call alerting: the number to call, international format.","example":"+919820000000"},"extra_ipv4":{"type":"integer","description":"Extra IPv4 addresses for it (0–64), each its own subscription.","example":0},"ipv4_id":{"type":"string","description":"One of your own unattached IPv4 addresses (GET /v1/ips) in this location, as its main address."},"ssh_key_ids":{"type":"array","description":"Ids of your SSH keys to put on the server.","example":["01a1…"],"items":{"type":"string"}},"ssh_public_keys":{"type":"array","description":"More public keys, as text (\"ssh-ed25519 AAAA… you@laptop\"). At most 10 keys in all.","items":{"type":"string"}},"password":{"type":"string","description":"A root/Administrator password (10+ characters, mixed case, a digit). Left out: one is generated (read it with GET /v1/servers/{id}/credentials)."},"coupon":{"type":"string","description":"A coupon code for the first invoice — with its free offers, if it has any (API 1.10.0). 422 on coupon says why one does not work; nothing is ordered then.","example":"WELCOME10"}},"required":["location","image","cpu","ram_gb","disk_gb"]}}}}}},"/v1/servers/{id}":{"get":{"operationId":"getServer","summary":"Get a server","description":"One server: status, power state, size, addresses, its app, this month's bandwidth, uptime (the rolling 30 days; month by month: GET …/uptime). network (API 1.9.0, in lists too): each address with its netmask or prefix, gateway and resolvers (dns), the IPv6 subnet routed to it (null when it has a single address), and whether each extra IPv4 is set up inside the server yet (inside) — network.setup says how the addresses inside it stand: done, updating (being set up through its guest agent), waiting_for_start (it is off: set up once it runs) or failed (its guest agent did not answer — set them up by hand). perks (API 1.10.0, not in lists): the free offers of the coupon it was ordered with, as GET /v1/subscriptions shows them — [] when none, null when they can't be read right now.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a10eff-7046-7490-84f7-6318061bb37d","hostname":"web-01.example.com","status":"active","power":"running","serial":"061B-B37D","type":"vps","location":"in-bom-1","location_name":"Mumbai","image":"ubuntu-24.04","image_label":"Ubuntu 24.04 LTS","os_family":"linux","cpu":2,"ram_gb":4,"disk_gb":60,"port_mbps":100,"ipv4":"203.0.113.16","ipv6":"2001:db8:100::16","network":{"ipv4":{"address":"203.0.113.16","prefix":24,"gateway":"203.0.113.1","netmask":"255.255.255.0","dns":["203.0.113.2","203.0.113.3"]},"ipv6":{"address":"2001:db8:100::16","prefix":64,"gateway":"2001:db8:100::1","subnet":null,"dns":["2001:db8:100::2"]},"ipv4_extra":[{"address":"203.0.113.40","prefix":24,"gateway":"203.0.113.1","inside":true}],"setup":{"state":"done","message":"Set up inside the server."}},"app":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null},"backups_enabled":true,"firewall_enabled":true,"call_alerting":false,"uptime_seconds":86400,"bandwidth":{"used_bytes":26843545600,"allowance_bytes":1099511627776,"percent":2.4,"limited":null,"limited_mbps":null,"resets_on":"2026-11-01"},"licence":null,"upgrade":null,"failure_reason":null,"created_at":"2026-10-06T07:49:12Z","sandbox":false,"uptime_30d":{"percent":99.982,"outages":1,"state":"up"},"perks":[{"kind":"addon","coupon":"WELCOME10","label":"Automatic backups","addon":"backups","periods":3,"periods_used":1,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"},{"kind":"resources","coupon":"WELCOME10","label":"+1 vCPU, +2 GB RAM, +20 GB disk","addon":null,"cpu":1,"ram_gb":2,"disk_gb":20,"periods":3,"periods_used":1,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"},{"kind":"renewals","coupon":"WELCOME10","label":"First 2 renewals 50% off","addon":null,"percent":50,"periods":2,"periods_used":0,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"renameServer","summary":"Rename a server","description":"Changes the hostname — in the panel, on invoices and inside the server (through its guest agent). rename (API 1.9.0) says when it takes effect inside: now (being set — follow it in the activity), next_start (the server is off or its guest agent does not answer: set the next time it runs) or next_restart (Windows takes the new computer name at its next restart); changed false and inside null when it already had that name.\n\nRequires the `servers:write` permission.","tags":["Servers"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a10eff-7046-7490-84f7-6318061bb37d","hostname":"web-02.example.com","status":"active","power":"running","serial":"061B-B37D","type":"vps","location":"in-bom-1","location_name":"Mumbai","image":"ubuntu-24.04","image_label":"Ubuntu 24.04 LTS","os_family":"linux","cpu":2,"ram_gb":4,"disk_gb":60,"port_mbps":100,"ipv4":"203.0.113.16","ipv6":"2001:db8:100::16","network":{"ipv4":{"address":"203.0.113.16","prefix":24,"gateway":"203.0.113.1","netmask":"255.255.255.0","dns":["203.0.113.2","203.0.113.3"]},"ipv6":{"address":"2001:db8:100::16","prefix":64,"gateway":"2001:db8:100::1","subnet":null,"dns":["2001:db8:100::2"]},"ipv4_extra":[{"address":"203.0.113.40","prefix":24,"gateway":"203.0.113.1","inside":true}],"setup":{"state":"done","message":"Set up inside the server."}},"app":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null},"backups_enabled":true,"firewall_enabled":true,"call_alerting":false,"uptime_seconds":86400,"bandwidth":{"used_bytes":26843545600,"allowance_bytes":1099511627776,"percent":2.4,"limited":null,"limited_mbps":null,"resets_on":"2026-11-01"},"licence":null,"upgrade":null,"failure_reason":null,"created_at":"2026-10-06T07:49:12Z","sandbox":false,"rename":{"changed":true,"previous":"web-01.example.com","inside":"now","message":"The hostname inside the server is being set now."}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"string","description":"The new hostname.","example":"web-02.example.com"}},"required":["hostname"]}}}}},"delete":{"operationId":"deleteServer","summary":"Destroy a server","description":"Ends its subscription and destroys it with its disks and backups. This cannot be undone. Disks and IPv4 addresses of your own on it are taken off and stay yours. The server moves to status terminated once it is gone. An order never paid is simply dropped.\n\nRequires the `servers:write` permission.","tags":["Servers"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a10eff-7046-7490-84f7-6318061bb37d","status":"terminating"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/actions":{"post":{"operationId":"serverAction","summary":"Power a server on or off","description":"start; shutdown (asks the operating system to shut down); reboot; stop (cuts the power, like pulling the plug). Returns at once — read the server to follow its power state.\n\nRequires the `servers:power` permission.\n\nSupports `Idempotency-Key`.","tags":["Servers"],"x-scope":"servers:power","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","type":"reboot","status":"running","server_id":"01a10eff-7046-7490-84f7-6318061bb37d"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"What to do.","example":"reboot","enum":["start","shutdown","reboot","stop"]}},"required":["type"]}}}}}},"/v1/servers/{id}/activity":{"get":{"operationId":"serverActivity","summary":"What happened to a server","description":"Its activity log, newest first: the build steps, power changes, renames, rebuilds, backups, firewall changes — with how far one still running is.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","action":"power","label":"Reboot","status":"ok","progress":null,"detail":null,"started_at":"2026-10-06T08:00:00Z","finished_at":"2026-10-06T08:00:21Z","duration_ms":21000,"created_at":"2026-10-06T08:00:00Z"}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/stats":{"get":{"operationId":"serverStats","summary":"Live usage","description":"CPU, memory, network and disk right now, read from the host. available is false while the server is not running normally. cpu_percent is a share of all its vCPUs, 0 to 100. Network and disk counters run since the server last started. memory_used_bytes is what the system inside reports in use — its page cache (Windows: standby memory) included, so a long-running server can read near full with plenty available; the high-usage alert judges its available memory instead (see its alerts) — and until it reports that (the first moments of a boot, or a server without the VirtIO balloon driver), the memory the server has touched as seen from outside, never more than memory_total_bytes.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"available":true,"power":"running","cpu_percent":12.5,"cpus":2,"memory_used_bytes":1288490188,"memory_total_bytes":4294967296,"uptime_seconds":86400,"network_in_bytes":52428800,"network_out_bytes":15728640,"disk_read_bytes":734003200,"disk_write_bytes":209715200}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/metrics":{"get":{"operationId":"serverMetrics","summary":"Usage graphs","description":"About 70 points over the range — each the average (or the peak) of its slot: CPU in percent of the server's vCPUs, memory in bytes (as in its live usage: what the system inside uses, or, until it reports that, the memory the server has touched as seen from outside — never more than memory_total_bytes), network in bits a second, disk in bytes a second. A slot with no data (the server off) is null.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"range","in":"query","required":false,"description":"hour, day (default), week, month or year.","schema":{"type":"string"}},{"name":"agg","in":"query","required":false,"description":"avg (default) or max.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"available":true,"range":"day","agg":"avg","step":1800,"cpus":2,"memory_total_bytes":4294967296,"points":[{"t":1791360000,"cpu":8.5,"memory":1288490188,"network_in":120000.0,"network_out":54000.0,"disk_read":0.0,"disk_write":40960.0}],"summary":{"cpu":{"avg":7.9,"max":31.2,"last":8.5}}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/bandwidth":{"get":{"operationId":"serverBandwidth","summary":"Bandwidth this month","description":"Data transfer in and out: this calendar month day by day, today and since the server was built, with the monthly allowance and where the month stands against it. Used up: the server is disconnected (or slowed) until the month ends or you add bandwidth — when_used_up says which (disconnect, slow or none). slow_mbps (API 1.9.0): with slow, the speed in Mbit/s it is slowed to once the allowance is used up; limited_mbps: while it is slowed (limited: slowed), the speed it runs at now.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"month":{"in":21474836480,"out":5368709120,"total":26843545600,"from":"2026-10-01","to":"2026-10-31"},"today":{"in":0,"out":0,"total":0},"allowance":{"unmetered":false,"bytes":1099511627776,"used":26843545600,"percent":2.4,"extra_tb":0,"limited":null,"when_used_up":"slow","slow_mbps":10,"limited_mbps":null,"resets_on":"2026-11-01"},"days":[{"day":"2026-10-01","in":1073741824,"out":268435456}],"timezone":"Asia/Kolkata"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/uptime":{"get":{"operationId":"serverUptime","summary":"Uptime by calendar month","description":"One calendar month of uptime, as the server page shows it (API 1.9.0): this month (so far) or one of the two before (months lists them) — each day's seconds up, down and off, and its share up, in the panel's time zone. Down: it should be running and isn't (or, with call alerting, its port stopped answering); off: stopped by you, suspended, disconnected for using up its bandwidth or held by a backup — off time doesn't count against it. A day with nothing counted (off all day, or before the server) has percent null; outages: the alerted ones that month. The rolling 30 days stay on GET /v1/servers/{id} (uptime_30d). A month that isn't one of the three answers 422 on month.\n\nRequires the `servers:read` permission.","tags":["Servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"month","in":"query","required":false,"description":"YYYY-MM: this month (default) or one of the two before.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"month":"2026-10","label":"October 2026","current":true,"months":[{"month":"2026-10","label":"October 2026"},{"month":"2026-09","label":"September 2026"},{"month":"2026-08","label":"August 2026"}],"percent":99.982,"up_s":1036620,"down_s":187,"off_s":600,"outages":1,"days":[{"day":"2026-10-01","up_s":86213,"down_s":187,"off_s":0,"percent":99.783}],"state":"up","since":"2026-09-14","timezone":"Asia/Kolkata"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/credentials":{"get":{"operationId":"serverCredentials","summary":"Its login","description":"The username and password to log in to the server (root, or Administrator on Windows), and the SSH command (Linux). Treat it like the password it is. API 1.17.0: ssh is null on Windows — sign in with Remote Desktop to ipv4 as the username.\n\nRequires the `servers:access` permission.","tags":["Server access"],"x-scope":"servers:access","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"username":"root","password":"q8Xn…","ipv4":"203.0.113.16","ssh":"ssh root@203.0.113.16"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/password":{"post":{"operationId":"serverPassword","summary":"Set a new login password","description":"Sets it inside the running server through its guest agent — open SSH sessions stay connected. Left out: a strong one is generated (read it with GET …/credentials). You are e-mailed that it changed.\n\nRequires the `servers:access` permission.","tags":["Server access"],"x-scope":"servers:access","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"generated":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"10+ characters with upper- and lower-case letters and a digit; keyboard characters only."}}}}}}}},"/v1/servers/{id}/console":{"post":{"operationId":"openConsole","summary":"Open the console","description":"A one-time ticket to the server's screen and keyboard (VNC), good for one connection within expires_in seconds: open a WebSocket to websocket_url, send token as the first message (within 3 seconds of it opening), then speak RFB 3.8 with security type None (the panel signs in to the console for you). Or open panel_url in a browser signed in to the panel. In the sandbox the ticket is simulated: nothing connects, and panel_url leads to this documentation.\n\nRequires the `servers:access` permission.","tags":["Server access"],"x-scope":"servers:access","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"websocket_url":"wss://panel.example.com/console/ws","token":"kS1v…","expires_in":60,"protocol":"rfb","panel_url":"https://panel.example.com/servers/01a1…/console"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/rebuild":{"get":{"operationId":"rebuildOptions","summary":"What it can be rebuilt with","description":"The operating systems it can get — each available, or why not (too small, or priced differently: a licence) — with the apps that can go on each, and the locations it can be rebuilt in (another location gives it a new IPv4 there). move_price (API 1.9.0): what a rebuild in another location costs before you order it — its extra disks are copied there, gb at the catalogue's rate per GB, plus tax; the same for every other location. gb 0 (no extra disks), moves priced at 0, or a Team account: free, nothing is charged. null when it can't be priced right now (move_price_error says why). move_order (API 1.9.0): a rebuild in another location ordered as a paid move — waiting for payment (pending), paid (it starts in a moment), started, done, refunded (it could not go ahead: reason says why, and the charge is back in the wallet) or void (dropped, or not paid in time) — the one waiting, else the latest of the last 7 days; null when there is none.\n\nRequires the `servers:read` permission.","tags":["Server tools"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"location","in":"query","required":false,"description":"The systems on offer in another location.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"images":[{"code":"debian-12","label":"Debian 12","family":"linux","current":false,"available":true,"reason":null,"apps":[{"code":"wordpress","available":true,"reason":null}]}],"locations":[{"code":"in-bom-1","name":"Mumbai","current":true,"available":true,"new_ip":false,"reason":null}],"move_price":{"gb":20,"rate":50,"rate_display":"₹0.50","amount":1000,"amount_display":"₹10.00","tax":180,"tax_label":"IGST 18%","total":1180,"total_display":"₹11.80","taxed":true,"free":false,"team":false},"move_price_error":null,"move_order":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"rebuildServer","summary":"Rebuild with a fresh system","description":"Erases the system disk and installs a fresh one — another image if you like, with an app — keeping the server's addresses (unless it moves location), extra disks, backups and firewall. Everything on the old system disk is lost. The server reads rebuilding until it is active again, usually a few minutes. In another location its extra disks are copied there, a one-time charge per GB copied plus tax (the catalogue's move resource; the system disk is not copied, so with no extra disks it is free): it is paid from the wallet at once, or the answer reads awaiting_payment with payment.required — pay its invoice (POST /v1/invoices/{id}/pay) and the rebuild starts then, or drop it (DELETE …/rebuild). Once paid it is checked again as it starts: if it can't be started there any more (no room, or its extra disks changed since it was ordered), nothing changes on the server and the charge goes back to the wallet; if the move fails part-way, it is rebuilt where it is, on its usual addresses, and the charge goes back too. payment is null when nothing was charged (nothing to copy, or moves are free). move_order (API 1.9.0): the paid move it was ordered as — follow it with GET …/rebuild (move_order) — or null when it was rebuilt directly.\n\nRequires the `servers:write` permission. Choosing its login — password, ssh_key_ids, ssh_public_keys, or an app whose first login is made on its setup page (login setup in the catalogue) — needs servers:access as well: 403 insufficient_scope (fields.scope servers:access) without it. With servers:write alone, leave them out: a password is made up (never answered — read it with servers:access) and the server's SSH keys are kept.\n\nSupports `Idempotency-Key`.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","status":"awaiting_payment","image":"debian-12","app":null,"location":"in-noi-1","moves":true,"password_generated":true,"payment":{"required":true,"invoice_id":"01a1…","total":1180,"total_display":"₹11.80","amount_due":1180},"move_order":{"id":"01a1…","kind":"rebuild","status":"pending","description":"Rebuilding web-01.example.com in Noida — 20 GB of extra disks copied","gb":20,"rate":50,"rate_display":"₹0.50","amount":1000,"amount_display":"₹10.00","total":1180,"total_display":"₹11.80","location":"in-noi-1","location_name":"Noida","server":null,"new_ip":null,"image":"debian-12","app":null,"invoice_id":"01a1…","reason":null,"created_at":"2026-10-13T09:00:00Z","paid_at":null,"finished_at":null}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-scope-also":{"scope":"servers:access","when":"Choosing its login — password, ssh_key_ids, ssh_public_keys, or an app whose first login is made on its setup page (login setup in the catalogue) — needs servers:access as well: 403 insufficient_scope (fields.scope servers:access) without it. With servers:write alone, leave them out: a password is made up (never answered — read it with servers:access) and the server's SSH keys are kept."},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string","description":"An image from GET …/rebuild.","example":"debian-12"},"location":{"type":"string","description":"Rebuild it in another location (it gets a new IPv4 there). Its extra disks are copied there, charged per GB."},"app":{"type":"string","description":"An app or control panel to install on the fresh system.","example":"wordpress"},"password":{"type":"string","description":"The new login password (needs servers:access as well). Left out: one is generated."},"keep_ssh_keys":{"type":"boolean","description":"Put the same SSH keys on the fresh system (default true when no keys are given)."},"ssh_key_ids":{"type":"array","description":"Your SSH keys for the fresh system instead (needs servers:access as well).","items":{"type":"string"}},"ssh_public_keys":{"type":"array","description":"More public keys, as text (needs servers:access as well).","items":{"type":"string"}},"coupon":{"type":"string","description":"In another location with extra disks to copy: a coupon code (any case) off that charge, before tax. 422 on coupon says why one does not work; nothing is charged then. A coupon for moves only works here too (API 1.10.0); one with free offers works only with POST /v1/servers."}},"required":["image"]}}}}},"delete":{"operationId":"cancelRebuildMove","summary":"Drop an unpaid rebuild elsewhere","description":"A rebuild in another location that is waiting for payment (it answered awaiting_payment) is dropped and its invoice voided; nothing changes on the server. Until it is paid or dropped, upgrades, moves and other rebuilds elsewhere answer 409 move_pending. 404 when none is waiting (a move of the server waiting for payment is dropped with DELETE …/move).\n\nRequires the `servers:write` permission.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"cancelled":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/move":{"get":{"operationId":"serverMoveOptions","summary":"Where it can move, and what it costs","description":"API 1.9.0. Every location it can be moved to, where it is first (current: another host there — it keeps its IP addresses, and a running VPS keeps running while it moves: live; where it can't move live, live is false and it is stopped for a few minutes during the move) — each available, or why not (reason) — and whether it gets a new IPv4 address there (new_ip). No host is ever named. blocked: why it can't be moved at all right now (not built yet, suspended, something else being done to it, a backup running, or moved less than gap_hours ago). price: what the move costs, once — the GB copied (gb: its system disk and the extra disks on it) at the catalogue's rate per GB, plus tax (tax_label); the same wherever it goes. For a Team account free and team are true and nothing is charged (amount, tax and total 0); a move that copies nothing, or moves priced at 0, is free too. null when it can't be priced right now (price_error says why). pending: a move waiting for payment (kind server — or a rebuild in another location, kind rebuild); recent: the latest other one of the last 7 days — paid (it starts in a moment), started, done, refunded (it could not go ahead: reason says why, and the charge is back in the wallet) or void (dropped, or not paid in time).\n\nRequires the `servers:read` permission.","tags":["Server tools"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"blocked":null,"running":true,"vds":false,"gap_hours":24,"gb":80,"system_gb":60,"extras_gb":20,"locations":[{"code":"in-bom-1","name":"Mumbai","country":"IN","current":true,"available":true,"reason":null,"new_ip":false,"live":true},{"code":"in-noi-1","name":"Noida","country":"IN","current":false,"available":true,"reason":null,"new_ip":true,"live":false}],"price":{"gb":80,"rate":50,"rate_display":"₹0.50","amount":4000,"amount_display":"₹40.00","tax":720,"tax_label":"IGST 18%","total":4720,"total_display":"₹47.20","taxed":true,"free":false,"team":false,"system_gb":60,"extras_gb":20},"price_error":null,"pending":null,"recent":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"moveServer","summary":"Move it to another location or host","description":"API 1.9.0. Orders the move the panel's move page makes: to another location (it gets a new IPv4 address there and is stopped for the move — point your domains at it afterwards; addresses of your own stay yours where they are), or to another host where it is (its own location: it keeps its addresses, and a running VPS keeps running — unless GET …/move says live false there: then it is stopped for a few minutes during the move). Its system, files, extra disks, firewall and plan come along; the plan's price stays the same. Backups taken so far stay where they are. The move is charged once — the GB copied, plus tax (GET …/move: price) — and paid from the wallet at once; it then starts by itself: the server reads migrating, then active (follow GET /v1/servers/{id}; you are e-mailed when it is done). If the wallet can't cover it, move.status is pending and payment.required is true: pay its invoice (POST /v1/invoices/{id}/pay) and it starts then, or drop it (DELETE). One that copies nothing, moves priced at 0, or a Team account's is never invoiced: payment.invoice_id is null. Once paid it is checked again as it starts: if it can't start any more (no room there now, its disks changed since it was ordered), or the move fails and it stays where it was, the charge goes back to the wallet — status refunded, with the reason (GET …/move: recent). One at a time: 409 move_pending while a move or a rebuild elsewhere waits for payment or is under way, 409 upgrade_pending while an upgrade waits for payment; 409 cannot_move says why it can't be moved now (once a day at most); 409 not_active while it is suspended or not running yet.\n\nRequires the `servers:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"move":{"id":"01a1…","kind":"server","status":"done","description":"Moving web-01.example.com to Noida — 80 GB copied","gb":80,"rate":50,"rate_display":"₹0.50","amount":4000,"amount_display":"₹40.00","total":4720,"total_display":"₹47.20","location":"in-noi-1","location_name":"Noida","server":null,"new_ip":true,"image":null,"app":null,"invoice_id":"01a1…","reason":null,"created_at":"2026-10-13T09:00:00Z","paid_at":"2026-10-13T09:00:01Z","finished_at":"2026-10-13T09:06:40Z"},"payment":{"required":false,"invoice_id":"01a1…","total":4720,"total_display":"₹47.20","amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location":{"type":"string","description":"A location from GET …/move: another one — or its own, for another host there.","example":"in-noi-1"},"coupon":{"type":"string","description":"A coupon code (any case) off the move, before tax — before the wallet pays it. 422 on coupon says why one does not work; nothing is ordered then. A coupon for moves only works here too (API 1.10.0); one with free offers works only with POST /v1/servers."}},"required":["location"]}}}}},"delete":{"operationId":"cancelServerMove","summary":"Drop an unpaid move","description":"API 1.9.0. The move waiting for payment (move.status pending) is dropped and its invoice voided; nothing changes on the server. 404 when none is waiting — a rebuild in another location waiting for payment is dropped with DELETE …/rebuild; 409 move_paid when it was paid meanwhile (it starts in a moment).\n\nRequires the `servers:write` permission.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"cancelled":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/upgrade":{"get":{"operationId":"getUpgrade","summary":"An upgrade waiting for payment","description":"The upgrade ordered and not paid yet, or null.\n\nRequires the `servers:read` permission.","tags":["Upgrades"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":7,"from":{"cpu":2,"ram_gb":4,"disk_gb":60,"summary":"VPS · 2 vCPU · 4 GB RAM · 60 GB NVMe"},"to":{"cpu":4,"ram_gb":8,"disk_gb":120,"summary":"VPS · 4 vCPU · 8 GB RAM · 120 GB NVMe"},"monthly":118000,"status":"pending","invoice_id":"01a1…","created_at":"2026-10-06T09:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"upgradeServer","summary":"Upgrade a server","description":"Orders the bigger plan and pays the rest of this period from the wallet; it is applied at once (status upgrading, a restart if vCPU or memory grow). If the wallet can't cover it, it waits for payment (payment.required) — pay its invoice, or drop it with DELETE.\n\nRequires the `servers:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Upgrades"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"upgrade":{"from":{"cpu":2,"ram_gb":4,"disk_gb":60,"summary":"VPS · 2 vCPU · 4 GB RAM · 60 GB NVMe"},"to":{"cpu":4,"ram_gb":8,"disk_gb":120,"summary":"VPS · 4 vCPU · 8 GB RAM · 120 GB NVMe"},"status":"applied"},"payment":{"required":false,"invoice_id":"01a1…","total":48616,"amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cpu":{"type":"integer","description":"vCPUs (at least today's).","example":4},"ram_gb":{"type":"integer","description":"Memory in GB (at least today's).","example":8},"disk_gb":{"type":"integer","description":"Storage in GB (at least today's — disks can't shrink).","example":120},"coupon":{"type":"string","description":"A coupon code (any case) off what is due now, before tax — before the wallet pays it. 422 on coupon says why one does not work; nothing is ordered then. A coupon for moves only, or one with free offers (POST /v1/servers only), is refused here (API 1.10.0).","example":"WELCOME10"}},"required":["cpu","ram_gb","disk_gb"]}}}}},"delete":{"operationId":"cancelUpgrade","summary":"Drop an unpaid upgrade","description":"The upgrade waiting for payment is dropped and its invoice voided.\n\nRequires the `servers:write` permission.","tags":["Upgrades"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"cancelled":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/upgrade/quote":{"post":{"operationId":"quoteUpgrade","summary":"Price an upgrade","description":"What a bigger plan costs: now (for the rest of the period) and for each 30 days from the next renewal, and whether the server restarts (more vCPU or memory: once; only more disk: no). Disks can't shrink, so a plan is never smaller. For a Team account (API 1.8.0) free and team are true and due_now is 0: the upgrade is applied without an invoice; monthly stays the list price, which is not billed. API 1.9.0: with your tax, as the panel shows it — due_now_tax and due_now_with_tax, monthly_tax and monthly_with_tax, tax_mode and tax_note; a Team account has no tax (tax_label null, each with-tax figure the same as without). The sandbox charges no tax.\n\nRequires the `servers:read` permission.","tags":["Upgrades"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"from":{"cpu":2,"ram_gb":4,"disk_gb":60,"summary":"VPS · 2 vCPU · 4 GB RAM · 60 GB NVMe"},"to":{"cpu":4,"ram_gb":8,"disk_gb":120,"summary":"VPS · 4 vCPU · 8 GB RAM · 120 GB NVMe"},"restart":true,"due_now":41200,"due_now_display":"₹412.00","monthly":118000,"monthly_display":"₹1,180.00","tax_label":"IGST 18%","renews_at":"2026-11-05T07:49:12Z","due_now_tax":7416,"due_now_with_tax":48616,"due_now_with_tax_display":"₹486.16","monthly_tax":21240,"monthly_with_tax":139240,"monthly_with_tax_display":"₹1,392.40","tax_mode":"exclusive","tax_note":null,"free":false,"team":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cpu":{"type":"integer","description":"vCPUs (at least today's).","example":4},"ram_gb":{"type":"integer","description":"Memory in GB (at least today's).","example":8},"disk_gb":{"type":"integer","description":"Storage in GB (at least today's — disks can't shrink).","example":120}},"required":["cpu","ram_gb","disk_gb"]}}}}}},"/v1/servers/{id}/main-ipv4":{"get":{"operationId":"mainIpv4Options","summary":"What its main IPv4 can become","description":"Its main address now, and your own addresses it could take instead (unattached ones in its location, or its own extras). A brand-new address can be asked for once a day (new_available_at).\n\nRequires the `servers:read` permission.","tags":["Server tools"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"main":"203.0.113.16","main_own":false,"own":[{"id":"01a1…","address":"203.0.113.40","where":"unattached"}],"new_available_at":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"changeMainIpv4","summary":"Change its main IPv4","description":"Gives the server another main address: one of your own (ip_id), or a new one from the pool. The old one is released — or stays yours, if it was your own. The network inside the server is set up again (it can drop for a few seconds).\n\nRequires the `servers:write` permission.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"from":"203.0.113.16","to":"203.0.113.40","kept":false}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"ip_id":{"type":"string","description":"One of your own addresses. Left out: a new address."}}}}}}}},"/v1/servers/{id}/licence":{"post":{"operationId":"activateLicence","summary":"Activate Windows with your key","description":"Windows servers: puts in a licence key bought anywhere (retail, volume or reseller, for the same version and edition) and activates Windows through the guest agent — follow it in the activity. An evaluation edition needs one restart afterwards. The key is never stored.\n\nRequires the `servers:write` permission.","tags":["Server tools"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"action":"licence","label":"Activating Windows","status":"running","id":"01a1…","progress":null,"detail":null,"started_at":"2026-10-06T08:00:00Z","finished_at":"2026-10-06T08:00:21Z","duration_ms":21000,"created_at":"2026-10-06T08:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","description":"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX."}},"required":["key"]}}}}}},"/v1/servers/{id}/app":{"get":{"operationId":"getApp","summary":"The app on a server","description":"The one-click app or control panel ordered with the server (or its rebuild): status installing → ready (or setup, waiting for you to finish its setup page — do it right away, whoever opens it first could; or failed), how far along, where it answers, its username and who may reach its login (every address, unless you limit it). null when it has none. API 1.13.0: tunnel — for an app that answers on the server alone (OpenClaw): the SSH command that opens a tunnel to it from your computer (as the server's own user) and the address it is then at; null for every other app, and until it is ready.\n\nRequires the `servers:read` permission.","tags":["Apps on servers"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null,"site":"https://wordpress.org/documentation/","login":"password","progress":100,"message":null,"minutes":5,"url_v6":"http://[2001:db8:100::16]/wp-admin/","username":"asha_k3","has_password":true,"note":"The site answers on this server's address for now…","access":null,"tunnel":null,"failure_reason":null,"started_at":"2026-10-06T07:51:02Z","finished_at":"2026-10-06T07:55:40Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/app/credentials":{"get":{"operationId":"appCredentials","summary":"The app's login","description":"The username and password made up for it (or a service's password: a database, Redis), and its address.\n\nRequires the `servers:access` permission.","tags":["Apps on servers"],"x-scope":"servers:access","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"username":"asha_k3","password":"Vb7q…","url":"http://203.0.113.16/wp-admin/","address":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/app/access":{"post":{"operationId":"appAccess","summary":"Who may reach its login","description":"Limits the app's login port to one address (mode mine) or opens it to every address again (anyone) — a rule on the server's firewall, applied at once. Apps without a login port of their own (a website) use the firewall instead.\n\nRequires the `servers:write` permission. While the app is installing or waits for its setup page (status installing or setup — whoever finishes that page is the app's admin), this needs servers:access as well: 403 insufficient_scope (fields.scope servers:access) without it. Once it is ready, servers:write is enough.","tags":["Apps on servers"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"code":"wordpress","name":"WordPress","kind":"app","status":"ready","url":"http://203.0.113.16/wp-admin/","address":null,"site":"https://wordpress.org/documentation/","login":"password","progress":100,"message":null,"minutes":5,"url_v6":"http://[2001:db8:100::16]/wp-admin/","username":"asha_k3","has_password":true,"note":"The site answers on this server's address for now…","access":null,"tunnel":null,"failure_reason":null,"started_at":"2026-10-06T07:51:02Z","finished_at":"2026-10-06T07:55:40Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-scope-also":{"scope":"servers:access","when":"While the app is installing or waits for its setup page (status installing or setup — whoever finishes that page is the app's admin), this needs servers:access as well: 403 insufficient_scope (fields.scope servers:access) without it. Once it is ready, servers:write is enough."},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","description":"mine: only from ip; anyone: every address.","example":"mine","enum":["mine","anyone"]},"ip":{"type":"string","description":"With mine: the address (its /24 or /64 network is allowed). Default: the address of this request.","example":"198.51.100.7"}},"required":["mode"]}}}}}},"/v1/servers/{id}/alerts":{"get":{"operationId":"getAlerts","summary":"Its alerts","description":"Free e-mail alerts when it goes down or comes back (email_alerts) and when CPU, memory or network stay high (usage_alerts); and with the Call alerting add-on, who is called (call). state: what the monitor sees now. usage_rule (API 1.9.0): what high means, for every server — CPU (a share of all its vCPUs), memory, or network in or out (against its port speed; not watched on a port without a limit) at cpu_percent / memory_percent / network_percent or more for for_seconds; one alert while it stays high, and none again within repeat_minutes. null when it can't be read just now. Memory is the share the system inside cannot give out — 100 less its available memory, its page cache (Windows: standby memory) counted as free — read inside the server through its guest agent whenever the host's own figure is near memory_percent or above it (that figure counts the cache as used, so it can read near full on a server with plenty available); it stays high for_seconds when two readings that far apart, and every one between them, are high; a server whose agent does not answer is not alerted on memory. API 1.14.0: quiet_minutes — no high-usage alert while the server is built, rebuilt or restored or its app installs, nor for quiet_minutes after (a first boot is busy); a metric still high when that ends is alerted only once it stays high for_seconds more; 0: no quiet period.\n\nRequires the `servers:read` permission.","tags":["Alerts"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"email_alerts":true,"usage_alerts":true,"call":{"enabled":true,"phones":["+919820000000"],"call":true,"email":true,"port":443},"state":"up","usage_rule":{"cpu_percent":85,"memory_percent":85,"network_percent":85,"for_seconds":90,"repeat_minutes":60,"quiet_minutes":30}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateAlerts","summary":"Change its alerts","description":"Fields left out stay as they are. call needs the Call alerting add-on: up to three phone numbers (international format), calls on or off, e-mail on or off, and a TCP port that must answer (null: the server only has to be up). The answer has the high-usage rule too (usage_rule, API 1.9.0; its quiet period after a build, a rebuild, a restore or an app's install, quiet_minutes, API 1.14.0: see GET) — staff set it, not this.\n\nRequires the `servers:write` permission.","tags":["Alerts"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"email_alerts":true,"usage_alerts":true,"call":{"enabled":true,"phones":["+919820000000"],"call":true,"email":true,"port":443},"state":"up","usage_rule":{"cpu_percent":85,"memory_percent":85,"network_percent":85,"for_seconds":90,"repeat_minutes":60,"quiet_minutes":30}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"email_alerts":{"type":"boolean","description":"E-mail when it goes down and comes back.","example":true},"usage_alerts":{"type":"boolean","description":"E-mail when CPU, memory or network stay high (usage_rule says how high, for how long, and how long it stays quiet after a build: quiet_minutes).","example":true},"call":{"type":"object","description":"Call alerting: {\"phones\": [\"+91…\"], \"call\": true, \"email\": true, \"port\": 443}.","example":{"phones":["+919820000000"],"port":443}}}}}}}}},"/v1/servers/{id}/alerts/test":{"post":{"operationId":"testAlert","summary":"Send a test alert","description":"Calls the alert numbers (and e-mails) once, so you know it works. Call alerting only; once every two minutes.\n\nRequires the `servers:write` permission.","tags":["Alerts"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"queued":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/addons":{"get":{"operationId":"listAddons","summary":"Its add-ons","description":"The add-ons on the server's subscription and what each costs per 30 days: backups, call alerting, the management service, extra bandwidth. One free with the coupon the server was ordered with (API 1.10.0) shows its normal price here — its invoices take it off while it is free; GET /v1/subscriptions (perks) says until when.\n\nRequires the `servers:read` permission.","tags":["Add-ons"],"x-scope":"servers:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":31,"type":"backups","name":"Automatic backups (60 GB) — web-01.example.com","quantity":1,"monthly":18000,"monthly_display":"₹180.00","status":"active","created_at":"2026-10-06T07:49:12Z","cancelled_at":null}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addAddon","summary":"Add an add-on","description":"Buys an add-on for a running server; the rest of this period is invoiced (prorated) and paid from the wallet, and it switches on in a few seconds. If the wallet can't cover it, payment.required is true — pay its invoice to switch it on. Extra disks and IPv4 addresses are subscriptions of their own: POST /v1/disks, POST /v1/ips.\n\nRequires the `servers:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Add-ons"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"addon":{"id":31,"type":"backups","name":"Automatic backups (60 GB) — web-01.example.com","quantity":1,"monthly":18000,"monthly_display":"₹180.00","status":"active","created_at":"2026-10-06T07:49:12Z","cancelled_at":null},"payment":{"required":false,"invoice_id":"01a1…","total":10620,"amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"Which add-on (codes in the catalogue).","example":"backups","enum":["backups","alerting","managed","bandwidth"]},"quantity":{"type":"integer","description":"bandwidth: how many TB a month (default 1).","example":1},"coupon":{"type":"string","description":"A coupon code (any case) off the prorated invoice, before tax — before the wallet pays it. 422 on coupon says why one does not work; nothing is added then. A coupon for moves only, or one with free offers (POST /v1/servers only), is refused here (API 1.10.0)."}},"required":["type"]}}}}}},"/v1/servers/{id}/addons/{addon_id}":{"delete":{"operationId":"removeAddon","summary":"Remove an add-on","description":"It stops at once and no longer appears on renewals. Removing backups deletes the server's backups. One free with a coupon (API 1.10.0) loses that offer: added again, it is at the normal price.\n\nRequires the `servers:write` permission.","tags":["Add-ons"],"x-scope":"servers:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"addon_id","in":"path","required":true,"description":"The add-on's id.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"status":"cancelled","cancelled_at":"2026-10-08T10:00:00Z","id":31,"type":"backups","name":"Automatic backups (60 GB) — web-01.example.com","quantity":1,"monthly":18000,"monthly_display":"₹180.00","created_at":"2026-10-06T07:49:12Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/backups":{"get":{"operationId":"listBackups","summary":"Its backups","description":"With the Automatic backups add-on: one every night, the newest few kept (keep), and whether one is running now. API 1.16.0: each backup's kind — manual (taken with Back up now) or nightly; null for one taken before the panel noted it. notes is always null.\n\nRequires the `backups:read` permission.","tags":["Backups"],"x-scope":"backups:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"available":true,"running":false,"keep":3,"time":"03:00","last_backup_at":"2026-10-07T21:30:04Z","backups":[{"id":"9c1e4b0a77d2f5e3a1b6c8d0","size_bytes":1288490188,"kind":"nightly","notes":null,"created_at":"2026-10-07T21:30:04Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createBackup","summary":"Back up now","description":"Takes a backup while the server keeps running (up to three by hand a day; the nightly one still runs). The server is locked for changes until it finishes, usually a few minutes.\n\nRequires the `backups:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Backups"],"x-scope":"backups:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"queued":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/backups/{backup_id}/restore":{"post":{"operationId":"restoreBackup","summary":"Restore a backup","description":"The server is stopped, its disks rolled back to the backup and started again (status rebuilding until it is active). Everything written since is lost. Refused while a disk of your own is on it (take it off first) or the backup is older than one of its disks.\n\nRequires the `backups:write` permission.","tags":["Backups"],"x-scope":"backups:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"backup_id","in":"path","required":true,"description":"The backup's id.","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"queued":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/backups/{backup_id}":{"delete":{"operationId":"deleteBackup","summary":"Delete a backup","description":"Gone for good.\n\nRequires the `backups:write` permission.","tags":["Backups"],"x-scope":"backups:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"backup_id","in":"path","required":true,"description":"The backup's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/firewall":{"get":{"operationId":"getFirewall","summary":"Its firewall","description":"On or off, the default policies, its own rules in order and the security groups it uses. Changes are saved first and reach the server when applied: pending says there are some waiting. enforced (API 1.9.0, on every answer that shows the firewall): false while the firewall at the server's location isn't switched on yet — its rules are kept and applied, but traffic is not filtered; warning says so while the firewall is on (null otherwise).\n\nRequires the `firewall:read` permission.","tags":["Firewall"],"x-scope":"firewall:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"security_groups":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rules":[{"id":14,"direction":"in","action":"accept","protocol":"tcp","port":"80,443","remote":null,"comment":"Web","position":1,"added_by":null}]}],"pending":false,"applying":false,"applied_at":"2026-10-06T08:10:00Z","failed":false,"can_apply":true,"enforced":true,"warning":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateFirewall","summary":"Switch it on or off; policies","description":"Fields left out stay. Switched on for the first time with no rules, it starts with SSH (remote desktop on Windows) and ping allowed, so you are not locked out. Apply to put it on the server.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"security_groups":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rules":[{"id":14,"direction":"in","action":"accept","protocol":"tcp","port":"80,443","remote":null,"comment":"Web","position":1,"added_by":null}]}],"pending":false,"applying":false,"applied_at":"2026-10-06T08:10:00Z","failed":false,"can_apply":true,"enforced":true,"warning":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean","description":"On or off.","example":true},"policy_in":{"type":"string","description":"Incoming traffic no rule matches.","example":"DROP","enum":["ACCEPT","DROP","REJECT"]},"policy_out":{"type":"string","description":"Outgoing traffic no rule matches.","example":"ACCEPT","enum":["ACCEPT","DROP","REJECT"]}}}}}}}},"/v1/servers/{id}/firewall/rules":{"post":{"operationId":"addFirewallRule","summary":"Add a rule","description":"Added at the end of its list (rules are checked top to bottom; the first that matches decides). Apply to put it on the server.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"direction":{"type":"string","description":"Incoming or outgoing traffic.","example":"in","enum":["in","out"]},"action":{"type":"string","description":"What to do with it (default accept).","example":"accept","enum":["accept","drop","reject"]},"protocol":{"type":"string","description":"Which protocol (default any).","example":"tcp","enum":["tcp","udp","icmp","icmpv6","any"]},"port":{"type":"string","description":"tcp/udp: a port, a range or a list — \"22\", \"8000-8100\", \"80,443\" (at most 10). Empty: every port.","example":"443"},"remote":{"type":"string","description":"The other end — sources for incoming, destinations for outgoing: addresses and CIDR ranges, comma separated. Empty: anywhere.","example":"0.0.0.0/0"},"comment":{"type":"string","description":"A note.","example":"HTTPS"}},"required":["direction"]}}}}}},"/v1/servers/{id}/firewall/rules/{rule_id}":{"delete":{"operationId":"deleteFirewallRule","summary":"Remove a rule","description":"Apply to take it off the server.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"rule_id","in":"path","required":true,"description":"The rule's id.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/firewall/rules/{rule_id}/move":{"post":{"operationId":"moveFirewallRule","summary":"Move a rule up or down","description":"One place up or down its list.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"rule_id","in":"path","required":true,"description":"The rule's id.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"security_groups":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rules":[{"id":14,"direction":"in","action":"accept","protocol":"tcp","port":"80,443","remote":null,"comment":"Web","position":1,"added_by":null}]}],"pending":false,"applying":false,"applied_at":"2026-10-06T08:10:00Z","failed":false,"can_apply":true,"enforced":true,"warning":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Which way.","example":"up","enum":["up","down"]}},"required":["to"]}}}}}},"/v1/servers/{id}/firewall/security-groups":{"post":{"operationId":"attachSecurityGroup","summary":"Use a security group","description":"Its rules come after the server's own. Apply to put them on the server.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"security_groups":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rules":[{"id":14,"direction":"in","action":"accept","protocol":"tcp","port":"80,443","remote":null,"comment":"Web","position":1,"added_by":null}]}],"pending":false,"applying":false,"applied_at":"2026-10-06T08:10:00Z","failed":false,"can_apply":true,"enforced":true,"warning":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"security_group_id":{"type":"string","description":"One of your security groups."}},"required":["security_group_id"]}}}}}},"/v1/servers/{id}/firewall/security-groups/{group_id}":{"delete":{"operationId":"detachSecurityGroup","summary":"Stop using a security group","description":"Apply to take its rules off the server.\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"group_id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"security_groups":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rules":[{"id":14,"direction":"in","action":"accept","protocol":"tcp","port":"80,443","remote":null,"comment":"Web","position":1,"added_by":null}]}],"pending":false,"applying":false,"applied_at":"2026-10-06T08:10:00Z","failed":false,"can_apply":true,"enforced":true,"warning":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{id}/firewall/apply":{"post":{"operationId":"applyFirewall","summary":"Apply it to the server","description":"Puts the saved firewall on the server — it takes a few seconds (applying, then applied_at).\n\nRequires the `firewall:write` permission.","tags":["Firewall"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"queued":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/security-groups":{"get":{"operationId":"listSecurityGroups","summary":"List security groups","description":"Named sets of firewall rules you can use on many servers.\n\nRequires the `firewall:read` permission.","tags":["Security groups"],"x-scope":"firewall:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z"}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createSecurityGroup","summary":"Create a security group","description":"Then add its rules and use it on servers.\n\nRequires the `firewall:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Up to 60 characters.","example":"web"},"description":{"type":"string","description":"What it is for.","example":"HTTP and HTTPS from anywhere"}},"required":["name"]}}}}}},"/v1/security-groups/{id}":{"get":{"operationId":"getSecurityGroup","summary":"Get a security group","description":"Its rules and the servers using it (pending: a server that hasn't had the latest rules applied).\n\nRequires the `firewall:read` permission.","tags":["Security groups"],"x-scope":"firewall:read","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateSecurityGroup","summary":"Rename a security group","description":"Its name and description; fields left out stay.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Up to 60 characters."},"description":{"type":"string","description":"What it is for."}}}}}}},"delete":{"operationId":"deleteSecurityGroup","summary":"Delete a security group","description":"Only once no server uses it.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/security-groups/{id}/rules":{"post":{"operationId":"addSecurityGroupRule","summary":"Add a rule to a group","description":"At the end of its list. Apply the group to put it on its servers.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"direction":{"type":"string","description":"Incoming or outgoing traffic.","example":"in","enum":["in","out"]},"action":{"type":"string","description":"What to do with it (default accept).","example":"accept","enum":["accept","drop","reject"]},"protocol":{"type":"string","description":"Which protocol (default any).","example":"tcp","enum":["tcp","udp","icmp","icmpv6","any"]},"port":{"type":"string","description":"tcp/udp: a port, a range or a list — \"22\", \"8000-8100\", \"80,443\" (at most 10). Empty: every port.","example":"443"},"remote":{"type":"string","description":"The other end — sources for incoming, destinations for outgoing: addresses and CIDR ranges, comma separated. Empty: anywhere.","example":"0.0.0.0/0"},"comment":{"type":"string","description":"A note.","example":"HTTPS"}},"required":["direction"]}}}}}},"/v1/security-groups/{id}/rules/{rule_id}":{"delete":{"operationId":"deleteSecurityGroupRule","summary":"Remove a rule from a group","description":"Apply the group to take it off its servers.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}},{"name":"rule_id","in":"path","required":true,"description":"The rule's id.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/security-groups/{id}/rules/{rule_id}/move":{"post":{"operationId":"moveSecurityGroupRule","summary":"Move a group's rule","description":"One place up or down.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}},{"name":"rule_id","in":"path","required":true,"description":"The rule's id.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Which way.","example":"down","enum":["up","down"]}},"required":["to"]}}}}}},"/v1/security-groups/{id}/servers":{"post":{"operationId":"addSecurityGroupServer","summary":"Use it on a server","description":"The same as adding the group on the server's firewall. Apply to put its rules on the server.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"server_id":{"type":"string","description":"One of your servers."}},"required":["server_id"]}}}}}},"/v1/security-groups/{id}/servers/{server_id}":{"delete":{"operationId":"removeSecurityGroupServer","summary":"Stop using it on a server","description":"Apply that server's firewall to take the rules off.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}},{"name":"server_id","in":"path","required":true,"description":"The server's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"web","description":"HTTP and HTTPS from anywhere","rule_count":2,"server_count":3,"created_at":"2026-10-02T08:00:00Z","updated_at":"2026-10-06T08:00:00Z","rules":[{"id":12,"direction":"in","action":"accept","protocol":"tcp","port":"22","remote":null,"comment":"SSH","position":1,"added_by":null}],"servers":[{"id":"01a1…","hostname":"web-01.example.com","pending":false}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/security-groups/{id}/apply":{"post":{"operationId":"applySecurityGroup","summary":"Apply a group everywhere","description":"Puts the group's current rules on every running server that uses it.\n\nRequires the `firewall:write` permission.","tags":["Security groups"],"x-scope":"firewall:write","parameters":[{"name":"id","in":"path","required":true,"description":"The security group's id.","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"servers":3}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/disks":{"get":{"operationId":"listDisks","summary":"List disks","description":"Your extra disks: on a server (device: what it is inside it) or on none, each with the servers it could go on now.\n\nRequires the `disks:read` permission.","tags":["Disks"],"x-scope":"disks:read","parameters":[{"name":"server_id","in":"query","required":false,"description":"Only the disks on this server.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"status":"attached","device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z"}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createDisk","summary":"Buy a disk","description":"A disk of its own, prepaid from the wallet for 30 days at a time: for a server (server_id; it is attached once paid and shows up as a new disk — /dev/sdb…) or on its own in a location, to attach later. If the wallet can't cover it, payment.required is true and it waits for its invoice to be paid.\n\nRequires the `disks:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"status":"attached","device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z","payment":{"required":false,"invoice_id":"01a1…","total":21240,"amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"size_gb":{"type":"integer","description":"Size in GB (see resources.volume in the catalogue).","example":100},"name":{"type":"string","description":"A name (letters, digits, spaces, dots, dashes). Default \"data\".","example":"data"},"server_id":{"type":"string","description":"Attach it to this server once paid."},"location":{"type":"string","description":"Without a server: where it is made.","example":"in-bom-1"},"coupon":{"type":"string","description":"A coupon for its first invoice. A coupon for moves only, or one with free offers (POST /v1/servers only), is refused here (API 1.10.0)."}},"required":["size_gb"]}}}}}},"/v1/disks/{id}":{"get":{"operationId":"getDisk","summary":"Get a disk","description":"One disk.\n\nRequires the `disks:read` permission.","tags":["Disks"],"x-scope":"disks:read","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"status":"attached","device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteDisk","summary":"Delete a disk","description":"Its subscription ends and it is erased — with everything on it.\n\nRequires the `disks:write` permission.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","status":"deleting"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/disks/{id}/resize":{"post":{"operationId":"resizeDisk","summary":"Grow a disk","description":"Disks only grow. The difference for the rest of the period is paid from the wallet (or waits for payment). Then extend the filesystem inside the server (resize2fs, xfs_growfs).\n\nRequires the `disks:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"status":"attached","device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z","payment":{"required":false,"invoice_id":"01a1…","total":10620,"amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"size_gb":{"type":"integer","description":"The new, larger size.","example":200},"coupon":{"type":"string","description":"A coupon code (any case) off the prorated difference, before tax — before the wallet pays it. 422 on coupon says why one does not work. A coupon for moves only, or one with free offers (POST /v1/servers only), is refused here (API 1.10.0)."}},"required":["size_gb"]}}}}}},"/v1/disks/{id}/attach":{"post":{"operationId":"attachDisk","summary":"Put a disk on a server","description":"A disk of your own on no server goes on a running server in its location (attachable_to lists them). It shows up as a new disk in a moment.\n\nRequires the `disks:write` permission.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"status":"attaching","id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"server_id":{"type":"string","description":"The server."}},"required":["server_id"]}}}}}},"/v1/disks/{id}/detach":{"post":{"operationId":"detachDisk","summary":"Take a disk off its server","description":"It keeps its data and stays yours. Unmount it inside the server first.\n\nRequires the `disks:write` permission.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"status":"detaching","id":"01a1…","name":"data","size_gb":100,"target_size_gb":null,"device":"/dev/sdb","server":{"id":"01a1…","hostname":"web-01.example.com"},"location":"in-bom-1","own_subscription":true,"locked":false,"attachable_to":[],"failure_reason":null,"created_at":"2026-10-06T09:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/disks/{id}/move":{"get":{"operationId":"diskMoveOptions","summary":"Where a disk can move, and what it costs","description":"API 1.9.0. A disk of its own on no server can go next to one of your servers it can't be put on where it is (servers: it is put on that server when it arrives) or to another location (locations: it waits there for a server) — each available, or why not (reason). blocked: why it can't move at all right now (on a server — it moves with that server, so take it off first; waiting for payment; locked; busy). A disk on its server's subscription (own_subscription false) moves with its server and is not priced here. price: all of it is copied (gb), at the catalogue's rate per GB plus tax; a disk not made yet (made false: it has never been on a server) has nothing to copy and moves for free, and so does a Team account's (free, team). null when it can't be priced (price_error says why). pending / recent: its move waiting for payment, and the latest other one of the last 7 days, as for servers (GET /v1/servers/{id}/move).\n\nRequires the `disks:read` permission.","tags":["Disks"],"x-scope":"disks:read","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"blocked":null,"made":true,"gb":100,"servers":[{"id":"01a1…","hostname":"web-02.example.com","location":"in-noi-1","location_name":"Noida","available":true,"reason":null}],"locations":[{"code":"in-noi-1","name":"Noida","country":"IN","available":true,"reason":null}],"price":{"gb":100,"rate":50,"rate_display":"₹0.50","amount":5000,"amount_display":"₹50.00","tax":900,"tax_label":"IGST 18%","total":5900,"total_display":"₹59.00","taxed":true,"free":false,"team":false},"price_error":null,"pending":null,"recent":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"moveDisk","summary":"Move a disk","description":"API 1.9.0. Next to one of your servers (server_id: it is put on that server once it arrives, and shows up there as a new disk) or to another location (location: it waits there for a server) — one of the two, from GET …/move. Its data comes along. Charged once — the GB copied, plus tax — and paid from the wallet; it then moves by itself (status migrating, then attached or detached). If the wallet can't cover it, move.status is pending and payment.required is true: pay its invoice (POST /v1/invoices/{id}/pay) and it moves then, or drop it (DELETE). A disk not made yet, moves priced at 0, or a Team account's move is never invoiced: payment.invoice_id is null. If it can't start once paid (no room there now; put on a server, grown or made since it was ordered) or ends where it was, the charge goes back to the wallet (status refunded, with the reason). 409 move_pending while another move of it waits or is under way; 409 disk_busy says why it can't move now; 409 not_movable for a disk on its server's subscription.\n\nRequires the `disks:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"move":{"id":"01a1…","kind":"disk","status":"started","description":"Moving disk \"data\" (100 GB) to Noida","gb":100,"rate":50,"rate_display":"₹0.50","amount":5000,"amount_display":"₹50.00","total":5900,"total_display":"₹59.00","location":"in-noi-1","location_name":"Noida","server":null,"new_ip":null,"image":null,"app":null,"invoice_id":"01a1…","reason":null,"created_at":"2026-10-13T09:00:00Z","paid_at":"2026-10-13T09:00:01Z","finished_at":null},"payment":{"required":false,"invoice_id":"01a1…","total":5900,"total_display":"₹59.00","amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"server_id":{"type":"string","description":"Next to this server of yours (GET …/move: servers), then put on it."},"location":{"type":"string","description":"Or to this location (GET …/move: locations).","example":"in-noi-1"},"coupon":{"type":"string","description":"A coupon code (any case) off the move, before tax — before the wallet pays it. 422 on coupon says why one does not work; nothing is ordered then. A coupon for moves only works here too (API 1.10.0); one with free offers works only with POST /v1/servers."}}}}}}},"delete":{"operationId":"cancelDiskMove","summary":"Drop an unpaid disk move","description":"API 1.9.0. The disk's move waiting for payment is dropped and its invoice voided; the disk stays where it is. 404 when none is waiting; 409 move_paid when it was paid meanwhile.\n\nRequires the `disks:write` permission.","tags":["Disks"],"x-scope":"disks:write","parameters":[{"name":"id","in":"path","required":true,"description":"The disk's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"cancelled":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ips":{"get":{"operationId":"listIps","summary":"List addresses","description":"Every address on the account, IPv4 and IPv6: each server's own (main), extras, and addresses of your own (own: true — with an id, on a server or unattached), with how many IPv4 addresses the account can hold. An older extra IPv4 bought as an add-on of its server has an id too (API 1.9.0): addon-<addon_id>, its add-on on the server (GET /v1/servers/{id}/addons) — it stays on that server, and DELETE /v1/ips/{id} releases it.\n\nRequires the `ips:read` permission.","tags":["IP addresses"],"x-scope":"ips:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","address":"203.0.113.40","version":4,"cidr":"203.0.113.40/24","gateway":"203.0.113.1","location":"in-bom-1","role":"extra","server":{"id":"01a1…","hostname":"web-01.example.com"},"own":true,"addon_id":null,"locked":false,"assigned_at":"2026-10-06T09:00:00Z","subscription":{"status":"active","paused":false,"monthly":20000,"monthly_display":"₹200.00","next_due_at":"2026-11-05T09:00:00Z"}}],"limits":{"ipv4":4,"ipv4_limit":5}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createIp","summary":"Buy an IPv4 address","description":"An address of your own, prepaid from the wallet for 30 days at a time: for a server (server_id; put on it and set up inside it once paid) or unattached in a location — to put on a server later, or to give a new server as its main address. If the wallet can't cover it, payment.required is true.\n\nRequires the `ips:write` permission.\n\nSupports `Idempotency-Key`.","tags":["IP addresses"],"x-scope":"ips:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","address":"203.0.113.40","version":4,"cidr":"203.0.113.40/24","gateway":"203.0.113.1","location":"in-bom-1","role":"extra","server":{"id":"01a1…","hostname":"web-01.example.com"},"own":true,"addon_id":null,"locked":false,"assigned_at":"2026-10-06T09:00:00Z","subscription":{"status":"active","paused":false,"monthly":20000,"monthly_display":"₹200.00","next_due_at":"2026-11-05T09:00:00Z"},"payment":{"required":false,"invoice_id":"01a1…","total":23600,"amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"server_id":{"type":"string","description":"Put it on this server once paid."},"location":{"type":"string","description":"Without a server: where it is.","example":"in-bom-1"},"coupon":{"type":"string","description":"A coupon for its first invoice. A coupon for moves only, or one with free offers (POST /v1/servers only), is refused here (API 1.10.0)."}}}}}}}},"/v1/ips/{id}":{"get":{"operationId":"getIp","summary":"Get an address of your own","description":"One address you bought on its own — or an older extra IPv4 bought as an add-on of its server, by its addon-… id (API 1.9.0).\n\nRequires the `ips:read` permission.","tags":["IP addresses"],"x-scope":"ips:read","parameters":[{"name":"id","in":"path","required":true,"description":"The address's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","address":"203.0.113.40","version":4,"cidr":"203.0.113.40/24","gateway":"203.0.113.1","location":"in-bom-1","role":"extra","server":{"id":"01a1…","hostname":"web-01.example.com"},"own":true,"addon_id":null,"locked":false,"assigned_at":"2026-10-06T09:00:00Z","subscription":{"status":"active","paused":false,"monthly":20000,"monthly_display":"₹200.00","next_due_at":"2026-11-05T09:00:00Z"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteIp","summary":"Release an address","description":"Its subscription ends and the address goes back to the pool. Not while it is a server's main address. An older extra IPv4 bought as an add-on of its server (addon-…, API 1.9.0): the add-on is removed, as DELETE /v1/servers/{id}/addons/{addon_id} does — the address comes off the server (and out of its network inside) and goes back to the pool after a cool-down, and it leaves the server's renewals; the current period is not refunded. Take it out of the server's own network settings first.\n\nRequires the `ips:write` permission.","tags":["IP addresses"],"x-scope":"ips:write","parameters":[{"name":"id","in":"path","required":true,"description":"The address's id.","schema":{"type":"string"}}],"responses":{"202":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","status":"released"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ips/{id}/attach":{"post":{"operationId":"attachIp","summary":"Put an address on a server","description":"An unattached address of yours goes on one of your running servers in the same network, and is set up inside it in a few seconds (the server's network.ipv4_extra says when: inside). An add-on extra IPv4 (addon-…) stays where it is: 409 addon_address.\n\nRequires the `ips:write` permission.","tags":["IP addresses"],"x-scope":"ips:write","parameters":[{"name":"id","in":"path","required":true,"description":"The address's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","address":"203.0.113.40","version":4,"cidr":"203.0.113.40/24","gateway":"203.0.113.1","location":"in-bom-1","role":"extra","server":{"id":"01a1…","hostname":"web-01.example.com"},"own":true,"addon_id":null,"locked":false,"assigned_at":"2026-10-06T09:00:00Z","subscription":{"status":"active","paused":false,"monthly":20000,"monthly_display":"₹200.00","next_due_at":"2026-11-05T09:00:00Z"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"server_id":{"type":"string","description":"The server."}},"required":["server_id"]}}}}}},"/v1/ips/{id}/detach":{"post":{"operationId":"detachIp","summary":"Take an address off its server","description":"It stays yours, unattached. (A server's main address can't be taken off — give the server another one first; an add-on extra IPv4, addon-…, can only be released: 409 addon_address.)\n\nRequires the `ips:write` permission.","tags":["IP addresses"],"x-scope":"ips:write","parameters":[{"name":"id","in":"path","required":true,"description":"The address's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"role":"unattached","server":null,"id":"01a1…","address":"203.0.113.40","version":4,"cidr":"203.0.113.40/24","gateway":"203.0.113.1","location":"in-bom-1","own":true,"addon_id":null,"locked":false,"assigned_at":"2026-10-06T09:00:00Z","subscription":{"status":"active","paused":false,"monthly":20000,"monthly_display":"₹200.00","next_due_at":"2026-11-05T09:00:00Z"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices":{"get":{"operationId":"listInvoices","summary":"List invoices","description":"Your invoices, newest first — all of them, one server's (server), or those matching q: an invoice number, a server's name or an IPv4 address, or part of one. Unpaid ones are temporary bills (temporary: true) that become numbered tax invoices once paid. ipv4: the address of the server (or the IPv4 address) an invoice is for — the one it had then; null for a disk or a top-up. API 1.9.0: type narrows it to tax invoices or temporary ones, and sort orders it by date, number, total or due date (dir asc or desc) — the filters and the search still apply.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"unpaid, paid or void.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Search: an invoice number, a server's name or an IPv4 address — or part of one, like 203.0.113.","schema":{"type":"string"}},{"name":"server","in":"query","required":false,"description":"Only this server's invoices, by its id: its order, renewals, add-ons, upgrades and moves (server_id works too). An IPv4 address or a disk of its own has its own invoices — its id works here as well.","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"description":"tax_invoice: only numbered invoices — each issued when it was paid; temporary: only temporary invoices still waiting for payment (API 1.9.0).","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"date (the date it carries: when it was paid and numbered, else when it was made), number, total or due (API 1.9.0). Left out: newest first.","schema":{"type":"string"}},{"name":"dir","in":"query","required":false,"description":"With sort: asc or desc (default desc). Empty values (no due date) come last either way.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","status":"paid","temporary":false,"currency":"INR","subtotal":59000,"discount":0,"coupon":null,"tax":10620,"tax_label":"IGST","total":69620,"total_display":"₹696.20","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16","period_start":"2026-10-01T00:00:00Z","period_end":"2026-10-31T00:00:00Z","issued_at":"2026-10-01T00:00:00Z","due_at":"2026-10-06T00:00:00Z","paid_at":"2026-10-01T00:00:03Z"}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}":{"get":{"operationId":"getInvoice","summary":"Get an invoice","description":"One invoice with its lines and any credit notes against it. API 1.9.0: everything its page in the panel prints for GST, from the invoice's own record (a later change of address or tax settings never rewrites it) — title (Tax invoice; Invoice when the seller has no GSTIN; Temporary invoice — tax_invoice false, and notice says it is not a tax invoice until it is paid), date (the date it carries), temporary_number (the temporary invoice it was, once paid), kind_label (what it is for, in words), place_of_supply, reverse_charge, taxable (the taxable value) and untaxed (lines not taxed), taxes (each tax at its rate: CGST and SGST in the seller's state, IGST elsewhere in India, none for an export), tax_mode (inclusive: the prices had the tax in them, the lines show them without it), tax_note (export, reverse charge, exempt), amount_in_words, seller (the business's name, address, GSTIN, PAN and state) and bill_to (the billing address it was made with), and on each line its unit, its SAC and whether it is taxed (taxed; included: free with the server). The same as a PDF: GET /v1/invoices/{id}/pdf. API 1.10.0: perk on each line — true for a coupon's free offer: a negative line right under what it frees (\"Free with coupon WELCOME10 — Automatic backups\"), or a renewal's % off (\"Coupon WELCOME10 offer — 50% off this renewal\"). They are not the coupon's discount: coupon and discount stay that (a coupon that only gives offers is on its order with discount 0).\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The invoice's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","status":"paid","temporary":false,"currency":"INR","subtotal":59000,"discount":0,"coupon":null,"tax":10620,"tax_label":"IGST","total":69620,"total_display":"₹696.20","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16","period_start":"2026-10-01T00:00:00Z","period_end":"2026-10-31T00:00:00Z","issued_at":"2026-10-01T00:00:00Z","due_at":"2026-10-06T00:00:00Z","paid_at":"2026-10-01T00:00:03Z","lines":[{"description":"web-01 — 1 Oct 2026 to 31 Oct 2026","quantity":1,"unit_amount":59000,"amount":59000,"unit":"× 30 days","taxed":true,"included":false,"sac":"998315","perk":false}],"credit_notes":[],"title":"Tax invoice","tax_invoice":true,"notice":null,"date":"2026-10-01T00:00:03Z","temporary_number":"PRO-000031","kind_label":"Renewal, 30 days","place_of_supply":"Maharashtra (27)","reverse_charge":false,"tax_mode":"exclusive","taxable":59000,"untaxed":0,"taxes":[{"name":"IGST","rate":"18%","rate_bp":1800,"amount":10620,"amount_display":"₹106.20","compound":false}],"tax_note":null,"amount_in_words":"Rupees Six Hundred Ninety Six and Twenty Paise Only","seller":{"name":"Example Hosting Pvt Ltd","address":"Plot 14, Sector 63\nNoida, Uttar Pradesh 201301","tax_id":"09AAICE1234F1Z5","tax_id_label":"GSTIN","pan":"AAICE1234F","state":"Uttar Pradesh","state_code":"09","country":"IN","email":"billing@example.com"},"bill_to":{"name":"Asha Verma","company":"Verma Labs Pvt Ltd","line1":"12 MG Road","line2":null,"city":"Pune","state":"Maharashtra","state_code":"27","postal_code":"411001","country":"IN","phone":null,"tax_id":"27AAPFU0939F1ZV","tax_id_label":"GSTIN"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}/pdf":{"get":{"operationId":"invoicePdf","summary":"An invoice as a PDF","description":"API 1.9.0. The invoice as an A4 PDF (Content-Type: application/pdf; the file name in Content-Disposition) with what its page in the panel shows: the seller and the buyer, place of supply, each line with its SAC, the taxable value, each tax at its rate, the total in figures and in words. A temporary invoice is titled so and says it is not a tax invoice; a sandbox invoice says it is make-believe. The rupee is written Rs. (the PDF's standard fonts). Errors still come as JSON.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The invoice's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}/pay":{"post":{"operationId":"payInvoice","summary":"Pay an invoice","description":"From the wallet when it covers it (paid: true). Otherwise a payment for the shortfall: open payment.checkout_url in a browser signed in to the panel to pay by card, UPI or netbanking, and follow it with GET /v1/payments/{id}. with: more unpaid invoices settled in the same payment (a server and its extra addresses). Set method to wallet to refuse rather than start a payment. coupon: a coupon put on the invoice first, by the rules of POST /v1/invoices/{id}/coupon (422 on coupon says why one does not work) — the same code already on it is fine (a retry), another one is refused: take it off with DELETE /v1/invoices/{id}/coupon first. It stays on the invoice even if the payment is then refused. The with invoices get none.\n\nRequires the `billing:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"id","in":"path","required":true,"description":"The invoice's id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"paid":false,"invoice":{"status":"unpaid","paid_at":null,"id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","temporary":false,"currency":"INR","subtotal":59000,"discount":0,"coupon":null,"tax":10620,"tax_label":"IGST","total":69620,"total_display":"₹696.20","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16","period_start":"2026-10-01T00:00:00Z","period_end":"2026-10-31T00:00:00Z","issued_at":"2026-10-01T00:00:00Z","due_at":"2026-10-06T00:00:00Z"},"payment":{"id":"01a1…","purpose":"invoice","status":"created","amount":69620,"amount_display":"₹696.20","currency":"INR","invoice_id":"01a1…","checkout_url":"https://panel.example.com/checkout/01a1…","created_at":"2026-10-06T10:00:00Z","captured_at":null}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"with":{"type":"array","description":"Other unpaid invoices to pay in the same go.","items":{"type":"string"}},"method":{"type":"string","description":"wallet: only from the balance (409 insufficient_funds otherwise). Default any.","enum":["any","wallet"]},"coupon":{"type":"string","description":"A coupon code (any case) to put on this invoice before paying it.","example":"RENEW10"}}}}}}}},"/v1/invoices/{id}/coupon":{"post":{"operationId":"applyInvoiceCoupon","summary":"Put a coupon on an invoice","description":"A coupon on an unpaid invoice that has none yet — a renewal, or an order placed without one. It comes off the whole invoice before tax, however much of it your wallet would cover; the tax is worked out again, and a payment already started for the invoice (POST /v1/invoices/{id}/pay) asks for that much less. Nothing is paid here: pay it after. One coupon per invoice; 422 on code says why one does not work (expired, used up, new orders only, …). API 1.10.0: it comes off what the invoice charges after any free offers on it; a coupon for moves only works on a move's invoice (or a rebuild elsewhere's), and one with free offers only with a new server's order (POST /v1/servers) — never put on later.\n\nRequires the `billing:write` permission.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"id","in":"path","required":true,"description":"The invoice's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"discount":5900,"discount_display":"₹59.00","invoice":{"status":"unpaid","paid_at":null,"coupon":"RENEW10","discount":5900,"subtotal":53100,"tax":9558,"total":62658,"total_display":"₹626.58","id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","temporary":false,"currency":"INR","tax_label":"IGST","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16","period_start":"2026-10-01T00:00:00Z","period_end":"2026-10-31T00:00:00Z","issued_at":"2026-10-01T00:00:00Z","due_at":"2026-10-06T00:00:00Z"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"The coupon code (any case).","example":"RENEW10"}},"required":["code"]}}}}},"delete":{"operationId":"removeInvoiceCoupon","summary":"Take the coupon off an invoice","description":"The unpaid invoice is back at its full price and the coupon's use is given back. Nothing happens when it has no coupon. 409 coupon_has_offers (API 1.10.0) on a new server's order whose coupon brought it free offers: they are part of that order, so the coupon stays — to undo it, drop the order (DELETE /v1/servers/{id}).\n\nRequires the `billing:write` permission.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"id","in":"path","required":true,"description":"The invoice's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"invoice":{"status":"unpaid","paid_at":null,"id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","temporary":false,"currency":"INR","subtotal":59000,"discount":0,"coupon":null,"tax":10620,"tax_label":"IGST","total":69620,"total_display":"₹696.20","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16","period_start":"2026-10-01T00:00:00Z","period_end":"2026-10-31T00:00:00Z","issued_at":"2026-10-01T00:00:00Z","due_at":"2026-10-06T00:00:00Z"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/wallet":{"get":{"operationId":"wallet","summary":"Wallet balance and recent movements","description":"The prepaid balance invoices are paid from, what is owed and what renews, and the last 50 movements — every one, a page at a time: GET /v1/wallet/ledger. API 1.9.0: each movement with amount_display and balance_after_display; team: true for a Team account, which is never billed — nothing renews (monthly 0, no next_renewal_at) and nothing is taken from the wallet.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"balance":250000,"currency":"INR","balance_display":"₹2,500.00","unpaid_total":0,"monthly":118000,"next_renewal_at":"2026-10-31T00:00:00Z","team":false,"ledger":[{"amount":-69620,"amount_display":"−₹696.20","kind":"invoice","reference":"01a10f00-…","note":"Invoice GWC/26-27/00012","balance_after":250000,"balance_after_display":"₹2,500.00","created_at":"2026-10-06T10:00:00Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/wallet/ledger":{"get":{"operationId":"walletLedger","summary":"Wallet history","description":"API 1.9.0. Every movement in the wallet, newest first, a page at a time: money in (kind payment, refund, adjustment…) and out (invoice), each with the balance after it. sort orders it by date, amount or note (dir asc or desc).\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"sort","in":"query","required":false,"description":"date, amount (money out is negative) or note. Left out: newest first.","schema":{"type":"string"}},{"name":"dir","in":"query","required":false,"description":"With sort: asc or desc (default desc).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"amount":-69620,"amount_display":"−₹696.20","kind":"invoice","reference":"01a10f00-…","note":"Invoice GWC/26-27/00012","balance_after":250000,"balance_after_display":"₹2,500.00","created_at":"2026-10-06T10:00:00Z"}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/wallet/top-ups":{"post":{"operationId":"topUp","summary":"Top up the wallet","description":"Starts a payment to add money: open checkout_url in a browser signed in to the panel to pay. Once it is in, invoices already due are paid from it automatically (and a server waiting for payment is built) — except renewals of a server with auto-renew off, which wait for you to pay them. A renewal raised ahead of its due date is paid from the wallet on that date when auto-renew is on — until then a coupon can still go on it (POST /v1/invoices/{id}/coupon); to pay it now, use POST /v1/invoices/{id}/pay or POST /v1/servers/{id}/renew. (Before API 1.6.0 a top-up paid every unpaid invoice at once.)\n\nRequires the `billing:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"purpose":"topup","invoice_id":null,"amount":250000,"amount_display":"₹2,500.00","id":"01a1…","status":"created","currency":"INR","checkout_url":"https://panel.example.com/checkout/01a1…","created_at":"2026-10-06T10:00:00Z","captured_at":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"string","description":"In rupees, like \"2500\" or \"2500.50\" (₹1 to ₹5,00,000).","example":"2500"}},"required":["amount"]}}}}}},"/v1/payments/{id}":{"get":{"operationId":"getPayment","summary":"Follow a payment","description":"status: created (waiting at checkout), captured (the money is in) or failed.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The payment's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","purpose":"invoice","status":"created","amount":69620,"amount_display":"₹696.20","currency":"INR","invoice_id":"01a1…","checkout_url":"https://panel.example.com/checkout/01a1…","created_at":"2026-10-06T10:00:00Z","captured_at":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/subscriptions":{"get":{"operationId":"listSubscriptions","summary":"What renews, and when","description":"Every subscription — servers, IPv4 addresses and disks of their own — with its amount for each 30 days (monthly) and next renewal, and its IPv4 (a server's main address, or the address itself; none for a disk). Ended ones are left out unless you ask for status=all. A Team account is never billed (API 1.9.0): its monthly_with_tax is the list price, with no tax. API 1.11.0: type tunnel — a Getwebup Tunnels plan (no IPv4); API 1.12.0: with plan, the plan it is for (while it waits for payment or is suspended, the account runs the free plan — GET /v1/tunnels/account). API 1.10.0: perks — the free offers of the coupon a server was ordered with ([] for none; monthly stays the normal price): kind addon (an add-on free; addon: its code), resources (extra vCPU, memory and storage free: cpu, ram_gb, disk_gb) or renewals (its renewals percent % off; 100: free), with the coupon, a label, periods (how many periods of 30 days it covers, the order's own the first — for renewals, how many renewals; null: for good), periods_used, periods_left (null: for good) and free_until (when the last of them ends; null: for good, or used up). The terms are those of the order: a later change to the coupon changes nothing.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"status","in":"query","required":false,"description":"all: ended ones too.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","type":"server","name":"web-01.example.com","ipv4":"203.0.113.10","description":"VPS · 2 vCPU · 4 GB RAM · 60 GB NVMe","location":"in-bom-1","status":"active","monthly":59000,"monthly_display":"₹590.00","monthly_with_tax":69620,"paused":false,"auto_renew":true,"next_due_at":"2026-11-05T07:49:12Z","created_at":"2026-10-06T07:49:12Z","cancelled_at":null,"perks":[{"kind":"addon","coupon":"WELCOME10","label":"Automatic backups","addon":"backups","periods":3,"periods_used":1,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"},{"kind":"resources","coupon":"WELCOME10","label":"+1 vCPU, +2 GB RAM, +20 GB disk","addon":null,"cpu":1,"ram_gb":2,"disk_gb":20,"periods":3,"periods_used":1,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"},{"kind":"renewals","coupon":"WELCOME10","label":"First 2 renewals 50% off","addon":null,"percent":50,"periods":2,"periods_used":0,"periods_left":2,"free_until":"2027-01-04T07:49:12Z"}]}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/subscriptions/{id}/auto-renew":{"put":{"operationId":"setAutoRenew","summary":"Auto-renew a server, or not","description":"On: each renewal of this server is paid from the wallet by itself on its due date (when the wallet has enough). Off: its renewal invoices wait for you to pay them (POST /v1/servers/{id}/renew); unpaid, the server is suspended and later removed as usual. Servers only — addresses and disks of their own always renew from the wallet. So does a Getwebup Tunnels plan, as in the panel (API 1.12.0): switching one off is 409 not_a_server (true is taken — it is how the panel has it).\n\nRequires the `billing:write` permission.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"id","in":"path","required":true,"description":"The subscription's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","type":"server","name":"web-01.example.com","status":"active","auto_renew":false,"next_due_at":"2026-11-05T07:49:12Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"auto_renew":{"type":"boolean","description":"true or false.","example":false}},"required":["auto_renew"]}}}}}},"/v1/servers/{id}/renew":{"post":{"operationId":"renewServer","summary":"Renew a server","description":"Pays the server's open renewal invoice — its next 30 days, issued a few days before it is due (GET /v1/subscriptions: next_due_at) — with a coupon if you give one. The coupon goes on it first, as POST /v1/invoices/{id}/coupon would put it: off the whole invoice before tax, one coupon per invoice, 422 on coupon when it does not work (expired, used up, new orders only, …); the same code already on it is fine, another one is refused. Paid from the wallet when it covers it (paid: true); otherwise a payment for the rest, as POST /v1/invoices/{id}/pay starts one — open payment.checkout_url in a browser signed in to the panel. A server suspended for an unpaid renewal is unsuspended once it is paid. Should more than one renewal be open, the oldest is the invoice (the coupon goes on it) and the others follow it from the wallet, oldest first; a payment is only ever for one invoice, so renewed lists the invoices paid or being paid by the payment returned, remaining the ones still open (renew again once it is paid), and paid is true once all of them are. 409 nothing_to_renew when no renewal is open — the message says when the next one is issued (or that there is none to pay). Sandbox keys: the sandbox has no renewal cycle, so when none is open a renewal invoice for the server's next 30 days (its price for each 30 days, monthly) is issued on the spot (kind renewal) for the call to pay; paying it changes nothing else there. Renew ahead (API 1.7.0): give periods (1–12) and, when no renewal is open, a temporary renewal invoice for that many periods of 30 days from the due date is made first — the coupon goes on it as it is made (refused: nothing is made) — then paid as above; with a renewal already open, periods must match it (409 renewal_open otherwise: pay that one first). pay: false only makes (or finds) the invoice — paid: false, payment: null — to pay later with POST /v1/invoices/{id}/pay. An invoice asked for ahead and left unpaid lapses after a few days, or once the usual renewal is about to be issued (void), and the usual renewal follows in its time. 409 not_renewable when it can't be renewed ahead now (suspended — contact support; its usual renewal is being issued; or an upgrade, add-on or bigger disk for it waits for payment — pay or cancel that first). An override coupon (\"for ₹99\") is the price of each 30 days: 12 periods cost 12 × ₹99. GET /v1/servers/{id}/renew lists what each choice costs. API 1.10.0: the free offers of the coupon the server was ordered with (GET /v1/subscriptions: perks) come off its renewals by themselves, period by period while they last, as lines of their own (perk: true) — not as its coupon, so a renewals coupon still goes on what is left; a renewal they take all of is ₹0 and paid as it is made (paid: true, nothing to pay).\n\nRequires the `billing:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Billing"],"x-scope":"billing:write","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"paid":true,"invoice":{"coupon":"RENEW10","discount":5900,"subtotal":53100,"tax":9558,"total":62658,"total_display":"₹626.58","period_start":"2026-11-05T07:49:12Z","period_end":"2026-12-05T07:49:12Z","issued_at":"2026-10-31T07:49:12Z","due_at":"2026-11-05T07:49:12Z","paid_at":"2026-11-01T10:00:00Z","id":"01a10f00-…","number":"GWC/26-27/00012","kind":"renewal","status":"paid","temporary":false,"currency":"INR","tax_label":"IGST","credited":0,"overdue":false,"server_id":"01a10eff-…","service":{"id":"01a10eff-…","type":"server","name":"web-01.example.com"},"ipv4":"203.0.113.16"},"payment":null,"renewed":["01a10f00-…"],"remaining":[]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"coupon":{"type":"string","description":"A coupon code (any case) that works on renewals.","example":"RENEW10"},"method":{"type":"string","description":"wallet: only from the balance (409 insufficient_funds otherwise). Default any.","enum":["any","wallet"]},"periods":{"type":"integer","description":"Renew ahead: 1 to 12 periods of 30 days, on a new invoice when none is open (API 1.7.0).","example":3},"pay":{"type":"boolean","description":"false: only make (or find) the renewal invoice, nothing is paid. Default true."}}}}}}},"get":{"operationId":"renewOptions","summary":"What renewing costs","description":"The server's open renewal invoice (open_invoice: pay that one), or — when none is open and it can be renewed — what renewing ahead for 1 to 12 periods of 30 days would cost now, with tax, before a coupon, and to when it would then be paid (paid_until). renewable false says why not (why_not). API 1.7.0. API 1.10.0: with the free offers of the coupon the server was ordered with already taken off, for the periods they still cover (0 when they cover it all).\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The server's id (a UUID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"server_id":"01a1…","next_due_at":"2026-11-12T05:00:00Z","auto_renew":true,"open_invoice":null,"renewable":true,"why_not":null,"max_periods":12,"options":[{"periods":1,"days":30,"paid_until":"2026-12-12T05:00:00Z","subtotal":118800,"tax":21384,"total":140184,"total_display":"₹1,401.84"},{"periods":3,"days":90,"paid_until":"2027-02-10T05:00:00Z","subtotal":356400,"tax":64152,"total":420552,"total_display":"₹4,205.52"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/credit-notes":{"get":{"operationId":"listCreditNotes","summary":"List credit notes","description":"Credit notes issued against your invoices (refunds and corrections), newest first.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","number":"GWC/CN/26-27/0003","invoice_id":"01a1…","invoice_number":"GWC/26-27/00012","reason":"Refund for downtime","currency":"INR","subtotal":10000,"tax":1800,"total":11800,"total_display":"₹118.00","created_at":"2026-10-07T11:00:00Z","taxable":10000,"untaxed":0}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/credit-notes/{id}":{"get":{"operationId":"getCreditNote","summary":"Get a credit note","description":"One credit note. API 1.9.0: what its page prints for GST, under the invoice's own tax rates — taxable and untaxed (in the list too), taxes (each at its rate), place_of_supply, invoice_date, amount_in_words, and the seller and bill_to of its invoice. As a PDF: GET /v1/credit-notes/{id}/pdf.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The credit note's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","number":"GWC/CN/26-27/0003","invoice_id":"01a1…","invoice_number":"GWC/26-27/00012","reason":"Refund for downtime","currency":"INR","subtotal":10000,"tax":1800,"total":11800,"total_display":"₹118.00","created_at":"2026-10-07T11:00:00Z","taxable":10000,"untaxed":0,"invoice_date":"2026-10-01T00:00:03Z","taxes":[{"name":"IGST","rate":"18%","rate_bp":1800,"amount":1800,"amount_display":"₹18.00","compound":false}],"place_of_supply":"Maharashtra (27)","amount_in_words":"Rupees One Hundred Eighteen Only","seller":{"name":"Example Hosting Pvt Ltd","address":"Plot 14, Sector 63\nNoida, Uttar Pradesh 201301","tax_id":"09AAICE1234F1Z5","tax_id_label":"GSTIN","pan":"AAICE1234F","state":"Uttar Pradesh","state_code":"09","country":"IN","email":"billing@example.com"},"bill_to":{"name":"Asha Verma","company":"Verma Labs Pvt Ltd","line1":"12 MG Road","line2":null,"city":"Pune","state":"Maharashtra","state_code":"27","postal_code":"411001","country":"IN","phone":null,"tax_id":"27AAPFU0939F1ZV","tax_id_label":"GSTIN"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/credit-notes/{id}/pdf":{"get":{"operationId":"creditNotePdf","summary":"A credit note as a PDF","description":"API 1.9.0. The credit note as an A4 PDF (Content-Type: application/pdf), as its page in the panel shows it: against which invoice, why, the taxable value and each tax reversed, the total credited in figures and in words. The sandbox has none (404). Errors still come as JSON.\n\nRequires the `billing:read` permission.","tags":["Billing"],"x-scope":"billing:read","parameters":[{"name":"id","in":"path","required":true,"description":"The credit note's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tickets":{"get":{"operationId":"listTickets","summary":"List tickets","description":"Your support tickets, the most recently active first (open ones before closed). awaiting: whose turn it is. API 1.9.0: search them with q and sort them (sort, dir) as the panel's support list does.\n\nRequires the `support:read` permission.","tags":["Support"],"x-scope":"support:read","parameters":[{"name":"page","in":"query","required":false,"description":"Page number, from 1.","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–100 (default 25).","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"active (default), closed or all.","schema":{"type":"string"}},{"name":"server_id","in":"query","required":false,"description":"Only tickets about this server.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Search (API 1.9.0): part of the subject, or of the server it is about (its name or address); or a ticket number (1042 or #1042).","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Sort by (API 1.9.0): number (the ticket number); subject (A → Z); department (by name); priority (low → urgent); status (open, customer_reply, answered, on_hold, closed); server (the server it is about (none last)); last_reply (the latest message); created (when it was opened). Left out: the usual order. Another word: 422.","schema":{"type":"string"}},{"name":"dir","in":"query","required":false,"description":"asc (default) or desc. Empty values come last either way; equal ones newest first.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","number":1042,"subject":"Port 25 is blocked","department":"technical","priority":"normal","status":"open","server_id":null,"message_count":1,"awaiting":"support","unread":false,"last_reply_at":"2026-10-07T10:00:00Z","last_reply_by":"customer","closed_at":null,"created_at":"2026-10-07T10:00:00Z"}],"pagination":{"page":1,"per_page":25,"total":1,"pages":1}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createTicket","summary":"Open a ticket","description":"Our team is told at once and answers by e-mail as well as on the ticket. Up to ten tickets an hour, and 30 messages an hour on your tickets — 10 of them with files.\n\nRequires the `support:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Support"],"x-scope":"support:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","number":1042,"subject":"Port 25 is blocked","department":"technical","priority":"normal","status":"open","server_id":null,"message_count":1,"awaiting":"support","unread":false,"last_reply_at":"2026-10-07T10:00:00Z","last_reply_by":"customer","closed_at":null,"created_at":"2026-10-07T10:00:00Z","messages":[{"attachments":[{"id":"01a3…","filename":"smtp-error.png","content_type":"image/png","size":48213}],"id":"01a1…","from":"you","ai":false,"author":"Asha Verma","body":"Mail from web-01 times out on port 25 since this morning.","created_at":"2026-10-07T10:00:00Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string","description":"4–160 characters.","example":"Port 25 is blocked"},"body":{"type":"string","description":"What happened (10–20,000 characters).","example":"Mail from web-01 times out on port 25 since this morning."},"department":{"type":"string","description":"Default technical.","example":"technical","enum":["technical","billing","sales","abuse","other"]},"priority":{"type":"string","description":"Default normal; urgent is for a service that is down.","example":"normal","enum":["low","normal","high","urgent"]},"server_id":{"type":"string","description":"The server it is about."},"attachments":{"type":"array","description":"Files to attach: [{\"filename\": \"error.png\", \"content\": \"<base64>\"}]. Up to 5 files, 10 MB each, 20 MB together; pictures (PNG, JPEG, GIF, WebP), PDF, text and logs (.txt, .log, .conf …), CSV, JSON or ZIP — the content must be what the name says. The body may then be up to 64 MB. Your files may come to 100 MB a ticket and 200 MB in 30 days (422 on attachments).","items":{"type":"object"}}},"required":["subject","body"]}}}}}},"/v1/tickets/{id}":{"get":{"operationId":"getTicket","summary":"Get a ticket","description":"The ticket and its conversation (it is marked read). Each message says who wrote it: from you, support or system (a note of what changed). API 1.15.0: ai — true on a message written by our AI support assistant (from is support; it signs as an AI assistant, and replying \"human\" brings in the team), false otherwise.\n\nRequires the `support:read` permission.","tags":["Support"],"x-scope":"support:read","parameters":[{"name":"id","in":"path","required":true,"description":"The ticket's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","number":1042,"subject":"Port 25 is blocked","department":"technical","priority":"normal","status":"open","server_id":null,"message_count":1,"awaiting":"support","unread":false,"last_reply_at":"2026-10-07T10:00:00Z","last_reply_by":"customer","closed_at":null,"created_at":"2026-10-07T10:00:00Z","messages":[{"id":"01a1…","from":"you","ai":false,"author":"Asha Verma","body":"Mail from web-01 times out on port 25 since this morning.","attachments":[],"created_at":"2026-10-07T10:00:00Z"},{"id":"01a2…","from":"support","author":"Ravi (Support)","body":"We opened port 25 for web-01 — please try again.","ai":false,"attachments":[],"created_at":"2026-10-07T10:00:00Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tickets/{id}/replies":{"post":{"operationId":"replyTicket","summary":"Reply to a ticket","description":"Writing on a closed ticket opens it again. Up to 30 messages an hour on your tickets — 10 of them with files.\n\nRequires the `support:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Support"],"x-scope":"support:write","parameters":[{"name":"id","in":"path","required":true,"description":"The ticket's id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","number":1042,"subject":"Port 25 is blocked","department":"technical","priority":"normal","status":"open","server_id":null,"message_count":1,"awaiting":"support","unread":false,"last_reply_at":"2026-10-07T10:00:00Z","last_reply_by":"customer","closed_at":null,"created_at":"2026-10-07T10:00:00Z","messages":[{"id":"01a1…","from":"you","ai":false,"author":"Asha Verma","body":"Mail from web-01 times out on port 25 since this morning.","attachments":[],"created_at":"2026-10-07T10:00:00Z"}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string","description":"Your message.","example":"Works now, thank you!"},"attachments":{"type":"array","description":"Files to attach: [{\"filename\": \"error.png\", \"content\": \"<base64>\"}]. Up to 5 files, 10 MB each, 20 MB together; pictures (PNG, JPEG, GIF, WebP), PDF, text and logs (.txt, .log, .conf …), CSV, JSON or ZIP — the content must be what the name says. The body may then be up to 64 MB. Your files may come to 100 MB a ticket and 200 MB in 30 days (422 on attachments).","items":{"type":"object"}}},"required":["body"]}}}}}},"/v1/tickets/{id}/attachments/{attachment_id}":{"get":{"operationId":"ticketAttachment","summary":"Download an attachment","description":"A file on one of the ticket's messages (each message lists its attachments), with its content in base64.\n\nRequires the `support:read` permission.","tags":["Support"],"x-scope":"support:read","parameters":[{"name":"id","in":"path","required":true,"description":"The ticket's id.","schema":{"type":"string"}},{"name":"attachment_id","in":"path","required":true,"description":"The attachment's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a3…","filename":"smtp-error.png","content_type":"image/png","size":48213,"content":"iVBORw0KGgoAAAANSUhEUgAA…"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tickets/{id}/close":{"post":{"operationId":"closeTicket","summary":"Close a ticket","description":"When it is sorted. Writing again opens it.\n\nRequires the `support:write` permission.","tags":["Support"],"x-scope":"support:write","parameters":[{"name":"id","in":"path","required":true,"description":"The ticket's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"status":"closed","awaiting":null,"closed_at":"2026-10-07T12:00:00Z","id":"01a1…","number":1042,"subject":"Port 25 is blocked","department":"technical","priority":"normal","server_id":null,"message_count":1,"unread":false,"last_reply_at":"2026-10-07T10:00:00Z","last_reply_by":"customer","created_at":"2026-10-07T10:00:00Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ssh-keys":{"get":{"operationId":"listSshKeys","summary":"List SSH keys","description":"The public keys you can put on new servers.\n\nRequires the `ssh_keys:read` permission.","tags":["SSH keys"],"x-scope":"ssh_keys:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"01a1…","name":"laptop","fingerprint":"SHA256:4m2…","public_key":"ssh-ed25519 AAAAC3Nza… you@laptop","private_key_kept":false,"created_at":"2026-10-06T07:49:12Z"}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addSshKey","summary":"Add an SSH key","description":"Adds a public key (ssh-ed25519, ssh-rsa, ecdsa-sha2-*).\n\nRequires the `ssh_keys:write` permission.\n\nSupports `Idempotency-Key`.","tags":["SSH keys"],"x-scope":"ssh_keys:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"laptop","fingerprint":"SHA256:4m2…","public_key":"ssh-ed25519 AAAAC3Nza… you@laptop","private_key_kept":false,"created_at":"2026-10-06T07:49:12Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"A name to recognise it by.","example":"laptop"},"public_key":{"type":"string","description":"The public key, as in ~/.ssh/id_ed25519.pub.","example":"ssh-ed25519 AAAAC3Nza… you@laptop"}},"required":["name","public_key"]}}}}}},"/v1/ssh-keys/generate":{"post":{"operationId":"generateSshKey","summary":"Generate an SSH key pair","description":"Makes an Ed25519 key pair and keeps its public half. The private key (OpenSSH format) is in this response — save it now (chmod 600). Where the panel keeps files off the server (storage on), a copy is kept encrypted and private_key_kept is true: GET …/private-key gives it again; otherwise it is never stored.\n\nRequires the `ssh_keys:write` permission.","tags":["SSH keys"],"x-scope":"ssh_keys:write","parameters":[],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"laptop","fingerprint":"SHA256:4m2…","public_key":"ssh-ed25519 AAAAC3Nza… you@laptop","private_key_kept":false,"created_at":"2026-10-06T07:49:12Z","private_key":"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjE…\n-----END OPENSSH PRIVATE KEY-----\n"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"A name to recognise it by.","example":"ci-runner"}},"required":["name"]}}}}}},"/v1/ssh-keys/{id}/private-key":{"get":{"operationId":"privateSshKey","summary":"Download a kept private key","description":"The private key of a pair made here, when its copy was kept (private_key_kept). It opens your servers, so it needs servers:access. Deleting the key deletes the copy.\n\nRequires the `servers:access` permission.","tags":["SSH keys"],"x-scope":"servers:access","parameters":[{"name":"id","in":"path","required":true,"description":"The key's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","name":"ci-runner","private_key":"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjE…\n-----END OPENSSH PRIVATE KEY-----\n"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ssh-keys/{id}":{"delete":{"operationId":"deleteSshKey","summary":"Delete an SSH key","description":"Servers that already have it keep it.\n\nRequires the `ssh_keys:write` permission.","tags":["SSH keys"],"x-scope":"ssh_keys:write","parameters":[{"name":"id","in":"path","required":true,"description":"The key's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"01a1…","deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/account":{"get":{"operationId":"tunnelAccount","summary":"Your Tunnels account and plan","description":"API 1.12.0. What the top of the panel's Tunnels page shows. plan: the plan your tunnels run on now (slug, name, interstitial — visitors first see a warning page — and its limits, as the catalogue's tunnel_plans give them; name, interstitial and limits are null for a plan not listed): the free plan while your subscription waits for payment or is suspended. status: your tunnel account, active or suspended. linked false: the tunnel server won't make your account (link_error taken — your e-mail is another Tunnels account's — or forbidden), link_message says so; open a support ticket. usage_state: warning (80 % of the month's traffic used) or exceeded (all of it: your tunnels have stopped until the 1st), else null. subscription: as GET /v1/subscriptions gives it (type tunnel, with plan: the plan it is for), null on the free plan; a Team account's monthly_with_tax is its list price. scheduled_change: a plan from the next period (ends true: the subscription ends, the free plan after; at: when; can_cancel false once that period is paid for — DELETE /v1/tunnels/change). Waiting for payment, each with its invoice — pay it with POST /v1/invoices/{id}/pay (billing:write): pending_order (an order not paid yet; it lapses after a few hours), pending_upgrade (a dearer plan ordered; DELETE /v1/tunnels/change drops it), pending_renewal (the renewal due; overdue: past its due date — unpaid past the grace days the plan is suspended, and it comes straight back once paid). A coupon goes on an upgrade's or a renewal's invoice the same way: POST /v1/invoices/{id}/pay with coupon, or POST /v1/invoices/{id}/coupon. Like the panel's Tunnels page, the first call makes your tunnel account at the tunnel server (your name and e-mail are sent to it) — whichever Tunnels call it is. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"plan":{"slug":"pro","name":"Pro","interstitial":false,"limits":{"max_tunnels":5,"max_tcp_tunnels":2,"max_reserved_subdomains":5,"max_reserved_tcp_ports":2,"max_custom_domains":2,"bandwidth_monthly_bytes":107374182400,"bandwidth_rate_bps":12500000,"requests_per_minute":600,"max_conns_per_tunnel":100}},"status":"active","linked":true,"link_error":null,"link_message":null,"usage_state":null,"team":false,"subscription":{"id":"01a1…","type":"tunnel","name":"Tunnels Pro","ipv4":null,"description":"Tunnels Pro","location":null,"status":"active","monthly":29900,"monthly_display":"₹299.00","monthly_with_tax":35282,"paused":false,"auto_renew":true,"next_due_at":"2026-11-16T07:49:12Z","created_at":"2026-10-17T07:49:12Z","cancelled_at":null,"perks":[],"plan":"pro"},"scheduled_change":null,"pending_upgrade":null,"pending_order":null,"pending_renewal":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/plans":{"get":{"operationId":"tunnelPlans","summary":"The plans, and what you can do with each","description":"API 1.12.0. The Plan tab's cards, cheapest first: the free plan and the plans on sale, each as the catalogue's tunnel_plans gives it (price_cents for 30 days before tax; limits) with interstitial and your tax on it, as POST /v1/quotes says it (price_with_tax, tax_label, tax_mode, tax_note; a Team account: free and team true, no tax — price_with_tax is the list price). current: your tunnels run on it now. action: what its button does — order (no subscription yet), upgrade (dearer than what your subscription is priced at: at once, the difference for the rest of the period invoiced), downgrade (cheaper, or the same price: from the next period) or cancel (the free plan: the subscription ends at its due date); null for the current plan and for your subscription's own while it waits for payment or is suspended. available false, with reason, while the subscription is suspended (\"Pay the renewal first\"), its order is unpaid (\"Your order is waiting for payment — pay it\") or a change waits (\"A change is planned\"). effective_at: when a downgrade or a cancel would apply. Order with POST /v1/tunnels/order, the rest with POST /v1/tunnels/change. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"slug":"business","name":"Business","description":"For teams and production webhooks","currency":"INR","price_cents":99900,"price_display":"₹999.00","is_default":false,"interstitial":false,"limits":{"max_tunnels":50,"max_tcp_tunnels":10,"max_reserved_subdomains":25,"max_reserved_tcp_ports":10,"max_custom_domains":10,"bandwidth_monthly_bytes":1099511627776,"bandwidth_rate_bps":62500000,"requests_per_minute":0,"max_conns_per_tunnel":0},"price_with_tax":117882,"price_with_tax_display":"₹1,178.82","tax_label":"IGST 18%","tax_mode":"exclusive","tax_note":null,"free":false,"team":false,"current":false,"action":"upgrade","available":true,"reason":null,"effective_at":null}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/order":{"post":{"operationId":"orderTunnelPlan","summary":"Order a Tunnels plan","description":"API 1.12.0. The Plan tab's Get Pro / Get Business, with no subscription yet: an order like any other — your billing address and identity verification first, a coupon if you give one (its rules for orders; a Team account takes none). Paid from the wallet when it covers it (payment.required false: subscription active); otherwise payment.required true — pay invoice_id with POST /v1/invoices/{id}/pay, whose checkout_url opens in a browser signed in to the panel; unpaid, the order lapses after a few hours. A Team account's is on at once, with no invoice. Your tunnels get the plan's limits within a minute. 409 already_subscribed with a plan already (change it instead); 409 order_pending while an order waits for payment (pay it first). Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"plan":"pro","subscription":{"id":"01a1…","type":"tunnel","name":"Tunnels Pro","ipv4":null,"description":"Tunnels Pro","location":null,"status":"active","monthly":29900,"monthly_display":"₹299.00","monthly_with_tax":35282,"paused":false,"auto_renew":true,"next_due_at":"2026-11-16T07:49:12Z","created_at":"2026-10-17T07:49:12Z","cancelled_at":null,"perks":[],"plan":"pro"},"payment":{"required":false,"invoice_id":"01a1…","total":35282,"total_display":"₹352.82","amount_due":0},"coupon":null}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); already_subscribed, order_pending, billing_profile_required, identity_verification_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After; limit_reached — too many wrong coupon codes (no Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","description":"A paid plan's slug from GET /v1/tunnels/plans (pro or business).","example":"pro"},"coupon":{"type":"string","description":"A coupon code (any case) for the order's invoice.","example":"WELCOME10"}},"required":["plan"]}}}}}},"/v1/tunnels/change":{"post":{"operationId":"changeTunnelPlan","summary":"Change your plan","description":"API 1.12.0. The Plan tab's Upgrade, Switch when the 30 days end and Cancel subscription. A dearer plan applies at once (change.kind upgrade): the difference for the rest of the period is invoiced and paid from the wallet when it covers it (status applied); otherwise status pending and payment.required — pay it with POST /v1/invoices/{id}/pay (with a coupon if you like, as on the panel's Billing page: it goes on the invoice first), or drop it with DELETE /v1/tunnels/change. A cheaper paid plan (downgrade), or the free plan (cancel: the subscription ends), is scheduled for the end of the period (status scheduled, effective_at; payment null) — until then nothing changes, and reserved subdomains, custom domains and TCP addresses over the new plan's limits are kept but only the oldest ones keep working. A Team account's upgrade applies at once, with nothing to pay. 409 no_subscription (order one instead), order_pending, suspended (pay the overdue renewal first), same_plan, change_pending (call the waiting change off first: DELETE /v1/tunnels/change), paid_ahead (the next period is paid for at the new price: it can be changed once it starts). Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.\n\nSupports `Idempotency-Key`.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":80},"description":"A unique value (a UUID) so a retry of this request is answered once, not done twice. Kept 24 hours."}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"change":{"kind":"upgrade","from":"pro","to":"business","status":"applied","effective_at":"2026-10-17T07:49:12Z"},"subscription":{"name":"Tunnels Business","description":"Tunnels Business","monthly":99900,"monthly_display":"₹999.00","monthly_with_tax":117882,"plan":"business","id":"01a1…","type":"tunnel","ipv4":null,"location":null,"status":"active","paused":false,"auto_renew":true,"next_due_at":"2026-11-16T07:49:12Z","created_at":"2026-10-17T07:49:12Z","cancelled_at":null,"perks":[]},"payment":{"required":false,"invoice_id":"01a1…","total":35282,"total_display":"₹352.82","amount_due":0}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); no_subscription, order_pending, suspended, same_plan, change_pending, paid_ahead","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","description":"The plan's slug from GET /v1/tunnels/plans — free cancels the subscription.","example":"business"}},"required":["plan"]}}}}},"delete":{"operationId":"cancelTunnelPlanChange","summary":"Call a plan change off","description":"API 1.12.0. The Plan tab's Keep: a change waiting for the next period is called off — you keep your plan, renewals at its price — and an upgrade not paid yet is dropped (its invoice void). 404 not_found when nothing waits; 409 paid_ahead when the next period is paid for already at the new price (it starts then); 409 order_pending, suspended. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"cancelled":true,"subscription":{"id":"01a1…","type":"tunnel","name":"Tunnels Pro","ipv4":null,"description":"Tunnels Pro","location":null,"status":"active","monthly":29900,"monthly_display":"₹299.00","monthly_with_tax":35282,"paused":false,"auto_renew":true,"next_due_at":"2026-11-16T07:49:12Z","created_at":"2026-10-17T07:49:12Z","cancelled_at":null,"perks":[],"plan":"pro"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found — no plan change is waiting","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); paid_ahead, order_pending, suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/usage":{"get":{"operationId":"tunnelUsage","summary":"A month's traffic","description":"API 1.12.0. The Usage tab: a calendar month (UTC) of your tunnels' traffic, in and out, against your plan's monthly quota (quota 0: unlimited, percent null) — level warning at 80 %, danger at 100 %: then open connections are cut within about 10 seconds and visitors see \"bandwidth limit reached\" until the 1st. The speed limit (rate_bps, bytes a second; 0: none), requests, and day by day. A month that has ended can still grow a little for a while. 409 not_ready while your tunnel account is being set up (a minute or so), not_linked when it can't be. Like the panel's Tunnels page, the first call makes your tunnel account at the tunnel server (your name and e-mail are sent to it) — whichever Tunnels call it is. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[{"name":"month","in":"query","required":false,"description":"YYYY-MM, up to this month (default: this month). 422 otherwise.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"month":"2026-10","label":"October 2026","current":true,"bytes_in":3221225472,"bytes_out":9663676416,"total":12884901888,"total_display":"12 GB","in_display":"3 GB","out_display":"9 GB","quota":107374182400,"quota_display":"100 GB","percent":12.0,"level":"ok","rate_bps":12500000,"speed_display":"100 Mbit/s","requests":48211,"days":[{"day":"2026-10-01","bytes_in":104857600,"bytes_out":314572800,"requests":1532}]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_ready (your tunnel account is being set up), not_linked (it can't be)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — month: YYYY-MM, up to this month","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/setup":{"get":{"operationId":"tunnelSetup","summary":"Install and connect the agent","description":"API 1.12.0. The Get started tab: the install commands for Windows (PowerShell) and macOS or Linux — command asks for your API key itself (hidden input); command_with_key has <YOUR_GETWEBUP_API_KEY> to put a key in, for a script — and the manual way, for an agent installed already. windows and unix are null, with install_error, when the tunnel server can't be asked just now (this call still answers 200); downloads_url: where the agent can be downloaded by hand (null: none). tunnel_domains: what tunnel_domain takes in POST /v1/tunnels/domains and /tcp-addresses, the default first. interstitial.applies: visitors of your tunnels first see a warning page (your plan's; null when the plan can't be read) — webhooks, API clients and scripts send the header to skip it. The agent signs in with an API key that holds tunnels:connect (or a full-access key from before Tunnels: GET /v1/key says connects_tunnels); make one in the panel — \"Create a key for tunnels\" — as a key never makes keys. Your key is never in this answer. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"install":{"windows":{"url":"https://getwebup.in/install.ps1","command":"irm https://getwebup.in/install.ps1 | iex","command_with_key":"$env:GETWEBUP_API_KEY=\"<YOUR_GETWEBUP_API_KEY>\"; irm https://getwebup.in/install.ps1 | iex"},"unix":{"url":"https://getwebup.in/install.sh","command":"curl -fsSL https://getwebup.in/install.sh | sh","command_with_key":"curl -fsSL https://getwebup.in/install.sh | GETWEBUP_API_KEY=\"<YOUR_GETWEBUP_API_KEY>\" sh"},"manual":{"command":"getwebup config add-api-key","command_with_key":"getwebup config add-api-key <YOUR_GETWEBUP_API_KEY>"}},"install_error":null,"downloads_url":null,"default_tunnel_domain":"tunnel.getwebup.in","tunnel_domains":["tunnel.getwebup.in"],"examples":["getwebup http 3000","getwebup http 8080 --subdomain myapp","getwebup tcp 22"],"interstitial":{"applies":true,"header":"getwebup-skip-browser-warning","value":"1","example":"curl -H \"getwebup-skip-browser-warning: 1\" https://<your-tunnel-address>"}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/live":{"get":{"operationId":"listLiveTunnels","summary":"Tunnels open now","description":"API 1.12.0. The Live tunnels tab: every tunnel your agents have open right now — its public address (an https:// address, or tcp://host:port), the local address it forwards to, the tunnel server it runs on (by name), the address the agent connected from, when it started and its traffic and requests so far. Not paged (a handful at most); poll it no more often than the panel does, every 15 seconds. Empty without a tunnel account yet. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":"tun_3f9a1c2b4d5e","name":"web","proto":"https","public_url":"https://brave-otter-3f9a.tunnel.getwebup.in","local_addr":"localhost:3000","server_name":"Mumbai 1","client_ip":"203.0.113.5","started_at":"2026-10-17T07:49:12Z","bytes_in":1048576,"bytes_out":5242880,"requests":214}]}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/live/{id}":{"delete":{"operationId":"stopTunnel","summary":"Stop a tunnel","description":"API 1.12.0. The Live tunnels tab's Stop: its public address stops answering at once (the agent says it was stopped from your account). 404 when it isn't open (any more). 409 tunnels_suspended while your tunnel account is suspended. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"id","in":"path","required":true,"description":"The tunnel's id, from GET /v1/tunnels/live.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":"tun_3f9a1c2b4d5e","stopped":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/domains":{"get":{"operationId":"listTunnelDomains","summary":"Reserved subdomains and custom domains","description":"API 1.12.0. The Domains tab: your reserved subdomains (kind subdomain — a name on one of our tunnel domains, only your tunnels can use it: getwebup http 8080 --subdomain myapp) and your own domains (kind custom, with the two DNS records to create: dns_records). status: reserved, verified, pending (a custom domain whose records aren't seen yet: POST …/verify) or inactive — after a move to a smaller plan the ones over its limits are kept, but only the oldest work (by when they were added). limits: how many you have and how many your plan holds (subdomain_limit, custom_domain_limit; 0: not in your plan) and the plans that hold more (upgrade_to); plan_known false: your plan can't be read right now — the limits are then null and nothing is marked inactive. On a plan without them the list is empty. 409 not_ready while your tunnel account is being set up (a minute or so), not_linked when it can't be. Like the panel's Tunnels page, the first call makes your tunnel account at the tunnel server (your name and e-mail are sent to it) — whichever Tunnels call it is. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":17,"kind":"custom","hostname":"app.example.com","tunnel_domain":"tunnel.getwebup.in","status":"pending","verified":false,"verified_at":null,"inactive":false,"created_at":"2026-10-17T07:49:12Z","dns_records":[{"type":"CNAME","name":"app.example.com","value":"custom.tunnel.getwebup.in"},{"type":"TXT","name":"_getwebup-challenge.app.example.com","value":"getwebup-verify=4f1c9a…"}]}],"limits":{"plan_known":true,"subdomains":0,"subdomain_limit":5,"custom_domains":1,"custom_domain_limit":2,"upgrade_to":{"subdomains":["business"],"custom_domains":["business"]}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_ready (your tunnel account is being set up), not_linked (it can't be)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addTunnelDomain","summary":"Reserve a subdomain or add your own domain","description":"API 1.12.0. The Domains tab's two forms: give subdomain (Reserve a subdomain: myapp → myapp.<tunnel domain>) or hostname (Add your own domain: app.example.com — it comes back with its dns_records; create them where its DNS is managed, then POST …/verify) — one of the two, trimmed and lower-cased; tunnel_domain picks one of GET /v1/tunnels/setup's (left out: the default). 422 on that field with the tunnel server's reason (not a valid name, reserved, taken — a name of yours already reserved is taken too); on tunnel_domain when it isn't one of ours. 409 not_in_plan when your plan doesn't include it, plan_limit_reached when it holds no more (GET /v1/tunnels/plans: upgrade); not_ready, not_linked, tunnels_suspended as for the list. A POST is sent to the tunnel server once: after a 5xx or a timeout it may have been made — GET the list before trying again. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":18,"kind":"subdomain","hostname":"myapp.tunnel.getwebup.in","tunnel_domain":"tunnel.getwebup.in","status":"reserved","verified":true,"verified_at":"2026-10-17T07:49:12Z","inactive":false,"created_at":"2026-10-17T07:49:12Z","dns_records":[]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); not_in_plan, plan_limit_reached, not_ready, not_linked, tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"subdomain":{"type":"string","description":"A name to reserve: lower-case letters, digits and dashes. null: not given.","example":"myapp"},"hostname":{"type":"string","description":"Or a domain of your own. null: not given.","example":"app.example.com"},"tunnel_domain":{"type":"string","description":"Which of our tunnel domains it is on, or served through (GET /v1/tunnels/setup). Default: the default one."}}}}}}}},"/v1/tunnels/domains/{id}/verify":{"post":{"operationId":"verifyTunnelDomain","summary":"Check a custom domain's DNS records","description":"API 1.12.0. The Domains tab's Verify: the tunnel server looks the CNAME and TXT records up now. verified true: your tunnels can use it (HTTPS is set up for it). Not yet is no error: verified false, and message says which record is missing or wrong, or that DNS changes can take a while to be seen — try again in a few minutes. domain: as the list shows it (null if it can't be read). At most 10 checks a minute, counted with the panel's — and the tunnel server takes only 5 in a row, then one every 10 seconds: either way 429 limit_reached (no Retry-After — not the API's rate limit; wait and check again, never plan_limit_reached). A subdomain is verified already. 409 not_ready, not_linked, tunnels_suspended as for the list. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"id","in":"path","required":true,"description":"The domain's id, from GET /v1/tunnels/domains.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"verified":true,"message":null,"domain":{"status":"verified","verified":true,"verified_at":"2026-10-17T08:02:40Z","id":17,"kind":"custom","hostname":"app.example.com","tunnel_domain":"tunnel.getwebup.in","inactive":false,"created_at":"2026-10-17T07:49:12Z","dns_records":[{"type":"CNAME","name":"app.example.com","value":"custom.tunnel.getwebup.in"},{"type":"TXT","name":"_getwebup-challenge.app.example.com","value":"getwebup-verify=4f1c9a…"}]}}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); not_ready, not_linked, tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After; limit_reached — 10 checks a minute, or the tunnel server's 5 in a row then one every 10 seconds (no Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/domains/{id}":{"delete":{"operationId":"deleteTunnelDomain","summary":"Remove a domain","description":"API 1.12.0. The Domains tab's Remove: a tunnel on it stops. A subdomain is released — someone else may reserve it after you; a custom domain can be added again later (and verified again). 404 when it isn't yours (any more). 409 not_ready, not_linked, tunnels_suspended as for the list. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"id","in":"path","required":true,"description":"The domain's id, from GET /v1/tunnels/domains.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":17,"deleted":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); not_ready, not_linked, tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tunnels/tcp-addresses":{"get":{"operationId":"listTunnelTcpAddresses","summary":"Reserved TCP addresses","description":"API 1.12.0. The TCP addresses tab: a fixed public address (host and port) for your TCP tunnels — SSH, a database, a game server — so it doesn't change every time the tunnel starts (without one, a TCP tunnel gets a random port each time). status reserved, or inactive past your plan's number after a move to a smaller plan (the oldest work). limits as for domains: tcp_addresses, tcp_address_limit (0: not in your plan), upgrade_to, plan_known. 409 not_ready, not_linked as for domains. Like the panel's Tunnels page, the first call makes your tunnel account at the tunnel server (your name and e-mail are sent to it) — whichever Tunnels call it is. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:read` permission.","tags":["Tunnels"],"x-scope":"tunnels:read","parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":[{"id":4,"port":22022,"address":"tcp.tunnel.getwebup.in:22022","status":"reserved","inactive":false,"created_at":"2026-10-17T07:49:12Z"}],"limits":{"plan_known":true,"tcp_addresses":1,"tcp_address_limit":2,"upgrade_to":["business"]}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_ready (your tunnel account is being set up), not_linked (it can't be)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"reserveTunnelTcpAddress","summary":"Reserve a TCP address","description":"API 1.12.0. The TCP addresses tab's Reserve: any free port (port left out, null or 0 — \"Any port\") or the one you ask for (\"A port I choose\": 422 when the tunnel server's range doesn't have it, or it is taken), on tunnel_domain (left out: the default). 422 on tunnel_domain when it isn't one of ours. 409 not_in_plan, plan_limit_reached; not_ready, not_linked, tunnels_suspended as for the list. Sent to the tunnel server once: after a 5xx or a timeout it may have been made — GET the list before trying again (another try for any port would reserve a second one). Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[],"responses":{"201":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":4,"port":22022,"address":"tcp.tunnel.getwebup.in:22022","status":"reserved","inactive":false,"created_at":"2026-10-17T07:49:12Z"}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); not_in_plan, plan_limit_reached, not_ready, not_linked, tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"port":{"type":"integer","description":"1–65535 for that port; left out or 0: any free one.","example":0},"tunnel_domain":{"type":"string","description":"Which of our tunnel domains the address is on (GET /v1/tunnels/setup). Default: the default one."}}}}}}}},"/v1/tunnels/tcp-addresses/{id}":{"delete":{"operationId":"releaseTunnelTcpAddress","summary":"Release a TCP address","description":"API 1.12.0. The TCP addresses tab's Release: a TCP tunnel on it stops, and it is no longer kept for you — someone else may get it later, and you may not get it back. 404 when it isn't yours (any more). 409 not_ready, not_linked, tunnels_suspended as for the list. Production keys only: a sandbox key gets 403 production_only (the sandbox has no tunnels).\n\nRequires the `tunnels:write` permission.","tags":["Tunnels"],"x-scope":"tunnels:write","parameters":[{"name":"id","in":"path","required":true,"description":"The address's id, from GET /v1/tunnels/tcp-addresses.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed a minute for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Left in the current minute."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"When the minute ends (Unix time)."},"X-Request-Id":{"schema":{"type":"string"},"description":"Quote it to support."},"X-Api-Mode":{"schema":{"type":"string","enum":["production","sandbox"]}}},"content":{"application/json":{"example":{"data":{"id":4,"released":true}}}}},"401":{"description":"missing_api_key, invalid_api_key, key_revoked, key_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, ip_not_allowed, account_suspended, identity_verification_required (production: the account must verify its identity before using the panel); production_only — a sandbox key (the sandbox has no tunnels)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not found (or not yours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"the request conflicts with the current state (e.g. not_active, idempotency_in_progress); not_ready, not_linked, tunnels_suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed — see fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error — something on our side; try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"upstream_error — the tunnel server didn't answer; try again in a few minutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer cx_live_… (production) or cx_test_… (sandbox). Create keys in the panel under API."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","required":["code","message","request_id"],"properties":{"code":{"type":"string","example":"insufficient_scope"},"message":{"type":"string"},"request_id":{"type":"string","example":"req_3f9a…"},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-field messages (validation errors)."}}}}}}},"x-scopes":{"account:read":"Read your account: profile, group and limits, verification and how it is taxed, billing address, e-mail preferences, the e-mails we sent you and the API request log.","account:write":"Change your name and phone, billing address and e-mail preferences; reset the sandbox.","catalog:read":"Read locations, operating systems, apps, server types and prices; price a server; check a coupon.","servers:read":"List servers and read their details, activity, live usage, graphs, bandwidth, apps, alerts, add-ons and upgrade, rebuild and move options and prices.","servers:write":"Create (order and pay from the wallet), rename, rebuild (in another location, copying its extra disks is paid from the wallet; its password made up and its SSH keys kept), upgrade, move to another location or host (paid from the wallet) and destroy servers; change their main IPv4, add-ons, alerts and Windows licence.","servers:power":"Start, shut down, reboot and power off servers.","servers:access":"Read servers' and apps' login passwords, set a new password, open the console; with servers:write, choose a rebuild's password, SSH keys or an app set up on its own page, and who may reach an app's setup page. Whoever holds it can get inside your servers.","backups:read":"List servers' backups.","backups:write":"Take a backup now, restore one (it replaces the server's disks) and delete backups.","firewall:read":"Read servers' firewalls and your security groups.","firewall:write":"Change servers' firewalls and security groups, and apply them.","disks:read":"List disks and read their details, and where they can move and what that costs.","disks:write":"Buy (paid from the wallet), grow, attach, detach, move (paid from the wallet) and delete disks.","ips:read":"List your IPv4 and IPv6 addresses.","ips:write":"Buy IPv4 addresses (paid from the wallet), move them between servers and release them.","billing:read":"Read invoices, credit notes, subscriptions, payments and the wallet.","billing:write":"Pay invoices from the wallet, and start card or UPI payments and wallet top-ups (finished in a browser).","support:read":"Read your support tickets and their messages.","support:write":"Open support tickets, reply to them and close them.","ssh_keys:read":"List SSH keys.","ssh_keys:write":"Add, generate and delete SSH keys.","tunnels:read":"Read your Tunnels plan, its limits and prices, a month's traffic, the agent's setup commands, the tunnels open now, and your reserved subdomains, custom domains (with the DNS records they need) and TCP addresses.","tunnels:write":"Stop tunnels; reserve and release subdomains and TCP addresses; add, verify and remove custom domains; order a Tunnels plan (paid from the wallet), change it, and call a change off.","tunnels:connect":"Connect the getwebup tunnel agent: open tunnels to your computer on your Tunnels plan. Gives no access to servers or billing."}}