Docs / Quickstart
Everything below runs against the free sandbox: a simulated registrar and Mollie test mode, so nothing costs real money and no real domains are registered. The flow is identical in production. Prefer an agent? Add Fairverra to Cursor, Claude or Claude Code, then copy a task from /prompts.
curl -X POST https://sandbox.api.fairverra.com/v1/signup \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
# → a restricted key right away (checks, pricing, WHOIS)
# plus a 6-digit verification code by email
curl -X POST https://sandbox.api.fairverra.com/v1/signup/verify \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "code": "123456"}'
# → { "api_key": "fv_test_..." } — full access, shown once, store it
# (the restricted key from step 1 is revoked — switch to this one)Use it on every call below: -H "Authorization: Bearer fv_test_...". No key yet? POST /domains/check also works keyless (strict IP limit, list prices) — try before you sign up.
curl -X POST https://sandbox.api.fairverra.com/v1/domains/check \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"domain": "my-new-project.com"}'
# → available, premium flag, prices.register (ex tax, EUR)
# Dollar labels: add "currency": "USD" — presentment is USD, prices stay EUR,
# wallet stays EUR. Works keyless too. Never convert FX yourself.
# One domain per call (anti-scrape); loop for more.curl -X POST https://sandbox.api.fairverra.com/v1/handles \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"first_name": "Ada", "last_name": "Lovelace",
"email": "ada@example.com",
"phone": { "country_code": "+31", "area_code": "6", "subscriber_number": "12345678" },
"street": "Main Street", "street_number": "1",
"postal_code": "1234AB", "city": "Amsterdam", "country": "NL"
}'
# → { "handle": { "id": "..." } }Which roles a TLD requires (registrant, admin, tech) is in GET /domains/registration-requirements?extension=com.
curl -X POST https://sandbox.api.fairverra.com/v1/quotes \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"action": "register",
"domains": ["my-new-project.com"],
"handles": { "registrant": "HANDLE_ID" },
"idempotency_key": "demo-register-1"
}'
# → { "approval_id": "...", "total": { "amount": "...", "currency": "EUR" }, "presentment": ..., "expires_at": "..." }Nothing is charged yet. A quote is a priced offer that expires; confirming it is the only thing that moves money.
# Low balance? Get a top-up link (Mollie test mode in the sandbox):
curl -X POST https://sandbox.api.fairverra.com/v1/wallet/deposit-links \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"amount": "25.00", "currency": "EUR"}'
# → open deposit_url, pay with a test method
curl -X POST https://sandbox.api.fairverra.com/v1/approvals/APPROVAL_ID/confirm \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" -d '{}'
# → wallet debited, domain registered (simulated), per-domain resultsIf a registration fails at the registry after payment, the amount is automatically credited back to the wallet — you never pay for a domain you did not get.