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

# Feeds

> Save filtered views of your mention stream, and watch them live from the terminal.

Flags and arguments below are the contract as the binary states it. The global flags (`--json`, `--timeout`, …) apply here too and are documented on [Global flags](/docs/cli/contract/global-flags). Error codes are a workspace-global contract, not a per-command one — the taxonomy, and how to read a code that is not in it, is on [The error envelope](/docs/cli/contract/error-envelope).

## `octolens feeds create`

Create a feed from a filter (flags, --filter-json, or --ai)

**Flags**

| Flag            | Type      | Required (headless) | Description                                                                                                                                                                   |
| --------------- | --------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--ai`          | `string`  | no                  | Describe the filter in plain English (e.g. "negative reddit posts about pricing"); the AI wizard builds it. Previews + confirms on a TTY; --yes/headless apply directly.      |
| `--filter-json` | `string`  | no                  | Full-fidelity filter as JSON — a simple `{ conditions: [...] }` or an advanced `{ top_level_operator, groups: [...] }`. Mutually exclusive with the ergonomic flags and --ai. |
| `--icon`        | `string`  | no                  | Feed icon (Heroicons name). Default BellIcon.                                                                                                                                 |
| `--keyword`     | `string`  | no                  | Filter by keyword name or id (repeatable)                                                                                                                                     |
| `--name`        | `string`  | yes (headless)      | Feed display name                                                                                                                                                             |
| `--sentiment`   | `string`  | no                  | Filter by sentiment: positive, neutral, negative (repeatable)                                                                                                                 |
| `--source`      | `string`  | no                  | Filter by source platform, e.g. reddit, twitter (repeatable)                                                                                                                  |
| `--yes`         | `boolean` | no                  | Skip the confirmation prompt and apply the --ai filter directly                                                                                                               |

**Examples**

```bash theme={null}
octolens feeds create --name "Negative Reddit" --source reddit --sentiment negative
octolens feeds create --name Pricing --ai "posts about pricing this week" --yes --json
octolens feeds create --name Advanced --filter-json '{"conditions":[{"field":"Source","values":"reddit"}]}'
```

**Returns**

With `--json`, stdout carries one JSON document with these fields. Backed by the v2 API operation `POST /api/v2/feeds`.

| Field                               | Type                                                   | Description                                                                                                            |
| ----------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                                | integer                                                | Feed id — what `--feed` flags and `feeds get` accept.                                                                  |
| `name`                              | string                                                 | Display name, shown in the app and in notifications.                                                                   |
| `icon`                              | string                                                 | Icon identifier (Heroicons outline name, e.g. `MegaphoneIcon`).                                                        |
| `simpleFilters`                     | object \| null                                         | Flat filter list, conditions combined with AND. `null` when the feed uses advanced filters (or none).                  |
| `simpleFilters.conditions[].field`  | string                                                 | Field the condition matches on (`Keywords`, `Source`, `Sentiment`, `Tags`, …). Case-sensitive.                         |
| `simpleFilters.conditions[].values` | string                                                 | Comma-separated values to match (keyword ids for `Keywords`, lowercase slugs for `Source`).                            |
| `advancedFilters`                   | object \| null                                         | Grouped conditions with AND/OR operators. `null` when the feed uses simple filters (or none).                          |
| `isDefault`                         | boolean                                                | Whether this feed is pinned as the workspace default.                                                                  |
| `destinations`                      | object\[]                                              | Notification destinations. Empty array = filter-only feed, nothing delivered.                                          |
| `destinations[].type`               | enum: `EMAIL`, `SLACK`, `WEBHOOK`                      | Delivery channel. The matching `emailDestination` / `slackDestination` / `webhookDestination` sub-object is populated. |
| `destinations[].frequency`          | enum: `hourly`, `hourlyAtTopOfHour`, `daily`, `weekly` | Delivery cadence. `daily`/`weekly` also carry `time` + `timezone` (and `dayOfWeek` for weekly).                        |
| `createdAt`                         | string                                                 | Creation time, ISO 8601.                                                                                               |
| `updatedAt`                         | string                                                 | Last update time, ISO 8601.                                                                                            |

Without `--json`: A terminal renders the created feed's definition, id included.

<Accordion title="Example output">
  ```json theme={null}
  {
    "id": 42,
    "name": "Competitor mentions",
    "icon": "MegaphoneIcon",
    "simpleFilters": {
      "conditions": [
        {
          "field": "Source",
          "values": "reddit,twitter"
        },
        {
          "field": "Sentiment",
          "values": "Negative"
        }
      ]
    },
    "advancedFilters": null,
    "isDefault": false,
    "destinations": [
      {
        "type": "EMAIL",
        "frequency": "daily",
        "deliveryMode": "batch",
        "time": "09:00",
        "timezone": "UTC",
        "emailDestination": {
          "emails": "alice@example.com, bob@example.com"
        }
      }
    ],
    "createdAt": "2026-06-01T09:30:00.000Z",
    "updatedAt": "2026-07-14T16:05:00.000Z"
  }
  ```
</Accordion>

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE · `8` CANCELLED. The full map is on [Exit codes](/docs/cli/contract/exit-codes).

## `octolens feeds get`

Get a single feed by id (pretty-prints its filter)

**Arguments**

| Argument | Type      | Required | Description                         |
| -------- | --------- | -------- | ----------------------------------- |
| `ID`     | `integer` | required | Numeric feed id (from `feeds list`) |

**Examples**

```bash theme={null}
octolens feeds get 42
octolens feeds get 42 --json
```

**Returns**

With `--json`, stdout carries one JSON document with these fields. Backed by the v2 API operation `GET /api/v2/feeds/{id}`.

| Field                               | Type                                                   | Description                                                                                                            |
| ----------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                                | integer                                                | Feed id — what `--feed` flags and `feeds get` accept.                                                                  |
| `name`                              | string                                                 | Display name, shown in the app and in notifications.                                                                   |
| `icon`                              | string                                                 | Icon identifier (Heroicons outline name, e.g. `MegaphoneIcon`).                                                        |
| `simpleFilters`                     | object \| null                                         | Flat filter list, conditions combined with AND. `null` when the feed uses advanced filters (or none).                  |
| `simpleFilters.conditions[].field`  | string                                                 | Field the condition matches on (`Keywords`, `Source`, `Sentiment`, `Tags`, …). Case-sensitive.                         |
| `simpleFilters.conditions[].values` | string                                                 | Comma-separated values to match (keyword ids for `Keywords`, lowercase slugs for `Source`).                            |
| `advancedFilters`                   | object \| null                                         | Grouped conditions with AND/OR operators. `null` when the feed uses simple filters (or none).                          |
| `isDefault`                         | boolean                                                | Whether this feed is pinned as the workspace default.                                                                  |
| `destinations`                      | object\[]                                              | Notification destinations. Empty array = filter-only feed, nothing delivered.                                          |
| `destinations[].type`               | enum: `EMAIL`, `SLACK`, `WEBHOOK`                      | Delivery channel. The matching `emailDestination` / `slackDestination` / `webhookDestination` sub-object is populated. |
| `destinations[].frequency`          | enum: `hourly`, `hourlyAtTopOfHour`, `daily`, `weekly` | Delivery cadence. `daily`/`weekly` also carry `time` + `timezone` (and `dayOfWeek` for weekly).                        |
| `createdAt`                         | string                                                 | Creation time, ISO 8601.                                                                                               |
| `updatedAt`                         | string                                                 | Last update time, ISO 8601.                                                                                            |

Without `--json`: A terminal renders the feed's definition: filters, destinations and metadata.

<Accordion title="Example output">
  ```json theme={null}
  {
    "id": 42,
    "name": "Competitor mentions",
    "icon": "MegaphoneIcon",
    "simpleFilters": {
      "conditions": [
        {
          "field": "Source",
          "values": "reddit,twitter"
        },
        {
          "field": "Sentiment",
          "values": "Negative"
        }
      ]
    },
    "advancedFilters": null,
    "isDefault": false,
    "destinations": [
      {
        "type": "EMAIL",
        "frequency": "daily",
        "deliveryMode": "batch",
        "time": "09:00",
        "timezone": "UTC",
        "emailDestination": {
          "emails": "alice@example.com, bob@example.com"
        }
      }
    ],
    "createdAt": "2026-06-01T09:30:00.000Z",
    "updatedAt": "2026-07-14T16:05:00.000Z"
  }
  ```
</Accordion>

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE. The full map is on [Exit codes](/docs/cli/contract/exit-codes).

## `octolens feeds list`

List your saved feeds

**Flags**

| Flag                           | Type      | Required (headless) | Description                                                             |
| ------------------------------ | --------- | ------------------- | ----------------------------------------------------------------------- |
| `--all`                        | `boolean` | no                  | Show the full collection (the default for this bounded list)            |
| `--exclude-with-notifications` | `boolean` | no                  | Only show feeds that don't have a notification destination attached yet |
| `--limit`                      | `integer` | no                  | Show only the first N items (mutually exclusive with --all)             |

**Examples**

```bash theme={null}
octolens feeds list
octolens feeds list --json
octolens feeds list --exclude-with-notifications
octolens feeds list --limit 5
```

**Returns**

With `--json`, stdout carries one JSON document with these fields. Backed by the v2 API operation `GET /api/v2/feeds`.

| Field                                      | Type                                                   | Description                                                                                                            |
| ------------------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `data`                                     | object\[]                                              | Every feed of the workspace (bounded — no paging needed).                                                              |
| `data[].id`                                | integer                                                | Feed id — what `--feed` flags and `feeds get` accept.                                                                  |
| `data[].name`                              | string                                                 | Display name, shown in the app and in notifications.                                                                   |
| `data[].icon`                              | string                                                 | Icon identifier (Heroicons outline name, e.g. `MegaphoneIcon`).                                                        |
| `data[].simpleFilters`                     | object \| null                                         | Flat filter list, conditions combined with AND. `null` when the feed uses advanced filters (or none).                  |
| `data[].simpleFilters.conditions[].field`  | string                                                 | Field the condition matches on (`Keywords`, `Source`, `Sentiment`, `Tags`, …). Case-sensitive.                         |
| `data[].simpleFilters.conditions[].values` | string                                                 | Comma-separated values to match (keyword ids for `Keywords`, lowercase slugs for `Source`).                            |
| `data[].advancedFilters`                   | object \| null                                         | Grouped conditions with AND/OR operators. `null` when the feed uses simple filters (or none).                          |
| `data[].isDefault`                         | boolean                                                | Whether this feed is pinned as the workspace default.                                                                  |
| `data[].destinations`                      | object\[]                                              | Notification destinations. Empty array = filter-only feed, nothing delivered.                                          |
| `data[].destinations[].type`               | enum: `EMAIL`, `SLACK`, `WEBHOOK`                      | Delivery channel. The matching `emailDestination` / `slackDestination` / `webhookDestination` sub-object is populated. |
| `data[].destinations[].frequency`          | enum: `hourly`, `hourlyAtTopOfHour`, `daily`, `weekly` | Delivery cadence. `daily`/`weekly` also carry `time` + `timezone` (and `dayOfWeek` for weekly).                        |
| `data[].createdAt`                         | string                                                 | Creation time, ISO 8601.                                                                                               |
| `data[].updatedAt`                         | string                                                 | Last update time, ISO 8601.                                                                                            |
| `pagination.nextCursor`                    | null                                                   | Always `null`: the whole feed set fits one response.                                                                   |

Without `--json`: A terminal renders the feed list with a filter summary per feed; piped stdout emits one tab-delimited record per feed.

<Accordion title="Example output">
  ```json theme={null}
  {
    "data": [
      {
        "id": 42,
        "name": "Competitor mentions",
        "icon": "MegaphoneIcon",
        "simpleFilters": {
          "conditions": [
            {
              "field": "Source",
              "values": "reddit,twitter"
            },
            {
              "field": "Sentiment",
              "values": "Negative"
            }
          ]
        },
        "advancedFilters": null,
        "isDefault": false,
        "destinations": [
          {
            "type": "EMAIL",
            "frequency": "daily",
            "deliveryMode": "batch",
            "time": "09:00",
            "timezone": "UTC",
            "emailDestination": {
              "emails": "alice@example.com, bob@example.com"
            }
          }
        ],
        "createdAt": "2026-06-01T09:30:00.000Z",
        "updatedAt": "2026-07-14T16:05:00.000Z"
      }
    ],
    "pagination": {
      "nextCursor": null
    }
  }
  ```
</Accordion>

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE. The full map is on [Exit codes](/docs/cli/contract/exit-codes).

## `octolens feeds rm`

Delete a feed by id

**Arguments**

| Argument | Type      | Required | Description                         |
| -------- | --------- | -------- | ----------------------------------- |
| `ID`     | `integer` | required | Numeric feed id (from `feeds list`) |

**Flags**

| Flag    | Type      | Required (headless) | Description                  |
| ------- | --------- | ------------------- | ---------------------------- |
| `--yes` | `boolean` | yes (headless)      | Skip the confirmation prompt |

**Examples**

```bash theme={null}
octolens feeds rm 42 --yes
octolens feeds rm 42 --yes --json
```

**Returns**

With `--json`, stdout carries one JSON document with these fields. Backed by the v2 API operation `DELETE /api/v2/feeds/{id}`.

| Field                    | Type       | Description                                                                                                                        |
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `ok`                     | boolean    | Always `true` — a refused deletion answers the error envelope instead.                                                             |
| `id`                     | integer    | Id of the deleted feed.                                                                                                            |
| `deletedNotificationIds` | integer\[] | Notifications destroyed with the feed (deleting a feed cascades to the notification attached to it). Empty when the feed had none. |

Without `--json`: A terminal prints one confirmation line naming the cascade, if any.

Example output:

```json theme={null}
{
  "ok": true,
  "id": 42,
  "deletedNotificationIds": [
    7
  ]
}
```

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE · `8` CANCELLED. The full map is on [Exit codes](/docs/cli/contract/exit-codes).

## `octolens feeds update`

Update a feed's name, icon, and/or filter

**Arguments**

| Argument | Type      | Required | Description                         |
| -------- | --------- | -------- | ----------------------------------- |
| `ID`     | `integer` | required | Numeric feed id (from `feeds list`) |

**Flags**

| Flag            | Type      | Required (headless) | Description                                                                                                                                                                   |
| --------------- | --------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--ai`          | `string`  | no                  | Describe the filter in plain English (e.g. "negative reddit posts about pricing"); the AI wizard builds it. Previews + confirms on a TTY; --yes/headless apply directly.      |
| `--filter-json` | `string`  | no                  | Full-fidelity filter as JSON — a simple `{ conditions: [...] }` or an advanced `{ top_level_operator, groups: [...] }`. Mutually exclusive with the ergonomic flags and --ai. |
| `--icon`        | `string`  | no                  | Replace the feed icon (Heroicons name)                                                                                                                                        |
| `--keyword`     | `string`  | no                  | Filter by keyword name or id (repeatable)                                                                                                                                     |
| `--name`        | `string`  | no                  | Replace the feed name                                                                                                                                                         |
| `--sentiment`   | `string`  | no                  | Filter by sentiment: positive, neutral, negative (repeatable)                                                                                                                 |
| `--source`      | `string`  | no                  | Filter by source platform, e.g. reddit, twitter (repeatable)                                                                                                                  |
| `--yes`         | `boolean` | no                  | Skip the confirmation prompt and apply the --ai filter directly                                                                                                               |

