Java client for the Langfuse API providing access to observability and analytics features for LLM applications
The Traces and Observations APIs provide retrieval and management of tracing data. Traces represent complete workflows or requests, while observations (spans, events, generations) represent individual operations within traces. For creating traces and observations, use the Ingestion API.
Client for retrieving and deleting traces.
/**
* Get a specific trace with full details
* Includes observations and scores
*
* @param traceId Unique trace identifier
* @param requestOptions Optional request configuration
*/
TraceWithFullDetails get(String traceId);
TraceWithFullDetails get(String traceId, RequestOptions requestOptions);
/**
* List traces with filters and pagination
*
* @param request Optional filters (userId, name, sessionId, tags, dates, etc.)
* @param requestOptions Optional request configuration
*/
Traces list();
Traces list(GetTracesRequest request);
Traces list(GetTracesRequest request, RequestOptions requestOptions);
/**
* Delete a specific trace
* Irreversible operation
*
* @param traceId Unique trace identifier
* @param requestOptions Optional request configuration
*/
DeleteTraceResponse delete(String traceId);
DeleteTraceResponse delete(String traceId, RequestOptions requestOptions);
/**
* Delete multiple traces at once
* Irreversible operation
*
* @param request List of trace IDs to delete
* @param requestOptions Optional request configuration
*/
DeleteTraceResponse deleteMultiple(DeleteTracesRequest request);
DeleteTraceResponse deleteMultiple(DeleteTracesRequest request, RequestOptions requestOptions);Usage Examples:
import com.langfuse.client.LangfuseClient;
import com.langfuse.client.resources.trace.requests.*;
import com.langfuse.client.resources.trace.types.*;
import com.langfuse.client.resources.commons.types.*;
import java.time.OffsetDateTime;
import java.util.List;
LangfuseClient client = LangfuseClient.builder()
.url("https://cloud.langfuse.com")
.credentials("pk-lf-...", "sk-lf-...")
.build();
// Get a specific trace
TraceWithFullDetails trace = client.trace().get("trace-123");
System.out.println("Trace: " + trace.getName());
System.out.println("Observations: " + trace.getObservations().size());
System.out.println("Scores: " + trace.getScores().size());
// List traces for a user
GetTracesRequest request = GetTracesRequest.builder()
.userId("user-456")
.limit(10)
.orderBy("timestamp.desc") // String format: "field.direction"
.build();
Traces traces = client.trace().list(request);
for (Trace t : traces.getData()) {
System.out.println(t.getName() + " - " + t.getTimestamp());
}
// Filter by tags and environment (tags is comma-separated string)
GetTracesRequest prodRequest = GetTracesRequest.builder()
.tags("production,critical") // Comma-separated string, not List
.environment("production")
.build();
Traces prodTraces = client.trace().list(prodRequest);
// Delete a trace
DeleteTraceResponse deleteResp = client.trace().delete("trace-123");
System.out.println("Deleted: " + deleteResp.getDeletedTraceIds());
// Delete multiple traces
DeleteTracesRequest deleteMultiple = DeleteTracesRequest.builder()
.traceIds(List.of("trace-1", "trace-2", "trace-3"))
.build();
DeleteTraceResponse batchDelete = client.trace().deleteMultiple(deleteMultiple);Client for retrieving observations (spans, events, generations).
/**
* Get a specific observation
*
* @param observationId Unique observation identifier
* @param requestOptions Optional request configuration
*/
ObservationsView get(String observationId);
ObservationsView get(String observationId, RequestOptions requestOptions);
/**
* Get a list of observations with filters
*
* @param request Optional filters (name, userId, type, traceId, dates, etc.)
* @param requestOptions Optional request configuration
*/
ObservationsViews getMany();
ObservationsViews getMany(GetObservationsRequest request);
ObservationsViews getMany(GetObservationsRequest request, RequestOptions requestOptions);Usage Examples:
import com.langfuse.client.resources.observations.types.*;
import com.langfuse.client.resources.observations.requests.GetObservationsRequest;
import com.langfuse.client.resources.ingestion.types.ObservationType;
import java.time.OffsetDateTime;
// Get a specific observation
ObservationsView observation = client.observations().get("obs-123");
System.out.println("Observation: " + observation.getName());
System.out.println("Type: " + observation.getType());
// List observations for a trace
GetObservationsRequest request = GetObservationsRequest.builder()
.traceId("trace-123")
.build();
ObservationsViews observations = client.observations().getMany(request);
for (ObservationsView obs : observations.getData()) {
System.out.println(obs.getName() + " (" + obs.getType() + ")");
}
// Filter by type and date range
GetObservationsRequest genRequest = GetObservationsRequest.builder()
.type("GENERATION") // String, not enum
.fromStartTime(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
.toStartTime(OffsetDateTime.parse("2025-10-14T23:59:59Z"))
.limit(50)
.build();
ObservationsViews generations = client.observations().getMany(genRequest);Import: import com.langfuse.client.resources.trace.requests.GetTracesRequest;
/**
* Request parameters for listing traces
* Located in requests package (not types)
*/
public final class GetTracesRequest {
Optional<Integer> getPage(); // Page number (default: 1)
Optional<Integer> getLimit(); // Items per page (default: 50)
Optional<String> getUserId(); // Filter by user ID
Optional<String> getName(); // Filter by trace name
Optional<String> getSessionId(); // Filter by session ID
Optional<OffsetDateTime> getFromTimestamp(); // Filter by start date
Optional<OffsetDateTime> getToTimestamp(); // Filter by end date
Optional<String> getOrderBy(); // Sort order as string (e.g., "timestamp.desc")
Optional<String> getTags(); // Comma-separated tags (must match all)
Optional<String> getVersion(); // Filter by version
Optional<String> getRelease(); // Filter by release
Optional<String> getEnvironment(); // Filter by environment
Optional<String> getFields(); // Comma-separated field groups (core, io, scores, observations, metrics)
static Builder builder();
}/**
* Request for deleting multiple traces
*/
public final class DeleteTracesRequest {
List<String> getTraceIds(); // List of trace IDs to delete
static Builder builder();
}Import: import com.langfuse.client.resources.observations.requests.GetObservationsRequest;
/**
* Request parameters for listing observations
* Located in requests package (not types)
*/
public final class GetObservationsRequest {
Optional<Integer> getPage(); // Page number (default: 1)
Optional<Integer> getLimit(); // Items per page (default: 50)
Optional<String> getName(); // Filter by observation name
Optional<String> getUserId(); // Filter by user ID
Optional<String> getType(); // Filter by type as string ("SPAN", "EVENT", "GENERATION")
Optional<String> getTraceId(); // Filter by trace ID
Optional<String> getParentObservationId(); // Filter by parent observation ID
Optional<String> getEnvironment(); // Filter by environment
Optional<OffsetDateTime> getFromStartTime(); // Filter by start date
Optional<OffsetDateTime> getToStartTime(); // Filter by end date
Optional<String> getVersion(); // Filter by version
static Builder builder();
}/**
* Trace with complete details including observations and scores
*/
public final class TraceWithFullDetails {
String getId();
OffsetDateTime getTimestamp(); // Timestamp as OffsetDateTime
Optional<String> getName();
Optional<String> getUserId();
Optional<Object> getMetadata();
Optional<String> getRelease();
Optional<String> getVersion();
Optional<String> getProjectId();
Optional<Boolean> getPublic();
Optional<Boolean> getBookmarked();
Optional<List<String>> getTags();
Optional<Object> getInput();
Optional<Object> getOutput();
Optional<String> getSessionId();
List<Observation> getObservations(); // All observations in trace
List<ScoreV1> getScores(); // All scores for trace
static Builder builder();
}/**
* Paginated list of traces
*/
public final class Traces {
List<Trace> getData();
MetaResponse getMeta(); // Pagination metadata
static Builder builder();
}Basic trace object (see Common Types for full definition).
/**
* Response after deleting trace(s)
*/
public final class DeleteTraceResponse {
List<String> getDeletedTraceIds(); // IDs of deleted traces
static Builder builder();
}/**
* Observation with additional computed fields
*/
public final class ObservationsView {
String getId();
String getTraceId();
String getProjectId();
Optional<ObservationType> getType(); // SPAN, EVENT, GENERATION
Optional<String> getParentObservationId();
Optional<String> getName();
Optional<Object> getMetadata();
Optional<String> getModel();
Optional<Object> getModelParameters();
Optional<String> getStartTime(); // ISO 8601 timestamp
Optional<String> getEndTime(); // ISO 8601 timestamp
Optional<String> getCompletionStartTime(); // ISO 8601 timestamp
Optional<Object> getInput();
Optional<Object> getOutput();
Optional<Usage> getUsage(); // Token usage
Optional<ObservationLevel> getLevel(); // DEBUG, DEFAULT, WARNING, ERROR
Optional<String> getStatusMessage();
Optional<String> getVersion();
Optional<String> getEnvironment();
Optional<String> getPromptId();
Optional<String> getPromptName();
Optional<Integer> getPromptVersion();
Optional<ModelPrice> getModelPrice(); // Computed pricing
Optional<Double> getTotalCost(); // Computed cost
Optional<Double> getLatency(); // Computed latency in seconds
static Builder builder();
}/**
* Paginated list of observations
*/
public final class ObservationsViews {
List<ObservationsView> getData();
MetaResponse getMeta(); // Pagination metadata
static Builder builder();
}Core observation object (see Common Types for full definition).
/**
* Sort order for traces
*/
public enum Sort {
TIMESTAMP_ASC,
TIMESTAMP_DESC
}/**
* Type of observation
*/
public enum ObservationType {
SPAN, // Operation or sub-process
EVENT, // Point-in-time occurrence
GENERATION // LLM generation call
}/**
* Log level for observations
*/
public enum ObservationLevel {
DEBUG,
DEFAULT,
WARNING,
ERROR
}import com.langfuse.client.LangfuseClient;
import com.langfuse.client.resources.trace.requests.*;
import com.langfuse.client.resources.trace.types.*;
import com.langfuse.client.resources.observations.requests.*;
import com.langfuse.client.resources.observations.types.*;
import com.langfuse.client.resources.commons.types.*;
import com.langfuse.client.resources.ingestion.types.ObservationType;
public class TraceAnalysisExample {
public static void main(String[] args) {
LangfuseClient client = LangfuseClient.builder()
.url("https://cloud.langfuse.com")
.credentials("pk-lf-...", "sk-lf-...")
.build();
// 1. List recent traces for a user
GetTracesRequest request = GetTracesRequest.builder()
.userId("user-123")
.fromTimestamp(OffsetDateTime.parse("2025-10-14T00:00:00Z"))
.orderBy("timestamp.desc") // String format, not Sort enum
.limit(10)
.build();
Traces traces = client.trace().list(request);
System.out.println("Found " + traces.getMeta().getTotalItems() + " traces");
// 2. Analyze each trace
for (Trace trace : traces.getData()) {
System.out.println("\nTrace: " + trace.getName());
System.out.println("ID: " + trace.getId());
System.out.println("User: " + trace.getUserId());
System.out.println("Session: " + trace.getSessionId().orElse("none"));
// Get full trace details
TraceWithFullDetails fullTrace = client.trace().get(trace.getId());
// Analyze observations
System.out.println("Observations: " + fullTrace.getObservations().size());
for (Observation obs : fullTrace.getObservations()) {
System.out.println(" - " + obs.getName().orElse("unnamed") +
" (" + obs.getType().orElse(null) + ")");
}
// Analyze scores
System.out.println("Scores: " + fullTrace.getScores().size());
for (ScoreV1 score : fullTrace.getScores()) {
System.out.println(" - " + score.getName() + ": " + score.getValue());
}
// Calculate trace metrics
if (!fullTrace.getObservations().isEmpty()) {
double totalCost = 0.0;
int totalTokens = 0;
for (Observation obs : fullTrace.getObservations()) {
// Get observation details for computed metrics
GetObservationsRequest obsReq = GetObservationsRequest.builder()
.traceId(trace.getId())
.build();
ObservationsViews obsViews = client.observations().getMany(obsReq);
for (ObservationsView view : obsViews.getData()) {
if (view.getTotalCost().isPresent()) {
totalCost += view.getTotalCost().get();
}
if (view.getUsage().isPresent()) {
Usage usage = view.getUsage().get();
if (usage.getTotal().isPresent()) {
totalTokens += usage.getTotal().get();
}
}
}
}
System.out.println("Total cost: $" + totalCost);
System.out.println("Total tokens: " + totalTokens);
}
}
// 3. Find all generations with errors
GetObservationsRequest errorRequest = GetObservationsRequest.builder()
.type("GENERATION") // String, not enum
.fromStartTime(OffsetDateTime.parse("2025-10-14T00:00:00Z"))
.limit(100)
.build();
ObservationsViews observations = client.observations().getMany(errorRequest);
System.out.println("\n\nGenerations with errors:");
for (ObservationsView obs : observations.getData()) {
if (obs.getLevel().isPresent() && obs.getLevel().get() == ObservationLevel.ERROR) {
System.out.println("Error in trace " + obs.getTraceId() + ": " +
obs.getStatusMessage().orElse("no message"));
}
}
// 4. Analyze high-cost traces
System.out.println("\n\nHigh-cost observations:");
for (ObservationsView obs : observations.getData()) {
if (obs.getTotalCost().isPresent() && obs.getTotalCost().get() > 0.01) {
System.out.println("Trace " + obs.getTraceId() +
" - Model: " + obs.getModel().orElse("unknown") +
" - Cost: $" + obs.getTotalCost().get());
}
}
// 5. Clean up old test traces
GetTracesRequest oldTestsRequest = GetTracesRequest.builder()
.tags("test") // String, not List
.toTimestamp(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
.limit(100)
.build();
Traces oldTests = client.trace().list(oldTestsRequest);
if (!oldTests.getData().isEmpty()) {
List<String> traceIds = oldTests.getData().stream()
.map(Trace::getId)
.collect(java.util.stream.Collectors.toList());
DeleteTracesRequest deleteRequest = DeleteTracesRequest.builder()
.traceIds(traceIds)
.build();
DeleteTraceResponse deleteResponse = client.trace().deleteMultiple(deleteRequest);
System.out.println("\nDeleted " + deleteResponse.getDeletedTraceIds().size() +
" old test traces");
}
}
}GetTracesRequest sessionRequest = GetTracesRequest.builder()
.sessionId("session-123")
.orderBy("timestamp.asc") // String format, not Sort enum
.build();
Traces sessionTraces = client.trace().list(sessionRequest);GetObservationsRequest childRequest = GetObservationsRequest.builder()
.parentObservationId("parent-obs-123")
.build();
ObservationsViews children = client.observations().getMany(childRequest);GetTracesRequest prodRequest = GetTracesRequest.builder()
.environment("production")
.version("v2.1.0")
.build();
Traces prodTraces = client.trace().list(prodRequest);Install with Tessl CLI
npx tessl i tessl/maven-com-langfuse--langfuse-java