> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tied.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dashboard apps

> Embedding your own app in the conversation sidebar.

Point Tied at a URL you control, and it renders that page as its own panel next to the conversation — passing it just enough context to be useful. What you build behind that URL is entirely yours: an internal tool, a record from another system, a custom action panel.

## Adding one

<Steps>
  <Step title="Open Settings → Integrations → Dashboard apps">
    Administrators only.
  </Step>

  <Step title="Give it a title and a URL">
    The URL must be `http://` or `https://` — that's the only transport a dashboard app supports
    today. There's no other app type besides an embedded frame.
  </Step>

  <Step title="Save">
    You can add more than one. Each gets its own panel in the sidebar.
  </Step>
</Steps>

## The context payload

Your iframe doesn't receive context automatically on load — it has to ask. Send this exact string to the parent window:

```js theme={null}
window.parent.postMessage('chatwoot-dashboard-app:fetch-info', '*');
```

Tied responds with a `message` event whose `data` is a JSON string:

```json theme={null}
{
  "event": "appContext",
  "data": {
    "conversation": { "...": "the open conversation" },
    "contact": { "...": "the conversation's contact" },
    "currentAgent": { "id": 1, "name": "Jane Doe", "email": "jane@example.com" }
  }
}
```

Parse it on receipt:

```js theme={null}
window.addEventListener('message', event => {
  let payload;
  try {
    payload = JSON.parse(event.data);
  } catch {
    return; // not every message on this channel is yours
  }
  if (payload.event === 'appContext') {
    const { conversation, contact, currentAgent } = payload.data;
  }
});
```

`currentAgent` is always just those three fields. `conversation` and `contact` are only populated once an agent has an actual conversation open — expect them empty otherwise.

<Warning>
  **Tied doesn't push a fresh payload when the agent switches conversations** while your panel stays
  mounted. If you need the current conversation rather than whichever one was open when you loaded, send
  the fetch-info message again — on an interval, or on whatever signal makes sense for your app.
</Warning>

## What it doesn't do

This is a read-only handoff in one direction — Tied tells your app what's open, and that's the entire contract. There's no message type for your app to act back on the conversation: insert a reply, resolve it, change its assignment. If you need Tied to *do* something in response to your app, that's a job for the API, not this channel — see [API reference](/api-reference).

## Next

<CardGroup cols={2}>
  <Card title="Using integrations" icon="blocks" href="/integrations">
    Pre-built, OAuth-based connectors, if you don't want to build and host your own iframe.
  </Card>

  <Card title="Security" icon="shield" href="/admin/security">
    What to consider before pointing a sidebar panel at conversation and contact data.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.