**Examples**

```bash theme={null}
octolens feeds update 42 --name "Renamed feed"
octolens feeds update 42 --source reddit --sentiment negative
octolens feeds update 42 --ai "only negative posts" --yes --json
```

**Returns**

With `--json`, stdout carries one JSON document with these fields. Backed by the v2 API operation `PATCH /api/v2/feeds/{id}`.

| Field                               | Type                                                   | Description                                                                                                            |
| ----------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                                | integer                                                | Feed id — what `--feed` flags and `feeds get` accept.                                                                  |
| `name`                              | string                                                 | Display name, shown in the app and in notifications.                                                                   |
| `icon`                              | string                                                 | Icon identifier (Heroicons outline name, e.g. `MegaphoneIcon`).                                                        |
| `simpleFilters`                     | object \| null                                         | Flat filter list, conditions combined with AND. `null` when the feed uses advanced filters (or none).                  |
| `simpleFilters.conditions[].field`  | string                                                 | Field the condition matches on (`Keywords`, `Source`, `Sentiment`, `Tags`, …). Case-sensitive.                         |
| `simpleFilters.conditions[].values` | string                                                 | Comma-separated values to match (keyword ids for `Keywords`, lowercase slugs for `Source`).                            |
| `advancedFilters`                   | object \| null                                         | Grouped conditions with AND/OR operators. `null` when the feed uses simple filters (or none).                          |
| `isDefault`                         | boolean                                                | Whether this feed is pinned as the workspace default.                                                                  |
| `destinations`                      | object\[]                                              | Notification destinations. Empty array = filter-only feed, nothing delivered.                                          |
| `destinations[].type`               | enum: `EMAIL`, `SLACK`, `WEBHOOK`                      | Delivery channel. The matching `emailDestination` / `slackDestination` / `webhookDestination` sub-object is populated. |
| `destinations[].frequency`          | enum: `hourly`, `hourlyAtTopOfHour`, `daily`, `weekly` | Delivery cadence. `daily`/`weekly` also carry `time` + `timezone` (and `dayOfWeek` for weekly).                        |
| `createdAt`                         | string                                                 | Creation time, ISO 8601.                                                                                               |
| `updatedAt`                         | string                                                 | Last update time, ISO 8601.                                                                                            |

