Everything you do in the panel, from your own code: order, power, rebuild, upgrade and destroy servers; their apps, alerts, add-ons, backups and firewall; security groups, disks and IPv4 addresses; invoices, payments, the wallet and subscriptions; support tickets, SSH keys and your account; and Getwebup Cloud Tunnels — the plan, traffic, live tunnels, reserved subdomains, custom domains and TCP addresses. It is a JSON REST API over HTTPS, versioned in the path.
Some things stay in the panel on purpose: your password, two-step sign-in and devices, identity verification, and API keys themselves — a key can never make or change keys.
Base URL
https://cloud.getwebup.in/api/v1
Format
JSON in and out, UTF-8
Auth
API key in Authorization: Bearer …
Spec
OpenAPI 3.1 — import into Postman, Insomnia or a client generator
Your first call
export API_KEY=cx_test_… # a sandbox key from the panel: API → New key
curl -s https://cloud.getwebup.in/api/v1/key -H "Authorization: Bearer $API_KEY"
Then create a server in the sandbox, watch it go from provisioning to active, reboot it and destroy it — without anything being built or billed. When your code works, swap in a production key.
Authentication
Create keys in the panel under API. Send the key on every request:
Authorization: Bearer cx_live_8kQ2…
cx_live_… keys are production; cx_test_… keys are sandbox. The key alone decides which — the URL is the same.
The secret is shown once, when the key is made. We keep only a keyed hash of it. Lost it? Roll the key: same settings, new secret, the old one stops at once.
Revoke a key and it stops immediately. Keys can also be given an expiry date, and stop working if the account is suspended.
Creating or rolling a production key e-mails the account owner.
Keys are for servers, not browsers: the API sends no CORS headers. Keep keys in environment variables or a secrets manager — never in front-end code, a mobile app or a repository.
Sandbox and production
Every account has a sandbox: a simulated copy of the platform where the same endpoints behave the same way, so an integration built against it works unchanged in production.
Sandbox (cx_test_)
Production (cx_live_)
Servers
Simulated: provisioning for ~20 s, then active, an app installing ~15 s more; power changes, rebuilds, restores and upgrades take a few seconds; live usage, graphs and bandwidth are made up
Really built, usually in a minute or two
Console
A ticket in the production shape, but nothing connects; its panel_url leads here
The server's real screen and keyboard
Firewall, disks, addresses, backups
Kept and applied in the simulation (a few seconds each)
On your real servers
Billing
A make-believe wallet of ₹10,000.00; nothing is charged. A payment or top-up started at checkout is made by itself 10 seconds later (its checkout_url leads here)
Paid from your real wallet; payments are made in a browser at checkout_url
Coupons and their offers
The real codes, checked by the real rules. A coupon's free offers on a new server (API 1.10.0) work as in production: the server is built with them and its order and renewals are priced with them (free periods counted per renewal, a ₹0 renewal paid at once) — for a Team account too, as the sandbox bills every account
On your real invoices; a Team account takes no coupon
Support tickets
Answered within seconds by the sandbox's own desk — real support never sees them
Answered by our team
Your account
Read from your real account; changes stay in the sandbox
Your real account
Catalogue and prices
The real ones, with the same validation
Addresses
From the documentation ranges (203.0.113.0/24, 2001:db8::/32)
Real public IPv4 and IPv6
SSH keys, invoices
Separate, sandbox only
Your account's
Tunnels
Not simulated: every /v1/tunnels call answers 403 production_only — a tunnel is real
Your real plan, tunnels and reservations
Rate limit
60 requests a minute per key
120 requests a minute per key
Reset the sandbox any time from the API page in the panel, or with a sandbox key: POST /v1/sandbox/reset. Responses from the sandbox carry X-Api-Mode: sandbox and servers have "sandbox": true.
Permissions
Every key has a set of permissions (scopes), and every endpoint needs exactly one. Give each key only what its job needs: a monitoring script needs servers:read, not servers:write. A call without the permission gets 403 insufficient_scope.
Two need servers:access as well for part of what they do, as only it gets inside a server: a rebuild that chooses its login (a password, SSH keys, or an app set up on its own page), and who may reach an app's login while it is installing or waits for its setup page. error.fields.scope names it.
Permission
Allows
Endpoints
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.
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.
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.
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.
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.
Connect the getwebup tunnel agent: open tunnels to your computer on your Tunnels plan. Gives no access to servers or billing.
Ready-made sets in the panel: Read only · Read + power · Full access · Tunnels only.
IP allowlists
A key can be limited to the addresses it is used from: single addresses or CIDR ranges, IPv4 and IPv6 (203.0.113.5, 198.51.100.0/24, 2001:db8:1234::/48), up to 50. A call from anywhere else gets 403 ip_not_allowed (the message names the address we saw — handy behind NAT). A key without an allowlist works from any address. We strongly recommend an allowlist for production keys used from fixed servers.
Requests and responses
Send bodies as JSON with Content-Type: application/json.
A single thing comes back as {"data": {…}}; a list as {"data": […], "pagination": {"page", "per_page", "total", "pages"}}. Page with ?page=2&per_page=50 (at most 100).
Times are ISO 8601 in UTC (2026-10-06T07:49:12Z). Money is in minor units (paise) with its currency, plus a *_display string.
Ids are UUIDs. Things that aren't yours answer 404, exactly like things that don't exist.
Every response has an X-Request-Id; errors repeat it as error.request_id. Quote it to support.
New fields may be added to responses at any time within v1; your code should ignore fields it doesn't know. Anything that would break a client comes as v2.
Errors
{
"error": {
"code": "validation_failed",
"message": "Please correct the highlighted fields.",
"request_id": "req_7c1e9a0f42b6d3a8e5f1",
"fields": {
"ram_gb": "Memory must be at least 1."
}
}
}
Status
code
Means
400
invalid_json
The body is not a JSON object.
401
missing_api_key
No Authorization: Bearer header.
401
invalid_api_key
The key doesn't exist (mistyped, or from another panel).
401
key_revoked
The key was revoked (or rolled — use the new secret). A password reset revokes every key of the account, sandbox ones too; a password change or signing out everywhere does unless the box is unticked.
401
key_expired
The key passed its expiry date.
403
insufficient_scope
The key lacks the permission the endpoint needs; error.fields.scope names it.
403
ip_not_allowed
The key has an IP allowlist and the caller's address isn't on it.
403
account_suspended
The account is suspended (or account_closed).
403
identity_verification_required
Production only: identity verification is set to "before using the panel" and the account has not verified yet — until it does (in the panel, error.fields.verify_url), its production keys reach only the key itself, the account, support and the request log, as the panel does. Re-read within a minute of it changing.
404
not_found
No such endpoint — or the thing doesn't exist or isn't yours.
405
method_not_allowed
The path exists with other methods (see the Allow header).
The request doesn't fit the current state (the server is busy, stopped, being built, or no longer there).
409
backup_running
A backup of the server is running: changes wait until it finishes (usually a few minutes).
409
insufficient_funds
POST /v1/invoices/{id}/pay with method wallet: the balance doesn't cover it.
409
renewal_due
An upgrade, an add-on or a bigger disk while the server's renewal is due (past its due date, or its renewal invoice overdue): pay the renewal first. A renewal ahead is refused the same way while an upgrade, add-on or bigger disk waits for payment (not_renewable).
What you asked for clashes with how things are (an upgrade, a move or a rebuild in another location waiting for payment, an add-on already on, a group still in use…). The message says what to do.
409
cannot_move / disk_busy / not_movable / move_paid
A server or disk can't be moved right now (being built or changed, a backup running, moved less than a day ago, a disk on a server), a disk that moves only with its server, or a move paid meanwhile that can no longer be dropped. The message says why.
429
limit_reached
A limit on the action itself — three manual backups a day, a test alert every two minutes, a new main IPv4 once a day, ten tickets an hour, 30 ticket messages an hour (10 with files), ten DNS checks a minute on a Tunnels domain (counted with the panel's; the tunnel server takes 5 in a row, then one every 10 seconds) or the tunnel server's own limit. Not the rate limit: no Retry-After.
409
idempotency_in_progress
A request with the same Idempotency-Key is still running.
409
identity_verification_required
Production only: the account must verify its identity through DigiLocker (in the panel, under Account) before ordering.
409
billing_profile_required
Production only: add a billing address in the panel before ordering.
415
unsupported_media_type
Send JSON with Content-Type: application/json.
422
validation_failed
Some fields are wrong; error.fields says which and why.
422
idempotency_mismatch
The Idempotency-Key was used for a different request.
429
rate_limited
Too many requests this minute; wait for Retry-After seconds.
500
internal_error
Our fault. Retry later; quote the request_id to support.
502
upstream_error
A part of the platform didn't answer; safe to retry (with an Idempotency-Key for POSTs).
503
api_disabled
The API is switched off for maintenance.
403
production_only
A Tunnels endpoint called with a sandbox key: tunnels are real, the sandbox has none — use a production key.
409
not_in_plan / plan_limit_reached
Tunnels: your plan doesn't include that (reserved subdomains, custom domains, TCP addresses), or holds no more of it — a bigger plan does (GET /v1/tunnels/plans). plan_limit_reached names the field.
409
not_ready / not_linked / tunnels_suspended
Tunnels: your tunnel account is being set up (a minute or so), can't be set up (open a support ticket — the message says why), or is suspended.
A Tunnels plan can't be ordered or changed right now: an order waits for payment, a change waits for the next period, or the plan is suspended or ended. The message says what to do.
Retry 429, 502 and 503 with backoff; don't retry other 4xx without changing the request.
Rate limits
Each key may make 120 requests a minute in production and 60 in the sandbox. Every response says where you stand:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1791385260 # Unix time the minute ends
Over the limit you get 429 rate_limited with Retry-After (seconds). Wait that long; don't hammer. Need more? Ask support.
Idempotency
Networks fail. To retry a POST safely — above all POST /v1/servers, which orders and pays — send an Idempotency-Key header with a unique value (a UUID). For 24 hours, a retry with the same key gets the first answer again (marked Idempotent-Replayed: true) instead of doing it twice.
The same key with a different body or path: 422 idempotency_mismatch.
A retry while the first request still runs: 409 idempotency_in_progress — wait and retry.
If the first attempt failed on our side (5xx), the key is released so the retry runs for real.
Request log
Every call is logged — answered, refused or failed: the key (or the beginning of an unknown one), the time, the caller's IP address and user agent, the method and path, the status and error code, how long it took and the Idempotency-Key. See it in the panel under API → Request log, or read it with GET /v1/requests; filter by key, environment, outcome, path or address. The log is kept 90 days.
Authentication
GET/v1/keyany key
The key you are using
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).
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.
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
key
query · string
Only this key's calls, by its id (GET /v1/key gives the id of the one you are using).
mode
query · string
production or sandbox: only the calls made with that kind of key.
status
query · string
2xx (answered), 4xx (refused) or 5xx (failed) — or one status, like 404.
q
query · string
Part of the path (/v1/servers), a request id (req_…) or an error code (insufficient_scope).
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.
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/sandbox/reset \
-H "Authorization: Bearer $API_KEY"
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).
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.
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).
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).
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.
Body (JSON)
email_alerts
boolean
E-mail when a server goes down and comes back.
usage_alerts
boolean
E-mail when CPU, memory or network stay at 85 % or more.
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.
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
sort
query · string
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.
dir
query · string
asc (default) or desc. Empty values come last either way; equal ones newest first.
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.
{
"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…"
}
}
Catalogue
GET/v1/catalogcatalog:read
Locations, images, apps, types and prices
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).
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)").
Body (JSON)
location required
string
A location code from the catalogue.
image required
string
An operating-system image code from the catalogue.
cpu required
integer
vCPUs.
ram_gb required
integer
Memory in GB.
disk_gb required
integer
NVMe storage in GB.
type
string
Server type code (default vps).
app
string
A one-click app or control panel code from the catalogue.
addons
object
Add-on codes and how many: {"backups": 1, "bandwidth": 2}.
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.
Body (JSON)
code required
string
The coupon code.
for
string · order | renewal | move | server
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).
amount
integer
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.
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.
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
status
query · string
Only these statuses, comma separated: provisioning, active, suspended, awaiting_payment, failed, upgrading, rebuilding, migrating, terminated.
q
query · string
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.
sort
query · string
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.
dir
query · string
asc (default) or desc. Empty values come last either way; equal ones newest first.
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).
Body (JSON)
hostname
string
A hostname (letters, digits, dots, dashes). Left out: one is made up.
location required
string
A location code from the catalogue.
image required
string
An operating-system image code from the catalogue.
cpu required
integer
vCPUs.
ram_gb required
integer
Memory in GB.
disk_gb required
integer
NVMe storage in GB.
type
string
Server type code (default vps).
app
string
A one-click app or control panel from the catalogue, installed on the fresh system (free).
addons
object
Add-ons and how many: backups, alerting (call alerting), managed, bandwidth (TB a month).
alert_phone
string
With call alerting: the number to call, international format.
extra_ipv4
integer
Extra IPv4 addresses for it (0–64), each its own subscription.
ipv4_id
string
One of your own unattached IPv4 addresses (GET /v1/ips) in this location, as its main address.
ssh_key_ids
array
Ids of your SSH keys to put on the server.
ssh_public_keys
array
More public keys, as text ("ssh-ed25519 AAAA… you@laptop"). At most 10 keys in all.
password
string
A root/Administrator password (10+ characters, mixed case, a digit). Left out: one is generated (read it with GET /v1/servers/{id}/credentials).
coupon
string
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.
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.
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.
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.
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.
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.
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.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
month
query · string
YYYY-MM: this month (default) or one of the two before.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
password
string
10+ characters with upper- and lower-case letters and a digit; keyboard characters only.
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.
Parameters
id required
path · string
The server's id (a UUID).
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/servers/01a10eff-7046-7490-84f7-6318061bb37d/console \
-H "Authorization: Bearer $API_KEY"
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.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
image required
string
An image from GET …/rebuild.
location
string
Rebuild it in another location (it gets a new IPv4 there). Its extra disks are copied there, charged per GB.
app
string
An app or control panel to install on the fresh system.
password
string
The new login password (needs servers:access as well). Left out: one is generated.
keep_ssh_keys
boolean
Put the same SSH keys on the fresh system (default true when no keys are given).
ssh_key_ids
array
Your SSH keys for the fresh system instead (needs servers:access as well).
ssh_public_keys
array
More public keys, as text (needs servers:access as well).
coupon
string
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.
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).
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).
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
location required
string
A location from GET …/move: another one — or its own, for another host there.
coupon
string
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.
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).
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).
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).
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
ip_id
string
One of your own addresses. Left out: a new address.
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.
Make a server bigger — more vCPU, memory or disk — in two calls: price it, then order it. The rest of the current period is paid from the wallet and the new size is applied at once (more vCPU or memory restarts the server once; more disk alone does not). If the wallet is short, the upgrade waits for payment: pay its invoice, or drop it. From the next renewal the server costs the new price for each 30 days. Disks can only grow.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
cpu required
integer
vCPUs (at least today's).
ram_gb required
integer
Memory in GB (at least today's).
disk_gb required
integer
Storage in GB (at least today's — disks can't shrink).
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
cpu required
integer
vCPUs (at least today's).
ram_gb required
integer
Memory in GB (at least today's).
disk_gb required
integer
Storage in GB (at least today's — disks can't shrink).
coupon
string
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).
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.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
mode required
string · mine | anyone
mine: only from ip; anyone: every address.
ip
string
With mine: the address (its /24 or /64 network is allowed). Default: the address of this request.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
email_alerts
boolean
E-mail when it goes down and comes back.
usage_alerts
boolean
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).
Calls the alert numbers (and e-mails) once, so you know it works. Call alerting only; once every two minutes.
Parameters
id required
path · string
The server's id (a UUID).
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/servers/01a10eff-7046-7490-84f7-6318061bb37d/alerts/test \
-H "Authorization: Bearer $API_KEY"
Response · 202
{
"data": {
"queued": true
}
}
Add-ons
GET/v1/servers/{id}/addonsservers:read
Its add-ons
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
type required
string · backups | alerting | managed | bandwidth
Which add-on (codes in the catalogue).
quantity
integer
bandwidth: how many TB a month (default 1).
coupon
string
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).
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.
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.
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.
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.
Parameters
id required
path · string
The server's id (a UUID).
backup_id required
path · string
The backup's id.
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/servers/01a10eff-7046-7490-84f7-6318061bb37d/backups/9c1e4b0a77d2f5e3a1b6c8d0/restore \
-H "Authorization: Bearer $API_KEY"
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).
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.
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.
Body (JSON)
size_gb required
integer
Size in GB (see resources.volume in the catalogue).
name
string
A name (letters, digits, spaces, dots, dashes). Default "data".
server_id
string
Attach it to this server once paid.
location
string
Without a server: where it is made.
coupon
string
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).
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).
Parameters
id required
path · string
The disk's id.
Body (JSON)
size_gb required
integer
The new, larger size.
coupon
string
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).
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).
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.
Parameters
id required
path · string
The disk's id.
Body (JSON)
server_id
string
Next to this server of yours (GET …/move: servers), then put on it.
location
string
Or to this location (GET …/move: locations).
coupon
string
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.
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.
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.
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.
Body (JSON)
server_id
string
Put it on this server once paid.
location
string
Without a server: where it is.
coupon
string
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).
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.
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.)
Parameters
id required
path · string
The address's id.
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/ips/01a10eff-7046-7490-84f7-6318061bb37d/detach \
-H "Authorization: Bearer $API_KEY"
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.
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.
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
status
query · string
unpaid, paid or void.
q
query · string
Search: an invoice number, a server's name or an IPv4 address — or part of one, like 203.0.113.
server
query · string
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.
type
query · string
tax_invoice: only numbered invoices — each issued when it was paid; temporary: only temporary invoices still waiting for payment (API 1.9.0).
sort
query · string
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.
dir
query · string
With sort: asc or desc (default desc). Empty values (no due date) come last either way.
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).
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.
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.
Parameters
id required
path · string
The invoice's id.
Body (JSON)
with
array
Other unpaid invoices to pay in the same go.
method
string · any | wallet
wallet: only from the balance (409 insufficient_funds otherwise). Default any.
coupon
string
A coupon code (any case) to put on this invoice before paying it.
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.
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}).
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.
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).
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
sort
query · string
date, amount (money out is negative) or note. Left out: newest first.
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.)
Body (JSON)
amount required
string
In rupees, like "2500" or "2500.50" (₹1 to ₹5,00,000).
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.
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).
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).
Parameters
id required
path · string
The server's id (a UUID).
Body (JSON)
coupon
string
A coupon code (any case) that works on renewals.
method
string · any | wallet
wallet: only from the balance (409 insufficient_funds otherwise). Default any.
periods
integer
Renew ahead: 1 to 12 periods of 30 days, on a new invoice when none is open (API 1.7.0).
pay
boolean
false: only make (or find) the renewal invoice, nothing is paid. Default true.
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).
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.
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.
"%PDF-1.4 … (the file itself: Content-Type: application/pdf, Content-Disposition: inline; filename=\"credit-note-GWC-CN-26-27-0003.pdf\")"
Support
GET/v1/ticketssupport:read
List tickets
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.
Parameters
page
query · integer
Page number, from 1.
per_page
query · integer
Items per page, 1–100 (default 25).
status
query · string
active (default), closed or all.
server_id
query · string
Only tickets about this server.
q
query · string
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).
sort
query · string
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.
dir
query · string
asc (default) or desc. Empty values come last either way; equal ones newest first.
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.
Default normal; urgent is for a service that is down.
server_id
string
The server it is about.
attachments
array
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).
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/tickets \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"subject":"Port 25 is blocked","body":"Mail from web-01 times out on port 25 since this morning."}'
Response · 201
{
"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"
}
]
}
}
GET/v1/tickets/{id}support:read
Get a ticket
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.
Writing on a closed ticket opens it again. Up to 30 messages an hour on your tickets — 10 of them with files.
Parameters
id required
path · string
The ticket's id.
Body (JSON)
body required
string
Your message.
attachments
array
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).
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.
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.
API 1.12.0. What the panel's Tunnels page does, with a production key: see the plans, then order one or change it — paid from the wallet when it covers it; otherwise pay the invoice it waits for (your account lists what waits: an order, an upgrade, the renewal). A move to a smaller plan keeps your reservations, but only the oldest within its limits keep working. The agent signs in with an API key that holds tunnels:connect — make it in the panel (Tunnels → Create a key for tunnels), as a key never makes keys; the setup commands ask for it. On a plan with the warning page, webhooks, API clients and scripts send getwebup-skip-browser-warning: 1 to reach your app.
GET/v1/tunnels/accounttunnels:read
Your Tunnels account and plan
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).
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).
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).
Body (JSON)
plan required
string
A paid plan's slug from GET /v1/tunnels/plans (pro or business).
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).
Body (JSON)
plan required
string
The plan's slug from GET /v1/tunnels/plans — free cancels the subscription.
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).
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).
Parameters
month
query · string
YYYY-MM, up to this month (default: this month). 422 otherwise.
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).
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).
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).
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).
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).
Body (JSON)
subdomain
string
A name to reserve: lower-case letters, digits and dashes. null: not given.
hostname
string
Or a domain of your own. null: not given.
tunnel_domain
string
Which of our tunnel domains it is on, or served through (GET /v1/tunnels/setup). Default: the default one.
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).
Parameters
id required
path · integer
The domain's id, from GET /v1/tunnels/domains.
Request
curl -s -X POST https://cloud.getwebup.in/api/v1/tunnels/domains/17/verify \
-H "Authorization: Bearer $API_KEY"
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).
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).
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).
Body (JSON)
port
integer
1–65535 for that port; left out or 0: any free one.
tunnel_domain
string
Which of our tunnel domains the address is on (GET /v1/tunnels/setup). Default: the default one.
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).
Parameters
id required
path · integer
The address's id, from GET /v1/tunnels/tcp-addresses.
API v1.17.0. Within v1, fields are only ever added, never removed or changed in meaning; endpoints are not removed. Breaking changes would come as /api/v2, with notice.