# Search your logs

Find what the agent, the tools, the knowledge base and your team did, and what each run cost.

**Logs** is under **Insights** for everyone. Only owners and admins can read it. Members see "Only admins and owners can see logs." See [Roles and permissions](/articles/roles-and-permissions).

## The header

| Control | Does |
| --- | --- |
| **Explore** | Opens the explorer on the Activity log. See [Explore from Logs](#explore-from-logs). |
| Range menu | Sets the time range |
| Pause or play button | Turns live updates off or on |
| **Refresh** | Reads the list again, up to now |
| **Export** | **Download CSV** or **Download JSON** |

The line under the title spells the range out.

## Pick a range

| Option | Span |
| --- | --- |
| **Last hour** | 1 hour |
| **Last 24 hours** | 24 hours |
| **Last 7 days** | 7 days |
| **Last 30 days** | 30 days. The page opens on this range. |
| **Last 90 days** | 90 days |
| **Custom range…** | A dialog with **From** and **To** dates. The range runs from midnight on the first day to the end of the last, on your clock. |

- Presets count back from the moment the list was read, not from midnight.
- Future dates cannot be picked. An end before the start reads "Pick an end date on or after the start."
- Selecting a bar on the volume chart also sets a custom range. The menu then reads **Custom range**.

## Live updates

The list reads up to a fixed moment, so paging holds still while new events arrive.

| Button | Tooltip | State |
| --- | --- | --- |
| Pause glyph, **Pause live updates** | Pause new events | Live. New events wait behind a pill at the top of the list, like **3 new events**. Press it to show them. |
| Play glyph, **Resume live updates** | Show new events as they happen | Paused. No pill appears. |
| Disabled, **Live updates, offline** | Reconnecting. Showing the last events received | The connection dropped |
| Disabled, **Live updates, off** | This range has ended | A custom range that ends in the past |

The pill counts up to 100 and then reads **100+ new events**. **Refresh** and the pill both move the list, the chart and the counts up to now.

## Filters

| Filter | Values | URL key |
| --- | --- | --- |
| **Search events** | Matches the event label, summary, error, event name and tool names. Up to 160 characters. | `search` |
| **Usage** | Only entries that used billed work, meaning model tokens, emails or web pages. Plan changes and credit purchases are not usage. | `usage=1` |
| **Type** | **AI**, **API**, **App access**, **Background work**, **Billing**, **Conversations**, **Customers**, **Email**, **Integrations**, **Keys**, **Knowledge**, **Settings**, **Signals**, **Site**, **Team**, **Tools**, **Webhooks** | `category` |
| **Status** | **Succeeded**, **Failed**, **Denied**, **Pending**, **Canceled** | `outcome` |
| **Done by** | **Team**, **Agent**, **Assistant**, **Customer**, **API**, **System** | `by` |
| **Person** | A teammate. Someone who has left reads **Former member**. | `actorId` |
| **One conversation** | Shown after **Show in list** in an entry's drawer | `conversationId` |

Each filter takes one value. **Clear** resets every filter and any custom range, and keeps the preset.

| Status | Means |
| --- | --- |
| **Succeeded** | It worked. Rows show a green dot and no pill. |
| **Failed** | It went wrong. The entry keeps the error. |
| **Denied** | It was refused, like a declined tool call, an API limit or running out of credits |
| **Pending** | It waits on someone or something, like an approval or a retry |
| **Canceled** | It stopped before it finished, like an approval that expired |

| Done by | Means |
| --- | --- |
| **Team** | A teammate, in the dashboard or signed in through the CLI or MCP |
| **Agent** | The support agent, in a customer's conversation |
| **Assistant** | The [assistant](/articles/ask-the-assistant), acting for a teammate |
| **Customer** | Someone on your site |
| **API** | A Median key |
| **System** | Median's own background work |

## The volume chart

The card above the list shows how many events match, like **1,204 events**, and 24 bars across the range.

- Hover a bar for its time span and count.
- Select a bar to narrow the range to that slice.
- A count that hit the reading cap carries a plus, and the tooltips say "at least".
- The card folds away when nothing matches.

## The list

Events run newest first, in one band per day. Each band names the day and counts the rows loaded for it. The list loads 100 events at a time. **Load older events** reads the next page.

A row reads left to right. The status dot, the area icon, the event label, the summary and a pill for anything but success come first. Who did it, what it used, one number and the time follow.

| Number | Shown for |
| --- | --- |
| Cost, like $0.0042 | Billed work. **Free** means nothing was charged. Empty while the price is still pending. |
| `HTTP 502` | Entries with an HTTP status, like API errors |
| Duration, like 1.2s or 340 ms | Anything else that timed itself |

| Empty state | Means |
| --- | --- |
| **No matches in the latest events** | Each page reads at most 1,000 entries, and none of them matched. **Keep looking** reads further back. |
| **No events match these filters** | Nothing in the range matches. **Clear filters** resets them. |
| **No events in the last 30 days** | Nothing was logged in the range. The preset's name fills in. |
| **No events yet** | The organization has no entries |

Entries do not expire. Once the range reaches the first entry, the foot of the list reads **History starts** and the date.

### Folded rows

Three or more entries of the same event in a row fold into one line, like **5 Tool calls**.

- The line names what the entries were about, like the tools called.
- It counts how the entries went. For billed work it also shows their total usage and cost.
- Its dot takes the worst outcome, so one failure inside shows red.
- A run broken by another event becomes two runs.
- Folding is off while a **Type** filter or a search is set.

Opening a folded line shows the outcome counts, the time span, a **Usage** total for billed work, and **Entries**. An entry opens in its place with **Back to 5 tool calls**.

## An entry

Press a row to open its drawer. The title is the event label.

| Section | Holds |
| --- | --- |
| Top | Outcome and area chips, the summary, and the time, like "Sat, Sep 26, 2026, 2:05:22 PM EDT · 3 minutes ago" |
| Error | What went wrong, when something did |
| **Usage** | Billed work only. **Cost**, **Tokens** with input and output under it, **Emails**, **Pages**, **Duration** and **Steps**. |
| **Linked to** | The **Conversation**, **Doc**, **Signal** and **Customer** it touched. Each opens its page. Anything deleted since is left out. |
| **Details** | **By**, **AI feature**, **Credits**, **Duration**, **Tool**, **Tools used**, **HTTP status**, **Changes** and **Changed**. Only what the entry recorded. **Credits** here means credits bought, like a top-up. Billed work shows its cost and duration under **Usage** instead. |
| **Reference** | **Event**, the event name like `tools.call`, and **Entry ID**. Both copy when pressed. |
| **This conversation** | Everything else logged about the same conversation, oldest first, up to the latest 50. **Show in list** narrows the list to it. |

**Only this person**, beside a teammate under **By**, narrows the list to that teammate.

Billed rows show tokens, emails or pages, and their cost. **View all** under **Recent usage** in **Settings → Billing** opens Logs with **Usage** on. Plans and prices are on [Billing](/articles/manage-your-plan-and-credits#plans).

## Share a view

Every filter, the range and the open entry live in the URL. Copy the address to share the view.

```txt
https://median.sh/logs?range=7d&category=tools&outcome=failed
```

| Key | Values |
| --- | --- |
| `range` | `1h`, `24h`, `7d`, `30d`, `90d`. Left out for `30d`. |
| `from`, `to` | A custom range, in Unix milliseconds. Wins over `range`. |
| `category` | `ai`, `api`, `access`, `system`, `billing`, `conversations`, `customers`, `email`, `integrations`, `keys`, `knowledge`, `settings`, `signals`, `team`, `tools`, `webhooks` |
| `outcome` | `success`, `failed`, `denied`, `pending`, `canceled` |
| `by` | `member`, `agent`, `assistant`, `customer`, `api`, `system` |
| `event` | An entry ID. Opens its drawer. |

A shared link reads up to the moment it is opened.

## Export

**Export** saves every event that matches the filters and range, not only the rows loaded.

| Format | Holds |
| --- | --- |
| **Download CSV** | Columns `at`, `outcome`, `event`, `message`, `summary`, `error`, `actorKind`, `actorId`, `durationMs`, `conversationId`. `at` is ISO 8601 in UTC. |
| **Download JSON** | `{ snapshot, count, records }`, with every field of each entry |

- Files are named like `median-logs-2026-09-26.csv`.
- While it runs, the button reads like **Exporting 1,200…**.
- One export reads up to 500 pages of 200 events. With a search, a **Done by** filter or two filters at once, a page can hold fewer matches, so the export can reach that limit with far fewer events. Past it the export fails with "Too many events to export at once. Narrow the range and try again."
- If paging stalls, it fails with "The export stopped partway. Try again."
- A failure shows an **Export failed** callout with the reason.

## What is logged

Events sit in the areas the **Type** filter lists.

| Type | Events |
| --- | --- |
| **AI** | Agent reply, Assistant reply, AI run, Handed to the team, Asked the team, Resolved automatically |
| **Tools** | Tool call, Approval requested, Tool call approved, Tool call declined, Approval expired, Tools synced, Tool endpoint changed, Tool switched on or off, Tool suggested |
| **Knowledge** | Knowledge sync, Knowledge import, Page read, Knowledge indexing, Doc created, Doc edited, Doc deleted, Change suggested, Suggestion approved, Suggestion dismissed |
| **Conversations** | Conversation deleted, Outreach sent |
| **Customers** | Customer deleted |
| **Signals** | Signal filed, Signals merged, Signal deleted, Marked as spam, Issue sync, Code linked |
| **Integrations** | Integration connected, Integration disconnected, Integration delivery |
| **Webhooks** | Webhook added, Webhook changed, Webhook removed, Webhook delivery |
| **Email** | Email settings changed, Incoming email, Email sent, Email delivery |
| **Team** | Member invited, Invite revoked, Member joined, Role changed, Member removed, Member left |
| **Keys** | Key created, Key revoked, Key rotated |
| **App access** | App access approved, App access removed |
| **Settings** | Agent settings changed, Workspace settings changed, Help site changed |
| **Site** | Site sign-in |
| **Billing** | Plan changed, Credits added, Out of credits, Plan needed |
| **API** | API limit reached, API error |
| **Background work** | Background work failed |

An AI run shows what it was for instead of its event label, like **Sentiment check** or **Analytics question**.

| Event | Logged when |
| --- | --- |
| Agent reply, Assistant reply, AI run | Every model call made for your organization, with tokens, credits, duration and tools used |
| Tool call | Once per call, with its duration and any error. A request to see the customer's screen logs once it is answered: **Succeeded** with a picture, **Denied** when they choose not to share, **Failed** when none arrives |
| Tools synced | A sync added, updated or removed tools, failed with a new error, or recovered |
| Knowledge sync | A sync changed documents, or failed with a new error |
| Page read, Email sent | Once per charge. A website import adds its pages to its own Knowledge import entry instead. |
| Knowledge indexing, Incoming email, Email delivery | Only when something failed |
| Webhook delivery | An endpoint stops answering, and again when it answers. Not every retry. |
| Integration delivery | A Slack or Discord message could not be delivered. The same error logs at most once an hour. |
| Out of credits | Paid work was refused because credits ran out. At most once an hour. The summary names the service, like "AI stopped". |
| Plan needed | Paid work was refused because the plan doesn't include it, such as AI on Explore. At most once an hour. |
| API limit reached | A request was refused with `429`. See [Rate limits](https://docs.median.sh/api/errors-and-limits#rate-limits). |
| API error | A request failed on Median's side with a `5xx` status |
| Background work failed | A background job failed. The same failure logs at most once an hour. |

### What is never logged

- Page views, reads and opened settings, including reading this page
- API requests that succeed, and API refusals other than rate limits
- Background work that succeeded
- Prompts, model answers and model names
- What customers wrote, and their names and email addresses. Entries link conversations and customers by ID and name them when opened.

Summaries and errors are one line of up to 300 characters. Anything shaped like a secret reads `[hidden]`. A URL keeps only its scheme and host.

## Explore from Logs

**Explore** opens the explorer on the Activity log, counted per day and split by outcome, over every day the range touches. Its samples are "Failed events by area", "Credits used by AI feature, per day" and "Slowest tools". Queries, datasets and charts are on [Analytics](/articles/read-your-analytics).

## From the API, CLI and MCP

Owners and admins can read the log from outside the app, with the same
filters as this page. The endpoints and examples are in
[Analytics and logs](https://docs.median.sh/api/analytics#logs) in the
developer docs.
