Resources·Docs

RareCloud API: tokens, scopes, errors and safe retries

Start with the RareCloud REST API: create a scoped token, make your first calls, read the response envelope and error codes, stay inside rate limits, and retry creates safely with an Idempotency-Key.

By RareCloud Team · 6 min read · 3 Nov 2026

In one paragraph: everything the console does runs on a public REST API at https://api.rarecloud.io/v1, so anything you can click you can script. You authenticate with a bearer token you create in the console and scope to the job. Every endpoint is in the API reference and the OpenAPI spec. This page covers what they all have in common. If you prefer not to write HTTP calls, the CLI, the Terraform provider and the MCP server use the same API.

Read the public catalog

Products, plans, regions and images need no token:

curl -s https://api.rarecloud.io/v1/catalog/regions | jq .data
curl -s https://api.rarecloud.io/v1/catalog/images | jq .data
curl -s https://api.rarecloud.io/v1/catalog/listings/cloud-vm | jq .data

Create a token

In the console open Account, then API tokens, then New token. Give it a name of up to 80 characters, pick its scopes, and optionally set an expiry date and a rate limit from 1 to 600 requests a minute (the default is 60). The token starts with rc_pat_ and is shown once, so copy it before you close the dialog.

export RARECLOUD_TOKEN=rc_pat_...
curl -s https://api.rarecloud.io/v1/services \
  -H "Authorization: Bearer $RARECLOUD_TOKEN" | jq .data

Revoke a token in the same place and it stops working. Creating, listing and revoking tokens needs a signed-in console session, so a token can never mint itself a stronger one.

Scopes

ScopeWhat it opens
account:read / account:writeProfile, SSH keys, contacts, activity / changes to them
services:read / services:writeServers, clusters, volumes, networks, firewalls, load balancers, Object Storage, the registry, sandboxes, proxies, limits / creating and changing them
billing:read / billing:writeInvoices, balance, ledgers / top-ups, paying invoices, payment methods, spend alerts, vouchers
domains:read / domains:writeDomains, DNS, TLD prices / registering, transferring, renewing, managing
tickets:read / tickets:writeTickets / opening, replying, closing
*All of the above

Scopes match exactly: services:write does not include services:read. A call without the scope it needs answers 403 PERMISSION_DENIED.

Responses

A success is { "ok": true, "data": ... }. A failure is:

{ "ok": false, "error": { "code": "INVALID_PARAM", "message": "...", "details": [{ "field": "...", "message": "..." }] } }

code is stable, so branch on it. details appears only when there is something to add. GET /v1/services can answer with an X-Partial-Results header naming a category that could not be read just now; the rest of the list is still valid.

An id that belongs to another account answers 404, the same as one that does not exist.

Error codes

HTTPcodeWhat to do
400INVALID_PARAMFix the request. details names the field.
401AUTH_REQUIRED, AUTH_TOKEN_EXPIREDSend a valid token.
403PERMISSION_DENIEDThe token lacks the scope. Create one that has it.
403RESOURCE_PROTECTEDAPI access is switched off for this resource in the console. Do not retry; ask its owner.
403ACCOUNT_ORDERING_BLOCKEDNew orders are paused on this account. Contact support.
403ACCOUNT_CLOSEDThe account is closed. Contact support.
404NOT_FOUNDWrong id, or not yours.
409CONFLICTThe resource's state does not allow this now. details may say why.
409NOT_READYThe resource is still getting ready. Wait and retry.
409REACTIVATION_WINDOW_CLOSEDA lapsed proxy can no longer be renewed. Order a new one.
409BACKEND_POLICY_BLOCKEDA service behind the API refused the request on a policy of its own. Nothing changed, and the same request can succeed later.
409QUOTA_EXCEEDEDA limit is in the way. See limits and quota requests.
409IDEMPOTENCY_IN_PROGRESSThe first request with this key is still running. Wait Retry-After, then retry with the same key.
413PAYLOAD_TOO_LARGEThe body or file is over the limit.
422IDEMPOTENCY_KEY_REUSEDThis key was used for a different request. Use a new key.
429RATE_LIMITEDWait Retry-After.
501NOT_IMPLEMENTEDThe operation is not available for this resource.
502BACKEND_BAD_RESPONSEA service behind the API refused or failed.
503BACKEND_UNAVAILABLEBriefly busy. Wait Retry-After; retry a create only with the same Idempotency-Key.
503ENV_UNAVAILABLEA sandbox could not take its environment variables. No sandbox was created.
503SANDBOX_LAUNCH_GATE_CLOSEDAI Sandboxes are not open on this account yet.
500INTERNALA real fault. Open a ticket.

Rate limits

Each token has its own limit per minute, counted separately per API area (/v1/services, /v1/billing and so on). Answers to token calls carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Past the limit you get 429 with Retry-After.

Safe retries

If a create times out, you cannot tell whether it happened. Send an Idempotency-Key header with a fresh value per operation (a UUID works; 1 to 255 printable ASCII characters) and the same value when you retry:

curl -s https://api.rarecloud.io/v1/volumes \
  -H "Authorization: Bearer $RARECLOUD_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f0c6c1e-8a43-4b8e-9f2a-0d4a2f6e9b17" \
  -d '{"name":"web-01-data","sizeGb":50}'

The API runs it at most once. A retry gets the first answer back, marked Idempotent-Replayed: true. Keys are kept for 24 hours. A one-time secret from the first answer, such as a console password, is not repeated: the replay lists the omitted fields in secretsOmittedOnReplay. The routes that take the header are marked in the API reference.

Check before you order

POST /v1/services/preflight takes the same body as POST /v1/services and runs the same balance check, with nothing created, held or charged. When the answer is no it says why, and where it applies gives the add-funds or pay-invoice link. It needs services:write.

Work that finishes in the background

Some creates answer before the work is done. A load balancer answers with status pending: poll GET /v1/load-balancers/{id} until it is active. A server resize answers 202: poll GET /v1/services/{id}. Poll instead of creating again.

Resources you made read-only

In the console you can switch API access off for a single resource. Tokens can still read it, but changes and reads of its credentials answer 403 RESOURCE_PROTECTED. Objects carry apiAccess (full or read_only), and GET /v1/api-access lists the read-only ones. No token can flip the switch.

Related