Authentication
Every /v1 request carries a project API key. Keys are scoped, hashed at rest, bound to one network, and never belong in a browser.
Send your key
Use the Authorization header with the Bearer scheme (X-API-Key also works). Requests without a valid key get 401 UNAUTHENTICATED.
GET /v1/me tells you which project, mode and scopes a key has — handy as a startup check. It never echoes the key.
Test and live keys
| Prefix | Works against | Funds |
|---|---|---|
fp_test_… | The local development chain (anvil, chain id 31337) — the FomoPay local stack | Local test ETH and a local 6-dp USDG at the real USDG address. No real value. |
fp_live_… | Robinhood Chain mainnet (chain id 4663) | Real ETH and USDG. Live keys are only issued once a deployment has mainnet enabled. |
A key used against the wrong network is refused with 403 FORBIDDEN — a test key can never move mainnet funds, and a live key never touches a test deployment.
Scopes
Give each key only what it needs. A game server that pays winners needs rewards:create (and payments:read to check status) — not webhooks:write.
| Scope | Allows | Endpoints |
|---|---|---|
payments:create | Create wallet (checkout) and vault payments, bulk batches | POST /v1/payments · /v1/payments/bulk |
payments:read | Read payments, list them, a profile's payments from this project | GET /v1/payments… · /v1/profiles/@handle/payments |
rewards:create | Vault-funded rewards — what fp.send() uses | POST /v1/rewards |
profiles:resolve | Resolve a handle to its identity state (no addresses) | GET /v1/resolve/@handle |
vaults:read | Vault balance, allowance and availability | GET /v1/vaults… |
webhooks:write | Manage webhook endpoints and rotate secrets | /v1/webhooks… |
A missing scope is a 403 INSUFFICIENT_SCOPE listing what was required:
How keys are stored
- Shown once. The raw key is displayed when you create it and never again. Lose it → create a new one and revoke the old.
- Hashed. FomoPay stores
HMAC-SHA256(server pepper, key)plus a short display prefix (fp_live_Ab12) — never the key itself, so a database leak doesn't leak working keys. - Revocable and expirable. Revoke from the dashboard at any time; revoked keys fail immediately. A key also stops working when its project is disabled.
- Audited. Key creation and revocation are written to the project audit log; every API call lands in the request log (method, endpoint, status, latency, request id — never bodies or secrets).
Never ship an API key to a browser, mobile app or public repo. The SDK refuses to run in a browser. If a key leaks, revoke it in API → Keys — FomoPay will never ask you for it, nor for any private key or seed phrase.
Rate limits
Limits apply per key (default 120 requests per minute, configurable per key) and per endpoint bucket. Resolution has extra anti-harvesting caps: a key can only look up a bounded number of distinct handles per day, because resolve exists for payments — not for building a directory.
Rate-limited endpoints answer with X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A refusal is 429 RATE_LIMITED with Retry-After (seconds); the SDK waits and retries with the same idempotency key.
Request ids
Every response has an x-request-id header; error bodies repeat it as error.request_id and the SDK exposes it as err.requestId. Include it when you contact support — it finds the exact request in the logs.