Skip to main content

Authentication

Neuroon exposes two credentials depending on where the request comes from. Pick the one that matches the call origin; they are not interchangeable.

Which one do I use?

Comparison

MechanismHeaderFormatTTLOriginEndpoints
Widget TokenX-Widget-TokenOpaque string24 hBrowser/api/widget/*
Shop API KeyX-Shop-API-Keysk_<32hex>Permanent (until rotation)Your server/api/plugin/shops/*

Widget Token flow (frontend)

  1. Your server signs the Widget Token locally using the X-Shop-API-Key as HMAC secret. See Recipe · Server-to-server token for the format and copy-paste code.
  2. Cache the token (~23 h) and inject it as data-token in the <script> your HTML serves.
  3. The widget sends the token on every request as X-Widget-Token.
  4. After 23 h+ have passed, your server signs again and rotates the token without downtime.

The token is opaque to your frontend; the browser never sees the Shop API Key.

Shop API Key flow (server-to-server)

  1. Generate a sk_<32hex> in the Dashboard.
  2. Store it in your secret manager.
  3. On each request to /api/plugin/shops/{shopId}/* include:
X-Shop-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1. If the request carries Origin (it's a browser), the backend validates it matches your registered shop.url. If not → 403 Forbidden.
  2. If the request has no Origin/Referer (server-to-server HTTP client: .NET HttpClient, curl, requests, axios from Node), it is allowed.

Common errors

SymptomLikely cause
401 Unauthorized with header presentToken expired, malformed or from a different environment
401 Unauthorized without headerYou forgot the header
403 Forbidden with Origin mismatchThe browser sent an Origin that does not match shop.url
403 Forbidden cross-tenantThe sk_* belongs to a different shopId than the URL
429 Too Many RequestsRate limit exceeded — see Retry-After

Per-error detail: Errors.

Further reading