Inbox & channels·Updated Jun 14, 2026 · 8 min read

Embedded Inbox

Embed Chatlane inside your own internal tools and reply in context.

The Embedded Inbox drops Chatlane into your own internal tools (a project board, an admin panel, a CRM) so your team can read and reply to a customer conversation in context — without leaving the host app. It's the team-facing counterpart to the customer-facing Website Chat Widget.

This page is the complete reference for the Chatlane.init(...) options. The embed's Embed → Embed options tab shows a live version of this list that reflects the scope locks you've configured.

Install

1. Add the loader + init to your host page (just before </body>):

<script src="https://your-chatlane-domain/embed.js?key=YOUR_EMBED_KEY" async></script>
<script>
  Chatlane.init({
    user: { email: currentUser.email, name: currentUser.name },
    user_hash: userHash,                 // computed on your server — see step 2
    inbox: inboxId,                      // omit if the embed is inbox-locked
    contact: { email: customer.email },  // standard inbox; or `entity:` for an entity inbox
  });
</script>

2. Compute user_hash on your server. This is what proves to Chatlane that the host genuinely vouches for user.email — without it, anyone who reads the public embed key from the page source could impersonate one of your teammates.

// On your backend — never expose the signing secret to the browser.
$signingSecret = '…';  // from Embed → Signing secret
$userHash = hash_hmac('sha256', $currentUser->email, $signingSecret);
// Inject $userHash into the page as the `user_hash` above.

user_hash = HMAC-SHA256(user.email, signing secret). The signing secret stays on your server forever; the browser only ever sees the resulting hash. Rotate it any time from the embed's Embed tab (every host integration must then recompute its hashes).

Options

Chatlane.init(options) accepts the following. Nested fields are listed individually.

Identity (always)

Option Type Required Example Description
key string Required* "KDhUK1dN…" Public embed key. Usually supplied in the script URL (?key=), so it can be omitted here.
user object Required { email, name } The signed-in member of your team using the widget.
user.email string Required "[email protected]" Must match an active member of the embed's team. Verified via user_hash.
user.name string Optional "Jordan Lee" Display name shown for the team member.
user_hash string Required "9f2a4c…" HMAC-SHA256(user.email, signing_secret), computed server-side (see Install step 2).

* Optional only because it's normally passed in the script src.

Inbox

Option Type Required Example Description
inbox integer Required unless the embed is inbox-locked 42 Id of the inbox to open. Omit it when the embed config locks an inbox.

Standard inbox — the customer

Provide one of conversation_id, contact_id, or contact.email. Omit all of these when the embed is contact-locked.

Option Type Required Example Description
conversation_id integer Optional 1234 Open a specific existing conversation directly.
contact_id integer Optional 987 Identify the customer by their Chatlane contact id.
contact object Required if no contact_id/conversation_id { email, name, phone } The customer this page is about.
contact.email string Required if no contact_id/conversation_id "[email protected]" Finds the contact in the team, or creates one.
contact.name string Optional "Maya Brennan" Used only when creating a new contact.
contact.phone string Optional "+44 7700 900482" Used only when creating a new contact.

Entity inbox — the record + contact

Option Type Required Example Description
entity object Required unless record-locked { type, external_id } The record this page is about.
entity.type string Required unless record-locked "orders" The entity slug — must match the inbox's entity.
entity.external_id string | number Required unless record-locked (or use entity.record_id) "ORD-100" The record's external id (your business id).
entity.record_id integer Optional 5567 Chatlane's internal record id — an alternative to type + external_id.
entity_contact object Optional — required in pre-selected contact mode { email } or { id } Which contact on the record to message. Omit when record-contact-locked.
entity_contact.email string See entity_contact "[email protected]" Must be a contact linked to the record.
entity_contact.id integer Optional 321 Contact id — an alternative to entity_contact.email.

Appearance overrides (optional)

Every embed has configured appearance defaults; pass any of these to override them for a specific page.

Option Type Example Description
trigger "bubble" | "side" | "custom" "bubble" Launcher type. custom renders no launcher — open it yourself with Chatlane.open().
position "bottom-right" | "bottom-left" "bottom-right" Launcher corner/edge.
surface "panel" | "drawer" "drawer" Opened surface — a floating panel or a full-height side drawer.
theme "light" | "dark" | "auto" "auto" Colour theme (auto follows the host's prefers-color-scheme).
accent string (hex) "#2e64fc" Accent colour for the header, your messages, and the launcher.

Methods

Method Description
Chatlane.init(options) Boot the embed with the options above.
Chatlane.open() Open the widget — use with trigger: "custom" from your own button.
Chatlane.close() Close the widget.

How scope locks change the requirements

Scope locks (configured under Embed → Appearance → Connection & scope) let you pin the embed below the host's reach. A locked level must not be passed at runtime — the host can't override it.

You lock… Effect on init
Inbox inbox is fixed — omit it.
Contact (standard inbox) The customer is fixed — omit contact / contact_id / conversation_id.
Entity record (entity inbox) The record is fixed — omit entity.
Entity-record contact (entity inbox) The recipient is fixed — omit entity_contact.

Nothing locked is a team-wide embed: the host passes the inbox and subject on every page. Combinations are validated both when you save the embed and when a host page initialises it, so a misconfigured call fails fast with a clear error.

Security notes

  • The embed key is public (it ships in the page). On its own it can't send anything.
  • The signing secret is server-only and powers user_hash. Treat it like a password.
  • Allowed origins restrict which host domains may frame the console (set them on the Embed tab; leave empty only in development).
  • A teammate can only ever do inside the embed what their Chatlane role already allows.
Was this article helpful?
Your feedback helps us improve our docs.