Canadian KVM VPS in Montréal from 8.50 CAD/month

API

Getting started with the FFxF API

Create a key, order an hourly machine and drive it from your own code, in four calls.

The API does from your code what you do in the console: order a machine, boot it, reinstall it, destroy it. It takes exactly the same path — same quotas, same credit, same refusals. If the console says no, the API says no, for the same reason.

This guide goes from an empty account to a running machine, in four calls.

1. Create a key

In the console, Account → API keys. Name it after what it does (CI runners, monitoring) and tick only the scopes that tool needs. A key that merely watches has no business holding the right to destroy.

The token is shown once. We keep only its fingerprint: lose it and you revoke it and make another — it cannot be recovered.

2. The first call

Check the key against your own account. This is also the response to read before any order: it says what you can spend.

bash
curl -s https://api.ffxf.net/v1/account \
     -H "Authorization: Bearer $FFXF_TOKEN"
bash
{
  "data": {
    "currency": "CAD",
    "credit": { "balance": "124.60" },
    "hourly": { "burn_rate": "0.069", "runway_hours": 1805.8, "active_machines": 3 },
    "quota": { "limit": 5, "used": 3, "remaining": 2 }
  }
}

burn_rate is what your fleet spends per hour, runway_hours how long that lasts at the current balance. A script watching those two numbers is never surprised.

3. Pick from the catalogue

Regions, plans and images are readable without a key: you can write your script before you even have an account.

bash
curl -s https://api.ffxf.net/v1/images?plan=nano | jq '.data[].slug'

The ?plan= filter keeps only the images that fit: on the Nano's 20 GB, a Windows image asking for 32 is simply absent from the list, rather than failing at order time.

4. Order a machine

Start with a dry run. dry_run runs every check — quota, credit, stock, compatibility — and prices the order without creating anything.

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":"runner-01","billing":"hourly","dry_run":true}'
bash
{
  "data": {
    "would_succeed": true,
    "hourly_rate": "0.018",
    "month_equivalent": "13.14",
    "required_credit": "0.44",
    "balance": "124.60",
    "runway_hours_after": 1428.0,
    "checks": [ { "name": "quota", "status": "pass" }, { "name": "credit", "status": "pass" } ]
  }
}

required_credit is 24 hours of usage here: that is the advance an hourly rental asks for. Drop dry_run and the machine goes into build.

The Idempotency-Key header is required, and it is not a formality: if your request times out with no answer, replaying it with the same key returns the first response instead of creating a second machine.

5. Follow the build

The response carries the machine and an action. Nothing is instant: a disk is cloned, an address reserved, an image booted.

bash
curl -s https://api.ffxf.net/v1/actions/90112 \
     -H "Authorization: Bearer $FFXF_TOKEN" | jq .data.status

Poll until the status leaves running. On failure the action carries the reason — no guessing through logs.

6. Destroy

bash
curl -s -X DELETE "https://api.ffxf.net/v1/vms/4312?confirm=runner-01" \
     -H "Authorization: Bearer $FFXF_TOKEN"

The hostname must be repeated in confirm. An id mispasted in a loop would destroy the wrong machine, and a disk does not come back. Hourly deletion is immediate, the hour under way is owed, and the meter stops with the machine.

Support & discussions

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