Knowledge base

Create an API token and make the first call

Scoped tokens, the handful of calls you will use on day one, and the rate limits and error shapes worth knowing before you script against them.

Make a token with the smallest scope that works

Tokens are created in the panel under the account and carry scopes: read, write, billing. A token with write can order servers, which is to say a leaked one costs money. Give a monitoring script read and nothing more.

Two settings worth using while you are there: an expiry date, and a source restriction pinning the token to the prefix your automation runs from. Both are optional. Both are cheap.

The value is shown once, because we store a hash of it rather than the token. Losing it means making another one.

export Paragon_TOKEN=...

Better than shell history, on a machine that runs unattended:

systemd-creds encrypt token.txt /etc/credstore.encrypted/paragon-token

The first call

curl -s https://paragonvps.com/api/v1/account -H "Authorization: Bearer $Paragon_TOKEN" | jq .

Everything is JSON, everything lives under /api/v1, and every response carries a request_id header. Quote that in a ticket and we find the exact call in seconds instead of asking you what time it was.

curl -s https://paragonvps.com/api/v1/instances -H "Authorization: Bearer $Paragon_TOKEN" | jq -r '.[] | .id + " " + .hostname + " " + .site + " " + .state'

Ordering one

curl -s -X POST https://paragonvps.com/api/v1/instances -H "Authorization: Bearer $Paragon_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: 2026-07-16-edge-01" -d '{"plan":"r-8","site":"AMS-01","image":"debian-13","hostname":"edge-01","ssh_keys":["primary"]}'

Send the Idempotency-Key header. Retrying a POST without one is how people end up with two servers and one intention; the key is remembered for twenty-four hours and returns the original result rather than building a second instance. Cloud-init user-data goes in the same body, base64-encoded, under user_data_b64.

An order draws on your account balance when the balance covers the first cycle. Otherwise the response carries an invoice and a payment address, and the instance appears once the invoice settles.

Rate limits and errors

Six hundred requests a minute per token. Cross it and you get a 429 with a Retry-After header, which is there to be read rather than replaced with a fixed sleep in a loop.

Errors are JSON carrying a code, a human message and the request_id. The status gives you the class: 400 you sent something wrong, 401 the token is invalid or revoked, 403 the token lacks the scope, 404 it does not exist or is not yours, 409 the instance is in a state that cannot do that, and 5xx is ours.

Pagination and polling

Collections take ?page= and ?per_page= and return a Link header. Long operations hand you a job rather than blocking, which covers provisioning, migration and restore:

curl -s https://paragonvps.com/api/v1/jobs/<job-id> -H "Authorization: Bearer $Paragon_TOKEN" | jq -r .state

Poll that every few seconds, or register a webhook and stop polling altogether. Webhooks are signed; check the signature before acting on one.

Revoking

Instant, from the panel or with another token:

curl -s -X DELETE https://paragonvps.com/api/v1/tokens/<token-id> -H "Authorization: Bearer $Paragon_TOKEN"

In-flight requests finish and the next one gets a 401. If you suspect a token has leaked, revoke first and investigate afterwards. A token cannot change your account email or your second factor, but it can certainly spend money.

The full reference, every endpoint and every field, is in the panel under API tokens.

Ready when you are

Pick a city. Pick a size. Pay in coin.

No forms about who you are, no wait for a human to approve you, no phone call to verify anything. The invoice clears and the credentials land in your inbox.