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
| Mechanism | Header | Format | TTL | Who uses it | Endpoints |
|---|---|---|---|---|---|
| Widget Token | X-Widget-Token | Opaque string | 24 h | Browser | /api/widget/* |
| Shop API Key | X-Shop-API-Key | sk_<32hex> | Permanent (until rotation) | Your server | /api/plugin/shops/* |
| OAuth2 JWT | Authorization: Bearer ... | Signed JWT | Configurable | Authenticated 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
| Symptom | Likely cause |
|---|---|
401 Unauthorized with header present | Token expired, malformed, or from another environment |
401 Unauthorized without header | You forgot to set the header |
403 Forbidden with Origin mismatch | The browser is sending an Origin that doesn't match shop.url |
403 Forbidden cross-tenant | The sk_* belongs to a different shopId than the one in the URL |
429 Too Many Requests | Rate limit exceeded — see Retry-After |
Detail of each: Errors.
Further reading
- Widget Token — issuance, rotation, usage.
- Shop API Key — format, Origin validation, rotation.
- Rate Limits — quotas per plan and backoff.
- Errors — codes, structure, field-level errors.