Skip to content
Quickstarts

cURL quickstart

No SDK at all — authenticate with a project API key and call the /platform/v1 Infrastructure API from the shell.

Everything the SDKs and generated clients do rides one plain HTTPS API. This quickstart makes your first authenticated /platform/v1 call with nothing but curl.

Prerequisites

  • A project and a project API key (fvpn_v1_…) minted in the console — the API keys guide walks through it
  • curl (and jq if you like your JSON pretty)

1. Export your credentials

export FVPN_API_KEY="fvpn_v1_…"          # shown exactly once at mint time
export FVPN_PROJECT_ID="<your-project-uuid>"

2. First authenticated call

List the project's API keys — the simplest authenticated read:

curl https://api.fvpn.net/platform/v1/api-keys \
  -H "Authorization: Bearer $FVPN_API_KEY" \
  -H "X-Project-Id: $FVPN_PROJECT_ID"

A 200 returns the project's keys, redacted — no secret ever appears in a list response:

[
  {
    "id": "8b9c1a2e-…",
    "name": "ci-deploy",
    "key_prefix": "fvpn_v1_ab12…cd34",
    "created_at": "2026-07-01T10:12:03Z",
    "last_used_at": "2026-07-08T09:41:57Z"
  }
]

Two rules to remember:

  • Bearer is the whole story. The key goes in Authorization: Bearer fvpn_v1_… — no cookies, no signature scheme.
  • Keys are project-bound. X-Project-Id must name the key's own project; any other project id is a 401.

3. Go further

Every /platform/v1 and /consumer/v1 operation is documented in the API reference, generated from the same OpenAPI documents the clients are built from. Good next calls:

# The projects you belong to
curl https://api.fvpn.net/platform/v1/projects \
  -H "Authorization: Bearer $FVPN_API_KEY" \
  -H "X-Project-Id: $FVPN_PROJECT_ID"

# Recent billing webhook events for the project
curl https://api.fvpn.net/platform/v1/billing/webhooks \
  -H "Authorization: Bearer $FVPN_API_KEY" \
  -H "X-Project-Id: $FVPN_PROJECT_ID"

Verified by

scripts/quickstart-verify/api-key-auth.sh — runs this page's exact funnel (mint a key → authenticated 200 → revoke) against a live stack on every run where one is available, and skips loudly where not.