---
title: 'flexkit logs'
description: 'Read API request, webhook delivery and AI model call logs from the terminal, filter them and follow new entries live.'
---

# `flexkit logs`

Reads the project's [logs](/docs/dashboard/logs): GraphQL API requests, webhook deliveries and AI model calls made by the chat agent and automations. Pick a time range, filter by operation, status or event, print JSON for scripts, or follow new entries as they arrive while you test.

## Synopsis

```bash
flexkit logs [api|webhooks|llm] [options]
```

The log type defaults to `api`, so `flexkit logs --since 2h` reads API requests. Entries are printed oldest first, so the newest entry is at the bottom of the table.

| Type       | What it shows                                                                                       |
| ---------- | --------------------------------------------------------------------------------------------------- |
| `api`      | GraphQL API requests: time, operation, status code, duration, request plus response size, location. |
| `webhooks` | Webhook deliveries: time, event and entity, status code, HTTP method, duration, URL, error.         |
| `llm`      | AI model calls: time, model, input and output tokens, cost, duration, automation id.                |

## Time ranges

`--since`, `--until` and `--before` take either a duration back from now or an absolute time:

| Value                       | Meaning                                                                                         |
| --------------------------- | ----------------------------------------------------------------------------------------------- |
| `30s`, `15m`, `1h`, `1.5h`  | Seconds, minutes or hours ago.                                                                  |
| `2d`, `1w`                  | Days or weeks ago.                                                                              |
| `now`                       | The current time.                                                                               |
| `2026-11-02`                | Midnight on that day, in your local time.                                                       |
| `2026-11-02T08:30`          | A date-time without a zone is read in local time, as the table prints it; with `--utc`, as UTC. |
| `2026-11-02T08:30:00+02:00` | A date-time with a zone or `Z` is read as written.                                              |

Without flags, `flexkit logs` shows the last hour, up to 50 entries. A range can span at most 90 days, and one request returns at most 500 entries. When a range holds more than `--limit` entries you get the newest ones, and the command prints the `--before` value that continues with older entries.

## `logs api`

Show GraphQL API requests made to the project. Filter by the exact operation name with `--operation` and by HTTP status code with `--status`. Alias: `requests`.

```bash
flexkit logs api [--operation <name>] [--status <code>] [--since <time>] [--until <time>] [--limit <n>] [--follow] [--json]
```

### Examples

```bash
# API requests from the last hour
flexkit logs

# Server errors over the last two days
flexkit logs api --since 2d --status 500

# Watch one operation while you test a page
flexkit logs api --operation GetProducts --follow

# The ten slowest requests of a day
flexkit logs api --since 2026-11-02 --until 2026-11-03 --limit 500 --json \
  | jq '.data | sort_by(-.duration_ms) | .[:10] | .[] | {timestamp, operation_name, duration_ms}'
```

## `logs webhooks`

Show [webhook](/docs/api/webhooks) deliveries: the event that triggered them, the status code your endpoint answered, and the error of failed deliveries. Filter by event with `--event create|update|delete` and by result with `--status succeeded|failed`. Alias: `webhook`.

```bash
flexkit logs webhooks [--event <event>] [--status succeeded|failed] [--since <time>] [--until <time>] [--limit <n>] [--follow] [--json]
```

### Examples

```bash
# Failed deliveries in the last day
flexkit logs webhooks --since 1d --status failed

# Watch deliveries while you work on your endpoint
flexkit logs webhooks -f

# Only deliveries for deleted records, as JSON
flexkit logs webhooks --event delete --since 1w --json

# Count last week's failures per URL
flexkit logs webhooks --since 1w --status failed --limit 500 --json \
  | jq '.data | group_by(.url) | map({url: .[0].url, failures: length})'
```

## `logs llm`

Show AI model calls made by the chat agent and by [automations](/docs/automations): the model, input and output tokens, cost and the automation that made the call (empty for chat).

```bash
flexkit logs llm [--since <time>] [--until <time>] [--limit <n>] [--follow] [--json]
```

### Examples

```bash
# Model calls from the last hour
flexkit logs llm

# Cost in dollars of the last 7 days (up to 500 calls)
flexkit logs llm --since 7d --limit 500 --json | jq '[.data[].actual_cost_micros] | add / 1000000'

# Watch an automation run spend tokens
flexkit logs llm --follow --interval 2
```

## Following new entries

