Authentication
Every API call is authenticated. Merchant backends use API keys; the dashboard uses session cookies. This page covers API keys, which is what your integration needs.
API keys#
Send the key in the x-api-key header:
curl -s http://localhost:4000/v1/decision \
-H "content-type: application/json" \
-H "x-api-key: $PAYINFERENCE_API_KEY" \
-d '{ "merchant_id": "m_123", "order_id": "order_456", "transaction": { "amount": 14900, "currency": "USD", "country": "US", "payment_method": "card" }, "available_providers": ["stripe"] }'
Key format tells you the mode:
| Prefix | Mode | Use |
|---|---|---|
pi_test_… |
test | Integration and testing; decisions are marked "mode": "test" |
pi_live_… |
live | Production traffic |
The local seed also creates pi_demo_key_123, a live-mode demo key for the seeded demo workspace.
Scopes#
Keys carry scopes, and each endpoint requires one. Create keys with only the scopes the service needs.
| Scope | Grants |
|---|---|
decision:write |
POST /v1/decision |
outcome:write |
POST /v1/outcomes |
health:read |
GET /v1/provider-health |
policy:read |
GET /v1/decisions, GET /v1/decisions/:id, GET /v1/policies/:merchantId, POST /v1/policies/simulate |
policy:write |
POST /v1/policies, POST /v1/policies/translate |
A typical checkout service needs decision:write and outcome:write only. A missing scope returns 403 with the missing scope names in the message.
Keys can also be scoped to a single merchant. A merchant-scoped key can only create decisions, report outcomes, and read data for that merchant; using another merchant_id returns 403.
Keep keys server-side#
API keys are secrets that authenticate your backend. Rules that follow from that:
- Never ship a key in frontend code, mobile apps, or the checkout page. Anyone with the key can create decisions and read your decision history.
- Never call PayInference from the browser. The checkout page talks to your backend; your backend talks to PayInference. The browser package
@payinference/sdk-jsdeliberately contains no authentication and no PayInference API access. - Load keys from environment variables or your secret manager (
PAYINFERENCE_API_KEYin the examples), not from source control. - Keys are stored hashed server-side (SHA-256 with a salt). The raw key is shown once at creation and cannot be recovered, only replaced.
Creating and rotating keys#
Keys are managed from the dashboard (or its underlying session-authenticated endpoints, GET/POST /v1/api-keys and DELETE /v1/api-keys/:id). Key management deliberately requires a dashboard login with the owner, admin, or developer role; an API key cannot mint or revoke other API keys.
To rotate a key:
- Create a new key with the same scopes.
- Deploy the new key to your services.
- Revoke the old key. Revocation takes effect within about a minute (server-side auth caches expire after 60 seconds).
Keys support optional expiry dates. Creation and revocation are audit-logged.
Authentication errors#
| Status | Body | Cause |
|---|---|---|
401 |
Provide an x-api-key header or a session token |
No credentials sent |
401 |
Invalid API key |
Unknown, revoked, or expired key |
403 |
API key is missing scopes: … |
Key lacks the required scope |
403 |
API key is scoped to a different merchant |
Merchant-scoped key used for another merchant |
403 |
Tenant is not active |
Workspace suspended |