# Scores API

The Scores API allows you to retrieve score data (evaluations, annotations, and API-ingested scores) from Langfuse for use in custom workflows, evaluation pipelines, and analytics.

If you need aggregated score metrics (e.g., average scores grouped by trace name, user, or time period) rather than individual scores, the [Metrics API](/content/docs/metrics/features/metrics-api/index.html) is designed for this and avoids the need to fetch and aggregate raw data yourself.

For general information about API authentication, base URLs, and SDK access, see the [Public API documentation](/content/docs/api-and-data-platform/features/public-api/index.html).

This page covers reading scores. Scores are created via `POST /api/public/scores` or the SDK helpers; see [scores via API/SDK](/content/docs/evaluation/evaluation-methods/scores-via-sdk/index.html).

## Scores API v3

Where is this feature available?

- Hobby: Available
- Core: Available
- Pro: Available
- Enterprise: Available
- Self Hosted: Langfuse v3.179.0+

```
GET /api/public/v3/scores
```

Responses carry a single typed `value` field, and results are paginated with a cursor.

### `value` Field

Every score carries exactly one `value`. Its type is determined by the score's `dataType`:

| `dataType`   | `value` type | Notes |
|--------------|--------------|-------|
| `NUMERIC`    | number       |       |
| `BOOLEAN`    | boolean      |       |
| `CATEGORICAL`| string       | The category |
| `TEXT`       | string       |       |
| `CORRECTION` | string       | Empty string if no correction |

If your pipeline handles mixed score types, branch on `dataType`.

### Field Groups

Responses always include a lean core (`id`, `projectId`, `name`, `value`, `dataType`, `source`, `timestamp`, `environment`, `createdAt`, `updatedAt`), and you opt into additional groups via a comma-separated `fields` parameter:

```
?fields=details,subject,annotation
```

| Group | Fields |
|-------|--------|
| core | Always included (see above) |
| `details` | comment, configId, metadata |
| `subject` | subject (the entity the score is attached to, see below) |
| `annotation` | authorUserId, queueId |

Unknown group names return HTTP 400.

### `subject` Object

Every score is attached to exactly one entity. Request the `subject` field group to see which one; it is discriminated by `kind`:

```
{ "kind": "observation", "id": "obs-1", "traceId": "trace-1" }
```

- `kind: "trace"`: `id` is the trace ID
- `kind: "observation"`: `id` is the observation ID; includes the parent `traceId`
- `kind: "session"`: `id` is the session ID
- `kind: "experiment"`: `id` is the dataset run ID

### Cursor-Based Pagination

