Masheev Developers

Open Markdown · Agent index

Privacy and cookies

This page lists what the Masheev chat widget and the headless SDK store in a visitor's browser, when they store it and for how long, and what you need to tell your visitors. You run the website and decide to offer the chat, so you are responsible for your site's privacy notice and cookie notice. Masheev processes the conversation on your behalf under the Data Processing Addendum.

What the widget stores

The widget does not set cookies. It uses browser storage in the widget's own frame (https://iframe.masheev.com), which browsers keep separate from your site's storage.

KeyStorageWhat it holdsWhen it is writtenHow long it stays
widget_visitor_{inboxId}localStorageA random visitor identifier issued by Masheev, a signed access grant for it, and the time it was last usedWhen the visitor starts a chat (see below). Never on page loadDeleted the next time the widget loads after 13 months without a chat. Each new chat session resets the clock
widget_workflow_{inboxId}_{workflowId}localStorageThe same, for a conversation workflow in sessionMode: "workflow"When the visitor starts the workflowAs above
masheev:scheduler-pending-intent:{inboxId}:{conversationId}sessionStorageIDs of booking requests still waiting for a resultOnly while a booking request is in progressRemoved when the request settles, or when the tab closes

With sessionMode: "ephemeral" the widget stores no visitor identifier at all, and every page load starts a new conversation.

Earlier widget versions stored the identifier as plain text under widget_visitor_{inboxId} and the grant under widget_visitor_{inboxId}_token. The widget converts these to the format above the first time it reads them and deletes the _token key.

When a chat starts

Loading a page with the widget only fetches the inbox's public appearance (colours, greeting, AI disclosure). No visitor identifier is created, sent or stored.

The identifier is created by Masheev's server and stored in the browser when the visitor starts a chat:

  • chat-widget mode: when the visitor opens the chat.
  • prompt-input mode: when the visitor opens the conversation or sends a first message.
  • embedded mode: when the visitor first clicks, taps or types in the chat area. A browser that already holds an identifier for the inbox restores its conversation straight away.

Cloudflare Turnstile, which protects session creation from bots, also loads only at that point, not on page load. Refer to Cloudflare's documentation for what the challenge itself processes.

The UK and EU rules on storage in a user's device (PECR regulation 6 in the UK, Article 5(3) of the ePrivacy Directive in the EU) require consent unless the storage is strictly necessary to provide a service the user asked for. Because the widget stores nothing until the visitor starts a chat, and the identifier is what lets the visitor continue that conversation, Masheev's view is that this storage falls within that exemption. This is a reasonable reading of the rules and of ICO guidance, not a ruling, and your own legal adviser should confirm it for your site. If you prefer to ask first, turn on requireConsent.

With requireConsent: true the widget shows a consent step before any chat session starts, in every mode (chat-widget, prompt-input and embedded). Until the visitor ticks the box and selects Start Chat:

  • no session is created and no visitor identifier is stored;
  • a message typed in prompt-input mode waits and is sent only after the visitor agrees.
Masheev.init({
  inboxId: "inbox_abc",
  requireConsent: true,
  privacyUrl: "https://example.com/privacy",
});

The consent time is sent with the session request and kept on the contact record on Masheev's servers as evidence. The browser does not store a consent flag. When a returning visitor's browser still holds its identifier, the server confirms the earlier consent and the visitor is not asked again until the consent wording changes.

Headless SDK

The headless SDK runs on your own site, so its storage is on your site's origin.

KeyStorageWhat it holdsWhen it is writtenHow long it stays
masheev_visitor_{inboxId}Depends on storage (below)Visitor identifier, signed access grant, last-used timeAfter the first session is created (createSession() or the first sendMessage()). Never on mountDeleted when read after 13 months without use. Each new session resets the clock

Choose where it is kept with the storage prop on <MasheevProvider>:

  • "persistent" (default): localStorage, so a returning visitor continues the conversation.
  • "session": sessionStorage, cleared when the tab closes.
  • "none": nothing is stored. Every page load starts a new conversation.

Set requireConsent to stop any session until you call giveConsent() from useMasheev(), typically from your own consent dialog:

<MasheevProvider inboxId="inbox_abc" storage="session" requireConsent>
  <Chat />
</MasheevProvider>;

function Chat() {
  const { hasConsent, giveConsent, sendMessage } = useMasheev();
  if (!hasConsent) return <button onClick={giveConsent}>I agree, start chat</button>;
  // ...
}

Turnstile loads only when a session is requested.

Your privacy policy in the widget

The widget links to your privacy policy, because you decide why and how the chat is used. Add its address in the dashboard under the chat inbox's settings (Privacy policy URL, https:// only). An active chat inbox's settings cannot be saved without it. You can also pass privacyUrl in the embed code, which takes precedence.

If no address is set, the widget does not link to Masheev's policy. It shows "This chat is provided by {your business name} using Masheev" instead.

AI disclosure

Visitors are told they are chatting with AI before the conversation starts:

  • The widget shows the disclosure (for example "You're chatting with Alex, an AI assistant for Acme Corp.") above the conversation, before the greeting, as a note screen readers announce first.
  • Every widget footer starts with "AI-powered ·" when an AI agent answers.
  • AI-written messages carry data-ai-generated="true" in the page.
  • If you build your own interface with the headless SDK or the API, Masheev adds the disclosure to the start of the first AI reply in each conversation. POST /api/widget/session also returns disclosure whenever an AI agent is configured, resumed sessions included. Send disclosureRendered: true in that request only if your interface shows the disclosure before the conversation itself; the reply is then left unchanged.

What to tell your visitors

As the business offering the chat, your privacy notice should cover:

  • that your site offers a chat answered by an AI assistant, with your team able to take over;
  • what visitors may share in the chat and what you use it for;
  • that Masheev processes the conversation for you as your service provider;
  • how long you keep conversations and how visitors can ask for access or deletion;
  • the browser storage listed on this page, in your cookie or storage notice.

Keep the privacy policy URL in the inbox settings pointing at that notice.