---
title: "Export Eval Runs"
method: POST
path: "/api/platform/v1/evals/export"
tags: ["observability"]
---

# Export Eval Runs

`POST /api/platform/v1/evals/export`

## Request

- Base URL: `https://docs.amdahl.ai`
- URL: `https://docs.amdahl.ai/api/platform/v1/evals/export`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Pull this workspace's graded eval runs as flat rows for analysis elsewhere. Use when you need many runs at once rather than one verdict: filter by eval, version, date range, status and verdict, and read back a row per run carrying the score alongside the fields that qualify it. Pass count_only to learn how many runs match — and how many instrument versions they span — before pulling them.

## Request body

- object
  - `eval` string: Eval slug or id. Default 'prompt-and-message-eval'. Required in effect — columns and versions are per-eval, so one export covers one eval.
  - `eval_versions` string[]: Restrict to these eval_version values. Omit for every version, but read the version spread on the count first: scores from different versions are produced by different instruments and are not comparable.
  - `from` string: ISO-8601 lower bound on created_at (inclusive).
  - `to` string: ISO-8601 upper bound on created_at (exclusive).
  - `statuses` string[]: Restrict to these run statuses. Omit for every status.
  - `verdicts` string[]: Restrict to these verdict buckets. Omit for every bucket. `ungraded` is a pseudo-bucket for runs carrying no verdict at all - the ones whose overall_score cell is empty - so you can isolate or exclude them; it is not a value any run stores.
  - `count_only` boolean: Return only the count block (total, cap, version spread, date range) without the rows. Cheap enough to call on every filter change.
  - `redact_quotes` boolean: Blank the verbatim customer quotes in the exported verdict. Affects the raw JSONL download only; the flat rows never carry quote text.
  - `allow_truncation` boolean: Proceed when more than 5000 runs match, taking the most recent 5000. Without it an over-cap response is refused rather than silently cut. The .csv / .jsonl file downloads stream and have no cap, so they never need this.
  - `limit` number: Take at most this many runs, most recent first (max 5000 here). A deliberate top-N, not a truncation: it satisfies the cap on its own, so a limited call is never refused for matching a larger set.

## Response `200`

OK

- object
  - `data` object, required
    - `success` boolean, required
    - `eval_slug` string
    - `count` object: total, truncated, max_rows, versions (distinct eval_version values in the set), first_run_at and last_run_at. Read `versions` before pooling: more than one means the rows were scored by more than one instrument.
    - `rows` unknown[]: One flat row per run. Every score ships with the fields that qualify it — overall_score with applicable, lift with lift_reportable, the submitted score with input_simulated. A null score is an empty value, never zero.
      - unknown
    - `scope` string: self (your own runs) or workspace (every run; workspace admins only).
    - `error` object

## Other responses

- `400`: Invalid input - failed schema validation
- `401`: Authentication required
- `403`: Forbidden - missing scope or role
- `500`: Internal server error

---

[API](https://skmtc.dev/amdahl/apis/amdahl-platform-api.md) · [All operations](https://skmtc.dev/amdahl/apis/amdahl-platform-api/llms.txt) · [OpenAPI document](https://skmtc.dev/amdahl/apis/amdahl-platform-api/revisions/d4eee33e2472?raw)