Without `--json`: A terminal renders the feed's definition after the update.

<Accordion title="Example output">
  ```json theme={null}
  {
    "id": 42,
    "name": "Competitor mentions",
    "icon": "MegaphoneIcon",
    "simpleFilters": {
      "conditions": [
        {
          "field": "Source",
          "values": "reddit,twitter"
        },
        {
          "field": "Sentiment",
          "values": "Negative"
        }
      ]
    },
    "advancedFilters": null,
    "isDefault": false,
    "destinations": [
      {
        "type": "EMAIL",
        "frequency": "daily",
        "deliveryMode": "batch",
        "time": "09:00",
        "timezone": "UTC",
        "emailDestination": {
          "emails": "alice@example.com, bob@example.com"
        }
      }
    ],
    "createdAt": "2026-06-01T09:30:00.000Z",
    "updatedAt": "2026-07-14T16:05:00.000Z"
  }
  ```
</Accordion>

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE · `8` CANCELLED. The full map is on [Exit codes](/docs/cli/contract/exit-codes).

## `octolens feeds watch`

Live-watch your feed with keyboard triage (polling live view). The first poll emits the CURRENT first page (the \~20 newest existing mentions) as if they had just arrived; every later poll only ever emits mentions NEWER than the newest one already shown. Pass --backlog none for a tail-only stream (no initial burst) when an agent ACTS on each line. --json emits NDJSON: one Mention JSON document per line, forever. If the stream terminates on a fatal error after emitting mentions, the LAST line is a \{"type":"error","error":\{...},"emitted":N,"watermark":...} record (the same typed error also goes to stderr, with the mapped non-zero exit code); every other line has no `type` field and is a Mention.

