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.

·6 min read ·Updated 3 Sep 2026

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-is

This 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.

StatusMeaningWhat to do
401Missing or invalid credentialsStop. Ask the merchant to re-enter their pair. Retrying will not help.
403Valid credentials, but the plan does not include API accessStop. 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:

  1. Ask each merchant for a credential pair during onboarding.
  2. Store it against their record, encrypted at rest.
  3. Call GET /auth/who-is immediately to confirm it works and to capture their organization_id.
  4. Use organization_id to route data internally, since that is also what arrives on every webhook delivery as X-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.

A Stockpilot engineer talking through an integration with a developer

Stuck on something

Ask a person, not a search box

The API surface is wide, and some of it only makes sense once someone explains why it works that way. If a payload is not doing what you expect, or you are weighing two approaches, say so and we will look at it with you.