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

# Read a run log

> Returns a run's log, the text its phases and agents wrote. Send just `run_id` for the
whole log. To follow a running run, send `after_id` (start with `0`): each reply has at
most one chunk of up to 64 KB and its end offset as `id`; send that as the next
`after_id` until `run_state` is finished and no chunk comes back. Sending `limit` also
turns on follow mode; its value is not used.

An unknown run is not an error: the reply has an empty log and `run_state: unknown`.

From the CLI: `cliq logs <run>`.

No credential is needed from this machine. From another host, send `Authorization: Bearer` with a dispatch token CliqHub signed for this daemon or a `cliq_tok_…` personal token of a user in the daemon's realm; this only works once the daemon is connected to CliqHub. See [Authentication](/daemon-api/overview#authentication).



## OpenAPI

````yaml /openapi/daemon-by-tag/daemon-runs.yaml post /v1/runs/logs
openapi: 3.1.0
info:
  title: cliqd API
  version: 1.9.48
  description: >-
    HTTP API of `cliqd`, the local Cliq daemon. Generated from the daemon source
    by `scripts/generate_daemon_openapi.mjs` — do not edit by hand. See the
    [overview](/daemon-api/overview).
servers:
  - url: http://127.0.0.1:4900
    description: Local daemon (default port; `CLIQ_DAEMON_PORT` changes it)
security: []
tags:
  - name: Daemon Runs
    description: >-
      Runs on this daemon. Start one with Start a run (Workspaces); everything
      after that is

      here: list runs, read a run's log, phases and tree of sub-runs, follow it
      live, supply

      the inputs a paused run is waiting for, and rerun a finished run from a
      phase.


      Wherever a body takes `run_id` you may also send the run's **name**,
      except the event

      endpoints, which need the id. Run ids are UUIDs.


      A run's life: `running` → (`awaiting_input` ↔ `running`)* → `completed`,
      `failed`,

      `cancelled` or `crashed`.
paths:
  /v1/runs/logs:
    post:
      tags:
        - Daemon Runs
      summary: Read a run log
      description: >-
        Returns a run's log, the text its phases and agents wrote. Send just
        `run_id` for the

        whole log. To follow a running run, send `after_id` (start with `0`):
        each reply has at

        most one chunk of up to 64 KB and its end offset as `id`; send that as
        the next

        `after_id` until `run_state` is finished and no chunk comes back.
        Sending `limit` also

        turns on follow mode; its value is not used.


        An unknown run is not an error: the reply has an empty log and
        `run_state: unknown`.


        From the CLI: `cliq logs <run>`.


        No credential is needed from this machine. From another host, send
        `Authorization: Bearer` with a dispatch token CliqHub signed for this
        daemon or a `cliq_tok_…` personal token of a user in the daemon's realm;
        this only works once the daemon is connected to CliqHub. See
        [Authentication](/daemon-api/overview#authentication).
      operationId: daemon_post_runs_logs
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                run_id:
                  description: Run id or run name
                  type:
                    - string
                    - number
                after_id:
                  description: 'Follow mode: byte offset to read after'
                  type: number
                limit:
                  description: 'Follow mode: switches to chunked reads when set'
                  type: number
              required:
                - run_id
              additionalProperties: {}
            examples:
              whole:
                summary: The whole log
                value:
                  run_id: fix-login-timeout
              follow:
                summary: Follow mode, next chunk after byte 4096
                value:
                  run_id: 0c8d7e6f-5a4b-4c3d-9e2f-1a0b9c8d7e6f
                  after_id: 4096
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                required:
                  - ok
                  - data
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    $ref: '#/components/schemas/RunLog'
              examples:
                whole:
                  summary: Whole log
                  value:
                    ok: true
                    data:
                      run_id: 0c8d7e6f-5a4b-4c3d-9e2f-1a0b9c8d7e6f
                      log: |
                        [review] claude-code started
                        [review] 3 findings written to review.md
                        [review] done in 4m30s
                      run_state: completed
                follow:
                  summary: Follow mode
                  value:
                    ok: true
                    data:
                      chunks:
                        - id: 4180
                          chunk: |
                            [review] done in 4m30s
                      run_state: running
        '400':
          description: >-
            `PAYLOAD_INVALID` — The body (query string for `GET`) fails the
            request schema. `details` lists each issue.


            `BAD_REQUEST` — The body is not valid JSON or is larger than the
            route allows (10 MB; artifact uploads more).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorReply'
              examples:
                PAYLOAD_INVALID:
                  summary: PAYLOAD_INVALID
                  value:
                    ok: false
                    error:
                      code: PAYLOAD_INVALID
                      message: 'run_id: run_id is required'
                      details:
                        - path: run_id
                          message: run_id is required
                BAD_REQUEST:
                  summary: BAD_REQUEST
                  value:
                    ok: false
                    error:
                      code: BAD_REQUEST
                      message: >-
                        Request body could not be read: Unexpected token } in
                        JSON at position 12
        '401':
          description: >-
            `UNAUTHORIZED` — A caller on another host sent no `Authorization:
            Bearer` token, or one that does not verify (expired, wrong
            audience).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorReply'
              examples:
                UNAUTHORIZED:
                  summary: UNAUTHORIZED
                  value:
                    ok: false
                    error:
                      code: UNAUTHORIZED
                      message: Missing or invalid Authorization Bearer token
        '403':
          description: >-
            `WEB_REQUEST_REFUSED` — The request carries an `Origin` header (it
            came from a web page).


            `HOST_NOT_LOCAL` — A loopback caller addressed a `Host` other than
            localhost (DNS rebinding guard).


            `LOCAL_ONLY` — The daemon isn't connected to CliqHub (no dispatch
            key) and the caller is on another host.


            `FORBIDDEN` — A `cliq_tok_…` token's user is not in this daemon's
            realm ACL, or the ACL is not loaded yet.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorReply'
              examples:
                WEB_REQUEST_REFUSED:
                  summary: WEB_REQUEST_REFUSED
                  value:
                    ok: false
                    error:
                      code: WEB_REQUEST_REFUSED
                      message: cliqd doesn't accept requests from web pages
                HOST_NOT_LOCAL:
                  summary: HOST_NOT_LOCAL
                  value:
                    ok: false
                    error:
                      code: HOST_NOT_LOCAL
                      message: cliqd only answers requests addressed to localhost
                LOCAL_ONLY:
                  summary: LOCAL_ONLY
                  value:
                    ok: false
                    error:
                      code: LOCAL_ONLY
                      message: >-
                        This cliqd isn't connected to CliqHub yet, so from
                        another machine it only accepts a local token (minted by
                        tokens/create on the machine running cliqd)
                FORBIDDEN:
                  summary: FORBIDDEN
                  value:
                    ok: false
                    error:
                      code: FORBIDDEN
                      message: Access denied — identity not in realm ACL
        '500':
          description: >-
            `INTERNAL_ERROR` — An unexpected daemon fault. The message names the
            request id; the cause is in the cliqd log.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorReply'
              examples:
                INTERNAL_ERROR:
                  summary: INTERNAL_ERROR
                  value:
                    ok: false
                    error:
                      code: INTERNAL_ERROR
                      message: >-
                        cliqd hit an unexpected error (request 7f3a…). Details
                        are in the cliqd log.
      security:
        - {}
        - DaemonBearer: []
