Neural Inverse is Open Source →
DocsObservations API
DocsAPI & Data PlatformFeaturesObservations API

Observations API

The Observations API allows you to retrieve observation data (spans, generations, events) from Neural Inverse for use in custom workflows, evaluation pipelines, and analytics.

If you need aggregated metrics (e.g., total cost, token counts, or trace volumes grouped by user, model, or time period) rather than individual observations, the Metrics API 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.

Older trace and observation read APIs remain available, but are not recommended as the default for new data extraction workflows because they are less performant at scale. Use Observations API v2 for row-level data extraction.

Observations API v2

Cloud-only: The v2 Observations API is only available on Neural Inverse Cloud. We are working on a robust migration path for self-hosted deployments.

Data availability: Data from older SDKs (langfuse-python < 4.0.0, langfuse-js < 5.0.0) or direct OpenTelemetry exporters that do not send x-langfuse-ingestion-version: 4 can be delayed by up to 10 minutes on v2 endpoints. Upgrade to Python SDK v4 or JS/TS SDK v5, or set that header on your OTEL span exporter, to see new data in real time.

GET /api/public/v2/observations

The v2 Observations API is a redesigned endpoint optimized for high-performance data retrieval. It addresses the performance bottlenecks of the v1 API by minimizing the work Neural Inverse has to perform per query.

Upgrade from older trace and observation reads

Existing usageRecommended replacement
List traces with GET /api/public/tracesUse GET /api/public/v2/observations?fromStartTime=<from>&toStartTime=<to> and group rows by traceId
Fetch one trace with GET /api/public/traces/{traceId}Use GET /api/public/v2/observations?traceId=<traceId>&fromStartTime=<from>&toStartTime=<to>
List observations with GET /api/public/observationsUse GET /api/public/v2/observations?fromStartTime=<from>&toStartTime=<to>
Fetch one observation with GET /api/public/observations/{observationId}Use GET /api/public/v2/observations?filter=<id filter>&fromStartTime=<from>&toStartTime=<to>

Always include fromStartTime and toStartTime to keep each request bounded.

The v2 Observations API returns observation rows, not full trace objects. Group rows by traceId when you need to reconstruct trace activity, and use Metrics API v2 for aggregate reporting with trace-level dimensions such as traceName, traceRelease, or traceVersion. For single-observation lookups, pass a URL-encoded filter condition on the id column; see the v2 Observations API Reference for the filter schema.

Key Improvements

1. Selective Field Retrieval

The v1 API returns complete rows with all fields (input/output, usage, metadata, etc.), forcing the database to scan every column even when you only need a subset. The v2 API lets you specify which field groups you need as a comma-separated string:

?fields=core,basic,usage

Available Field Groups

GroupFields
coreAlways included: id, traceId, startTime, endTime, projectId, parentObservationId, type
basicname, level, statusMessage, version, environment, bookmarked, public, userId, sessionId
timecompletionStartTime, createdAt, updatedAt
ioinput, output
metadatametadata
modelprovidedModelName, internalModelId, modelParameters
usageusageDetails, inputUsage, outputUsage, totalUsage, costDetails, inputCost, outputCost, totalCost, usagePricingTierName
promptpromptId, promptName, promptVersion
metricslatency, timeToFirstToken
trace_contexttags, release, traceName

If fields is not specified, core and basic field groups are returned by default. Fields from groups you do not request are absent from the response — not null. The following fields are an exception and are always present but only populated when the field group model is selected: modelId, inputPrice, outputPrice, and totalPrice. Note that 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.

2. Cursor-Based Pagination

The v1 API uses offset-based pagination (page numbers) which becomes increasingly slow for large datasets. The v2 API uses cursor-based pagination for better and more consistent performance.

