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.