Skip to main content

Authentication

Neuroon exposes three authentication mechanisms depending on who is making the request and from where.

Decision tree

Who is calling the API?
├── A browser (embedded widget)
│ └── X-Widget-Token (TTL 24 h, opaque, issued by Neuroon)
│ Endpoints: /api/widget/*

├── Your server (any stack)
│ └── X-Shop-API-Key (format sk_<32hex>, permanent until rotation)
│ + Origin validation (no-Origin = server-to-server allowed)
│ Endpoints: /api/plugin/shops/*

└── Public search (cross-shop catalog, anonymous use)
└── OAuth2 JWT (user authenticated on the Neuroon platform)
or anonymous (rate-limited)
Endpoints: /api/search/*

Comparison table

MechanismHeaderFormatTTLWho uses itEndpoints
Widget TokenX-Widget-TokenOpaque string24 hBrowser/api/widget/*
Shop API KeyX-Shop-API-Keysk_<32hex>Permanent (until rotation)Your server/api/plugin/shops/*
OAuth2 JWTAuthorization: Bearer ...Signed JWTConfigurableAuthenticated apps / anonymous/api/search/*

Flow diagrams

Widget Token (frontend)

1. Your team issues a Widget Token in the Neuroon Dashboard
2. You embed it in data-token of the CDN <script>
3. The widget reads the token and sends it as X-Widget-Token on every request
4. Backend validates: signature + expiration + scope
5. If it expires: regenerate from the Dashboard (or automatically via your backend)

The client does not sign anything with HMAC. The token is opaque and issued by Neuroon.

Shop API Key (server-to-server)

1. You generate a sk_<32hex> in the Dashboard
2. You store it in your secret manager
3. On every request to /api/plugin/shops/{shopId}/* you add:
X-Shop-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4. If the request comes with Origin (browser): the backend validates that it
matches shop.url. If it doesn't match -> 403.
5. If the request has no Origin/Referer (server-to-server client: .NET HttpClient,
curl, Python requests, axios from Node): it is allowed.

OAuth2 JWT (public / authenticated)

The /api/search/* routes accept both JWTs signed by our identity provider and anonymous calls (with strict rate limiting). This mechanism is intended for cross-shop catalog experiences, not for store integration.

Common errors

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

Detail of each: Errors.

Further reading