Deploy a pay-as-you-go Cloud VPS
5 steps · Checked against the API code 3 November 2026
A guide does one task from start to finish. Every endpoint, with all its fields and cases, is in the API reference.
There are two ways to get a VPS through the API:
- Order a VPS: a fixed price per month or year. You pay an invoice first. You choose the operating system and an SSH key in the order.
- Deploy a Cloud VPS (this guide): billed by the hour, with no invoice up front. The account must be verified and have paid Hostup at least 2,000 SEK. You cannot choose the operating system or an SSH key at deploy.
You choose the CPU cores, memory and disk. CPU and memory are billed by the hour while the server runs. The disk is billed for as long as the server exists. Data transfer is billed per GB. One public IPv4 address is included.
Before you start
Section titled “Before you start”- Your API key in
$HOSTUP_API_KEY, as set in the Quickstart. It needs these scopes (Keys and scopes):read:vmto read the options, the limits and the server.write:billingto deploy and to ask for a higher limit. It also coversread:billingfor the monthly estimate after the steps.
- An account that may use Cloud VPS. It needs a verified identity, Cloud VPS turned on, a country in the account details and at least 2,000 SEK paid to Hostup. In some countries it also needs a saved card. Step 1 shows what is missing.
jqfor the loop in step 4.
1. Check that the account can deploy
Section titled “1. Check that the account can deploy”Get Cloud VPS deployment options says whether this account can deploy now. It also gives the hourly rates, the sizes one server can have and the regions.
curl "https://cloud.hostup.se/api/v2/vps/payg/deployments" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "available": true, "reason": null, "access": { "verified": true, "cloudAccessEnabled": true, "trustedHistoryEligible": true, "blockerReasons": [], "…": "…" }, "actions": { "canDeploy": { "allowed": true, "reason": null } }, "pricing": { "currencyCode": "SEK", "cpuPerCoreHour": 0.015, "memoryPerGbHour": 0.004, "storagePerGbHour": 0.00025, "bandwidthPerGb": 0.01, "ipPerHour": 0.03 }, "defaults": { "regionId": "stockholm", "resources": { "cpuCores": 2, "memoryGb": 2, "storageGb": 50 } }, "limits": { "cpuCores": { "min": 1, "max": 32 }, "memoryGb": { "min": 1, "max": 256 }, "storageGb": { "min": 50, "max": 2000 } }, "regions": [ { "id": "stockholm", "name": "Stockholm, Sweden", "available": true } ]}pricing holds the hourly rates in the account’s currency (currencyCode): cpuPerCoreHour, memoryPerGbHour and storagePerGbHour. bandwidthPerGb is the rate per GB of data transfer. ipPerHour is the rate for each extra IPv4 address. The included address is not billed.
limits is the size range for one server. regions lists where it can run.
canDeploy does not show an overdue Cloud VPS invoice. The deploy refuses that with its own error, payg_payment_overdue.
If canDeploy.allowed is false
Section titled “If canDeploy.allowed is false”reason is a short general text about one blocker. It does not always say what to do. access.blockerReasons lists every blocker as a code. Clear each one:
not_verified: verify the account in the client area at cloud.hostup.se/verify-account.no_cloud_access: verifying the account turns Cloud VPS on. If it stays off on a verified account, ask Hostup support.insufficient_trusted_history: the account has not paid enough to Hostup yet.access.paidSpendSekis what it has paid.access.trustedHistoryThresholdSekis what it needs. Both are in SEK.no_card_on_file: save a card on the account in the client area.country_not_supported: the account details have no country. Add it in the client area.
2. Check the account’s limits
Section titled “2. Check the account’s limits”Get Cloud VPS account limits shows how much the account may use across all its Cloud VPS together. The limits in step 1 are for one server. These are for the whole account.
curl "https://cloud.hostup.se/api/v2/vps/payg/limits" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "current": { "cpuCores": 2, "memoryGb": 4, "storageGb": 80, "instanceCount": 1, "…": "…" }, "max": { "cpuCores": 8, "memoryGb": 16, "storageGb": 500, "instanceCount": 3, "…": "…" }, "remaining": { "cpuCores": 6, "memoryGb": 12, "storageGb": 420, "instanceCount": 2, "…": "…" }, "hasPendingRequests": false, "pendingRequests": [], "…": "…"}max is the account’s limit. current is what its Cloud VPS use now. remaining is what is left. Plan the new server inside remaining.
The deploy itself does not check these limits today. A server past them is still created and billed. Later resizes and extra disks are then refused.
If the server does not fit
Section titled “If the server does not fit”Ask for a higher limit before you deploy. Request a higher Cloud VPS limit asks for one limit at a time.
curl -X POST "https://cloud.hostup.se/api/v2/vps/payg/limits/requests" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "limitType": "cpuCores", "currentLimit": 8, "requestedLimit": 16, "reason": "Load tests for the new web shop need 16 cores" }'{ "id": "payglim_01hxa3b4c5d6e7f8g9h0j1k2m3", "status": "submitted"}limitTypeiscpuCores,memoryGb,storageGborvmCountfor the limits above. The number of servers is calledvmCounthere andinstanceCountin the limits. The reference lists the other limit types.currentLimitis the limit now: the matching value inmaxabove. Leave it out and the request records 0.requestedLimitis the limit you want. It must be higher thancurrentLimit.reasonneeds at least 10 characters.
Hostup reviews each request. The account holder gets an e-mail with the decision. When a request for cores, memory, disk or servers is approved, max in the limits above shows the new limit. Until the decision the request is listed in pendingRequests. Only one request per limit can wait at a time.
3. Deploy the server
Section titled “3. Deploy the server”Create a Cloud VPS creates the server. The request has no field for the operating system or for an SSH key. The server starts without a key. You log in with the root password from step 5. To run another system, reinstall the server once it is ready.
Set the server’s name. The request sends it and step 4 finds the server by it:
export VPS_NAME="app-01.example.com" # the host name you wantnameis the server’s host name: 3 to 253 characters, with letters, digits, hyphens and dots. It is stored in lower case. Leave it out and Hostup picks a name for you.cpuCoresis 1 to 32.memoryGbis 1 to 256.storageGbis 50 to 2000. All three are required whole numbers.regionis required. Use anidfromregionsin step 1. Today the API does not check the value against that list. It does not change where the server is built.- Any other field gets 400.
curl -X POST "https://cloud.hostup.se/api/v2/vps/payg/deployments" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "'$VPS_NAME'", "cpuCores": 2, "memoryGb": 4, "storageGb": 80, "region": "stockholm" }'{ "status": "provisioning", "vpsId": "vps_01hxa3b4c5d6e7f8g9h0j1k2m3", "orderId": "ord_01hxa3b4c5d6e7f8g9h0j1k2m3", "invoiceId": "inv_01hxa3b4c5d6e7f8g9h0j1k2m3", "deployment": { "name": "app-01.example.com", "region": "stockholm", "resources": { "cpuCores": 2, "memoryGb": 4, "storageGb": 80 } }}The call takes a few seconds. The build starts at once. It does not wait for a payment.
deployment.name is the name step 4 looks for. When you left name out, it is the name Hostup picked. Set VPS_NAME to it then. vpsId can be null. Then the server was not in the account yet when the call returned. Step 4 gets the ID either way.
4. Wait for the server and get its ID
Section titled “4. Wait for the server and get its ID”The deployment gives you no job to follow. Follow the server in List VPS instances, filtered by its name. data is empty until the server shows up in the account. While the server is being built, serviceStatus is pending. It is ready when serviceStatus is active and primaryIp is set.
curl "https://cloud.hostup.se/api/v2/vps?name=$VPS_NAME" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "data": [ { "id": "vps_01hxa3b4c5d6e7f8g9h0j1k2m3", "name": "app-01.example.com", "primaryIp": "192.0.2.10", "serviceStatus": "active", "powerState": "running", "…": "…" } ], "hasMore": false, "nextCursor": null}The same as a loop, every 30 seconds:
for attempt in $(seq 1 60); do VPS=$(curl -s "https://cloud.hostup.se/api/v2/vps?name=$VPS_NAME" \ -H "Authorization: Bearer $HOSTUP_API_KEY" | jq '.data[0]') echo "$VPS" | jq -r '[.id, .serviceStatus, .primaryIp] | @tsv' [ "$(echo "$VPS" | jq -r '.serviceStatus')" = "active" ] && \ [ "$(echo "$VPS" | jq -r '.primaryIp')" != "null" ] && break sleep 30doneid is the server’s ID. Use it for every later call on this server.
export VPS_ID="vps_…" # the id the loop printedThe loop stops after 60 tries, about 30 minutes. If serviceStatus is still pending by then, contact Hostup support with the id.
5. Log in to the server
Section titled “5. Log in to the server”The deploy installs no SSH key. Get VPS details and action gates has the login.
curl "https://cloud.hostup.se/api/v2/vps/$VPS_ID/details" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "id": "vps_01hxa3b4c5d6e7f8g9h0j1k2m3", "ipv4": "192.0.2.10", "powerState": "running", "operatingSystem": { "displayName": "Ubuntu 24.04", "family": "ubuntu", "version": "24.04", "variant": null }, "sshKeys": [], "access": { "username": "root", "rootPassword": "example-root-password" }, "…": "…"}Log in as access.username with the password in access.rootPassword. operatingSystem shows the system the server got. Connect to the IP address:
To log in with a key instead, add a saved key with Change the SSH keys that can log in to a VPS.
See the monthly estimate for the server
Section titled “See the monthly estimate for the server”Get a VPS cost breakdown estimates what this server costs in a whole calendar month (UTC) if it runs every hour. It counts the full month, also the hours before the server was built. It is not what has been charged.
curl "https://cloud.hostup.se/api/v2/vps/$VPS_ID/billing-breakdown" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "available": true, "kind": "payg_estimate", "estimate": { "basis": "max_24_7", "currencyCode": "SEK", "estimatedMonthlyAmount": 44.64, "lineItems": [ { "type": "cpu", "quantity": 2, "estimatedAmount": 21.6, "…": "…" }, { "type": "memory", "quantity": 4, "estimatedAmount": 11.52, "…": "…" }, { "type": "storage", "quantity": 80, "estimatedAmount": 11.52, "…": "…" }, { "type": "ipv4", "quantity": 0, "estimatedAmount": 0, "…": "…" } ], "…": "…" }, "…": "…"}estimate.estimatedMonthlyAmount is the total. Each line item has its rate and estimatedAmount. The ipv4 line counts extra addresses only. Data transfer is not in the estimate.
Switch an existing VPS instead
Section titled “Switch an existing VPS instead”A VPS with a fixed price can move to Cloud VPS billing without a new server. Check a switch to Cloud VPS (same IP, no restart) says whether it can. Switch a VPS to Cloud VPS billing makes the change at the end of the period you have paid for.
What happens next
Section titled “What happens next”- Money. The server has no price to pay up front. Its usage is metered from when it is built. Usage from all Cloud VPS on the account is billed together on one usage invoice each month. Break down a Cloud VPS usage invoice splits such an invoice per server. That includes servers you have deleted since.
orderIdandinvoiceIdfrom step 3 point to the order the deployment created. - Stopping and deleting. A stopped server costs no CPU or memory. Its disk is billed until you delete the server.
- The e-mail. When the server is up, the account holder gets an e-mail that it is ready. It holds the server name, the operating system and the IP address. The password is not in it. Step 5 reads it through the API.
Next: Point a domain at your server
Errors you may hit
Section titled “Errors you may hit”- 403
not_verified,no_cloud_access,insufficient_trusted_history,no_card_on_fileorcountry_not_supported: the account cannot deploy yet. Clear the blockers as step 1 shows. The limits in step 2 also answer 403 for an account without Cloud VPS access. - 403
payg_payment_overdue: a Cloud VPS invoice is overdue. New deployments are refused until every overdue Cloud VPS invoice is paid. The block lifts on its own after payment. Pay an invoice, then deploy again. - 400
invalid_request: a size is out of range,regionis missing or the body has a field the API does not know.errors[].pointernames the field. A limit request also gets 400 when a request for the same limit is still waiting. It gets the same whenrequestedLimitis not higher thancurrentLimit. Those two answers have noerrors[].pointerand only a generaldetail. CheckpendingRequestsandmaxin step 2 first. - 401 or 403 without one of the codes above: the key was refused. When a key is refused gives each cause and what to do.
Related endpoints
Section titled “Related endpoints”- Get Cloud VPS deployment options
- Get Cloud VPS account limits
- Request a higher Cloud VPS limit
- Create a Cloud VPS
- List VPS instances
- Get VPS details and action gates
- Change the SSH keys that can log in to a VPS
- Get a VPS cost breakdown
- Break down a Cloud VPS usage invoice
- Check a switch to Cloud VPS (same IP, no restart)
- Switch a VPS to Cloud VPS billing