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

# Interaction Search access and CSV export

> Understand who can read the Interactions list, who can export it, what each row contains, and why a viewer sees a friendly permission toast instead of a raw error.

# Interaction Search access and CSV export

The **Interactions** page brings conversations and calls into one recency-ordered list. Reading the list and exporting its contact-linked data are intentionally separate permissions. Use this guide to predict what each role can do before you hand an export to a teammate or an auditor.

## 1. Auth model: reading is broader than exporting

The page is available to **owner**, **admin**, **developer**, and **viewer** roles. These roles can open the page, search the list, apply filters, load more rows, and follow a row back to its source surface. A role outside this set cannot open the page.

| Role | Read and search | Follow source links | Export CSV |
| - | - | - | - |
| Owner | Yes | Yes | Yes, when the request meets the export scope policy |
| Admin | Yes | Yes | Yes, when the request meets the export scope policy |
| Developer | Yes | Yes | Yes, when the request meets the export scope policy |
| Viewer | Yes | Yes | No — the API returns `403` and the dashboard shows a friendly toast |

CSV export is a bulk pull of contact-linked history, so the backend applies a stricter gate: **owner, admin, or developer with the `contacts:read` scope**. Dashboard sessions are checked by role. API-key requests must carry `contacts:read`; a key with only `conversations:read` can search but cannot export. If a viewer selects **Export CSV**, the request is rejected by design and the dashboard explains that an owner or administrator must run the export or grant the required access. You do not get a raw error page, and the viewer can continue searching.

## 2. What the list contains

Each row represents one conversation or one call. The list merges the two record families without creating a third record:

* **Channel badge** — identifies the source channel. Call rows use the `voice` badge.
* **Contact** — shows the linked name and any available phone number or email. Select the contact to open its record when a contact link exists.
* **Status and preview** — conversation rows show lifecycle and delivery status plus a plain-text preview; call rows show the call status and a call placeholder.
* **Timestamp** — **Last activity** is the conversation's latest-message time or the call's start time, shown in your local timezone.
* **Quick jump** — select a conversation row to open its inbox thread, or a call row to open call details. Use the Contact link when you need the full contact record instead.

The list is a read projection of the existing conversation and call records. Sending a message or placing a call does not require a separate Interactions write; the source record appears here when it is available to the tenant.

## 3. Recency ordering and pagination

Interactions sorts every row by `last_activity_at`, newest first. Conversations use their latest-message timestamp; calls use their call-start timestamp. When two rows share a timestamp, the row `id` breaks the tie. This composite `(last_activity_at, id)` keyset keeps the order deterministic across page boundaries, so rows with the same timestamp are not skipped or repeated just because they tied.

Select **Load more** to request the next page with the opaque cursor returned by the previous page. The response reports whether another page exists in `meta.pagination.has_more`; stop when it is `false`. The API defaults to 25 rows per page and accepts up to 100. Changing a filter starts a new cursor chain from the first page. Because the list is live, a newly active conversation or call can move higher between requests; export a filtered snapshot when you need one bounded file instead of walking pages.

For the fan-out contract behind cross-surface search, see [Global search fan-out](/concepts/global-search-fan-out). For the message-only search surface, see [Search message history](/guides/search-message-history).

## 4. CSV export: columns and the viewer response

Select **Export CSV** after narrowing the list. The export uses the same filters as the current view and returns these columns, in order:

```text theme={null}
id, type, channel, status, delivery_status, contact_id,
contact_name, contact_phone, contact_email, direction, preview,
last_activity_at
```

The endpoint applies the same tenant scope and export permission policy described above. It is capped at 20,000 rows per response and limited to five exports per minute. If more rows match, the response is truncated at the cap and includes `X-Export-Truncated: true`; narrow the date range, channel, type, contact, or status and export again. Every export is recorded in the tenant's audit log with its row count, truncation state, and cap. This audit entry is a tenant-owned workspace control, not a platform-wide compliance gate.

A viewer can still use every read control on the page. Clicking **Export CSV** produces a friendly toast such as `Export failed. Permission denied (403).` Ask an owner, admin, or developer to run the export, or ask them to provide the required `contacts:read` access. This toast is the expected authorization path, not an indication that the list or tenant data is unavailable.

## 5. Channel coverage and limits

The projection folds in the channels represented by the messaging and voice surfaces:

* **Messaging:** `sms`, `whatsapp`, `rcs`, `email`, `viber`, `instagram`, `messenger`, `telegram`, `video`, `web_chat`, `apple_messages`, `line`, `wechat`, `kakao`, `zalo`, and `agent`.
* **Voice:** `voice`, represented as call rows rather than messaging conversations.

A channel must have a corresponding conversation or call record in the tenant to appear. **MMS and fax are not included in this list's channel filter**; they are separate reply/export surfaces rather than Interaction Search conversation channels. Other channels not in the vocabulary above, including push notifications, are not folded into this projection. Interactions does not replace the source surfaces, invent rows for a channel that has no record, or combine unrelated records into one row. It also does not provide the fielded, provider-ID lookup that the message-only [Search message history](/guides/search-message-history) guide describes; use that guide when you need a single message by `message_id`, provider reference, or body.

## Related reading

* [Global search fan-out](/concepts/global-search-fan-out) — the cross-surface fan-out contract.
* [Search message history](/guides/search-message-history) — the message-only variant.
* [Interactions list CSV export troubleshooting](/troubleshooting/interactions-list.csv-export) — resolve 403 responses, pagination surprises, and empty results.
* [Search every conversation and call in one list](/guides/interaction-search) — filters, API parameters, and cursor details.


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