---
title: Agent Analytics export API
description: "Export sessions, datasets, and evaluator configs for offline evaluation."
product: general
lang: en
token_estimate: 3525
---
# Agent Analytics export API

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

The export API returns production agent data as JSON so you can run evaluations in your own tooling. The API covers sessions, the datasets you curate in Amplitude, and the evaluator configurations you define. An offline pipeline can read the same sessions and the same judging criteria the product uses.

This API is read-only. To send data in, refer to [Send agent events without the AI SDK](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-http-api).

These endpoints aren't part of the OpenAPI-defined [Developer API](https://amplitude.com/docs/apis/developer), so they don't appear in that reference and the `amp` CLI doesn't support them. Call them directly over HTTP.

## Authentication and request requirements

- All endpoints use HTTP Basic authentication. Use your project's API key as the username and the secret key as the password. Refer to [Find your API key and secret key](https://amplitude.com/docs/apis/authentication#find-your-api-key-and-secret-key).
- The authenticated project determines which data you receive. No `project_id` parameter exists, and a key can't request another project's data.
- Pagination cursors are opaque strings. Pass `next_page_token` from the previous response unchanged.
- Keep `sort_order` and all filters identical across every page of one traversal. Pagination reads live data rather than a snapshot, so data that changes during a traversal can change later pages.

## Regions

Send requests to the data center that hosts your project.

| Region | Base URL |
| --- | --- |
| US | `https://developer-api.amplitude.com` |
| EU | `https://developer-api.eu.amplitude.com` |

Keys aren't interchangeable between regions. A US project's key returns `401` against the EU host.

## Lookback and session visibility

Two product rules shape what a response contains, and both apply before pagination:

- **Lookback window**: Your plan's entitlement limits how far back sessions are available. A request for an explicit time range outside that window returns `400` rather than narrowing the range. An organization with no lookback entitlement can't use the session and dataset endpoints. Assign an entitlement before you start.
- **Session cap**: An organization that reached its session cap can't export newer sessions. Sessions already enriched stay available.

Amplitude reports excluded sessions rather than dropping them silently. Collection responses carry an `omissions` array that counts what the filters removed and why.

The two collection endpoints exclude a withheld session and count it in `omissions`. The single-session endpoint returns `403` instead, because there's nothing to omit from.

| Reason | Meaning |
| --- | --- |
| `session_not_found` | A dataset member's session no longer exists. |
| `outside_lookback_window` | The session falls outside your lookback entitlement. |
| `session_cap` | The organization reached its session cap, so Amplitude withholds the session. |

Omission counts describe the whole matching collection, not the current page. The counts repeat on every page, so don't add them across pages.

## List sessions

Returns a paginated list of sessions for the authenticated project, with metadata and human review. Traces, spans, and turns come from the single-session endpoint.

`GET /v1/agent-analytics/export/sessions`

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/sessions' \
-u '{api_key}:{secret_key}'
```

Filter by agent and time range:

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/sessions?agent_name=support-bot&start_time=2026-01-01T00%3A00%3A00Z&end_time=2026-01-31T23%3A59%3A59Z&page_size=100' \
-u '{api_key}:{secret_key}'
```