components:
  schemas:
    RunLog:
      description: >
        Without `after_id` / `limit`: the whole log (`run_id`, `log`,
        `run_state`).

        With either: follow mode, the next chunk (`chunks`, `run_state`).
      oneOf:
        - type: object
          title: Whole log
          required:
            - run_id
            - log
            - run_state
          properties:
            run_id:
              type: string
              description: The run id (or the reference you sent, when no run matched).
              example: 0c8d7e6f-5a4b-4c3d-9e2f-1a0b9c8d7e6f
            log:
              type: string
              description: The log text. Empty when the run has no log or does not exist.
            run_state:
              type: string
              description: The run's state, or `unknown` when no run matches.
              enum:
                - running
                - awaiting_input
                - completed
                - failed
                - cancelled
                - crashed
                - unknown
        - type: object
          title: Follow mode
          required:
            - chunks
            - run_state
          properties:
            chunks:
              type: array
              description: >-
                Zero or one chunk. Empty when there is nothing after `after_id`
                yet.
              items:
                type: object
                required:
                  - id
                  - chunk
                properties:
                  id:
                    type: integer
                    description: >-
                      Byte offset after this chunk. Send it as `after_id` next
                      time.
                    example: 4096
                  chunk:
                    type: string
                    description: Up to 64 KB of log text.
            run_state:
              type: string
              enum:
                - running
                - awaiting_input
                - completed
                - failed
                - cancelled
                - crashed
                - unknown
              description: >-
                Stop following once this is a finished state and `chunks` is
                empty.
    ErrorReply:
      type: object
      description: >-
        Every failure. Switch on `error.code` — it is stable; `message` is for
        people and may change.
      required:
        - ok
        - error
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable error code. See [Errors](/daemon-api/errors).
              example: TEAM_NOT_FOUND
            message:
              type: string
              description: What went wrong and, where possible, what to do.
              example: Team 'acme/code-review' not found
            details:
              description: >-
                Structured detail when there is some: the list of schema issues
                for `PAYLOAD_INVALID`, the agent problems for
                `TEAM_AGENT_CONFIG_REQUIRED`, …
  securitySchemes:
    DaemonBearer:
      type: http
      scheme: bearer
      description: >-
        Not needed from the same machine. From another host: a dispatch JWT
        CliqHub signed for this daemon, or a `cliq_tok_…` personal token whose
        user is in the daemon's realm.

````

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