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

# lua logs

> Read the agent's execution logs by source, primitive, or end user, as text or JSON

`lua logs` lists execution logs for the configured agent, newest first, filtered by log source, by a named primitive, or by end user. It reads only.

*Verified against lua-cli 3.33.0.*

## Synopsis

```bash theme={null}
lua logs [--type <type>] [--name <name>] [--user-id <id>] [--agent-id <id>] [--limit <n>] [--page <n>] [--json]
lua logs --type calls [--direction <inbound|outbound>] [--status <status>] [--limit <n>] [--page <n>] [--json]
```

## Description

Without `--type`, `--name`, `--user-id`, or `--json`, the command opens a menu: all agent logs, or a filter by skills, jobs, webhooks, preprocessors, postprocessors, devices, user messages, agent responses, agent errors, MCP tools, runtime, knowledge base (RAG), device triggers, or voice calls, with page navigation. With any of those flags it prints one page and exits. `--ci` does not stop the menu; pass `--type` or `--json`.

`--type` accepts `all`, `skill`, `job`, `webhook`, `preprocessor`, `postprocessor`, `mcp`, `device`, `device-trigger`, `user_message`, `agent_response`, `agent_error`, `runtime`, `rag`, and `calls`. Plural and short forms such as `skills`, `pre`, `post`, `kb`, `error`, `response`, and `user` are normalized. Any other value exits 2 and lists the valid values; that `Valid values` hint omits `all` and `calls`, which are handled before the check and are accepted. `--name` narrows one of the entity types (`skill`, `job`, `webhook`, `preprocessor`, `postprocessor`, `device`) to one primitive by name or id; it requires `--type`, is refused for the other types, and exits 3 when the primitive does not exist. `--user-id` keeps only logs produced for one end user. `--agent-id` reads another agent you administer instead of the one in `lua.skill.yaml`.

There is no time filter and no environment filter. Sandbox and production entries are stored together, and `metadata.channel`, where present, is `dev` for every message sent from `lua chat` in either environment, while end-user traffic carries its channel (`pop` for the web widget, `whatsapp`, `slack`, `email`, `api`, and so on); to bound a check, compare `timestamp` in `jq`. A tool that throws is written as an `error` entry under its own source (`--type skill`, or `mcp`); `agent_error` holds failures of the message pipeline itself, such as billing, validation, and model errors, so a post-release check reads both.

Pages hold `--limit` entries (default 20) and `--page` selects one (default 1); the server caps a page at 100 entries, so `--limit 500` returns 100 and `pagination.limit` reports the cap. The API returns entries newest first and `--json` keeps that order; the text view prints a page oldest to newest so the latest entry is at the bottom, and ends with a hint block unless `LUA_NO_HINTS` is set. `--type calls` reads voice call records instead of execution logs, accepts `--direction` and `--status`, and prints a table or a different JSON shape. A failure keeps the typed `✖` line on stderr even with `--json`; there is no JSON error envelope.

## Arguments

None.

## Options

| Option              | Description                                                   | Default          |
| ------------------- | ------------------------------------------------------------- | ---------------- |
| `--type <type>`     | Log source to show; see the accepted list in the description. | interactive      |
| `--name <name>`     | Primitive name or id. Requires an entity `--type`.            | all              |
| `--user-id <id>`    | Only logs for this end user.                                  | all              |
| `--agent-id <id>`   | Read another agent's logs.                                    | `lua.skill.yaml` |
| `--limit <n>`       | Entries per page; the server caps it at 100.                  | `20`             |
| `--page <n>`        | Page number.                                                  | `1`              |
| `--json`            | Print JSON.                                                   | off              |
| `--direction <dir>` | `calls` only: `inbound` or `outbound`.                        | both             |
| `--status <status>` | `calls` only: filter by call status, for example `failed`.    | all              |

## Output