Fetch the next page:

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/sessions?page_size=100&page_token={next_page_token}' \
-u '{api_key}:{secret_key}'
```

### Query parameters

| Name | Description |
| --- | --- |
| `user_id` | Optional. String. Returns sessions for one user ID. |
| `agent_name` | Optional. String. Returns sessions for one agent. |
| `start_time` | Optional. ISO 8601 string with a timezone offset. Lower bound on session start time, inclusive. A value outside your lookback window returns `400`. |
| `end_time` | Optional. ISO 8601 string with a timezone offset. Upper bound on session start time, inclusive. An end time earlier than the start time returns `400`. |
| `page_size` | Optional. Integer between 1 and 200. Defaults to `50`. |
| `page_token` | Optional. String. Opaque cursor from a previous response's `next_page_token`. |
| `sort_order` | Optional. String. `desc` returns newest sessions first (default). `asc` returns oldest first. Keep `sort_order` consistent across pages. |

### Response

```json
{
  "sessions": [
    {
      "session": {
        "object": "agent_session",
        "id": "string",
        "project_id": "string",
        "user_id": "string",
        "agent_name": "string",
        "start_time": "2026-01-15T10:00:00.000Z",
        "end_time": "2026-01-15T10:04:12.000Z",
        "duration_ms": 252000,
        "num_traces": 3,
        "num_errors": 0,
        "models_used": ["string"],
        "total_input_tokens": 2406,
        "total_output_tokens": 225,
        "total_cost_usd": 0.001285,
        "status": "enriched",
        "enrichment_status": "completed",
        "last_message": "string",
        "metadata": {}
      },
      "human_review": { "comments": [], "tags": [] }
    }
  ],
  "next_page_token": "string",
  "omissions": [{ "reason": "session_cap", "count": 12 }]
}
```

| Property | Description |
| --- | --- |
| `sessions[].session.id` | Session identifier. Use this value as `{session_id}` when you request a single session. |
| `sessions[].session.duration_ms` | Wall-clock duration of the session in milliseconds. |
| `sessions[].session.status` | Lifecycle state of the session, such as `closed` or `enriched`. |
| `sessions[].session.enrichment_status` | State of quality-signal enrichment, such as `pending` or `completed`. |
| `sessions[].session.last_message` | The final message in the conversation, when message content is available. |
| `sessions[].human_review` | Comments and tags reviewers added in Amplitude. |
| `next_page_token` | Cursor for the next page. Absent on the last page. |
| `omissions` | Counts of sessions the filters removed, by reason. |

## Get one session

Returns one session with its full traces, spans, sanitized turns, enrichments, and dataset memberships.

`GET /v1/agent-analytics/export/sessions/{session_id}`

Use the `id` from the session list. Session IDs are the identifiers your instrumentation sends, not the numeric row IDs shown elsewhere in Amplitude.

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/sessions/{session_id}' \
-u '{api_key}:{secret_key}'
```

### Response

```json
{
  "session": { "object": "agent_session" },
  "traces": [
    {
      "object": "agent_trace",
      "id": "string",
      "spans": [
        {
          "object": "agent_span",
          "id": "string",
          "name": "llm_completion",
          "attributes": {},
          "raw_input": "string",
          "raw_output": "string"
        }
      ]
    }
  ],
  "turns": [
    {
      "object": "agent_turn",
      "id": "string",
      "trace_id": "string",
      "turn_index": 1,
      "role": "user",
      "latency_ms": 0,
      "created_at": "2026-01-15T10:00:00.000Z"
    }
  ],
  "enrichments": [{ "object": "agent_session_enrichment" }],
  "datasets": [],
  "human_review": { "comments": [], "tags": [] },
  "conversation_turn_count": 4,
  "shared_attributes": {}
}
```

