Skip to main content

Widget Token

The Widget Token authenticates the calls the widget makes to /api/widget/* from the shopper's browser. Your server issues it; you inject it into the <script> tag from the CDN.

X-Widget-Token: <token>

Token nature

The token is a Base64 string that encodes shopId:timestamp:HMAC-SHA256. Our backend signs it using your Shop API Key as the secret, which means only we can mint valid tokens. HMAC validation runs on every request: tampering with the string yields 401.

From your JavaScript client's standpoint the token is opaque: pass it as data-token and the widget sends it back as X-Widget-Token on every call. You don't need to verify the signature or inspect the contents — that's the backend's job.

Issuing a token

POST /api/shops/{shopId}/widget-token authenticated with your Shop API Key:

curl -X POST https://api.neuroon.ai/api/shops/$SHOP_ID/widget-token \
-H "X-Shop-API-Key: $NEUROON_API_KEY"

Response (status 200):

{
"token": "c2hvcF9hYmM6MTcxNTAwMDAwMDoxYTJiM2M..."
}

The response body is exactly { "token": string }. It does not include expiresAt — the TTL is fixed at 24 hours from issuance.

Lifetime

  • Validity: 24 h (app.widget.token-validity-seconds = 86400 in the backend).
  • Not renewable: to get a new one, call the same endpoint again.
  • Recommended rotation: every 23 h with a 1 h safety margin. Cache the last token plus its issuance timestamp on your server; when more than 23 h have elapsed, call the endpoint again before the next render.

HTML injection

Server-side (any framework: Next.js, Razor, PHP, Express, Rails…):

<div id="neuroon-search"></div>
<script
src="https://cdn.neuroon.ai/widget.js"
data-token="<%= widgetToken %>"
data-container="#neuroon-search"
data-theme="auto">
</script>

Replace <%= widgetToken %> with your template engine's syntax. The token is already cached on your server; you just print it here.

Errors

CodeCauseAction
401 Unauthorized with missing headerX-Widget-Token missingThe widget adds it automatically; check data-token is present
401 Unauthorized with tokenInvalid signature or token tamperedMint a new token from your server
401 Unauthorized after 24 hToken expiredCall the issue endpoint again
403 Forbidden with origin mismatchBrowser calls from a domain that does not match shop.url nor app.widget.allowed-originsAdd the domain to the shop or verify it

Best practices

  • Never expose the Shop API Key in the browser. That key is server-only and grants far more capabilities than the Widget Token.
  • Do not reuse the same Widget Token between Production and Development. They are signed with different secrets.
  • Store tokens encrypted in your stack's secret manager (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Vault, encrypted wp_options, etc.).
  • Never log tokens to public logs. Treat them as sensitive data.

Next reads