Authentication
Authenticate every request with your API key as a bearer token:
Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Key format
Keys are prefixed sk_ (secret key) followed by a random secret. A key operates
on your real organization data.
Only a hash of the key is ever stored. The raw key is shown once when you create it in Settings ▸ API Integration. If you lose it, revoke it and mint a new one — it cannot be recovered.
A newly created key takes up to about a minute to activate. During that brief
window requests with the new key may return a 403 (the key is registered but not yet
propagated). This is expected — wait ~1 minute and retry. (The 403 body is a raw AWS
authorizer message, not a fixed string — branch on the status code, not the body. See
Errors.)
This API is for server-to-server use. It does not support browser (CORS) requests, and your secret key must never be embedded in client-side code.
Access
Every API key grants full access to all endpoints in this API. There are no per-entity scopes to choose — a key can read and write every organization entity (employees, sectors, cost centers, job roles, groups, products) and read every transaction (withdrawals, returns, exchanges). A key only ever sees your own organization's data.
Webhook endpoints are managed in the web console (Settings ▸ API Integration), not over this API.
Revoking
Revoke a key from the console. Revocation takes effect within about a minute — authentication results are briefly cached, so a revoked key may keep working for up to ~60 seconds before it is rejected. Plan for this small window when rotating a compromised key. Existing keys are never auto-rotated — rotate by minting a replacement, updating your integration, then revoking the old key.
IP allow-listing (optional)
A key may be restricted to a set of CIDR ranges at creation time. Requests from outside those ranges are rejected.
Rate limits
Rate limits apply per organization, not per key — all of your keys share one
throttle + quota bucket. Holding more keys does not raise your limit. When you exceed
the limit, requests return 429 with the body {"message":"Too Many Requests"}. A
Retry-After header is not guaranteed on a 429 (the burst-rate throttle does not
send one), so do not depend on it — back off and retry with your own exponential
backoff. The default ceilings are generous (well above normal integration traffic);
contact your provider if you have a legitimate need for more.