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

# Logs

> List, search, and tail workspace runtime logs across requests, capability calls, agent runs, and error traces.

export const ErrorTable = ({errors}) => <div className="gv-error-table" role="table" aria-label="Errors and fixes">
    <div className="gv-error-table__head" role="row">
      <span className="gv-error-table__col-head" role="columnheader">Error</span>
      <span className="gv-error-table__col-head" role="columnheader">Cause</span>
      <span className="gv-error-table__col-head" role="columnheader">Fix</span>
    </div>
    {errors.map((err, i) => <div className="gv-error-table__row" role="row" key={i}>
        <code className="gv-error-table__code" role="cell">{err.code}</code>
        <div className="gv-error-table__cause" role="cell">{err.cause}</div>
        <div className="gv-error-table__fix" role="cell">{err.fix}</div>
      </div>)}
  </div>;

export const Def = ({term, type, defaultValue, required, children}) => <>
    <dt className="gv-def-list__term">
      <span className="gv-def-list__name">{term}</span>
      {type && <span className="gv-def-list__type">{type}</span>}
      {required && <span className="gv-def-list__required">required</span>}
      {defaultValue !== undefined && <span className="gv-def-list__default">
          default <code>{defaultValue}</code>
        </span>}
    </dt>
    <dd className="gv-def-list__description">{children}</dd>
  </>;

export const DefList = ({children}) => <dl className="gv-def-list">{children}</dl>;

export const ExpectedOutput = ({caption = "Expected output", children}) => <div className="gv-output">
    <div className="gv-output__label">
      <svg className="gv-output__icon" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <polyline points="15 10 20 15 15 20" />
        <path d="M4 4v7a4 4 0 0 0 4 4h12" />
      </svg>
      <span>{caption}</span>
    </div>
    <div className="gv-output__body">{children}</div>
  </div>;

export const APIBadge = ({method = "GET", path, scope}) => {
  const m = method.toUpperCase();
  return <span className="gv-api-badge">
      <span className={`gv-api-badge__method gv-api-badge__method--${m.toLowerCase()}`}>
        {m}
      </span>
      <code className="gv-api-badge__path">{path}</code>
      {scope && <span className="gv-api-badge__scope">
          <span className="gv-api-badge__scope-label">scope</span>
          <code>{scope}</code>
        </span>}
    </span>;
};

export const Eyebrow = ({label, tone = "default"}) => <div className={`gv-eyebrow gv-eyebrow--${tone}`}>
    <span className="gv-eyebrow__bar" aria-hidden="true" />
    <span className="gv-eyebrow__label">{label}</span>
  </div>;

<Eyebrow label="RESOURCE" />

The Logs resource exposes your workspace's runtime log stream. Entries cover inbound requests, capability calls, agent run output, and error traces. Three access patterns are available — paginated listing with time-range filters, full-text search with structured filters, and live tail. By the end of this page you will know which endpoint matches which question.

## A log entry in shape

<ExpectedOutput>
  ```json theme={null}
  {
    "ts":         "2026-03-12T10:14:32.441Z",
    "level":      "error",
    "source":     "capability",
    "message":    "send-email: SMTP connection timeout",
    "request_id": "req_01H..."
  }
  ```
</ExpectedOutput>

Use `request_id` to correlate entries across a single inbound request.

## Endpoints

<APIBadge method="GET" path="/v1/workspaces/{slug}/logs" scope="logs:read" />

List entries with cursor pagination and time-range filters.

<APIBadge method="GET" path="/v1/workspaces/{slug}/logs/search" scope="logs:read" />

Full-text query with structured filters.

<APIBadge method="GET" path="/v1/workspaces/{slug}/logs/tail" scope="logs:read" />

Stream new entries as they arrive.

## Which one to call

<DefList>
  <Def term="Walk a time range backwards">Use `/logs` with `since`, `until`, `limit`, `cursor`.</Def>
  <Def term="Find specific errors or trace a request id">Use `/logs/search` with `q`, `level`, `source`, `since`, `until`.</Def>
  <Def term="Watch activity as it happens">Use `/logs/tail`.</Def>
</DefList>

## Filter parameters

<DefList>
  <Def term="since" type="string (ISO 8601)">Applies to list and search. Return entries at or after this time.</Def>
  <Def term="until" type="string (ISO 8601)">Applies to list and search. Return entries before this time.</Def>
  <Def term="cursor" type="string">Applies to list and search. Standard pagination cursor from `next_cursor`.</Def>
  <Def term="limit" type="integer">Applies to list and search. Number of entries per page.</Def>
  <Def term="q" type="string">Search only. Full-text query against the `message` field.</Def>
  <Def term="level" type="string">Search only. One of `debug`, `info`, `warn`, `error`.</Def>
  <Def term="source" type="string">Search only. The producing component — typically `request`, `capability`, or `agent`.</Def>
</DefList>

## Tail protocol

`GET /logs/tail` streams entries with the same shape as `/logs` — one entry per event. Each carries `ts`, `level`, `source`, `message`, and `request_id`.

```bash theme={null}
curl -N "https://api.gavai.app/v1/workspaces/acme/logs/tail" \
  -H "Authorization: Bearer gak_live_xxxxxxxxxxxxx"
```

## Common errors

<ErrorTable
  errors={[
{ code: "403 insufficient_scope", cause: "Token lacks `logs:read`.", fix: "Mint a token with `logs:read`." },
{ code: "404 not_found", cause: "No workspace with this slug accessible to the token.", fix: "Verify the slug and that the token can see the workspace." },
]}
/>

## Related

<Card title="Deployments" icon="rocket" href="/api-reference/resources/deployments">
  List deployments, inspect status, cancel in-flight builds, or promote to live.
</Card>
