Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langfuse Langfuse OTel Traces Handler

From Leeroopedia
Knowledge Sources
Domains Observability, Ingestion, OpenTelemetry
Last Updated 2026-02-14 00:00 GMT

Overview

Concrete tool for receiving OpenTelemetry ExportTraceServiceRequest payloads over HTTP provided by Langfuse.

Description

This is a Next.js API route handler located at /api/public/otel/v1/traces that serves as the entry point for all OpenTelemetry trace ingestion into Langfuse. The handler:

  1. Disables the default Next.js body parser to gain control over raw body streaming.
  2. Wraps the route in withMiddlewares for consistent error handling and CORS support.
  3. Uses createAuthedProjectAPIRoute to enforce project-level authentication and apply rate limiting under the ingestion resource.
  4. Checks for ingestion suspension (usage threshold exceeded) and throws ForbiddenError if suspended.
  5. Marks the project as an OTel user via markProjectAsOtelUser().
  6. Streams the raw request body into a Buffer, then decompresses it with gzip if the Content-Encoding header indicates gzip compression.
  7. Parses the body as either Protobuf (using the generated $root.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest decoder) or JSON, depending on the Content-Type header.
  8. Extracts configurable propagated headers for enterprise ingestion masking.
  9. Instantiates an OtelIngestionProcessor with project context and calls publishToOtelIngestionQueue(resourceSpans).

Usage

This handler is invoked by any OpenTelemetry SDK or collector configured to export traces to Langfuse. The endpoint URL follows the OTLP HTTP convention:

POST /api/public/otel/v1/traces

Clients authenticate via Langfuse project API keys passed as standard HTTP Basic Auth or bearer tokens.

Code Reference

Source Location

  • Repository: langfuse
  • File: web/src/pages/api/public/otel/v1/traces/index.ts
  • Lines: 20-133

Signature

withMiddlewares({
  POST: createAuthedProjectAPIRoute({
    name: "OTel Traces",
    querySchema: z.any(),
    responseSchema: z.any(),
    rateLimitResource: "ingestion",
    fn: async ({ req, res, auth }) => {
      // ... handler body
    },
  }),
})

Import

import { withMiddlewares } from "@/src/features/public-api/server/withMiddlewares";
import { createAuthedProjectAPIRoute } from "@/src/features/public-api/server/createAuthedProjectAPIRoute";
import { OtelIngestionProcessor, logger, markProjectAsOtelUser } from "@langfuse/shared/src/server";
import { z } from "zod/v4";
import { $root } from "@/src/pages/api/public/otel/otlp-proto/generated/root";
import { gunzip } from "node:zlib";
import { ForbiddenError } from "@langfuse/shared";

I/O Contract

Inputs

Name Type Required Description
req.body Buffer (ExportTraceServiceRequest) Yes Raw HTTP body containing OTel ExportTraceServiceRequest in Protobuf or JSON format
Content-Type string Yes Must include application/json or application/x-protobuf
Content-Encoding string No If set to gzip, the body will be decompressed before parsing
auth.scope.projectId string Yes Authenticated project identifier (provided by middleware)
auth.scope.publicKey string Yes Public API key for the project
auth.scope.orgId string No Organization identifier
auth.scope.isIngestionSuspended boolean Yes Whether ingestion is suspended due to usage limits

Outputs

Name Type Description
HTTP 200 (empty object) object Returned on successful enqueue or when resourceSpans is empty
HTTP 400 (error object) object Returned when body read, decompression, or parsing fails; includes error message
HTTP 403 (ForbiddenError) Error Thrown when ingestion is suspended for the project
Side effect: S3 upload void resourceSpans JSON uploaded to S3 via publishToOtelIngestionQueue
Side effect: BullMQ job void Job enqueued to OtelIngestionQueue for async processing

Usage Examples

Sending a JSON OTel Trace

curl -X POST https://cloud.langfuse.com/api/public/otel/v1/traces \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic <base64(publicKey:secretKey)>" \
  -d '{
    "resourceSpans": [{
      "resource": {
        "attributes": [
          {"key": "service.name", "value": {"stringValue": "my-service"}}
        ]
      },
      "scopeSpans": [{
        "scope": {"name": "langfuse-sdk", "version": "3.5.0"},
        "spans": [{
          "traceId": "abc123",
          "spanId": "def456",
          "name": "chat-completion",
          "startTimeUnixNano": "1700000000000000000",
          "endTimeUnixNano": "1700000001000000000",
          "attributes": []
        }]
      }]
    }]
  }'

Sending a Gzip-Compressed Protobuf Trace

curl -X POST https://cloud.langfuse.com/api/public/otel/v1/traces \
  -H "Content-Type: application/x-protobuf" \
  -H "Content-Encoding: gzip" \
  -H "Authorization: Basic <base64(publicKey:secretKey)>" \
  --data-binary @compressed_trace.pb.gz

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment