Getting credentials
GuideDevelopersSince version 0.3.0
The three identities an operation can require, and how to present them. The API's contract says which ones each operation accepts (
security).Product side: Identity and zero trust; operations side: Wiring your identity provider, API keys, Client certificates (mTLS).
Which credential for which case
| You are | Credential | Presented by |
|---|---|---|
| An application acting for a person, or a service | An OIDC token from the operator's identity provider | Authorization: Bearer <token> |
| A known integration with no user (partner, batch) | An API key handed out by the operator | Authorization: ApiKey <key> |
| A partner server | A client certificate (mTLS) declared by the operator | The TLS handshake |
| An AI agent (MCP) | An OIDC token issued for the MCP surface | See MCP |
Your tenant (the customer you act for) always comes from the credential: a claim of the token, the key or the certificate. A tenant header you write never reaches the API.
OIDC token
Ask the operator's identity provider for a token, for the API's audience and with the scopes the contract requires. For a service with no user, the client credentials flow:
TOKEN=$(curl -s https://login.example.com/oauth2/token \
-d grant_type=client_credentials -d client_id=billing -d client_secret="$SECRET" \
-d scope="orders:read" -d audience=api | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/orders/42The exact audience parameter depends on the provider (audience, resource, a dedicated scope);
the operator gives you the provider's URL, the audience and the scopes.
API key
| Rule | Detail |
|---|---|
| Format | fwk_ followed by 43 characters; shown once when created |
| Header | Authorization: ApiKey <key> only - never X-Api-Key, never in the URL (ignored) |
| Scope | Bound to one tenant, to named operations and to an end date |
| Rotation | The operator issues a second key, you switch, the old one is removed |
| Rate | Counted per key |
curl -H "Authorization: ApiKey $FLEXWAY_KEY" https://api.example.com/invoicesClient certificate
curl --cert client.crt --key client.key https://api.example.com/settlements -X POST -d @settle.jsonThe certificate is declared by the operator (preferably by its URI SAN, which survives a renewal) and bound to a tenant and to operations.
What you get
| Situation | Response |
|---|---|
| No credential | 401, WWW-Authenticate: Bearer |
| Invalid, expired, wrong-issuer or wrong-audience token | 401, error="invalid_token" - never the exact reason |
| Valid token without the scope | 403, error="insufficient_scope", scope="..." |
Unknown or expired key, or one without the fwk_ prefix |
401, WWW-Authenticate: ApiKey |
| Valid key on an operation it does not name | 403 |
| Undeclared certificate, or none | 401 |
A token on an operation that accepts mutualTLS only |
401 |
A token never stands in for a key, nor the reverse: the contract says which alternative each operation accepts.