1. Make your initial request with a `limit` parameter (default 50, max 100)
2. If more results exist, the response includes a `cursor` in the `meta` object
3. Pass this cursor via the `cursor` parameter in your next request, repeating the same filter parameters as the initial request (the cursor encodes only the read position, not your query)
4. Repeat until no cursor is returned (you've reached the end)

For recurring full exports to your data warehouse, use the [scheduled blob storage export](/content/docs/api-and-data-platform/features/export-to-blob-storage/index.html) instead of paginating through the API.

### Filtering

- **Multi-value filters:** most filters accept comma-separated lists: `id`, `name`, `source`, `dataType`, `environment`, `configId`, `queueId`, `authorUserId`, `traceId`, `sessionId`, `observationId`, `experimentId`. Values within one parameter are OR-ed; parameters are AND-ed: `name=hallucination,toxicity&source=EVAL` returns eval scores named either `hallucination` or `toxicity`.
- **Value filters:** use `value` for exact matches (comma-separated, requires a single `dataType` of `NUMERIC`, `BOOLEAN`, or `CATEGORICAL`) or `valueMin`/`valueMax` for inclusive numeric range bounds (require `dataType=NUMERIC`).
- **Mutual exclusivity:** `traceId`, `sessionId`, and `experimentId` are mutually exclusive. `observationId` requires `traceId` because observation IDs are scoped to a trace.
- **Case-insensitive enums:** `source` and `dataType` accept any casing (`numeric` and `NUMERIC` are equivalent).
- **Timestamp bounds:** `fromTimestamp` is inclusive, `toTimestamp` is exclusive.

Invalid filter combinations are rejected with HTTP 400 rather than silently ignored.

### Common Use Cases

**Pulling failing evals:**
```
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?name=hallucination,toxicity&dataType=NUMERIC&valueMax=0.5"
```

**Getting scores for specific traces, including what they are attached to:**
```
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?traceId=trace-1,trace-2&fields=details,subject"
```

**Fetching a single score by ID:**
```
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?id=your-score-id"
```

**Paginating through results:**
```
# First request
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?fromTimestamp=2026-06-01T00:00:00Z&limit=100"

# Response includes: "meta": { "limit": 100, "cursor": "eyJsYXN0..." }

# Next request with cursor
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?fromTimestamp=2026-06-01T00:00:00Z&limit=100&cursor=eyJsYXN0..."
```

### SDK Access

The generated SDK clients expose the v3 endpoint directly. Score creation uses separate SDK helpers (e.g. `create_score` in Python); this client is for reads.

Python SDK:
```
from langfuse import get_client

langfuse = get_client()

# v3 (recommended)
scores = langfuse.api.scores_v3.get_many_v3(
    name="hallucination,toxicity",
    data_type="NUMERIC",
    value_max=0.5,
    fields="details,subject",
    limit=100,
)
```

Also available as async via `langfuse.async_api.scores_v3.get_many_v3(...)`.

### Parameters

| Parameter      | Type     | Description |
|----------------|----------|-------------|
| `limit`        | integer  | Number of items per page. Defaults to 50, max 100 (larger values return HTTP 400) |
| `cursor`       | string   | URL-safe base64 cursor for pagination (from previous response) |
| `fields`       | string   | Comma-separated field groups to include in addition to core: `details`, `subject`, `annotation` |
| `id`           | string   | Comma-separated list of score IDs |
| `name`         | string   | Comma-separated list of score names |
| `source`       | string   | Comma-separated list of score sources (`API`, `ANNOTATION`, `EVAL`), case-insensitive |
| `dataType`     | string   | Comma-separated list of data types (`NUMERIC`, `BOOLEAN`, `CATEGORICAL`, `TEXT`, `CORRECTION`), case-insensitive. Must be a single value when combined with `value`, `valueMin`, or `valueMax` |
| `environment`  | string   | Comma-separated list of environments |
| `configId`     | string   | Comma-separated list of score config IDs |
| `queueId`      | string   | Comma-separated list of annotation queue IDs |
| `authorUserId` | string   | Comma-separated list of author user IDs |
| `value`        | string   | Comma-separated list of exact values. Requires a single `dataType` of `NUMERIC`, `BOOLEAN`, or `CATEGORICAL`. For `BOOLEAN` pass `true` or `false`; for `NUMERIC` each value must be a finite number |
| `valueMin`     | number   | Inclusive lower bound on the numeric value. Requires `dataType=NUMERIC` |
| `valueMax`     | number   | Inclusive upper bound on the numeric value. Requires `dataType=NUMERIC` |
| `traceId`      | string   | Comma-separated list of trace IDs. Mutually exclusive with `sessionId`, `experimentId` |
| `sessionId`    | string   | Comma-separated list of session IDs. Mutually exclusive with `traceId`, `observationId`, `experimentId` |
| `observationId`| string   | Comma-separated list of observation IDs. Requires `traceId` |
| `experimentId` | string   | Comma-separated list of dataset run IDs (experiment IDs). Mutually exclusive with `traceId`, `sessionId`, `observationId` |
| `fromTimestamp`| datetime | Inclusive lower bound on the score timestamp |
| `toTimestamp`  | datetime | Exclusive upper bound on the score timestamp |

### Sample Response

With `fields=details,subject,annotation`:
```json
{
  "data": [
    {
      "id": "score-1",
      "projectId": "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a",
      "name": "hallucination",
      "value": 0.25,
      "dataType": "NUMERIC",
      "source": "EVAL",
      "timestamp": "2026-06-15T10:30:00Z",
      "environment": "default",
      "createdAt": "2026-06-15T10:30:01Z",
      "updatedAt": "2026-06-15T10:30:01Z",
      "comment": "Low hallucination risk",
      "configId": null,
      "metadata": {},
      "authorUserId": null,
      "queueId": null,
      "subject": {
        "kind": "observation",
        "id": "support-chat-7-950dc53a-gen",
        "traceId": "support-chat-7-950dc53a"
      }
    },
    {
      "id": "score-2",
      "projectId": "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a",
      "name": "helpful",
      "value": true,
      "dataType": "BOOLEAN",
      "source": "ANNOTATION",
      "timestamp": "2026-06-15T11:00:00Z",
      "environment": "default",
      "createdAt": "2026-06-15T11:00:02Z",
      "updatedAt": "2026-06-15T11:00:02Z",
      "comment": null,
      "configId": "cfg-1",
      "metadata": {},
      "authorUserId": "user-123",
      "queueId": "queue-1",
      "subject": {
        "kind": "trace",
        "id": "support-chat-7-950dc53a"
      }
    }
  ],
  "meta": {
    "limit": 50,
    "cursor": "eyJ2IjoxLCJsYXN0VGltZXN0YW1wIjoiMjAyNi0wNi0xNVQxMTowMDowMFoiLCJsYXN0SWQiOiJzY29yZS0yIn0"
  }
}
```
