Help

Troubleshooting

What to check when the chat does not show, a Contact is not recognised or a webhook does not arrive.

Updated October 28, 2026

Start with the browser’s or Metro’s console: each install problem leaves a message there that starts with Zean.

The chat does not show on the site

  1. The domain: the page must be on the App’s Domain, www. included, or on localhost. Another subdomain is not. See Set your site’s Domain.
  2. The code: both script tags, together, in this order, before </body>, on the page you test.
  3. The key: copy the code from App settings > Developers > Getting started rather than typing it again.
  4. A paused App: past the Plan’s limit, the newest Apps are paused and the chat shows “The chat is unavailable for now.”
  5. An ad blocker or a privacy extension: test in a private browsing window, without extensions.

The console messages:

  • Zean: no App has the key "…": the key is wrong.
  • Zean: … is not the App’s Domain: type this domain in “Domain”, or open the site on its right domain.
  • Zean: … is not the App’s Bundle ID / Package name: type it in “Bundle ID (iOS)” or “Package name (Android)”.
  • Zean: the chat stays closed: this page is one of the App’s Hidden pages.: your code opened the chat on a page in “Hidden pages”, in App settings > Developers > Domain, apps and pages. Remove the page from the list to keep the chat there.
  • Zean: set window.zean = { appKey: "…" } before loading the chat.: the first script is missing, or comes after the second.
  • Zean: the chat could not load from …: the loader’s address is blocked or wrong: a blocker or a CSP.

React and Vue sites

  • Render ZeanChat once, in the root layout, or install createZean() once. A second key on the same page is ignored, and the console says so.
  • With a CSP, allow the loader’s host (the script address in your Install code) in script-src and frame-src: the chat opens in a frame served from that same host.
  • A Permissions-Policy header that denies display-capture to the chat’s frame stops the browser from capturing the tab: the Screenshot button then redraws the page, without videos, maps and images from other sites. For an exact capture, allow the loader’s host: display-capture=("https://loader-host").
  • A change of locale waits for the next page load.

React Native apps

  • The chat does not show: the app’s Bundle ID or Package name is not the one set in App settings > Developers > Domain, apps and pages. Metro’s console says which one it read. Expo Go always shows it.
  • Zean: the chat could not read this app’s Bundle ID or Package name: install expo-application (Expo) or react-native-device-info (React Native CLI), then build the app again.
  • The chat only opens with open() from useZean(): it has no floating button. ZeanChat must be rendered once, at the root.
  • The conversation starts over at each launch, and Metro’s console says no storage found: install AsyncStorage, MMKV or Expo SQLite, then build the app again. The chat finds it by itself.
  • No photo button: neither expo-image-picker nor react-native-image-picker is installed, or the app was not built again since. These modules are native: they need a new build of the app. Expo Go already has them.
  • App Store refuses the build for a missing photo text: add NSPhotoLibraryUsageDescription in Info.plist with React Native CLI, or the expo-image-picker plugin in app.json with Expo.
  • iPhone HEIC photos are sent as JPEG: the SDK asks the picker for the compatible version. A photo is 10 MB at most.

Verified Contacts

  • Zean: the user was left out: it needs an id, text or a number.: user has no id. The Contact stays anonymous.
  • Zean: left out of the user, as they do not fit: email.: that detail is left out, the rest goes through. An email must be valid, a phone written in digits, a language a tag such as pt or pt-BR.
  • A second device shows “Chatted with us on another device?”: this is expected. The person gets a code at their saved email and types it to get their Conversation back. Until then, this device is “Not verified” in the dashboard.
  • No code offered on a second device: the Verified Contact has no saved email. Pass email in user on a device that has already joined the Contact.
  • A signed-in device shows “Wrote to us before signing in?”: an anonymous Conversation gave this email. The person types the code sent there to bring it in, or chooses “Not me” to hide the offer on this device.
  • A refused code: it works for 10 minutes and 5 tries, only on the device that asked for it. After 3 codes in an hour, the person waits an hour before asking for another.
  • To switch from one person to another, pass the new user, or call signOut() in between.

A webhook does not arrive

Open App settings > Developers > Webhook > “Recent deliveries” first: each call is there with its status code or error, the start of your server’s reply and the time it took. “Send again” replays it once the problem is fixed.

  • No call in the list: is the address saved? An automatic AI reply sends no event.
  • “Address not found”, “Certificate error” or “Connection refused”: is the address public, https, with a valid certificate, and is your server listening? localhost and private networks are refused: on your computer, use the Zean CLI.
  • “Timed out” or repeated calls: answer with a 2xx code within 10 seconds, or the call is tried again. Skip duplicates with id.
  • A 401 or 403 code: your server refuses the signature. Compute it over the raw body, before any JSON parsing; check the secret after a regeneration, and your server’s clock. In development, with the Zean CLI, the secret is the Listen secret. See Verify a webhook signature.
  • “Send a test event” is off: no Zean CLI runs for the App. A test event never goes to the webhook address.
  • The Zean CLI stopped with a message: the CLI key was regenerated. Run it again with the new key.

Still stuck? Read The chat does not show in the help desk too, or write to us in the chat with the console message.