`--json` prints `{ logs, pagination }`. Each entry has `id`, `timestamp`, `type` (`log` or `metric`), `subType` (`error`, `warn`, `info`, `debug`, `start`, `complete`), `message`, an optional `duration` in milliseconds, and `metadata` with `logSource`, `primitiveId`, `primitiveName`, `toolId`, `toolName`, `userId`, `agentId`, `runId`, and `channel` as available. There is no `level` field; filter errors on `subType`. Trimmed to one entry:

```json Output theme={null}
{
  "logs": [
    {
      "_id": "6aa54ccd47f5e6a851ccf9fe",
      "id": "1789217997644-jtoulxxxq",
      "timestamp": "2026-09-12T12:59:57.644Z",
      "type": "log",
      "subType": "debug",
      "message": "Execute function completed in 0 ms",
      "metadata": {
        "userId": "user_…",
        "agentId": "agent_…",
        "logSource": "postprocessor",
        "primitiveId": "postprocessor_d39f9879-b73b-4a71-9032-40eeab2ad429",
        "primitiveName": "ticket-footer",
        "toolId": null,
        "toolName": null,
        "channel": "dev"
      }
    },
    …
  ],
  "pagination": {
    "currentPage": 1,
    "totalPages": 43,
    "totalCount": 86,
    "limit": 2,
    "hasNextPage": true,
    "hasPrevPage": false,
    "nextPage": 2,
    "prevPage": null
  }
}
```

`--type calls --json` prints `{ calls, total, page, limit, totalPages }`, where each call has `startedAt`, `direction`, `from`, `to`, `status`, and optional `durationSeconds` and `recordingUrl`:

```json Output theme={null}
{
  "calls": [],
  "total": 0,
  "page": 1,
  "limit": 1,
  "totalPages": 0
}
```

## Examples

Check for errors after a test message or a promote:

```bash theme={null}
lua logs --type agent_error --limit 5
```

Follow one skill's tool executions:

```bash theme={null}
lua logs --type skill --name tickets --limit 10
```

Export everything one end user triggered, for a support case:

```bash theme={null}
lua logs --user-id <user-id> --json > user-logs.json
```

Fail a CI step when a pipeline error or a throwing tool was logged after a point in time:

```bash theme={null}
since=$(date -u +%Y-%m-%dT%H:%M:%SZ)
lua chat -e production -m "What is the status of my tickets? My email is user@example.com" -t --clear
lua logs --type agent_error --limit 50 --json --ci | jq -e --arg s "$since" '[.logs[] | select(.timestamp > $s)] | length == 0'
lua logs --type skill --limit 50 --json --ci | jq -e --arg s "$since" '[.logs[] | select(.timestamp > $s and .subType == "error")] | length == 0'
```

A wrong `--type` exits 2 and lists the accepted values:

```bash theme={null}
lua logs --type bogus
```

```text Output theme={null}
✖ usage: lua: "bogus" is not a valid logs.type value.
💡 Valid values: agent_error, agent_response, device, device-trigger, job, mcp, postprocessor, preprocessor, rag, runtime, skill, user_message, webhook
```

List failed voice calls:

```bash theme={null}
lua logs --type calls --status failed --json
```

## Exit codes

| Code | Meaning                                                                                                       |
| ---- | ------------------------------------------------------------------------------------------------------------- |
| `0`  | A page was printed, including an empty one.                                                                   |
| `1`  | The call-records request failed for any reason other than a rejected credential; the message is the server's. |
| `2`  | Invalid `--type`, `--name` without `--type`, `--name` with a non-entity type, or not inside a project.        |
| `3`  | The `--name` primitive does not exist.                                                                        |
| `9`  | No credential, or the server rejected it.                                                                     |
| `10` | The credential may not read this agent's logs.                                                                |
| `11` | The server or network is unavailable.                                                                         |

## See also

* [Read logs and debug](/ship/logs-and-debugging) — the verification loop after a promote
* [Troubleshooting](/ship/troubleshooting)
* [`lua chat`](/reference/cli/chat) — what triggers the per-turn error probe
* [`lua voice`](/reference/cli/voice) — where call records come from
