---
title: How do I migrate off the deprecated Langfuse APIs?
sidebarTitle: Deprecated API migration
description: Per-endpoint mapping from Langfuse's deprecated REST endpoints and SDK methods to their supported replacements, with parameter mappings, semantic differences, examples, and endpoint references.
tags: [platform, public-api]
---

# Migration of deprecated APIs

This page maps every deprecated Langfuse REST endpoint and the Python and JS/TS SDK methods that call it to their supported replacements. It includes parameter mappings, semantic differences, and before/after examples. Many of these changes follow from the [observations-first data model](/docs/v4): traces and observations are no longer separate entities, and reads are consolidated onto fewer, faster endpoints.

If you access these endpoints through a Langfuse SDK, each section includes the methods in Python SDK v4 and JS/TS SDK v5 that call them. Deprecated Public API methods remain callable in these SDK majors, so replacing them is separate from upgrading the SDK itself. If you still need to upgrade, first follow [Python v3 to v4](/docs/observability/sdk/upgrade-path/python-v3-to-v4) or [JS/TS v4 to v5](/docs/observability/sdk/upgrade-path/js-v4-to-v5), then return here to replace deprecated API methods.

Still need the deprecated endpoints? They are documented in the [reference section below](#endpoints).

This page is also served as plain markdown at `https://langfuse.com/faq/all/deprecated-api-migration.md` for programmatic use, e.g. by coding agents. The section anchors below are stable.

## Quick reference [#quick-reference]

| Deprecated endpoint                                                                                                             | Replacement                                                                | Details                       |
| ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------- |
| `GET /observations`, `GET /observations/{id}`                                                                                   | `GET /v2/observations`                                                     | [Observations](#observations) |
| `GET /traces`, `GET /traces/{id}`                                                                                               | `GET /v2/observations`, filtered by `traceId`                              | [Traces](#traces)             |
| `GET /sessions`, `GET /sessions/{id}`                                                                                           | `GET /v2/observations`, filtered by `sessionId`                            | [Sessions](#sessions)         |
| `GET /metrics`, `GET /metrics/daily`                                                                                            | `GET /v2/metrics`                                                          | [Metrics](#metrics)           |
| `GET /scores`, `GET /scores/{id}`, `GET /v2/scores`, `GET /v2/scores/{id}`                                                      | `GET /v3/scores`                                                           | [Scores](#scores)             |
| `GET /datasets/{name}/runs`, `GET /datasets/{name}/runs/{runName}`                                                              | `GET /experiments`, then `GET /experiment-items`                           | [Dataset runs](#dataset-runs) |
| `GET /dataset-run-items`                                                                                                        | `GET /experiment-items`                                                    | [Dataset runs](#dataset-runs) |
| `DELETE /datasets/{name}/runs/{runName}`                                                                                        | No direct replacement; `DELETE /traces` removes the underlying trace data  | [Dataset runs](#dataset-runs) |
| `POST /dataset-run-items`                                                                                                       | Experiment runner SDK or `POST /otel/v1/traces` with experiment attributes | [Dataset runs](#dataset-runs) |
| Trace and observation events sent to `POST /ingestion`, plus `POST /traces`, `POST /spans`, `POST /generations`, `POST /events` | `POST /otel/v1/traces` (OTLP/HTTP)                                         | [Ingestion](#ingestion)       |

All paths are relative to `/api/public`.

`score-create` events sent to `POST /ingestion` by the current SDKs are not deprecated. They remain supported after the v4 cutover.

If you access the public API from shell scripts or coding agents, the [Langfuse CLI](/docs/api-and-data-platform/features/cli) provides commands for all supported endpoints.
Use at least langfuse-cli version `v1.1.0` to benefit from the new endpoints.

### SDK method quick reference [#sdk-method-quick-reference]

These mappings cover the latest Python SDK v4 and JS/TS SDK v5 method surfaces. The examples use `client` for a Langfuse client instance and `context` for an experiment-action `RunnerContext`. Python exposes the same generated methods asynchronously under `client.async_api`; use the same replacement with `await`. Upgrade within the current major if a replacement is missing: Scores v3 requires Python `4.8.1+` or JS/TS `5.5.0+`, and experiment reads require Python `4.13.1+` or JS/TS `5.10.0+`.

| Area                                            | Python SDK v4                                                                                                                                                                                                                                                                 | JS/TS SDK v5                                                                                                                                                                                                                                                                                          |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Observations](#observations-sdk-methods)       | `client.api.legacy.observations_v1.get_many(...)` / `.get(...)` → `client.api.observations.get_many(...)`                                                                                                                                                                     | `client.api.legacy.observationsV1.getMany(...)` / `.get(...)` and `client.fetchObservation(...)` → `client.api.observations.getMany(...)`                                                                                                                                                             |
| [Traces](#traces-sdk-methods)                   | `client.api.trace.list(...)` / `.get(...)` → `client.api.observations.get_many(...)`                                                                                                                                                                                          | `client.api.trace.list(...)` / `.get(...)` and `client.fetchTraces(...)` / `.fetchTrace(...)` → `client.api.observations.getMany(...)`                                                                                                                                                                |
| [Sessions](#sessions-sdk-methods)               | `client.api.sessions.list(...)` / `.get(...)` → `client.api.observations.get_many(...)`                                                                                                                                                                                       | `client.api.sessions.list(...)` / `.get(...)` and `client.fetchSessions(...)` → `client.api.observations.getMany(...)`                                                                                                                                                                                |
| [Metrics](#metrics-sdk-methods)                 | `client.api.legacy.metrics_v1.metrics(...)` → `client.api.metrics.metrics(...)`. No Python v4 method calls `GET /metrics/daily`.                                                                                                                                              | `client.api.legacy.metricsV1.metrics(...)` → `client.api.metrics.metrics(...)`. No JS/TS v5 method calls `GET /metrics/daily`.                                                                                                                                                                        |
| [Scores](#scores-sdk-methods)                   | `client.api.scores.get_many(...)` / `.get_by_id(...)` → `client.api.scores_v3.get_many_v3(...)`. No Python v4 method reads Scores API v1.                                                                                                                                     | `client.api.scores.getMany(...)` / `.getById(...)` → `client.api.scoresV3.getManyV3(...)`. No JS/TS v5 method reads Scores API v1.                                                                                                                                                                    |
| [Dataset reads](#dataset-read-sdk-methods)      | `client.api.dataset_run_items.list(...)`, `client.api.datasets.get_runs(...)` / `.get_run(...)`, and `client.get_dataset_runs(...)` / `.get_dataset_run(...)` → `client.api.experiments.list(...)` / `.list_items(...)`                                                       | `client.api.datasetRunItems.list(...)`, `client.api.datasets.getRuns(...)` / `.getRun(...)`, and `client.getDatasetRuns(...)` / `.getDatasetRun(...)` → `client.api.experiments.list(...)` / `.listItems(...)`                                                                                        |
| [Dataset writes](#dataset-write-sdk-methods)    | Direct `client.api.dataset_run_items.create(...)` callers should use the experiment runner. Dataset-backed `client.run_experiment(...)`, `dataset.run_experiment(...)`, and `context.run_experiment(...)` currently originate this call inside the SDK; keep the SDK updated. | Direct `client.api.datasetRunItems.create(...)` and `datasetItem.link(...)` callers should use the experiment runner. Dataset-backed `client.experiment.run(...)`, `dataset.runExperiment(...)`, and `context.runExperiment(...)` currently originate this call inside the SDK; keep the SDK updated. |
| [Dataset deletion](#dataset-delete-sdk-methods) | `client.api.datasets.delete_run(...)` and `client.delete_dataset_run(...)` → list experiment items with `client.api.experiments.list_items(...)`, then delete their traces with `client.api.trace.delete_multiple(...)`.                                                      | `client.api.datasets.deleteRun(...)` → list experiment items with `client.api.experiments.listItems(...)`, then delete their traces with `client.api.trace.deleteMultiple(...)`.                                                                                                                      |
| [Ingestion](#ingestion-sdk-methods)             | `client.api.ingestion.batch(...)` for trace and observation events → current SDK tracing, which exports via OpenTelemetry.                                                                                                                                                    | `client.api.ingestion.batch(...)` for trace and observation events → current SDK tracing, which exports via OpenTelemetry.                                                                                                                                                                            |

## Observations [#observations]

**Deprecated:** `GET /observations`, `GET /observations/{observationId}`. Langfuse Cloud serves these endpoints until November 16, 2026 (2026-11-16); migrate to v4 before this date.

**Replacement:** [`GET /v2/observations`](/docs/api-and-data-platform/features/observations-api#v2) ([reference](https://api.reference.langfuse.com/#tag/observationsv2/GET/api/public/v2/observations)).

### SDK methods [#observations-sdk-methods]

| SDK       | Deprecated caller                                       | Use instead                                                                                                  |
| --------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Python v4 | `client.api.legacy.observations_v1.get_many(...)`       | `client.api.observations.get_many(from_start_time=..., to_start_time=...)`                                   |
| Python v4 | `client.api.legacy.observations_v1.get(observation_id)` | `client.api.observations.get_many(filter="<observation ID filter>", from_start_time=..., to_start_time=...)` |
| JS/TS v5  | `client.api.legacy.observationsV1.getMany(...)`         | `client.api.observations.getMany({ fromStartTime, toStartTime })`                                            |
| JS/TS v5  | `client.api.legacy.observationsV1.get(observationId)`   | `client.api.observations.getMany({ filter: "<observation ID filter>", fromStartTime, toStartTime })`         |
| JS/TS v5  | `client.fetchObservation(observationId)`                | `client.api.observations.getMany({ filter: "<observation ID filter>", fromStartTime, toStartTime })`         |

There is no v2 single-observation getter; filter `get_many` / `getMany` by ID and take the matching row. Always bound observation queries with a time range and follow cursor pagination. `client.fetchObservations(...)` is not listed because in JS/TS v5 it already calls Observations API v2.

### Parameter mapping

| Deprecated (v1)                                                                                                               | v2 equivalent                                                                        |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `page`                                                                                                                        | `cursor` (from the previous response's `meta.cursor`)                                |
| `limit` (default 50, max 100)                                                                                                 | `limit` (default 50, max 1,000)                                                      |
| `GET /observations/{observationId}`                                                                                           | `filter` condition on the `id` column                                                |
| `name`, `userId`, `type`, `traceId`, `level`, `parentObservationId`, `environment`, `version`, `fromStartTime`, `toStartTime` | Unchanged; always set `fromStartTime` and `toStartTime` to keep each request bounded |
| -                                                                                                                             | `fields`: comma-separated field groups; defaults to `core,basic`                     |

### Semantic differences

- Responses include only the requested `fields` groups; fields from groups you did not request are **absent**, not `null`. One exception: `modelId`, `inputPrice`, `outputPrice`, and `totalPrice` are always present but `null` unless the `model` field group is requested.
- `input`/`output` are returned as raw strings; parse them in your pipeline when you need JSON (v1 parsed them automatically). The `parseIoAsJson` parameter is deprecated: omit it or set it to `false`; setting it to `true` returns a `400` error.
- Pagination is cursor-based: pass `meta.cursor` from the previous response until no cursor is returned. Results are always sorted by `startTime` descending.
- When the `model` group is requested, `inputPrice`, `outputPrice`, and `totalPrice` are returned as strings (e.g. `"0.000005"`) to preserve decimal precision; cast them to a numeric type in your pipeline.

### Example

```bash
# Before (v1)
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/observations?type=GENERATION&limit=10&page=1"

# After (v2)
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations?type=GENERATION&limit=10&fields=core,basic,usage&fromStartTime=2026-07-01T00:00:00Z&toStartTime=2026-07-16T00:00:00Z"
```

## Traces [#traces]

**Deprecated:** `GET /traces`, `GET /traces/{traceId}`. Langfuse Cloud serves this endpoint until November 16, 2026 (2026-11-16); migrate to v4 before this date.

**Replacement:** [`GET /v2/observations`](/docs/api-and-data-platform/features/observations-api#v2), grouped by `traceId` on the client side.

### SDK methods [#traces-sdk-methods]

| SDK       | Deprecated caller                | Use instead                                                                                   |
| --------- | -------------------------------- | --------------------------------------------------------------------------------------------- |
| Python v4 | `client.api.trace.list(...)`     | `client.api.observations.get_many(from_start_time=..., to_start_time=...)`                    |
| Python v4 | `client.api.trace.get(trace_id)` | `client.api.observations.get_many(trace_id=trace_id, from_start_time=..., to_start_time=...)` |
| JS/TS v5  | `client.api.trace.list(...)`     | `client.api.observations.getMany({ fromStartTime, toStartTime })`                             |
| JS/TS v5  | `client.fetchTraces(...)`        | `client.api.observations.getMany({ fromStartTime, toStartTime })`                             |
| JS/TS v5  | `client.api.trace.get(traceId)`  | `client.api.observations.getMany({ traceId, fromStartTime, toStartTime })`                    |
| JS/TS v5  | `client.fetchTrace(traceId)`     | `client.api.observations.getMany({ traceId, fromStartTime, toStartTime })`                    |

These replacements return observation rows, not the legacy trace response shape. Group them by `traceId` and reconstruct trace-level fields as described below.

### Parameter mapping

| Deprecated (`GET /traces`)     | v2 equivalent                                                      |
| ------------------------------ | ------------------------------------------------------------------ |
| `GET /traces/{traceId}`        | `traceId=<traceId>`                                                |
| `name`                         | `filter` condition on the `traceName` column                       |
| `tags`                         | `filter` condition on the `tags` column (`arrayOptions` type)      |
| `sessionId`                    | `filter` condition on the `sessionId` column                       |
| `userId`                       | `userId` (unchanged)                                               |
| `fromTimestamp`, `toTimestamp` | `fromStartTime`, `toStartTime`                                     |
| `orderBy`                      | Not available; results are always sorted by `startTime` descending |
| `page`                         | `cursor`                                                           |

Request `fields=core,basic,trace_context` to include the trace-level attributes `traceName`, `tags`, and `release` on each row.

### Semantic differences

- **The response contains observation rows, not trace objects.** Group rows by `traceId` to reconstruct trace activity.
- **v4 has no trace-level `input`/`output`.** Reconstruct them from the root observation of each trace: the row with `parentObservationId == null`.
- For trace-level aggregates (counts, costs, latency grouped by `traceName`, `traceRelease`, or `traceVersion`), use the [Metrics API v2](/docs/metrics/features/metrics-api#v2) instead of fetching and aggregating rows yourself.

### Example

```bash
# Before (v1): list traces by name
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/traces" \
  --data-urlencode "name=support-conversation" \
  --data-urlencode "limit=50"

# After (v2): fetch observation rows filtered by trace name, group by traceId
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations" \
  --data-urlencode 'filter=[{"type":"string","column":"traceName","operator":"=","value":"support-conversation"}]' \
  --data-urlencode "fields=core,basic,io,trace_context" \
  --data-urlencode "fromStartTime=2026-07-01T00:00:00Z" \
  --data-urlencode "toStartTime=2026-07-16T00:00:00Z" \
  --data-urlencode "limit=50"
```

## Sessions [#sessions]

**Deprecated:** `GET /sessions`, `GET /sessions/{sessionId}`. Langfuse Cloud serves this endpoint until November 16, 2026 (2026-11-16); migrate to v4 before this date. On Langfuse v4, these will return `404`.

**Replacement:** [`GET /v2/observations`](/docs/api-and-data-platform/features/observations-api#v2) with a `filter` condition on the `sessionId` column, grouped by `sessionId` on the client side.

### SDK methods [#sessions-sdk-methods]

| SDK       | Deprecated caller                     | Use instead                                                                                            |
| --------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Python v4 | `client.api.sessions.list(...)`       | `client.api.observations.get_many(from_start_time=..., to_start_time=...)`, then group by `session_id` |
| Python v4 | `client.api.sessions.get(session_id)` | `client.api.observations.get_many(session_id=session_id, from_start_time=..., to_start_time=...)`      |
| JS/TS v5  | `client.api.sessions.list(...)`       | `client.api.observations.getMany({ fromStartTime, toStartTime })`, then group by `sessionId`           |
| JS/TS v5  | `client.api.sessions.get(sessionId)`  | `client.api.observations.getMany({ sessionId, fromStartTime, toStartTime })`                           |
| JS/TS v5  | `client.fetchSessions(sessionId)`     | `client.api.observations.getMany({ sessionId, fromStartTime, toStartTime })`                           |

Despite its plural name, `fetchSessions(sessionId)` calls the deprecated single-session endpoint. None of these replacements return the legacy session object shape.

### Parameter mapping

| Deprecated (`GET /sessions`)   | v2 equivalent                                |
| ------------------------------ | -------------------------------------------- |
| `GET /sessions/{sessionId}`    | `filter` condition on the `sessionId` column |
| `fromTimestamp`, `toTimestamp` | `fromStartTime`, `toStartTime`               |
| `environment`                  | `environment` (unchanged)                    |
| `page`                         | `cursor`                                     |

### Semantic differences

- The response contains observation rows; a "session" is the set of rows sharing a `sessionId`. Group by `sessionId` (and within a session, by `traceId`) to reconstruct the session structure.
- Like traces, sessions have no dedicated input/output object in v4. Reconstruct the conversation from the root observations of the traces within the session.
- `sessionId` is a high-cardinality field: it is available for **filtering** in the [Metrics API v2](/docs/metrics/features/metrics-api#v2), but not for grouping.

### Example

```bash
# Before (v1): fetch one session
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/sessions/chat-session-42"

# After (v2): fetch the session's observation rows
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations" \
  --data-urlencode 'filter=[{"type":"string","column":"sessionId","operator":"=","value":"chat-session-42"}]' \
  --data-urlencode "fields=core,basic,io" \
  --data-urlencode "fromStartTime=2026-07-01T00:00:00Z" \
  --data-urlencode "toStartTime=2026-07-16T00:00:00Z"
```

## Metrics [#metrics]

**Deprecated:** `GET /metrics` (v1) and `GET /metrics/daily`. Langfuse Cloud serves this endpoint until November 16, 2026 (2026-11-16); migrate to v4 before this date.

**Replacement:** [`GET /v2/metrics`](/docs/metrics/features/metrics-api#v2) ([reference](https://api.reference.langfuse.com/#tag/metricsv2/GET/api/public/v2/metrics)).

### SDK methods [#metrics-sdk-methods]

| SDK       | Deprecated caller                                 | Use instead                             |
| --------- | ------------------------------------------------- | --------------------------------------- |
| Python v4 | `client.api.legacy.metrics_v1.metrics(query=...)` | `client.api.metrics.metrics(query=...)` |
| JS/TS v5  | `client.api.legacy.metricsV1.metrics({ query })`  | `client.api.metrics.metrics({ query })` |

This is not only a method rename: adapt the query as described below. In particular, the removed `traces` view has no drop-in replacement.

### Parameter mapping

The query object structure carries over; the key changes are inside the query:

| Deprecated (v1)                                                    | v2 equivalent                                                                                    |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| `view: "traces"`                                                   | `view: "observations"` with trace-level dimensions (`traceName`, `traceRelease`, `traceVersion`) |
| `view: "observations"`, `"scores-numeric"`, `"scores-categorical"` | Unchanged                                                                                        |
| Grouping by `userId`, `sessionId`, `id`, `traceId`                 | Not available; high-cardinality fields remain available as **filters** only                      |
| Default result size                                                | `config.row_limit` (default 100); set explicitly for larger result sets                          |

### Semantic differences

- **The `traces` view is removed.** In the `observations` view, measures such as `count`, `latency`, `totalCost`, and `totalTokens` are calculated over observation rows, not traces. For trace-level counts, filter on the v2-only `isRootObservation = true` dimension. See [Logical root observations](/docs/api-and-data-platform/features/observations-api#logical-root-observations) for root semantics and trace-counting edge cases. For trace durations or raw per-trace data, use [Observations API v2](/docs/api-and-data-platform/features/observations-api#v2) and group by `traceId` client-side.
- When ordering by an aggregated metric, use the returned field name in the format `{aggregation}_{measure}`, e.g. `sum_totalCost`.

### Example

```bash
# Before (v1): trace count by name
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  --data-urlencode 'query={"view":"traces","metrics":[{"measure":"count","aggregation":"count"}],"dimensions":[{"field":"name"}],"filters":[],"fromTimestamp":"2026-07-01T00:00:00Z","toTimestamp":"2026-07-16T00:00:00Z"}' \
  "https://cloud.langfuse.com/api/public/metrics"

# After (v2): trace count by name
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  --data-urlencode 'query={"view":"observations","metrics":[{"measure":"count","aggregation":"count"}],"dimensions":[{"field":"traceName"}],"filters":[{"column":"isRootObservation","operator":"=","value":true,"type":"boolean"}],"fromTimestamp":"2026-07-01T00:00:00Z","toTimestamp":"2026-07-16T00:00:00Z"}' \
  "https://cloud.langfuse.com/api/public/v2/metrics"
```

### Daily metrics [#daily-metrics-migration]

#### SDK methods [#daily-metrics-sdk-methods]

Python v4 and JS/TS v5 do not expose wrappers for `GET /metrics/daily`. Calls to this route come from direct REST usage or an older SDK. Recreate the query with `client.api.metrics.metrics(...)` as shown below.

`GET /metrics/daily` returned daily cost and usage timeseries broken down by model. Reproduce it with a v2 query using a daily time dimension:

```bash
curl -G \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  --data-urlencode 'query={"view":"observations","metrics":[{"measure":"count","aggregation":"count"},{"measure":"totalCost","aggregation":"sum"},{"measure":"totalTokens","aggregation":"sum"}],"dimensions":[{"field":"providedModelName"}],"timeDimension":{"granularity":"day"},"filters":[],"fromTimestamp":"2026-07-01T00:00:00Z","toTimestamp":"2026-07-16T00:00:00Z"}' \
  "https://cloud.langfuse.com/api/public/v2/metrics"
```

The deprecated endpoint's filters map to v2 `filters` entries: `traceName` and `userId` are available as filter columns; `tags` filters on trace tags.

## Scores [#scores]

**Deprecated:** `GET /scores` (v1), `GET /scores/{scoreId}`, `GET /v2/scores`, `GET /v2/scores/{scoreId}`. Langfuse Cloud serves these endpoints until November 16, 2026 (2026-11-16); migrate to v4 before this date. On Langfuse v4, these will return `404`.

**Replacement:** [`GET /v3/scores`](https://api.reference.langfuse.com/#tag/scores/GET/api/public/v3/scores). See the [Scores API v3 announcement](/changelog/2026-06-10-scores-v3-api) for background.

This migration applies only to score reads. Score writes remain supported through `POST /scores` and the current SDK score helpers. The SDKs batch score writes as `score-create` events through `POST /ingestion`; Langfuse v4 continues to accept those events after the cutover. This also covers evaluations created by the experiment runner and third-party integrations that use the current SDK score helpers. No client update or direct REST workaround is required for these score writes.

### SDK methods [#scores-sdk-methods]

| SDK       | Deprecated caller                       | Use instead                                      |
| --------- | --------------------------------------- | ------------------------------------------------ |
| Python v4 | `client.api.scores.get_many(...)`       | `client.api.scores_v3.get_many_v3(...)`          |
| Python v4 | `client.api.scores.get_by_id(score_id)` | `client.api.scores_v3.get_many_v3(id=score_id)`  |
| JS/TS v5  | `client.api.scores.getMany(...)`        | `client.api.scoresV3.getManyV3(...)`             |
| JS/TS v5  | `client.api.scores.getById(scoreId)`    | `client.api.scoresV3.getManyV3({ id: scoreId })` |

Scores v3 requires Python SDK `4.8.1+` or JS/TS SDK `5.5.0+`. It always returns a list response, including when filtering by ID.

Python v4 and JS/TS v5 do not expose read wrappers for the v1 `GET /scores` or `GET /scores/{id}` endpoints. Calls to those routes come from direct REST usage or an older SDK. Do not migrate current score-creation helpers merely because they send supported `score-create` events through `/ingestion`.

### Parameter mapping

| Deprecated (v1/v2)                                                 | v3 equivalent                                                                                                         |
| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `page`                                                             | `cursor` (from the previous response's `meta`); `limit` max 100                                                       |
| `GET /scores/{scoreId}`, `GET /v2/scores/{scoreId}`                | `id=<scoreId>` filter; there is no get-by-id endpoint in v3                                                           |
| `value` + `stringValue` (split by type)                            | Single `value` field, typed by `dataType`                                                                             |
| `operator` + `value` (numeric comparison)                          | `valueMin` / `valueMax` (inclusive bounds, require `dataType=NUMERIC`)                                                |
| `datasetRunId`                                                     | `experimentId`                                                                                                        |
| `fromTimestamp`, `toTimestamp`                                     | Unchanged names, but `fromTimestamp` is now inclusive and `toTimestamp` exclusive                                     |
| `userId`, `traceTags`                                              | Removed; for trace-level score questions, use the [Metrics API v2](/docs/metrics/features/metrics-api#v2) score views |
| `filter` (JSON, e.g. metadata conditions)                          | Removed; for metadata conditions, request `fields=details` and filter on `metadata` client-side                       |
| `name`, `source`, `dataType`, `environment`, `configId`, `queueId` | Unchanged, and now accept comma-separated lists (OR within a parameter, AND across parameters)                        |

### Semantic differences

- **One typed `value` field.** `NUMERIC` scores return a number, `BOOLEAN` scores a boolean, and `CATEGORICAL`/`TEXT`/`CORRECTION` scores a string; no more parallel `value`/`stringValue` fields.
- **Field groups.** Core fields are always returned; request more via `fields=details,subject,annotation`. The `subject` group replaces the flat `traceId`/`observationId`/`sessionId`/`datasetRunId` response fields with one object describing what the score is attached to (`kind`: `trace`, `observation`, `session`, or `experiment`).
- Use at most one of the `traceId`, `sessionId`, and `experimentId` filters; they cannot be combined. `observationId` requires `traceId` alongside it (observation IDs are scoped to a trace).
- `fromTimestamp` is inclusive; `toTimestamp` is exclusive.
- **No trace joins.** v3 queries scores directly and does not return trace fields (the v2 `trace` field group is gone). For row-level filtering by trace properties, query [Observations API v2](/docs/api-and-data-platform/features/observations-api#v2) with the corresponding filters and `fields=core,trace_context`, collect the distinct trace IDs, then pass them to v3's comma-separated `traceId` filter.
- **Row counts can differ.** v2 silently dropped scores whose referenced trace could not be found (e.g., deleted or never ingested); v3 returns every matching score, so the same query can return more rows on v3.

### Example

```bash
# Before (v2): numeric scores for a trace
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/scores?traceId=trace-123&dataType=NUMERIC"

# After (v3)
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v3/scores?traceId=trace-123&dataType=NUMERIC&fields=details,subject"
```

## Dataset runs → Experiments [#dataset-runs]

**Deprecated:** Langfuse Cloud serves these endpoints until November 16, 2026 (2026-11-16); migrate to v4 before this date.

- `GET /datasets/{datasetName}/runs`
- `GET /datasets/{datasetName}/runs/{runName}`
- `GET /dataset-run-items`
- `DELETE /datasets/{datasetName}/runs/{runName}`
- `POST /dataset-run-items`

"Dataset run" and "experiment" refer to the same concept; Langfuse is standardizing on "experiment" ([terminology note](/faq/all/retrieve-experiment-scores)).

  **Legacy dataset endpoints:** `GET /api/public/datasets` and
  `GET /api/public/datasets/{name}` were replaced by their
  `/api/public/v2/datasets` equivalents independently of this dataset-run
  migration. Python SDK `v2.37.0+` and JS/TS SDK `v4.0.0+` use the v2 endpoints;
  direct API integrations should migrate to v2 as well. The additional `runs`
  property returned by the legacy endpoints does not include v4 experiments.
  Use `GET /experiments` to list experiments. Other dataset response fields
  remain current.

### SDK methods [#dataset-sdk-methods]

Experiment reads require Python SDK `4.13.1+` or JS/TS SDK `5.10.0+`. Both APIs require `fromStartTime` / `from_start_time`; use a timestamp that includes the experiments you need.

#### Read methods [#dataset-read-sdk-methods]

| SDK       | Deprecated caller                                                   | Use instead                                                                                                               |
| --------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Python v4 | `client.api.dataset_run_items.list(...)`                            | `client.api.experiments.list_items(dataset_id=dataset_id, experiment_name=run_name, from_start_time=...)`                 |
| JS/TS v5  | `client.api.datasetRunItems.list(...)`                              | `client.api.experiments.listItems({ datasetId, experimentName: runName, fromStartTime })`                                 |
| Python v4 | `client.api.datasets.get_runs(...)`; `client.get_dataset_runs(...)` | Resolve the dataset ID, then use `client.api.experiments.list(dataset_id=dataset_id, from_start_time=...)`                |
| JS/TS v5  | `client.api.datasets.getRuns(...)`; `client.getDatasetRuns(...)`    | Resolve the dataset ID, then use `client.api.experiments.list({ datasetId, fromStartTime })`                              |
| Python v4 | `client.api.datasets.get_run(...)`; `client.get_dataset_run(...)`   | Use `client.api.experiments.list(...)` for experiment metadata and `client.api.experiments.list_items(...)` for its items |
| JS/TS v5  | `client.api.datasets.getRun(...)`; `client.getDatasetRun(...)`      | Use `client.api.experiments.list(...)` for experiment metadata and `client.api.experiments.listItems(...)` for its items  |

If you already know both the dataset ID and experiment name, `list_items` / `listItems` can retrieve the items directly with those filters. Experiment APIs do not return the legacy combined dataset-run response shape. Follow `meta.cursor` until it is empty: both APIs return 50 rows by default and at most 100 rows per request.

#### Write methods [#dataset-write-sdk-methods]

| SDK       | Deprecated caller                                                                                            | Use instead                                                                                                                                       |
| --------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Python v4 | `client.api.dataset_run_items.create(...)`                                                                   | Use `client.run_experiment(...)` or `dataset.run_experiment(...)`                                                                                 |
| Python v4 | Dataset-backed `client.run_experiment(...)`, `dataset.run_experiment(...)`, or `context.run_experiment(...)` | No user-side code change currently removes this call; the SDK creates the legacy link internally. Keep using the runner and keep the SDK updated. |
| JS/TS v5  | `client.api.datasetRunItems.create(...)`                                                                     | Use `client.experiment.run(...)` or `dataset.runExperiment(...)`                                                                                  |
| JS/TS v5  | `datasetItem.link(...)`                                                                                      | Use `client.experiment.run(...)` or `dataset.runExperiment(...)`                                                                                  |
| JS/TS v5  | Dataset-backed `client.experiment.run(...)`, `dataset.runExperiment(...)`, or `context.runExperiment(...)`   | No user-side code change currently removes this call; the SDK creates the legacy link internally. Keep using the runner and keep the SDK updated. |

The experiment runner is the supported abstraction for creating experiment data. Current runners still call `POST /dataset-run-items` internally for Langfuse dataset items; moving direct callers to the runner makes the application inherit the SDK-side migration when it becomes available.

#### Delete methods [#dataset-delete-sdk-methods]

| SDK       | Deprecated caller                                                       | Use instead                                                                                                       |
| --------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Python v4 | `client.api.datasets.delete_run(...)`; `client.delete_dataset_run(...)` | List experiment items, collect their trace IDs, then call `client.api.trace.delete_multiple(trace_ids=trace_ids)` |
| JS/TS v5  | `client.api.datasets.deleteRun(...)`                                    | List experiment items, collect their trace IDs, then call `client.api.trace.deleteMultiple({ traceIds })`         |

There is no experiment-delete API. Follow cursor pagination through every experiment-item page, deduplicate the trace IDs, then delete them in batches of at most 1,000 per `delete_multiple` / `deleteMultiple` request. Deleting the underlying traces also deletes their observations and related scores, so confirm that this broader deletion matches your intent.

### Read experiment data

Use [`GET /experiments`](https://api.reference.langfuse.com/#tag/experiments) to list experiments or find one by its dataset ID and name. Use `GET /experiment-items?experimentId=<id>` to retrieve the items belonging to an experiment.

### Parameter mapping

| Deprecated                                             | v4 equivalent                                                           |
| ------------------------------------------------------ | ----------------------------------------------------------------------- |
| `{datasetName}` path segment                           | `datasetId` filter; resolve the ID via `GET /v2/datasets/{datasetName}` |
| `{runName}` path segment                               | `name` filter on `GET /experiments`                                     |
| Run items embedded in the run response                 | `GET /experiment-items?experimentId=<id>`                               |
| `GET /dataset-run-items?datasetId=<id>&runName=<name>` | Resolve the experiment with `GET /experiments`, then list its items     |
| `page`                                                 | `cursor`; `limit` max 100                                               |
| -                                                      | `fromStartTime` (**required** on both endpoints), `toStartTime`         |

### Semantic differences

- Experiments are queried by dataset **ID**, not name.
- Item inputs, outputs, and expected outputs are behind the `fields=io` group on `GET /experiment-items`; scores are behind `fields=scores` on both endpoints. This replaces the old workaround of fetching each run item's trace to collect scores.

### Create experiment data

For Python and JS/TS, use the [Experiment runner SDK](/docs/evaluation/experiments/experiments-via-sdk). It applies the required experiment semantics automatically and is the recommended replacement for `POST /dataset-run-items`.

The experiment runner's `Evaluation` results use the supported SDK score-write path. Although the SDK batches them as `score-create` events through `POST /ingestion`, those events remain accepted after the v4 cutover; the legacy ingestion deprecation applies only to trace and observation events.

For other languages, send experiment traces to [`POST /otel/v1/traces`](https://api.reference.langfuse.com/#tag/opentelemetry/POST/api/public/otel/v1/traces) and apply the [required experiment attributes](/integrations/native/opentelemetry/experiments).

### Delete experiment data

Langfuse v4 does not provide an endpoint that deletes only an experiment.

This is not semantically equivalent to the deprecated endpoint: deleting the traces also deletes their observations and related scores. See [Data Deletion](/docs/administration/data-deletion) for details.

### Example

```bash
# Before: fetch a dataset run with its items
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/datasets/my-dataset/runs/my-run"

# After: resolve the dataset ID, find the experiment, then list its items
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/datasets/my-dataset"

curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/experiments?fromStartTime=2026-07-01T00:00:00Z&datasetId=<dataset-id>&name=my-run&fields=core,scores"

curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/experiment-items?fromStartTime=2026-07-01T00:00:00Z&experimentId=<experiment-id>&fields=io,scores"
```

## Ingestion [#ingestion]

**Deprecated for trace and observation ingestion:** trace and observation event types sent to `POST /ingestion`, and the older synchronous endpoints `POST /traces`, `POST /spans`, `POST /generations`, `POST /events`. Langfuse Cloud serves these trace-ingestion paths until November 16, 2026 (2026-11-16); migrate to v4 before this date.

**Replacement:** the OpenTelemetry endpoint [`POST /otel/v1/traces`](https://api.reference.langfuse.com/#tag/opentelemetry/POST/api/public/otel/v1/traces) (OTLP/HTTP), or an upgraded SDK ([Python v4.7.0+](/docs/observability/sdk/upgrade-path/python-v3-to-v4), [JS/TS v5.4.0+](/docs/observability/sdk/upgrade-path/js-v4-to-v5)). Set the `x-langfuse-ingestion-version: 4` header on your OTEL span exporter and propagate trace attributes to all observations; see the [OpenTelemetry integration guide](/integrations/native/opentelemetry).

### SDK methods [#ingestion-sdk-methods]

| SDK       | Deprecated caller                                                  | Use instead                                                                         |
| --------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| Python v4 | `client.api.ingestion.batch(...)` with trace or observation events | Python SDK `4.7.0+` tracing and instrumentation, which export through OpenTelemetry |
| JS/TS v5  | `client.api.ingestion.batch(...)` with trace or observation events | JS/TS SDK `5.4.0+` tracing and instrumentation, which export through OpenTelemetry  |

Score writes are unaffected. Direct REST clients can continue using `POST /scores`. Current Python and JS/TS SDKs intentionally batch score writes as `score-create` events through `POST /ingestion`; Langfuse v4 continues to accept that event type after November 16, 2026 (2026-11-16). No SDK release that reroutes score writes to `POST /scores` is required for compatibility.

## Deprecated endpoints [#endpoints]

These endpoints are deprecated and receive security patches only, no other fixes or new functionality. Langfuse Cloud serves these endpoints until November 16, 2026 (2026-11-16); migrate to v4 before this date.
All paths are relative to `/api/public`.

| Deprecated endpoint(s)                                         | Parameters                                                                                                | Replacement                                                                                                                                                                                                                              |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /traces`, `/traces/{id}`                                  | [API reference](https://api.reference.langfuse.com/#tag/trace/GET/api/public/traces)                      | [Observations API v2, filtered by `traceId`](#traces)                                                                                                                                                                                    |
| `GET /observations`, `/observations/{id}`                      | [API reference](https://api.reference.langfuse.com/#tag/legacyobservationsv1/GET/api/public/observations) | [Observations API v2](#observations)                                                                                                                                                                                                     |
| `GET /sessions`, `/sessions/{id}`                              | [API reference](https://api.reference.langfuse.com/#tag/sessions/GET/api/public/sessions)                 | [Observations API v2, filtered by `sessionId`](#sessions)                                                                                                                                                                                |
| `GET /scores`, `/v2/scores` (+ `/{id}`)                        | [API reference](https://api.reference.langfuse.com/#tag/scores/GET/api/public/v2/scores)                  | [Scores API v3](#scores)                                                                                                                                                                                                                 |
| `GET /metrics`                                                 | [Documented below](#metrics-v1)                                                                           | [Metrics API v2](#metrics)                                                                                                                                                                                                               |
| `GET /metrics/daily`                                           | [Documented below](#daily-metrics)                                                                        | [Metrics API v2](#daily-metrics-migration)                                                                                                                                                                                               |
| `GET /datasets/{name}/runs`, `/datasets/{name}/runs/{runName}` | [API reference](https://api.reference.langfuse.com/#tag/datasets)                                         | [`GET /experiments`, then `GET /experiment-items`](#dataset-runs)                                                                                                                                                                        |
| `GET /dataset-run-items`                                       | [API reference](https://api.reference.langfuse.com/#tag/dataset-run-items)                                | [`GET /experiment-items`](#dataset-runs)                                                                                                                                                                                                 |
| `DELETE /datasets/{name}/runs/{runName}`                       | [API reference](https://api.reference.langfuse.com/#tag/datasets)                                         | [No direct replacement; optionally list the experiment items and delete their traces](#dataset-runs)                                                                                                                                     |
| `POST /dataset-run-items`                                      | [API reference](https://api.reference.langfuse.com/#tag/dataset-run-items)                                | [Experiment runner SDK](/docs/evaluation/experiments/experiments-via-sdk) (recommended for Python and JS/TS), or [`POST /otel/v1/traces` with experiment attributes](/integrations/native/opentelemetry/experiments) for other languages |
| Trace and observation events sent to `POST /ingestion`         | [API reference](https://api.reference.langfuse.com/#tag/ingestion/POST/api/public/ingestion)              | [OpenTelemetry ingestion](#ingestion); `score-create` and `sdk-log` events remain supported                                                                                                                                              |
| `POST /traces`, `/spans`, `/generations`, `/events`            | Not in the API reference                                                                                  | [OpenTelemetry ingestion](#ingestion)                                                                                                                                                                                                    |

## Metrics API v1 [#metrics-v1]

```
GET /api/public/metrics
```

The v1 Metrics API supports querying across different views (traces, observations, scores) and allows you to:

- Select specific dimensions to group your data
- Apply multiple metrics with different aggregation methods
- Filter data based on metadata, timestamps, and other properties
- Analyze data across time with customizable granularity
- Order results

Langfuse Cloud serves this endpoint until November 16, 2026 (2026-11-16); migrate to v4 before this date.

**Replacement:** [Metrics API v2](#metrics).

### Query Parameters

The v1 API accepts a JSON query object passed as a URL-encoded parameter:

| Parameter | Type        | Description                                                |
| --------- | ----------- | ---------------------------------------------------------- |
| `query`   | JSON string | The encoded query object defining what metrics to retrieve |

#### Query Object Structure

| Field           | Type   | Required | Description                                                                                                                                                              |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `view`          | string | Yes      | The data view to query: `"traces"`, `"observations"`, `"scores-numeric"`, `"scores-categorical"`, or `"scores-boolean"`                                                  |
| `dimensions`    | array  | No       | Array of dimension objects to group by, e.g. `[{ "field": "name" }]`                                                                                                     |
| `metrics`       | array  | Yes      | Array of metric objects to calculate, e.g. `[{ "measure": "latency", "aggregation": "p95" }]`                                                                            |
| `filters`       | array  | No       | Array of filter objects to narrow results, e.g. `[{ "column": "metadata", "operator": "contains", "key": "customKey", "value": "customValue", "type": "stringObject" }]` |
| `timeDimension` | object | No       | Configuration for time-based analysis, e.g. `{ "granularity": "day" }`                                                                                                   |
| `fromTimestamp` | string | Yes      | ISO timestamp for the start of the query period                                                                                                                          |
| `toTimestamp`   | string | Yes      | ISO timestamp for the end of the query period                                                                                                                            |
| `orderBy`       | array  | No       | Specification for result ordering, e.g. `[{ "field": "name", "direction": "asc" }]`                                                                                      |

#### Dimension Object Structure

```json
{ "field": "name" }
```

#### Metric Object Structure

```json
{ "measure": "count", "aggregation": "count" }
```

Common measure types include:

- `count` - Count of records
- `latency` - Duration/latency metrics

Aggregation types include:

- `sum` - Sum of values
- `avg` - Average of values
- `count` - Count of records
- `max` - Maximum value
- `min` - Minimum value
- `p50` - 50th percentile
- `p75` - 75th percentile
- `p90` - 90th percentile
- `p95` - 95th percentile
- `p99` - 99th percentile

#### Filter Object Structure

```json
{
  "column": "metadata",
  "operator": "contains",
  "key": "customKey",
  "value": "customValue",
  "type": "stringObject"
}
```

#### Time Dimension Object

```json
{
  "granularity": "day"
}
```

Supported granularities include: `hour`, `day`, `week`, `month`, and `auto`.

### Example

Here's an example of querying the number of traces grouped by name:

<LangTabs items={["API", "Python SDK"]}>
  <Tab label="API">

```bash
curl \
-H "Authorization: Basic <BASIC AUTH HEADER>" \
-G \
--data-urlencode 'query={
  "view": "traces",
  "metrics": [{"measure": "count", "aggregation": "count"}],
  "dimensions": [{"field": "name"}],
  "filters": [],
  "fromTimestamp": "2025-05-01T00:00:00Z",
  "toTimestamp": "2025-05-13T00:00:00Z"
}' \
https://cloud.langfuse.com/api/public/metrics
```

  </Tab>
  <Tab label="Python SDK">

```python
query = """
{
  "view": "traces",
  "metrics": [{"measure": "count", "aggregation": "count"}],
  "dimensions": [{"field": "name"}],
  "filters": [],
  "fromTimestamp": "2025-05-01T00:00:00Z",
  "toTimestamp": "2025-05-13T00:00:00Z"
}
"""

langfuse.api.legacy.metrics_v1.metrics(query = query)
```

  </Tab>
</LangTabs>

Response:

```json
{
  "data": [
    { "name": "trace-test-2", "count_count": "10" },
    { "name": "trace-test-3", "count_count": "5" },
    { "name": "trace-test-1", "count_count": "3" }
  ]
}
```

### Data Model

The v1 Metrics API provides access to several data views, each with its own set of dimensions and metrics you can query. This section outlines the available options for each view.

#### Available Views

| View                 | Description                         |
| -------------------- | ----------------------------------- |
| `traces`             | Query data at the trace level       |
| `observations`       | Query data at the observation level |
| `scores-numeric`     | Query numeric scores                |
| `scores-categorical` | Query categorical (string) scores   |
| `scores-boolean`     | Query boolean scores                |

#### Trace Dimensions

| Dimension         | Type     | Description                             |
| ----------------- | -------- | --------------------------------------- |
| `id`              | string   | Trace ID                                |
| `name`            | string   | Trace name                              |
| `tags`            | string[] | Trace tags                              |
| `userId`          | string   | User ID associated with the trace       |
| `sessionId`       | string   | Session ID associated with the trace    |
| `release`         | string   | Release tag                             |
| `version`         | string   | Version tag                             |
| `environment`     | string   | Environment (e.g., production, staging) |
| `observationName` | string   | Name of related observations            |
| `scoreName`       | string   | Name of related scores                  |

#### Trace Metrics

| Metric              | Description                         |
| ------------------- | ----------------------------------- |
| `count`             | Count of traces                     |
| `observationsCount` | Count of observations within traces |
| `scoresCount`       | Count of scores within traces       |
| `latency`           | Trace duration in milliseconds      |
| `totalTokens`       | Total tokens used in the trace      |
| `totalCost`         | Total cost of the trace             |

#### Observation Dimensions

| Dimension             | Type   | Description                             |
| --------------------- | ------ | --------------------------------------- |
| `id`                  | string | Observation ID                          |
| `traceId`             | string | Associated trace ID                     |
| `traceName`           | string | Name of the parent trace                |
| `environment`         | string | Environment (e.g., production, staging) |
| `parentObservationId` | string | ID of parent observation                |
| `type`                | string | Observation type                        |
| `name`                | string | Observation name                        |
| `level`               | string | Log level                               |
| `version`             | string | Version                                 |
| `providedModelName`   | string | Model name                              |
| `promptName`          | string | Prompt name                             |
| `promptVersion`       | string | Prompt version                          |
| `userId`              | string | User ID from parent trace               |
| `sessionId`           | string | Session ID from parent trace            |
| `traceRelease`        | string | Release from parent trace               |
| `traceVersion`        | string | Version from parent trace               |
| `scoreName`           | string | Related score name                      |

#### Observation Metrics

| Metric             | Description                          |
| ------------------ | ------------------------------------ |
| `count`            | Count of observations                |
| `latency`          | Observation duration in milliseconds |
| `totalTokens`      | Total tokens used                    |
| `totalCost`        | Total cost                           |
| `timeToFirstToken` | Time to first token in milliseconds  |
| `countScores`      | Count of related scores              |

#### Score Dimensions (Common)

| Dimension                  | Type   | Description                                |
| -------------------------- | ------ | ------------------------------------------ |
| `id`                       | string | Score ID                                   |
| `name`                     | string | Score name                                 |
| `environment`              | string | Environment                                |
| `source`                   | string | Score source                               |
| `dataType`                 | string | Data type                                  |
| `traceId`                  | string | Related trace ID                           |
| `traceName`                | string | Related trace name                         |
| `userId`                   | string | User ID from trace                         |
| `sessionId`                | string | Session ID from trace                      |
| `observationId`            | string | Related observation ID                     |
| `observationName`          | string | Related observation name                   |
| `observationModelName`     | string | Model used in related observation          |
| `observationPromptName`    | string | Prompt name used in related observation    |
| `observationPromptVersion` | string | Prompt version used in related observation |
| `configId`                 | string | Configuration ID                           |

#### Score Metrics

##### Numeric Scores

| Metric  | Description         |
| ------- | ------------------- |
| `count` | Count of scores     |
| `value` | Numeric score value |

##### Boolean Scores

| Metric  | Description                                                                                                |
| ------- | ---------------------------------------------------------------------------------------------------------- |
| `count` | Count of scores                                                                                            |
| `value` | Numeric score value, where `0` is false and `1` is true. Use the `avg` aggregation to return the true rate |

Boolean scores have an additional dimension:

| Dimension      | Type    | Description                                           |
| -------------- | ------- | ----------------------------------------------------- |
| `booleanValue` | boolean | Boolean value of the score for grouping and filtering |

##### Categorical Scores

| Metric  | Description     |
| ------- | --------------- |
| `count` | Count of scores |

Categorical scores have an additional dimension:

| Dimension     | Type   | Description                           |
| ------------- | ------ | ------------------------------------- |
| `stringValue` | string | String value of the categorical score |

## Daily Metrics API [#daily-metrics]

```
GET /api/public/metrics/daily
```

The Daily Metrics API returns aggregated daily usage and cost metrics for downstream use in analytics, billing, and rate limiting, and allows you to:

- Retrieve daily timeseries of [cost](/docs/model-usage-and-cost) in USD and trace and observation counts
- Break down usage (e.g. tokens, split by input and output) and cost by model name
- Filter by trace name, user, or tags

**Replacement:** [Metrics API v2 with a daily time dimension](#daily-metrics-migration).

### Query Parameters

All parameters are optional:

| Parameter       | Type     | Description                                                                              |
| --------------- | -------- | ---------------------------------------------------------------------------------------- |
| `traceName`     | string   | Filter by trace name, commonly the application type depending on how you use trace names |
| `userId`        | string   | Filter by [user](/docs/observability/features/users)                                     |
| `tags`          | string[] | Filter by [tags](/docs/observability/features/tags)                                      |
| `fromTimestamp` | datetime | Start of the date range                                                                  |
| `toTimestamp`   | datetime | End of the date range                                                                    |
| `page`, `limit` | number   | Page-based pagination                                                                    |

### Example

```
GET /api/public/metrics/daily?traceName=my-copilot&userId=john&limit=2
```

```json
{
  "data": [
    {
      "date": "2024-02-18",
      "countTraces": 1500,
      "countObservations": 3000,
      "totalCost": 102.19,
      "usage": [
        {
          "model": "llama2",
          "inputUsage": 1200,
          "outputUsage": 1300,
          "totalUsage": 2500,
          "countTraces": 1000,
          "countObservations": 2000,
          "totalCost": 50.19
        },
        {
          "model": "gpt-4",
          "inputUsage": 500,
          "outputUsage": 550,
          "totalUsage": 1050,
          "countTraces": 500,
          "countObservations": 1000,
          "totalCost": 52.0
        }
      ]
    },
    {
      "date": "2024-02-17",
      "countTraces": 1250,
      "countObservations": 2500,
      "totalCost": 250.0,
      "usage": [
        {
          "model": "llama2",
          "inputUsage": 1000,
          "outputUsage": 1100,
          "totalUsage": 2100,
          "countTraces": 1250,
          "countObservations": 2500,
          "totalCost": 250.0
        }
      ]
    }
  ],
  "meta": {
    "page": 1,
    "limit": 2,
    "totalItems": 60,
    "totalPages": 30
  }
}
```

<!-- agent-instructions -->

---

## Agent Instructions

This page is part of the [Langfuse](https://langfuse.com) documentation, published as plain Markdown for AI agents. Every page is available as Markdown by appending `.md` to its URL, or by sending an `Accept: text/markdown` header. This page: `https://langfuse.com/faq/all/deprecated-api-migration.md`.

### Querying these docs

If the answer is not on this page, query the documentation instead of guessing:

- **Semantic search** across all Langfuse docs, returning an answer with the relevant pages and excerpts. Ask a specific, self-contained question:

  ```bash
  curl -sG "https://langfuse.com/api/search-docs" --data-urlencode "query=How do I trace a LangGraph agent?"
  ```

- **Index of every page**: <https://langfuse.com/llms.txt>, with per-section indexes [llms-docs.txt](https://langfuse.com/llms-docs.txt), [llms-integrations.txt](https://langfuse.com/llms-integrations.txt), and [llms-self-hosting.txt](https://langfuse.com/llms-self-hosting.txt).

### Before writing Langfuse code

- **Install the [Langfuse Agent Skill](https://langfuse.com/docs/api-and-data-platform/features/agent-skill).** It encodes Langfuse's own best practices for instrumentation, prompt management, and evaluation, and materially improves results.
- **Read [What does a good trace look like?](https://langfuse.com/docs/observability/best-practices.md)** before instrumenting an application.
- **Verify endpoints, parameters, and response fields** against the [API reference](https://api.reference.langfuse.com) instead of inferring them from code examples.
- **Use the [Langfuse CLI](https://langfuse.com/docs/api-and-data-platform/features/cli)** (`npx langfuse-cli api <resource> <action>`) to read or write traces, prompts, datasets, and scores from the terminal.

Found an error in these docs? Please open an issue at <https://github.com/langfuse/langfuse-docs/issues>.
