Guide
Authentication
How Stockpilot API credentials work: the two headers, what a 401 versus a 403 means, plan gating, and how to handle credentials when you serve many merchants.
Stockpilot uses static API key authentication. There is no OAuth flow, no bearer token and no refresh cycle. A merchant generates a credential pair in the app and hands it to you.
The two headers
Send both on every request, including reads:
X-CLIENT-ID: sp_live_a1b2c3d4e5f6
X-CLIENT-SECRET: sk_live_9f8e7d6c5b4a3210
curl -s https://api.stockpilot.dev/auth/who-is \
-H "X-CLIENT-ID: $SP_CLIENT_ID" \
-H "X-CLIENT-SECRET: $SP_CLIENT_SECRET"
There is no Authorization header and no query parameter alternative. Sending a bearer token will get you a 401.
Generating a pair
In the Stockpilot app, open Settings then API. The secret is displayed once at creation and cannot be retrieved afterwards. If it is lost, generate a new pair and retire the old one.
Treat the secret exactly as you would a database password: environment variables or a secrets manager, never a repository, never a front end bundle, never a URL.
Verifying credentials
GET /auth/who-isThis is the cheapest call in the API and the right thing to run at startup, in a health check, or immediately after a merchant pastes their credentials into your onboarding form.
{
"organization": "Acme Commerce BV",
"organization_id": 4812,
"plan": "growth"
}
401 versus 403
The two failure modes mean different things and deserve different handling.
| Status | Meaning | What to do |
|---|---|---|
401 | Missing or invalid credentials | Stop. Ask the merchant to re-enter their pair. Retrying will not help. |
403 | Valid credentials, but the plan does not include API access | Stop. Tell the merchant they need Growth tier or higher. |
API access is gated by plan. A merchant on a lower tier can hold valid credentials that are refused at every endpoint, so surface the distinction in your own error messages rather than showing a generic “login failed”.
Errors arrive as JSON with a detail or error key:
{ "detail": "Upgrade to Growth tier or higher for API access" }
One key, all permissions
There is no scoping. A credential pair that can read inventory can also fulfil orders, cancel them and request shipping labels. Plan around that:
- Use separate pairs per integration. Rate limits are applied per key, so a misbehaving job throttles only itself, and you can revoke one integration without disturbing the others.
- Give agents and scripts their own pair. Same reason, plus you can see which key was responsible when something unexpected happens.
- Never ship a pair inside a client application. Anything running on a customer device is a published secret.
Serving many merchants
If you are building an integration that many Stockpilot organizations will use, note that there is no app install flow, no partner registry and no per-app tokens. Every merchant generates their own pair and gives it to you.
The practical shape of that:
- Ask each merchant for a credential pair during onboarding.
- Store it against their record, encrypted at rest.
- Call
GET /auth/who-isimmediately to confirm it works and to capture theirorganization_id. - Use
organization_idto route data internally, since that is also what arrives on every webhook delivery asX-Stockpilot-Organization.
For the webhook side of multi-tenant work, including when a shared secret is and is not appropriate, see the webhooks guide.
Rotating a credential
There is no rotation endpoint. To rotate, generate a new pair in the app, deploy it, confirm traffic is flowing on the new key, then delete the old one. Because both pairs are valid simultaneously until the old one is removed, this can be done without downtime.
