# Read run logs (/en/docs/api/native/automation/listRunLogs)





Return a log page within the 30-day retention window by default. Accept: text/event-stream opens a live stream using event: log; id is the resume cursor and Last-Event-ID takes precedence over cursor. : ping arrives every 20 seconds and event: end closes the stream after a terminal run.

`GET /automation/v1/runs/{id}/logs`

## Authentication [#authentication]

`Authorization: Bearer $PRAXIS_API_KEY`

## Request fields [#request-fields]

| Parameter | Type | Description |
| --- | --- | --- |
| path: id | `string` | required; Run ID (run_). |
| query: limit | `integer` | optional; Run ledger page size: integer 1–200, default 50; other collections are capped at 100. minimum: 1; maximum: 200 |
| query: cursor | `string` | optional; Opaque next_cursor from the previous page; keep the original filters when paging. |
| header: Accept | `"application/json"` / `"text/event-stream"` | optional; application/json (default) reads a ledger page; text/event-stream subscribes to the live stream. |
| header: Last-Event-ID | `string` | optional; SSE resume cursor; read entries after this event. Takes precedence over cursor and applies only to streams. |

## Examples [#examples]

[SDK installation and example environment](/en/docs/api/native/automation)

Set these environment variables to your own resources:

| Variable | Source |
| --- | --- |
| RUN_ID | [Run id; suspend/resume require a workflow; cancel requires a nonterminal run](/en/docs/api/native/automation/createRun) |

```bash
: "${RUN_ID:?Set RUN_ID}"
curl --fail-with-body -X GET "https://api.deepraxis.ai/automation/v1/runs/${RUN_ID}/logs" \
  -H "Authorization: Bearer $PRAXIS_API_KEY" \
  -H "Accept: text/event-stream"
```

```typescript
import { createAutomationClient } from '@deepraxis/sdk/automation';

function env(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Set ${name}`);
  return value;
}
const automation = createAutomationClient({
  apiKey: env('PRAXIS_API_KEY'),
  baseUrl: 'https://api.deepraxis.ai',
  maxRetries: 0,
  timeoutMs: 90_000,
});
for await (const event of automation.runs.logs({
  "path": {
    "id": env("RUN_ID")
  }
})) {
  console.log(event);
}
```

## Response [#response]

### HTTP 200 [#http-200]

Success

`application/json`

| Field | Type | Description |
| --- | --- | --- |
| data | `object[]` | required; Log lines (LogLine) on this page, in time order. |
| data[].cursor | `string` | required; Cursor of this line; use it as cursor to page, or as Last-Event-ID to resume an SSE stream. |
| data[].ts | `string` | required; Time the line was logged (RFC 3339 UTC). |
| data[].level | `"debug"` / `"info"` / `"warn"` / `"error"` | required; Log level. debug is diagnostic detail; info is general information; warn is a warning; error is an error. |
| data[].message | `string` | required; Log message text. |
| next_cursor | `null` / `string` | required; Cursor for the next page: pass it unchanged as cursor with the same filters; null when there are no more pages. No total is returned. |

`text/event-stream`

| Field | Type | Description |
| --- | --- | --- |
| id | `string` | optional; Resume cursor of this entry; send it back as Last-Event-ID, or as cursor on the JSON form, to continue after it. Absent on the end event. |
| event | `"log"` / `"end"` | required; SSE event name: log carries one log line in data; end is sent once when the run has reached a terminal status and closes the stream. |
| data | `object` / `object` | required; Decoded JSON of one log line; for the end event, an empty object. |
| data (variant 1).cursor | `string` | required; Cursor of this line; use it as cursor to page, or as Last-Event-ID to resume an SSE stream. |
| data (variant 1).ts | `string` | required; Time the line was logged (RFC 3339 UTC). |
| data (variant 1).level | `"debug"` / `"info"` / `"warn"` / `"error"` | required; Log level. debug is diagnostic detail; info is general information; warn is a warning; error is an error. |
| data (variant 1).message | `string` | required; Log message text. |
|  (variant 1).event | `"log"` | optional; SSE event name: log, one log line is carried in data. |
|  (variant 1).data | `object` | optional; One log line produced by a run, retained for 30 days. no additional fields. |
|  (variant 1).data.cursor | `string` | required; Cursor of this line; use it as cursor to page, or as Last-Event-ID to resume an SSE stream. |
|  (variant 1).data.ts | `string` | required; Time the line was logged (RFC 3339 UTC). |
|  (variant 1).data.level | `"debug"` / `"info"` / `"warn"` / `"error"` | required; Log level. debug is diagnostic detail; info is general information; warn is a warning; error is an error. |
|  (variant 1).data.message | `string` | required; Log message text. |
|  (variant 2).event | `"end"` | optional; SSE event name end: sent once when the run has reached a terminal status, and the stream then closes. |
|  (variant 2).data | `object` | optional; Always an empty object for the end event. |

### Measured response [#measured-response]

HTTP 200

```text
event: end
data: {}


```

## Errors [#errors]

| HTTP | Codes and description |
| --- | --- |
| 400 | INVALID_PARAMS: Invalid request parameters, path, cursor, or body format. |
| 404 | RUN_NOT_FOUND: The run does not exist or is not visible to this tenant. |
| default | RFC 9457 automation problem. 429 includes Retry-After. |

[Authentication and common errors](/en/docs/api/errors) · Retain the `X-Request-Id` response header for troubleshooting.