**Flags**

| Flag          | Type                    | Required (headless) | Description                                                                                                                                       |
| ------------- | ----------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--backlog`   | enum: `all`, `none`     | no                  | Initial burst: all (default — emit the current first page) or none (tail-only: emit nothing that existed when the watch started) (default: `all`) |
| `--feed`      | `integer`               | no                  | Reuse a saved feed id as the base filter                                                                                                          |
| `--interval`  | `string`                | no                  | Poll interval in seconds (min 2) (default: `15`)                                                                                                  |
| `--keyword`   | `string`                | no                  | Filter by keyword name or id (repeatable)                                                                                                         |
| `--relevance` | enum: `relevant`, `all` | no                  | relevant (default) or all (include low-relevance mentions)                                                                                        |
| `--sentiment` | `string`                | no                  | Filter by sentiment: positive, neutral, negative (repeatable)                                                                                     |
| `--source`    | `string`                | no                  | Filter by source platform, e.g. reddit, twitter (repeatable)                                                                                      |

**Examples**

```bash theme={null}
octolens feeds watch
octolens feeds watch --keyword 'social listening'
octolens feeds watch --source reddit --interval 30
octolens feeds watch --json | jq -r --unbuffered 'select(.type != "error") | .sourceId'
octolens feeds watch --backlog none --json | jq -r --unbuffered 'select(.type != "error") | .sourceId'
```

**Returns**

With `--json`, stdout is an NDJSON STREAM — one complete JSON document per line, each with these fields. Backed by the v2 API operation `POST /api/v2/mentions`.

| Field                | Type                                              | Description                                                                                                                              |
| -------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                 | integer                                           | Internal numeric post id. `mentions update` accepts it as an alternative to the sourceId.                                                |
| `sourceId`           | string                                            | Stable mention key (e.g. `reddit_t3_1abc234`) — the id `mentions get`, `mentions update` and `feedback submit` take.                     |
| `url`                | string                                            | Canonical URL of the original post.                                                                                                      |
| `title`              | string \| null                                    | Post title. `null` on platforms without titles (tweets, etc.).                                                                           |
| `body`               | string \| null                                    | Post text. May be empty or `null`.                                                                                                       |
| `source`             | string                                            | Platform slug, lowercase (`reddit`, `twitter`, `linkedin`, …).                                                                           |
| `timestamp`          | string                                            | When the mention was posted: UTC datetime `YYYY-MM-DD HH:mm:ss.SSS`, no `Z` suffix. Pass it back verbatim where a timestamp is required. |
| `author`             | string \| null                                    | Author handle. `null` when not captured.                                                                                                 |
| `authorName`         | string \| null                                    | Author display name, when distinct from the handle.                                                                                      |
| `authorAvatar`       | string \| null                                    | Author avatar image URL.                                                                                                                 |
| `authorUrl`          | string \| null                                    | Author profile URL.                                                                                                                      |
| `authorFollowers`    | integer \| null                                   | Author follower count at collection time.                                                                                                |
| `relevance`          | enum: `relevant`, `not_relevant`                  | AI relevance classification (unscored posts collapse to `not_relevant`).                                                                 |
| `relevanceComment`   | string \| null                                    | The AI's justification for its relevance verdict, when available.                                                                        |
| `sentiment`          | enum: `Positive`, `Neutral`, `Negative` — or null | Sentiment classification. `null` until scored.                                                                                           |
| `language`           | string \| null                                    | Detected language as a full lowercase name (`english`, `spanish`, …; `undetermined` when detection fails) — never an ISO code.           |
| `tags`               | string\[]                                         | AI-assigned topic tags (e.g. `competitor_mention`, `buy_intent`).                                                                        |
| `keywords`           | object\[]                                         | Monitored keywords this mention matched.                                                                                                 |
| `keywords[].id`      | integer                                           | Tracked keyword id.                                                                                                                      |
| `keywords[].keyword` | string                                            | Keyword text.                                                                                                                            |
| `engaged`            | boolean                                           | Whether a workspace member marked this mention engaged-with.                                                                             |
| `relevanceScore`     | integer \| null                                   | Raw relevance score behind `relevance` (0 high, 1 medium, 2 low). Optional — not every response carries it.                              |

The stream is NOT homogeneous: a fatal error after at least one emitted record appends ONE terminator record — `{"type":"error","error":{"code","message","status"},"emitted":N,"watermark":<newest mention timestamp | null>}` — at the position the data stopped, then the process exits with the mapped code and the same error envelope on stderr. A Mention record never carries a `type` field, so `select(.type != "error")` cleanly splits data from framing. Transient poll failures are NOT on stdout: in `--json` mode each becomes one JSON diagnostic line on stderr (`{"event":"poll_failed","error":{…},"retryInMs":N}`).

Without `--json`: A terminal renders an interactive live stream with a keyboard-triage panel; non-TTY stdout without `--json` emits the same tab-delimited mention records as `mentions list`.

<Accordion title="Example line">
  ```json theme={null}
  {
    "id": 1298401,
    "sourceId": "reddit_t3_1abc234",
    "url": "https://reddit.com/r/socialmedia/comments/1abc234/best_social_listening_tools",
    "title": "Best social listening tools in 2026?",
    "body": "Looking for a tool that tracks Reddit and X mentions of our brand…",
    "source": "reddit",
    "timestamp": "2026-05-06 13:35:37.000",
    "author": "jane_doe",
    "authorName": "Jane Doe",
    "authorAvatar": "https://styles.redditmedia.com/avatars/jane_doe.png",
    "authorUrl": "https://reddit.com/user/jane_doe",
    "authorFollowers": 1240,
    "relevance": "relevant",
    "relevanceComment": "Asks for social-listening tool recommendations — a buying signal.",
    "sentiment": "Neutral",
    "language": "english",
    "tags": [
      "buy_intent"
    ],
    "keywords": [
      {
        "id": 42,
        "keyword": "social listening"
      }
    ],
    "engaged": false,
    "relevanceScore": 0
  }
  ```
</Accordion>

**Exit codes** — `0` OK · `1` UNEXPECTED · `2` USAGE. The full map is on [Exit codes](/docs/cli/contract/exit-codes).
