Widget Token
TL;DR. The Widget Token is a runtime credential with 24 h TTL that your server (not Neuroon) generates and hands to the widget via data-token. There are two ways to obtain it: a Dashboard button (quick, manual) or sign it on your server with the Shop API Key (automated, recommended in production). It does not live in .env and is not obtained by calling Neuroon's public API.
Header
X-Widget-Token: <token>
Token nature
The Widget Token is an opaque string signed with your Shop API Key. It lives 24 h and only authorizes the widget to call the backend. From your JavaScript client it is opaque — pass it as data-token and the widget sends it back as X-Widget-Token on every request.
How to obtain it
Option A — Dashboard (manual)
- Open Dashboard → Shops and enter the shop.
- Click Generate widget token.
- Copy the token and paste it into your HTML as
data-token. - Repeat every 24 h.
Useful for development, demos or static sites. In production, prefer Option B so you don't depend on a human every day.
Option B — Server-side signing (automated)
Your server signs the token locally using your Shop API Key as the HMAC secret. It does not need to call Neuroon. The backend validates the signature on every request.
Token format:
Base64URL( shopId : unixTimestamp : HMAC-SHA256(hex)( "shopId:unixTimestamp", secret = shopApiKey ) )
shopId: your Shop ID (shop_xxx…).unixTimestamp: timestamp in seconds (UTC).- The signature is computed over the string
shopId:unixTimestampusing your Shop API Key. - The full token is the colon-joined concatenation, Base64 URL-safe encoded (no
=padding). The backend also accepts standard Base64 (with+,/,=) — pick whichever is more convenient in your stack.
Neuroon's backend recomputes the signature with the Shop API Key it has stored for your shop and checks unixTimestamp is within the last 24 h.
Canonical implementations with cache + rotation: Recipe · Server-to-server token.
HTML injection
Server-side (any framework):
<div id="neuroon-search"></div>
<script
src="https://cdn.neuroon.ai/widget@0.9.10/widget.js"
data-token="<%= widgetToken %>"
data-container="#neuroon-search"
data-theme="auto">
</script>
Replace <%= widgetToken %> with your template engine's syntax.
Lifetime
- Validity: 24 h from the moment you signed
unixTimestamp. - Not renewable: to get a new one, sign again.
- Recommended rotation: every 23 h with a 1 h safety margin. Cache the last token plus its
issuedAton your server; once 23 h have passed, sign again before the next render.
Errors
| Code | Cause | Action |
|---|---|---|
401 Unauthorized with missing header | X-Widget-Token missing | The widget adds it automatically; check data-token is present |
401 Unauthorized with token | Invalid signature or token tampered | Sign again (or regenerate from the Dashboard) |
401 Unauthorized after 24 h | Token expired | Sign again |
403 Forbidden with origin mismatch | The browser calls from a domain that does not match shop.url nor the trusted-domain list | Edit shop.url in the Dashboard or ask support to whitelist the domain |
Best practices
- Never expose the Shop API Key in the browser. It is server-only and signs every Widget Token.
- Do not reuse the same Widget Token between Production and Development. Your Shop API Key is different per environment.
- Cache it in Redis or in-process memory, not in a secret manager. Secret managers (AWS Secrets Manager, Vault, etc.) are for long-lived credentials like your
sk_*. Cache TTL ~23 h + recompute on miss. - Don't put it in environment variables either or static config (
appsettings.json,.env,wp-config.php). It expires in under a day and your integration breaks on its own. - Never log tokens to public logs. Treat them as sensitive data while they live.
Next reads
- Recipe · Server-to-server token — full implementations in Node, .NET, Python, PHP.
- Shop API Key — the server-only credential that signs tokens.
- Rate Limits — per-endpoint quotas.
- Errors — codes, structure, field-level errors.