Appearance
Troubleshooting
Almost every failure looks the same from the page: the form is ordinary and the widget never appears. That is deliberate — a broken SDK must not break the form — so the diagnosis is in the console and the network tab, not on screen.
Start here
Open the console, then the network tab, and reload.
| What you see | What it is |
|---|---|
| No network request at all | The SDK never started. The console names which of the three it was. |
POST …/landing-page-sessions → 401 | The key is wrong for this page. |
POST …/landing-page-sessions → 403 | The key is right; the origin is not permitted. |
| A session, but no greeting | The stream connected and the agent did not answer in 12 seconds. The SDK restores the form. |
The SDK never started
One console.warn beginning [namakina] landing page: says which:
- no
data-nam-landing-page— the attribute is missing or empty. It is the only one the SDK refuses to start without, anddiscoverFormsselects on it, so without it your form is invisible. intakeUrlandmessagingUrlare required; not starting — one or both were missing frominit(), or from thedata-intake-url/data-messaging-urlattributes on the script tag.- no publishable key — none of
data-nam-key,init({ key })orwindow.__NAMAKINA_LANDING_PAGE__.keyyielded one. The SDK will not start half configured: an open backend would make a broken credential path look exactly like a working one.
401 — a broken key
401 AuthenticationError — Invalid publishable keyThe key on the form is not this page's key. Re-read the output of the setup run, or ask for a rotate and re-paste.
A rotate invalidates the previous key, so a page still carrying the old one starts failing the moment someone rotates — including a second tool that mints on every run.
The SDK recovers from a 401 once, on its own: it opens one new session and retries. A persistent 401 is a wrong key, not a stale session.
403 — a broken origin
403 ForbiddenError — Origin is not permitted for this pageThe key was accepted and the host was not. Your page's host has to be on your partner's embed-permitted domain list, exactly — including sub-domain and port.
A leading *. covers sub-domains but not the bare domain: *.acme.com does not cover acme.com, which has to be listed separately.
A 403 is never the key, and a 401 is never the origin
The key is authenticated first and only then is the origin checked, so a 403 proves the key was accepted. Rotating and re-pasting the key after a 403 changes nothing and costs you another deploy.
A 403 is never retried — the SDK restores the form and logs the reason.
The widget appears and then vanishes
That is restore(), and the console says why. The usual causes are the stream not connecting within 8 seconds, no greeting within 12, or two failed posts in a row.
It works for you and not for a colleague
Check the holdout before anything else. With data-nam-rollout below 100, some visitors are supposed to see the plain page — and the arm is derived from a hash of their own token, so it is stable per person and different between people.
Append ?nam_arm=assist to force the agent while testing. If that changes nothing, the override is being ignored because ALLOW_ARM_OVERRIDE is not set in that environment, which is the intended behaviour on a live page.
The theme did not apply
data-nam-theme is parsed leniently and fails silently back to the sampled colours. The common cause is an unescaped single quote inside the JSON — a font name like 'DM Sans' — which truncates the attribute at that character. Write it as '. See Theming.
A field is never asked for
See The fields. In order of likelihood: a skipped control kind, data-nam-ignore on an ancestor, a locked consent checkbox working as designed, or a control that does not exist until JavaScript has run.
Console warnings that are not errors
These mean the SDK held a contract and carried on. The turn still rendered.
ask ignored beside cards— the agent sent both; the cards are the control.second ask ignored,second stage block ignored— one block per turn.- An unknown action type — an older bundle was offered something it cannot draw. It renders what it knows and ignores the rest.