The API uses the OAuth2 client credentials flow. Each integration owns a
client_id / client_secret pair, issued and managed in the Fidly interface.
Retrieving the keys
POST /auth/token accepts a JSON body and two grant types:
Both return the same shape:
Access token
The access_token is a JWT valid for 1 hour (expires_in: 3600), sent on
every request in the Authorization: Bearer <access_token> header.
The client’s permissions are embedded in it at issuance: a permission granted or
revoked in the interface takes effect on the next access_token, not on those
already issued.
Refresh token
The refresh_token lets you get a new pair of keys without re-sending the
client_secret. Its validity is unlimited as long as it is not consumed. It is
single-use: consuming it invalidates the one you sent and returns a new
access_token + refresh_token pair — the refresh_token you receive is brand
new, its validity starts over.
Each client_id is only allowed one active refresh_token at a time. If several
processes share one client_id, have them share the keys — each fetching its own
would log the others out. Cache the access_token and reuse it for its full hour
of validity, rather than requesting a new one on every call.
Permissions
Your client’s permissions are set with a per-action, per-resource granularity:
for each resource (document, relation, bank_account, journal, branding),
each action — create, read, update, delete — can be allowed or not from the Fidly
interface. All four actions can always be configured; an action with no matching
route today simply has no effect.
The reference lists (/units-of-measure, /currencies, /countries) require a
valid access_token but no resource permission.
Security
A few choices in how the keys are handled, worth knowing to integrate confidently:
Temporary lockout on failures. Repeated failed authentications on the same
client_id trigger a temporary 429 too_many_requests, to slow down brute force.
Back off and retry later; a successful authentication resets the counter.
One active pair per client. Re-creating a pair via the client credentials
overwrites the previous refresh_token: any earlier refresh session is
invalidated. An already-issued access_token however stays valid until it expires
— revoking a permission therefore takes effect at most one hour later.
Rotation reveals theft. A refresh_token that was already used fails with
401 invalid_grant. If that happens with no explanation on your side, treat the
pair as compromised and start over from your client credentials.
Nothing sensitive in the clear. On Fidly’s side, the client_secret and the
refresh_token are stored hashed: a leak would yield no reusable key.
We recommend keeping your keys around to reuse them for their validity period — in
memory or in a database, whichever fits your architecture — and never logging a
full token or the client_secret.