# Frame protocol

Generated from `contracts/frame.schema.json` by `node docs/gen.mjs`. Do not edit by hand.

Messages travel between the host page and the chat frame over the embed channel. Each message is `{type, id?, data}`; the tables below describe `data`.

| Type | Direction | Meaning |
|---|---|---|
| [`call-incoming`](#call-incoming) | frame to host | Frame to host: a call is incoming for the viewer. |
| [`close`](#close) | host to frame | Host to frame: closes the chat. |
| [`expired`](#expired) | frame to host | Frame to host: the session expired and could not be renewed. |
| [`guest`](#guest) | frame to host | Frame to host: a guest token for the host to store. |
| [`insets`](#insets) | host to frame | Host to frame: the host page's safe-area insets, sent on connect and on every change. |
| [`lang`](#lang) | host to frame | Host to frame: sets the language of the chat. |
| [`layout`](#layout) | frame to host | Frame to host: the chat's layout state; embed.js sizes the iframe from it. |
| [`logout`](#logout) | host to frame | Host to frame: signs the viewer out of the chat. |
| [`mc:hello`](#mchello) | frame to host | Frame to host: the first message, posted to the parent window with target origin `*`. |
| [`mc:port`](#mcport) | host to frame | Host to frame: embed.js answers the hello and transfers a `MessagePort` the frame keeps. |
| [`navigate`](#navigate) | frame to host | Frame to host: asks the host page to go to a URL or run its own flow. |
| [`need-token`](#need-token) | frame to host | Frame to host: asks for a token; the host replies `token`. |
| [`notify`](#notify) | frame to host | Frame to host: a message arrived. |
| [`open`](#open) | host to frame | Host to frame: opens the chat, optionally on a conversation with one user. |
| [`purchase`](#purchase) | frame to host | Frame to host: asks the host page to pay a purchase; the host replies `purchase-result`. |
| [`purchase-result`](#purchase-result) | host to frame | Host to frame: the outcome of a purchase the host page paid. |
| [`refresh`](#refresh) | host to frame | Host to frame: refetches the inbox, the conversation and the catalog. |
| [`token`](#token) | host to frame | Host to frame: the client token and guest token, answering `need-token`. |
| [`unread`](#unread) | frame to host | Frame to host: the viewer's total unread count. |

## `call-incoming`

Frame to host: a call is incoming for the viewer.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `from` | [FromUser](#fromuser-model) | required | Who is calling. |

## `close`

Host to frame: closes the chat.

Direction: host to frame

No fields.

## `expired`

Frame to host: the session expired and could not be renewed.

Direction: frame to host

No fields.

## `guest`

Frame to host: a guest token for the host to store.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `guest_token` | string | required | The guest token for the host to store. |

## `insets`

Host to frame: the host page's safe-area insets, sent on connect and on every change.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `bottom` | number, at least 0 | required | Bottom safe-area inset in px. |
| `bubble` | boolean | `false` | True when an open chat is a panel with embed.js's close bubble under it. |
| `left` | number, at least 0 | required | Left safe-area inset in px. |
| `right` | number, at least 0 | required | Right safe-area inset in px. |
| `top` | number, at least 0 | required | Top safe-area inset in px. |

## `lang`

Host to frame: sets the language of the chat.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `lang` | string | required | Language code to show the chat in. |

## `layout`

Frame to host: the chat's layout state; embed.js sizes the iframe from it.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `launcher` | [LauncherData](#launcherdata-model) | required | Launcher position and brand colours. |
| `state` | `"hidden"`, `"launcher"`, `"open"`, `"call-fullscreen"` | required | How embed.js sizes the iframe. |
| `toast` | boolean | `false` | True while the launcher shows an arrival toast; embed.js widens the iframe. |
| `toast_width` | number or null | `null` | Room in px the toast needs; embed.js widens the iframe that far plus 16px. |

## `logout`

Host to frame: signs the viewer out of the chat.

Direction: host to frame

No fields.

## `mc:hello`

Frame to host: the first message, posted to the parent window with target origin `*`.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `v` | `1` | required | Protocol version. |

## `mc:port`

Host to frame: embed.js answers the hello and transfers a `MessagePort` the frame keeps.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `v` | `1` | required | Protocol version. |

## `navigate`

Frame to host: asks the host page to go to a URL or run its own flow.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `amount_minor` | integer or null | `null` | Amount in minor units of `currency`, where one is carried. |
| `conversation_id` | string or null | `null` | Conversation the navigation concerns, set with `notify`. |
| `currency` | string or null | `null` | ISO 4217 currency of the amount. |
| `external_id` | string or null | `null` | For `profile` without a url, the peer's external id; for `notify`, the viewer's own; for `topup` without a url, the seller's. |
| `purchase_id` | string or null | `null` | Purchase to top up, set with `topup` and no url. |
| `reason` | `"signup"`, `"login"`, `"profile"`, `"services"`, `"checkout"`, `"topup"`, `"conversation"`, `"notify"` | required | Why the frame asks the host to navigate. |
| `url` | string or null | `null` | Where to go; null when the host resolves the address itself. |

## `need-token`

Frame to host: asks for a token; the host replies `token`.

Direction: frame to host

No fields.

## `notify`

Frame to host: a message arrived.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `conversation_id` | string | required | Conversation the message arrived in. |
| `from` | [FromUser](#fromuser-model) | required | Who sent the message. |
| `preview` | string | required | Preview of the message. |
| `sound` | boolean | `false` | Asks embed.js to play the arrival chime on the host page. |

## `open`

Host to frame: opens the chat, optionally on a conversation with one user.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `vouch` | string or null | `null` | Vouch token that lets the viewer start a conversation. |
| `with` | string or null | `null` | External id of the user to open a conversation with. |

## `purchase`

Frame to host: asks the host page to pay a purchase; the host replies `purchase-result`.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `id` | string | required | Request id the host echoes in `purchase-result`. |
| `purchase` | [Purchase](#purchase-model) | required | The purchase the host page pays. |

## `purchase-result`

Host to frame: the outcome of a purchase the host page paid.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `external_ref` | string or null | `null` | Your reference for the payment. |
| `id` | string | required | Id of the `purchase` request this answers. |
| `status` | `"paid"`, `"failed"`, `"cancelled"`, `"pending"` | required | How the page's payment ended. |

## `refresh`

Host to frame: refetches the inbox, the conversation and the catalog.

Direction: host to frame

No fields.

## `token`

Host to frame: the client token and guest token, answering `need-token`.

Direction: host to frame

| Field | Type | Default | Meaning |
|---|---|---|---|
| `guest` | string or null | required | The guest token embed.js stored, or null. |
| `token` | string or null | required | The client token from your server, or null. |

## `unread`

Frame to host: the viewer's total unread count.

Direction: frame to host

| Field | Type | Default | Meaning |
|---|---|---|---|
| `count` | integer | required | Total unread messages of the viewer. |

## Shared models

### FromUser model

The user a notification or call comes from.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `external_id` | string | required | External id of the user. |
| `name` | string | required | Display name of the user. |

### LauncherData model

Launcher settings carried by `layout`.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `enabled` | boolean | required | Whether the launcher bubble shows. |
| `on_primary` | string or null | `null` | Colour of text on `primary`. |
| `position` | `"right"`, `"left"` | required | Corner of the launcher. |
| `primary` | string or null | `null` | Brand colour embed.js paints its close bubble with. |

### Purchase model

A purchase of an item by a buyer from a seller.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `buyer_id` | uuid | required | The buyer's id. |
| `conversation_id` | uuid or null | required | The conversation it belongs to, or null. |
| `created_at` | date-time | required | When the purchase was created. |
| `currency` | string | required | ISO 4217 currency of the price. |
| `external_ref` | string or null | `null` | Your reference for the purchase, such as an order id. |
| `id` | uuid | required | The purchase's id. |
| `item` | [PurchaseItem](#purchaseitem-model) | required | The item that was bought. |
| `mode` | `"server_charge"`, `"page_callback"`, `"checkout_url"`, `"external"` | required | How it is paid: the app's `commerce.payment_mode`, or `external` for a purchase recorded from your server. |
| `price_minor` | integer | required | The price in minor units. |
| `seller_id` | uuid | required | The seller's id. |
| `status` | `"pending"`, `"paid"`, `"insufficient"`, `"failed"`, `"cancelled"` | required | `pending` until paid; `insufficient` when the balance was short. |

### PurchaseItem model

What was bought.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `description` | string, up to 2000 chars or null | `null` | More about it. |
| `id` | string or null | `null` | The catalog item's id, when there is one. |
| `kind` | string or null | `null` | The item's kind; `custom` for a custom amount. |
| `title` | string, up to 200 chars | required | The item's name. |