| Property | Description |
| --- | --- |
| `traces[].spans[].attributes` | Span attributes as your instrumentation sent them. The key set varies by SDK and agent. |
| `traces[].spans[].raw_input` | Input text for the span, when message content is available. |
| `traces[].spans[].raw_output` | Output text for the span, when message content is available. |
| `turns` | Ordered turn records. Message content lives on the spans, not on turns. |
| `turns[].created_at` | Timestamp of the turn. Sort on this value to reconstruct the conversation in order. |
| `enrichments` | Quality signals, topic classifications, and rubric scores Amplitude computed. |
| `datasets` | Datasets this session belongs to. |
| `conversation_turn_count` | Number of user-facing conversation turns. |
| `shared_attributes` | Deduplicated span attributes. Refer to [Shared attributes](#shared-attributes). |

### Shared attributes

A span attribute that repeats across spans, such as a system prompt or a tool definition, is stored once in the session-level `shared_attributes` map. Each occurrence carries a reference in place of the value:

```json
{ "$shared_attribute": "a1b2c3d4" }
```

Resolve a reference by looking up its value in `shared_attributes`. Deduplication is lossless, and it can reduce a response from several megabytes to a few hundred kilobytes. A session with nothing repeated returns `shared_attributes` as an empty object.

A session too large to return in one response fails with `400` rather than returning partial data. An export never silently truncates traces or turns.

## Get a dataset

Returns a dataset with a paginated list of its member sessions, including ground-truth labels and human review.

`GET /v1/agent-analytics/export/datasets/{dataset_id}`

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/datasets/{dataset_id}?page_size=50' \
-u '{api_key}:{secret_key}'
```

### Query parameters

| Name | Description |
| --- | --- |
| `page_size` | Optional. Integer between 1 and 200. Defaults to `50`. |
| `page_token` | Optional. String. Opaque cursor from a previous response's `next_page_token`. |
| `sort_order` | Optional. String. `desc` (default) or `asc`, ordered by when the session was added to the dataset. |

Session filters such as `user_id` and `agent_name` aren't valid on this endpoint and return `400`.

### Response

```json
{
  "dataset": {
    "object": "agent_dataset",
    "id": "string",
    "project_id": "string",
    "name": "string",
    "description": "string",
    "agent_name": "string",
    "source_type": "manual",
    "created_at": "2026-01-15T10:00:00.000Z",
    "updated_at": "2026-01-15T10:00:00.000Z"
  },
  "members": [
    {
      "object": "agent_dataset_member",
      "session_id": "string",
      "added_at": "2026-01-15T10:00:00.000Z",
      "selection_reason": "string",
      "ground_truth_labels": {
        "evaluator_results": {},
        "overridden_evaluators": [],
        "review_status": "partial",
        "reviewed_by": "string",
        "reviewed_at": "2026-01-15T10:00:00.000Z"
      },
      "session": { "object": "agent_session" },
      "human_review": { "comments": [], "tags": [] }
    }
  ],
  "next_page_token": "string",
  "omissions": []
}
```

| Property | Description |
| --- | --- |
| `members[].ground_truth_labels` | Human-verified labels for this session. `evaluator_results` maps evaluator ID to its verified verdict, and `overridden_evaluators` lists the evaluators a reviewer corrected. |
| `members[].ground_truth_labels.review_status` | How complete the review is, such as `partial` or `verified`. |
| `members[].session` | Session metadata, in the same shape the session list returns. |

Each member carries session metadata only. Request the session individually for its traces and turns.

## Get an evaluator configuration

Returns one evaluator configuration, including its prompt, model, and labels, so you can reproduce the same judgment in your own tooling.

`GET /v1/agent-analytics/export/evaluators/{evaluator_id}`

This endpoint doesn't read session data, so the lookback window and session cap don't apply.

```bash
curl 'https://developer-api.amplitude.com/v1/agent-analytics/export/evaluators/{evaluator_id}' \
-u '{api_key}:{secret_key}'
```

### Response

```json
{
  "config": {
    "object": "agent_evaluator",
    "id": "string",
    "project_id": "string",
    "topic": "string",
    "status": "draft",
    "output_type": "binary",
    "run_on": "all",
    "description": "string",
    "tags": [{ "id": "yes", "label": "True", "description": "string", "examples": [] }],
    "prompt": "string",
    "model": "string",
    "evaluation_method": "llm",
    "granularity": "session",
    "created_at": "2026-01-15T10:00:00.000Z",
    "updated_at": "2026-01-15T10:00:00.000Z"
  }
}
```

| Property | Description |
| --- | --- |
| `config.topic` | Display name of the evaluator. |
| `config.status` | Whether the evaluator is `draft` or active. |
| `config.output_type` | Shape of the verdict, such as `binary` or `rubric`. |
| `config.tags` | The labels the evaluator can return, with descriptions and examples. |
| `config.prompt` | The judging prompt, for LLM evaluators. |
| `config.model` | The model the evaluator runs on, for LLM evaluators. |
| `config.evaluation_method` | `llm` for a model-judged evaluator, `code` for a deterministic one. |

## Status and error codes

| Code | Description |
| --- | --- |
| `200 OK` | Successful request. |
| `400 Bad Request` | Invalid parameter, a time range outside your lookback window, a reversed time range, or a session too large to return. |
| `401 Unauthorized` | Missing or invalid credentials, or a key from a different region. |
| `403 Forbidden` | The requested session is withheld by the session cap. Only the single-session endpoint returns this code. |
| `404 Not Found` | No session, dataset, or evaluator with that ID exists in the authenticated project. |
| `429 Too Many Requests` | Rate limit exceeded. Retry after the interval in the `Retry-After` header. |
| `503 Service Unavailable` | Temporary. Retry after the interval in the `Retry-After` header. |

Errors use `application/problem+json` with an `error_code` field and a `retryable` flag.