`--follow` (`-f`) prints the matching entries of the time range, then checks for new ones every 5 seconds (change it with `--interval`, minimum 2) until you press Ctrl+C. Each check starts 30 seconds before the end of the previous one, measured by the server's clock, so entries that are recorded a little late still show up. An error that won't go away by itself, such as a revoked token or lost access, stops the command. An entry is printed once even when two checks return it. `--follow` can't be combined with `--until` or `--before`.

Entries are recorded a few seconds after the request finishes, so a request you just made can take a moment to appear.

## JSON output

`--json` prints JSON on stdout, with times as ISO 8601 UTC strings and the same fields as the Logs page:

- Without `--follow`: the page as the API returns it, an object with the entries in `data`, **newest first**, and `nextBefore`, the `--before` value for the next page (`null` when there are no more entries). It also has `type`, `since`, `until` and `limit`.
- With `--follow`: one entry per line (NDJSON), **oldest first**, first the entries of the time range and then each new entry as it arrives. Pipe it to `jq -c` or another line-based tool.

```json
{
  "type": "api",
  "since": "2026-11-03T11:00:00.000Z",
  "until": "2026-11-03T12:00:00.000Z",
  "limit": 50,
  "data": [
    {
      "type": "api-requests",
      "timestamp": "2026-11-03T11:59:58.250Z",
      "operation_name": "GetProducts",
      "status_code": 200,
      "duration_ms": 42
    }
  ],
  "nextBefore": "2026-11-03T11:42:08.000Z"
}
```

Read every API request of a day, page by page, in a script:

```bash
before=""
while :; do
  page=$(flexkit logs api --since 2026-11-02 --until 2026-11-03 --limit 500 --json --before "${before:-now}")
  echo "$page" | jq -c '.data[]' >> requests.ndjson
  before=$(echo "$page" | jq -r '.nextBefore // empty')
  [ -n "$before" ] || break
done
```

Pages can repeat a few entries at their boundary (see the notes below), so drop the duplicates before counting: `jq -s 'unique | length' requests.ndjson`.

Follow server errors as they happen:

```bash
flexkit logs api -f --json | jq -c 'select(.status_code >= 500) | {timestamp, operation_name}'
```

## Options

| Option                 | Applies to | Description                                                                                               |
| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| `--since <time>`, `-s` | all        | Start of the time range. Default: 1 hour before the end of the range (`--until` or `--before`, else now). |
| `--until <time>`       | all        | End of the time range. Default: now.                                                                      |
| `--before <time>`      | all        | Only entries older than this time, to page back through a busy range.                                     |
| `--limit <n>`, `-n`    | all        | Entries to fetch, 1–500. Default: 50.                                                                     |
| `--operation <name>`   | `api`      | Only requests with this exact GraphQL operation name.                                                     |
| `--status <code>`      | `api`      | Only requests that returned this HTTP status code, such as `500`.                                         |
| `--status <result>`    | `webhooks` | Only `succeeded` or `failed` deliveries.                                                                  |
| `--event <event>`      | `webhooks` | Only deliveries for `create`, `update` or `delete` events.                                                |
| `--follow`, `-f`       | all        | Keep running and print new entries as they arrive. Ctrl+C stops.                                          |
| `--interval <seconds>` | all        | How often `--follow` checks for new entries. Default: 5, minimum: 2.                                      |
| `--utc`                | all        | Print times in UTC instead of your local time zone (JSON is always UTC).                                  |
| `--json`               | all        | Print JSON on stdout: the page, or one entry per line with `--follow`.                                    |
| `--project <ID>`, `-p` | all        | Project to use. Default: the [linked](/docs/cli/link) project.                                            |

See also the [global options](/docs/cli/global-options).

## Permissions

- Logs are read-only. Every project member can read them, whatever their role.
- Commands work with a `flexkit login` session and with project API tokens of any role, so a CI job can check for failed webhook deliveries with `FLEXKIT_TOKEN`.

## Notes

- Paging with `--before` works at whole seconds: the next page can repeat a few entries from the second where the previous page ended. When a whole page falls within one second, the next page starts before that second so paging keeps moving, and entries of that second beyond the page are skipped; raise `--limit` or narrow the range to see them all.
- A single `--follow` check returns at most 500 entries. If more arrive within one interval, lower `--interval` or narrow the filters.
- Webhook logs can't be filtered by webhook id yet; filter the JSON output by `webhook_id` with `jq` instead.


---

[View full sitemap](/docs/sitemap.md)