How it works:

  1. Make your initial request with a limit parameter
  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 to continue where you left off
  4. Repeat until no cursor is returned (you've reached the end)

Results are always sorted by startTime descending (newest first).

Example response with cursor:

{
  "data": [
    {"id": "obs-1", "traceId": "trace-1", "name": "llm-call", ...},
    {"id": "obs-2", "traceId": "trace-1", "name": "embedding", ...}
  ],
  "meta": {
    "cursor": "eyJsYXN0U3RhcnRUaW1lIjoiMjAyNS0xMi0xNVQxMDozMDowMFoiLCJsYXN0SWQiOiJvYnMtMTAwIn0="
  }
}

When the response has no cursor in meta (or meta.cursor is null), you've retrieved all matching observations.

3. Optimized I/O Handling

The v1 API always attempts to parse input/output as JSON which can be expensive. The v2 API returns I/O as strings by default. Set parseIoAsJson: true only when you need parsed JSON.

4. Stricter Limits

Featurev1v2
Default limit100050
Maximum limitUnlimited1,000

Common Use Cases

Polling for recent observations:

curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations?fromStartTime=2025-12-15T00:00:00Z&toStartTime=2025-12-16T00:00:00Z&limit=10"

Getting observations for a specific trace:

curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations?fields=core,basic,usage&traceId=your-trace-id"

Paginating through results:

# First request
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations?fromStartTime=2025-12-01T00:00:00Z&limit=100"

# Response includes: "meta": { "cursor": "eyJsYXN0..." }

# Next request with cursor
curl \
  -H "Authorization: Basic <BASIC AUTH HEADER>" \
  "https://cloud.langfuse.com/api/public/v2/observations?fromStartTime=2025-12-01T00:00:00Z&limit=100&cursor=eyJsYXN0..."

Parameters

ParameterTypeDescription
fieldsstringComma-separated list of field groups to include. Defaults to core,basic
limitintegerNumber of items per page. Defaults to 50, max 1,000
cursorstringBase64-encoded cursor for pagination (from previous response)
fromStartTimedatetimeRetrieve observations with startTime on or after this datetime
toStartTimedatetimeRetrieve observations with startTime before this datetime
traceIdstringFilter by trace ID
namestringFilter by observation name
typestringFilter by observation type (GENERATION, SPAN, EVENT)
userIdstringFilter by user ID
levelstringFilter by log level (DEBUG, DEFAULT, WARNING, ERROR)
parentObservationIdstringFilter by parent observation ID
environmentstringFilter by environment
versionstringFilter by version tag
parseIoAsJsonbooleanParse input/output as JSON (default: false)
filterstringJSON array of filter conditions (takes precedence over query params)

Sample Response

With all fields included

{
  "data": [
    {
      "id": "support-chat-7-950dc53a-gen",
      "traceId": "support-chat-7-950dc53a",
      "startTime": "2025-12-17T16:09:00.875Z",
      "projectId": "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a",
      "parentObservationId": null,
      "type": "GENERATION",
      "endTime": "2025-12-17T16:09:01.456Z",
      "name": "llm-generation",
      "level": "DEFAULT",
      "statusMessage": "",
      "version": "",
      "environment": "default",
      "bookmarked": false,
      "public": false,
      "completionStartTime": "2025-12-17T16:09:00.995Z",
      "createdAt": "2025-12-17T16:09:00.875Z",
      "updatedAt": "2025-12-17T16:09:01.456Z",
      "input": "{\"messages\":[{\"role\":\"user\",\"content\":\"Perfect.\"}]}",
      "output": "{\"role\":\"assistant\",\"content\":\"You're all set. Have a great day!\"}",
      "metadata": {},
      "providedModelName": "gpt-4o",
      "internalModelId": "clm1a2b3c4d5e6f7g8h9i0j1",
      "modelParameters": {
        "temperature": 0.2
      },
      "usageDetails": {
        "input": 98,
        "output": 68,
        "total": 166
      },
      "inputUsage": 98,
      "outputUsage": 68,
      "totalUsage": 166,
      "costDetails": {
        "input": 0.00049,
        "output": 0.00204,
        "total": 0.00253
      },
      "inputCost": 0.00049,
      "outputCost": 0.00204,
      "totalCost": 0.00253,
      "promptId": "",
      "promptName": "",
      "promptVersion": null,
      "latency": 0.581,
      "timeToFirstToken": 0.12,
      "userId": "",
      "sessionId": "support-chat-session",
      "modelId": "clm1a2b3c4d5e6f7g8h9i0j1",
      "inputPrice": "0.000005",
      "outputPrice": "0.00003",
      "totalPrice": null,
      "usagePricingTierName": null,
      "tags": ["support", "chat"],
      "release": "v1.4.2",
      "traceName": "support-chat"
    }
  ],
  "meta": {
    "cursor": "eyJsYXN0U3RhcnRUaW1lVG8iOiIyMDI1LTEyLTE3VDE2OjA5OjAwLjg3NVoiLCJsYXN0VHJhY2VJZCI6InN1cHBvcnQtY2hhdC03LTk1MGRjNTNhIiwibGFzdElkIjoic3VwcG9ydC1jaGF0LTctOTUwZGM1M2EtZ2VuIn0="
  }
}

API Reference: See the full v2 Observations API Reference for all available parameters, response schemas, and interactive examples.


Was this page helpful?