# Embed Message24 pages with embed tokens

> Show a business's Message24 orders, dashboard or call-center analytics inside an ERP, intranet or website with an iframe and an embed token.

Source: https://docs.message24.net/developers/embed/embed-dashboards/

An embed token lets you show a business's live Message24 pages inside another system, such as an ERP or an internal portal, without anyone logging in to Message24. You place an iframe on your page; the token in its URL signs the iframe in.

Each token acts as its own team member. When a token is created, Message24 adds a member to the business's team with the token's name and the role you choose. The embed sees and can do what a person with that role can, in that business only, except manage who has access to it.

Three pages can be embedded:

| Page | Path | Role needed | Shows |
|---|---|---|---|
| Orders | `/embed/orders` | Member | The orders list and order details. Orders can be edited, confirmed, cancelled and deleted, and the customer's contact details can be edited. |
| Business dashboard | `/embed/dashboard` | Admin | The business dashboard, including conversation drill-downs. |
| Call center | `/embed/cdr` | Admin | Call-center analytics: KPIs, trends, heatmap, agent performance and the call log. |

A page loaded with a token whose role is too low shows no data. Links that would leave the embed, such as opening a conversation in the inbox, are hidden.

## What a token exposes

Treat an embed token like a password. Anyone who has it can act as its team member through the Message24 API, from any browser, until it is revoked. The pages you embed don't limit it: the token can do anything its role can do anywhere in the business.

- A member token can view and change orders, including deleting them, edit customer contact details, and see the conversation messages shown with each order, in the channels it has access to.
- An admin token can do what a person with the admin role can, such as changing business, order and channel settings and connecting channels.

Whatever its role, a token can never manage who has access: it can't create, edit or revoke embed tokens, list or change team members or their channel access, create a business, or delete its own account. A token never reaches another business.

Pick the lowest role that covers the pages you embed. Only the dashboard and call-center pages need admin.

:::caution
The token is part of the iframe's URL, so anyone who can view the source of the page hosting the iframe can copy it. Only embed on pages that are themselves behind your own login.
:::

## Create a token

Embed tokens are managed by business admins. If you are the developer, ask an admin of the business to do this and send you the token.

1. In Message24, open **Settings > Embed Tokens**.
2. Under **New token**, enter a **Token name** that says where it will be used, for example "ERP production". This is the name that appears on the team page and in order history.
3. Under **Acts as**, choose **Member** or **Admin**.
4. Optionally fill in **Allowed embedding origins** (see [origin allowlist](#origin-allowlist)).
5. Press **Create**.

The token is shown **once**, together with a ready-made embed URL and a **Copy \<iframe\> snippet** button for each page. Pages that need the admin role are marked when the token is a member. Message24 stores only a hash of the token, so it cannot be shown again. If it is lost, create a new token and revoke the old one.

## URL format

```text
https://message24.net/embed/orders#embedToken=YOUR_TOKEN
https://message24.net/embed/dashboard#embedToken=YOUR_TOKEN
https://message24.net/embed/cdr#embedToken=YOUR_TOKEN
```

The token goes in the URL fragment, after `#`. Browsers never send the fragment to a server, so the token stays out of access logs and `Referer` headers. There are no other URL parameters.

:::note
`?embedToken=YOUR_TOKEN` as a query parameter also works, for older hand-built links, but it sends the token to the server with every page load. Use the fragment form.
:::

## Embed code

The snippet Message24 generates is a full-width iframe plus a small listener that resizes it to fit its content, so there is no inner scrollbar:

```html
<iframe src="https://message24.net/embed/orders#embedToken=YOUR_TOKEN" style="width:100%;border:0" height="900" title="Message24"></iframe>
<script>
  window.addEventListener('message', function (e) {
    if (e.origin !== 'https://message24.net' || !e.data || e.data.type !== 'm24-embed-height') return;
    document.querySelectorAll('iframe').forEach(function (f) {
      if (f.contentWindow === e.source) f.style.height = e.data.height + 'px';
    });
  });
</script>
```

The embedded page posts `{ type: "m24-embed-height", height: <pixels> }` to its parent whenever its layout changes. The height is the only data it sends. `height="900"` is the size used until the first message arrives, or if your page does not add the listener.

To embed several pages on one host page, add one iframe per page. A single listener handles all of them, since it matches each message to the iframe that sent it.

## Origin allowlist

**Allowed embedding origins** restricts which sites may frame a token. Enter origins separated by commas, spaces or new lines:

```text
https://erp.example.com, https://intranet.example.com
```

- An origin is the scheme, host and port, with no path. A trailing slash is ignored. Matching is exact: `https://example.com` does not allow `https://www.example.com`.
- **Leave it empty to allow any site.** The token list then shows "Embeddable on any origin".
- Opening the embed URL directly in a browser tab, not inside an iframe, is always allowed, so you can check a token by pasting its URL.
- When the page is framed by a site that is not on the list, it shows "Not authorized here".

The check runs in the browser. The embedded page reads its parent's origin from `window.location.ancestorOrigins` in Chromium and WebKit browsers, and from `document.referrer` elsewhere. If it cannot confirm the parent, it refuses to render. In browsers without `ancestorOrigins`, such as Firefox, a host page that sends `Referrer-Policy: no-referrer` therefore always shows "Not authorized here"; use a policy that sends at least the origin, such as the default `strict-origin-when-cross-origin`.

:::note
The allowlist stops other websites from framing a token in a normal browser. It does not make a leaked token safe: the token itself is the access boundary. Revoke any token that leaks.
:::

## Editing a token

In the token list, the edit button lets an admin change a token's name and allowed origins. The token value stays the same, so live embeds keep working.

The token's role and channel access are managed on the **Team** page, where it is listed with a key icon and "Embed token" in place of an email. A new token can see every channel the business had when it was created; channels added later have to be granted to a member token there. Removing the token's member from the team stops the embed from loading data, and the token list marks it "Removed from team".

## Revoking a token

Press the revoke button next to the token and confirm. The token stops working on the next request: embedded pages show "Invalid or revoked token". Its member is removed from the team; its name stays on anything it changed, such as order history. Revoked tokens stay in the list, greyed out with the date they were revoked, so there is a record of them. Each token also shows its creator, creation date and when it was last used.

## Messages the embed can show

| Message | Cause |
|---|---|
| Missing embed token | The URL has no `embedToken`. |
| Invalid or revoked token | The token is wrong, was revoked, or could not be verified. |
| Not authorized here | The host site is not in the token's allowed origins, or its origin could not be confirmed. |

## The API behind the embed

An embedded page calls the regular Message24 API at `https://message24.net/api/`, sending the token in an `X-Embed-Token` header instead of a session cookie. The API treats the request as coming from the token's team member, so every endpoint applies the same role, channel-access and business checks it applies to a person.

`GET /api/embed/context` returns the token's member (`account.id`, `account.name`), its `businessId` and its `allowedOrigins`. A missing, unknown or revoked token returns `401`; an action the role does not allow, or one of the access-management endpoints listed under [what a token exposes](#what-a-token-exposes), returns `403`.
