API

What you need first

Account, credit, key, quota: the five conditions to meet, and what happens when one is missing.

Five conditions, and nothing else. Each one is checkable in a single call, and each has an error code that names it: you will never have to guess which one is missing.

1. An account, with a verified e-mail

The API acts as you: it wants the same account as the console, and the same verified address. Until it is verified, every authenticated call answers 403 email_not_verified.

A suspended account answers 403 account_suspended. Only support can reopen that door. No key will.

2. Credit, worth 24 hours

Hourly rental is paid in advance. An order is accepted only if the balance covers the machine's first 24 hours: 0.44 CAD for a Nano, 0.80 CAD for a Starter. Below that, 402 insufficient_credit, with the missing amount to the cent.

Credit is topped up in the console, not through the API: committing a spend is one thing, charging a payment method is another. Automatic top-up is set once in the console and then works without you.

3. A key, with the right scopes

Created under Account → API keys, shown once. Tick only what the tool needs: a monitoring key has no business holding vms.destroy. A call outside a key's scopes answers 403 insufficient_scope and names the missing one.

4. Room in the quota

An account holds five machines by default. The ones that count are those holding resources (pending, active, suspended), not the deleted ones. Past that, 409 quota_reached. The cap is raised on request, by ticket; it is not a commercial limit, it is a guard against a script running away.

GET /v1/account returns the quota at any time, along with the balance and the runway. A well-behaved script reads it before ordering.

5. A budget you have not blown

If you set a monthly budget in the console, passing 120 % of it stops your machines and refuses new orders (402 budget_cap_reached). With no budget set, nothing cuts.

Checking all five at once

dry_run answers the five questions in one request, creating nothing and charging nothing:

bash
curl -s https://api.ffxf.net/v1/vms \
     -H "Authorization: Bearer $FFXF_TOKEN" \
     -H "Idempotency-Key: $(uuidgen)" \
     -H "Content-Type: application/json" \
     -d '{"plan":"nano","region":"montreal","image":"debian-13",
          "hostname":"probe","billing":"hourly","dry_run":true}' | jq .data.checks

Every check is there with its verdict: quota, stock, billing_mode, credit, budget. A single fail and the order would be refused, with that same code.

Support & discussions

Technical questions, incident reports, or infrastructure discussions, the team is reachable on Discord, Telegram, X, Instagram, Reddit, and IRC.