0
# Traces and Observations
1
2
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](./ingestion.md).
3
4
## Capabilities
5
6
### TraceClient
7
8
Client for retrieving and deleting traces.
9
10
```java { .api }
11
/**
12
* Get a specific trace with full details
13
* Includes observations and scores
14
*
15
* @param traceId Unique trace identifier
16
* @param requestOptions Optional request configuration
17
*/
18
TraceWithFullDetails get(String traceId);
19
TraceWithFullDetails get(String traceId, RequestOptions requestOptions);
20
21
/**
22
* List traces with filters and pagination
23
*
24
* @param request Optional filters (userId, name, sessionId, tags, dates, etc.)
25
* @param requestOptions Optional request configuration
26
*/
27
Traces list();
28
Traces list(GetTracesRequest request);
29
Traces list(GetTracesRequest request, RequestOptions requestOptions);
30
31
/**
32
* Delete a specific trace
33
* Irreversible operation
34
*
35
* @param traceId Unique trace identifier
36
* @param requestOptions Optional request configuration
37
*/
38
DeleteTraceResponse delete(String traceId);
39
DeleteTraceResponse delete(String traceId, RequestOptions requestOptions);
40
41
/**
42
* Delete multiple traces at once
43
* Irreversible operation
44
*
45
* @param request List of trace IDs to delete
46
* @param requestOptions Optional request configuration
47
*/
48
DeleteTraceResponse deleteMultiple(DeleteTracesRequest request);
49
DeleteTraceResponse deleteMultiple(DeleteTracesRequest request, RequestOptions requestOptions);
50
```
51
52
**Usage Examples:**
53
54
```java
55
import com.langfuse.client.LangfuseClient;
56
import com.langfuse.client.resources.trace.requests.*;
57
import com.langfuse.client.resources.trace.types.*;
58
import com.langfuse.client.resources.commons.types.*;
59
import java.time.OffsetDateTime;
60
import java.util.List;
61
62
LangfuseClient client = LangfuseClient.builder()
63
.url("https://cloud.langfuse.com")
64
.credentials("pk-lf-...", "sk-lf-...")
65
.build();
66
67
// Get a specific trace
68
TraceWithFullDetails trace = client.trace().get("trace-123");
69
System.out.println("Trace: " + trace.getName());
70
System.out.println("Observations: " + trace.getObservations().size());
71
System.out.println("Scores: " + trace.getScores().size());
72
73
// List traces for a user
74
GetTracesRequest request = GetTracesRequest.builder()
75
.userId("user-456")
76
.limit(10)
77
.orderBy("timestamp.desc") // String format: "field.direction"
78
.build();
79
80
Traces traces = client.trace().list(request);
81
for (Trace t : traces.getData()) {
82
System.out.println(t.getName() + " - " + t.getTimestamp());
83
}
84
85
// Filter by tags and environment (tags is comma-separated string)
86
GetTracesRequest prodRequest = GetTracesRequest.builder()
87
.tags("production,critical") // Comma-separated string, not List
88
.environment("production")
89
.build();
90
91
Traces prodTraces = client.trace().list(prodRequest);
92
93
// Delete a trace
94
DeleteTraceResponse deleteResp = client.trace().delete("trace-123");
95
System.out.println("Deleted: " + deleteResp.getDeletedTraceIds());
96
97
// Delete multiple traces
98
DeleteTracesRequest deleteMultiple = DeleteTracesRequest.builder()
99
.traceIds(List.of("trace-1", "trace-2", "trace-3"))
100
.build();
101
102
DeleteTraceResponse batchDelete = client.trace().deleteMultiple(deleteMultiple);
103
```
104
105
### ObservationsClient
106
107
Client for retrieving observations (spans, events, generations).
108
109
```java { .api }
110
/**
111
* Get a specific observation
112
*
113
* @param observationId Unique observation identifier
114
* @param requestOptions Optional request configuration
115
*/
116
ObservationsView get(String observationId);
117
ObservationsView get(String observationId, RequestOptions requestOptions);
118
119
/**
120
* Get a list of observations with filters
121
*
122
* @param request Optional filters (name, userId, type, traceId, dates, etc.)
123
* @param requestOptions Optional request configuration
124
*/
125
ObservationsViews getMany();
126
ObservationsViews getMany(GetObservationsRequest request);
127
ObservationsViews getMany(GetObservationsRequest request, RequestOptions requestOptions);
128
```
129
130
**Usage Examples:**
131
132
```java
133
import com.langfuse.client.resources.observations.types.*;
134
import com.langfuse.client.resources.observations.requests.GetObservationsRequest;
135
import com.langfuse.client.resources.ingestion.types.ObservationType;
136
import java.time.OffsetDateTime;
137
138
// Get a specific observation
139
ObservationsView observation = client.observations().get("obs-123");
140
System.out.println("Observation: " + observation.getName());
141
System.out.println("Type: " + observation.getType());
142
143
// List observations for a trace
144
GetObservationsRequest request = GetObservationsRequest.builder()
145
.traceId("trace-123")
146
.build();
147
148
ObservationsViews observations = client.observations().getMany(request);
149
for (ObservationsView obs : observations.getData()) {
150
System.out.println(obs.getName() + " (" + obs.getType() + ")");
151
}
152
153
// Filter by type and date range
154
GetObservationsRequest genRequest = GetObservationsRequest.builder()
155
.type("GENERATION") // String, not enum
156
.fromStartTime(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
157
.toStartTime(OffsetDateTime.parse("2025-10-14T23:59:59Z"))
158
.limit(50)
159
.build();
160
161
ObservationsViews generations = client.observations().getMany(genRequest);
162
```
163
164
## Request Types
165
166
### GetTracesRequest
167
168
**Import:** `import com.langfuse.client.resources.trace.requests.GetTracesRequest;`
169
170
```java { .api }
171
/**
172
* Request parameters for listing traces
173
* Located in requests package (not types)
174
*/
175
public final class GetTracesRequest {
176
Optional<Integer> getPage(); // Page number (default: 1)
177
Optional<Integer> getLimit(); // Items per page (default: 50)
178
Optional<String> getUserId(); // Filter by user ID
179
Optional<String> getName(); // Filter by trace name
180
Optional<String> getSessionId(); // Filter by session ID
181
Optional<OffsetDateTime> getFromTimestamp(); // Filter by start date
182
Optional<OffsetDateTime> getToTimestamp(); // Filter by end date
183
Optional<String> getOrderBy(); // Sort order as string (e.g., "timestamp.desc")
184
Optional<String> getTags(); // Comma-separated tags (must match all)
185
Optional<String> getVersion(); // Filter by version
186
Optional<String> getRelease(); // Filter by release
187
Optional<String> getEnvironment(); // Filter by environment
188
Optional<String> getFields(); // Comma-separated field groups (core, io, scores, observations, metrics)
189
190
static Builder builder();
191
}
192
```
193
194
### DeleteTracesRequest
195
196
```java { .api }
197
/**
198
* Request for deleting multiple traces
199
*/
200
public final class DeleteTracesRequest {
201
List<String> getTraceIds(); // List of trace IDs to delete
202
203
static Builder builder();
204
}
205
```
206
207
### GetObservationsRequest
208
209
**Import:** `import com.langfuse.client.resources.observations.requests.GetObservationsRequest;`
210
211
```java { .api }
212
/**
213
* Request parameters for listing observations
214
* Located in requests package (not types)
215
*/
216
public final class GetObservationsRequest {
217
Optional<Integer> getPage(); // Page number (default: 1)
218
Optional<Integer> getLimit(); // Items per page (default: 50)
219
Optional<String> getName(); // Filter by observation name
220
Optional<String> getUserId(); // Filter by user ID
221
Optional<String> getType(); // Filter by type as string ("SPAN", "EVENT", "GENERATION")
222
Optional<String> getTraceId(); // Filter by trace ID
223
Optional<String> getParentObservationId(); // Filter by parent observation ID
224
Optional<String> getEnvironment(); // Filter by environment
225
Optional<OffsetDateTime> getFromStartTime(); // Filter by start date
226
Optional<OffsetDateTime> getToStartTime(); // Filter by end date
227
Optional<String> getVersion(); // Filter by version
228
229
static Builder builder();
230
}
231
```
232
233
## Response Types
234
235
### TraceWithFullDetails
236
237
```java { .api }
238
/**
239
* Trace with complete details including observations and scores
240
*/
241
public final class TraceWithFullDetails {
242
String getId();
243
OffsetDateTime getTimestamp(); // Timestamp as OffsetDateTime
244
Optional<String> getName();
245
Optional<String> getUserId();
246
Optional<Object> getMetadata();
247
Optional<String> getRelease();
248
Optional<String> getVersion();
249
Optional<String> getProjectId();
250
Optional<Boolean> getPublic();
251
Optional<Boolean> getBookmarked();
252
Optional<List<String>> getTags();
253
Optional<Object> getInput();
254
Optional<Object> getOutput();
255
Optional<String> getSessionId();
256
List<Observation> getObservations(); // All observations in trace
257
List<ScoreV1> getScores(); // All scores for trace
258
259
static Builder builder();
260
}
261
```
262
263
### Traces
264
265
```java { .api }
266
/**
267
* Paginated list of traces
268
*/
269
public final class Traces {
270
List<Trace> getData();
271
MetaResponse getMeta(); // Pagination metadata
272
273
static Builder builder();
274
}
275
```
276
277
### Trace
278
279
Basic trace object (see [Common Types](./common-types.md) for full definition).
280
281
### DeleteTraceResponse
282
283
```java { .api }
284
/**
285
* Response after deleting trace(s)
286
*/
287
public final class DeleteTraceResponse {
288
List<String> getDeletedTraceIds(); // IDs of deleted traces
289
290
static Builder builder();
291
}
292
```
293
294
### ObservationsView
295
296
```java { .api }
297
/**
298
* Observation with additional computed fields
299
*/
300
public final class ObservationsView {
301
String getId();
302
String getTraceId();
303
String getProjectId();
304
Optional<ObservationType> getType(); // SPAN, EVENT, GENERATION
305
Optional<String> getParentObservationId();
306
Optional<String> getName();
307
Optional<Object> getMetadata();
308
Optional<String> getModel();
309
Optional<Object> getModelParameters();
310
Optional<String> getStartTime(); // ISO 8601 timestamp
311
Optional<String> getEndTime(); // ISO 8601 timestamp
312
Optional<String> getCompletionStartTime(); // ISO 8601 timestamp
313
Optional<Object> getInput();
314
Optional<Object> getOutput();
315
Optional<Usage> getUsage(); // Token usage
316
Optional<ObservationLevel> getLevel(); // DEBUG, DEFAULT, WARNING, ERROR
317
Optional<String> getStatusMessage();
318
Optional<String> getVersion();
319
Optional<String> getEnvironment();
320
Optional<String> getPromptId();
321
Optional<String> getPromptName();
322
Optional<Integer> getPromptVersion();
323
Optional<ModelPrice> getModelPrice(); // Computed pricing
324
Optional<Double> getTotalCost(); // Computed cost
325
Optional<Double> getLatency(); // Computed latency in seconds
326
327
static Builder builder();
328
}
329
```
330
331
### ObservationsViews
332
333
```java { .api }
334
/**
335
* Paginated list of observations
336
*/
337
public final class ObservationsViews {
338
List<ObservationsView> getData();
339
MetaResponse getMeta(); // Pagination metadata
340
341
static Builder builder();
342
}
343
```
344
345
### Observation
346
347
Core observation object (see [Common Types](./common-types.md) for full definition).
348
349
## Enums
350
351
### Sort
352
353
```java { .api }
354
/**
355
* Sort order for traces
356
*/
357
public enum Sort {
358
TIMESTAMP_ASC,
359
TIMESTAMP_DESC
360
}
361
```
362
363
### ObservationType
364
365
```java { .api }
366
/**
367
* Type of observation
368
*/
369
public enum ObservationType {
370
SPAN, // Operation or sub-process
371
EVENT, // Point-in-time occurrence
372
GENERATION // LLM generation call
373
}
374
```
375
376
### ObservationLevel
377
378
```java { .api }
379
/**
380
* Log level for observations
381
*/
382
public enum ObservationLevel {
383
DEBUG,
384
DEFAULT,
385
WARNING,
386
ERROR
387
}
388
```
389
390
## Complete Trace Analysis Example
391
392
```java
393
import com.langfuse.client.LangfuseClient;
394
import com.langfuse.client.resources.trace.requests.*;
395
import com.langfuse.client.resources.trace.types.*;
396
import com.langfuse.client.resources.observations.requests.*;
397
import com.langfuse.client.resources.observations.types.*;
398
import com.langfuse.client.resources.commons.types.*;
399
import com.langfuse.client.resources.ingestion.types.ObservationType;
400
401
public class TraceAnalysisExample {
402
public static void main(String[] args) {
403
LangfuseClient client = LangfuseClient.builder()
404
.url("https://cloud.langfuse.com")
405
.credentials("pk-lf-...", "sk-lf-...")
406
.build();
407
408
// 1. List recent traces for a user
409
GetTracesRequest request = GetTracesRequest.builder()
410
.userId("user-123")
411
.fromTimestamp(OffsetDateTime.parse("2025-10-14T00:00:00Z"))
412
.orderBy("timestamp.desc") // String format, not Sort enum
413
.limit(10)
414
.build();
415
416
Traces traces = client.trace().list(request);
417
418
System.out.println("Found " + traces.getMeta().getTotalItems() + " traces");
419
420
// 2. Analyze each trace
421
for (Trace trace : traces.getData()) {
422
System.out.println("\nTrace: " + trace.getName());
423
System.out.println("ID: " + trace.getId());
424
System.out.println("User: " + trace.getUserId());
425
System.out.println("Session: " + trace.getSessionId().orElse("none"));
426
427
// Get full trace details
428
TraceWithFullDetails fullTrace = client.trace().get(trace.getId());
429
430
// Analyze observations
431
System.out.println("Observations: " + fullTrace.getObservations().size());
432
433
for (Observation obs : fullTrace.getObservations()) {
434
System.out.println(" - " + obs.getName().orElse("unnamed") +
435
" (" + obs.getType().orElse(null) + ")");
436
}
437
438
// Analyze scores
439
System.out.println("Scores: " + fullTrace.getScores().size());
440
for (ScoreV1 score : fullTrace.getScores()) {
441
System.out.println(" - " + score.getName() + ": " + score.getValue());
442
}
443
444
// Calculate trace metrics
445
if (!fullTrace.getObservations().isEmpty()) {
446
double totalCost = 0.0;
447
int totalTokens = 0;
448
449
for (Observation obs : fullTrace.getObservations()) {
450
// Get observation details for computed metrics
451
GetObservationsRequest obsReq = GetObservationsRequest.builder()
452
.traceId(trace.getId())
453
.build();
454
455
ObservationsViews obsViews = client.observations().getMany(obsReq);
456
457
for (ObservationsView view : obsViews.getData()) {
458
if (view.getTotalCost().isPresent()) {
459
totalCost += view.getTotalCost().get();
460
}
461
if (view.getUsage().isPresent()) {
462
Usage usage = view.getUsage().get();
463
if (usage.getTotal().isPresent()) {
464
totalTokens += usage.getTotal().get();
465
}
466
}
467
}
468
}
469
470
System.out.println("Total cost: $" + totalCost);
471
System.out.println("Total tokens: " + totalTokens);
472
}
473
}
474
475
// 3. Find all generations with errors
476
GetObservationsRequest errorRequest = GetObservationsRequest.builder()
477
.type("GENERATION") // String, not enum
478
.fromStartTime(OffsetDateTime.parse("2025-10-14T00:00:00Z"))
479
.limit(100)
480
.build();
481
482
ObservationsViews observations = client.observations().getMany(errorRequest);
483
484
System.out.println("\n\nGenerations with errors:");
485
for (ObservationsView obs : observations.getData()) {
486
if (obs.getLevel().isPresent() && obs.getLevel().get() == ObservationLevel.ERROR) {
487
System.out.println("Error in trace " + obs.getTraceId() + ": " +
488
obs.getStatusMessage().orElse("no message"));
489
}
490
}
491
492
// 4. Analyze high-cost traces
493
System.out.println("\n\nHigh-cost observations:");
494
for (ObservationsView obs : observations.getData()) {
495
if (obs.getTotalCost().isPresent() && obs.getTotalCost().get() > 0.01) {
496
System.out.println("Trace " + obs.getTraceId() +
497
" - Model: " + obs.getModel().orElse("unknown") +
498
" - Cost: $" + obs.getTotalCost().get());
499
}
500
}
501
502
// 5. Clean up old test traces
503
GetTracesRequest oldTestsRequest = GetTracesRequest.builder()
504
.tags("test") // String, not List
505
.toTimestamp(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
506
.limit(100)
507
.build();
508
509
Traces oldTests = client.trace().list(oldTestsRequest);
510
511
if (!oldTests.getData().isEmpty()) {
512
List<String> traceIds = oldTests.getData().stream()
513
.map(Trace::getId)
514
.collect(java.util.stream.Collectors.toList());
515
516
DeleteTracesRequest deleteRequest = DeleteTracesRequest.builder()
517
.traceIds(traceIds)
518
.build();
519
520
DeleteTraceResponse deleteResponse = client.trace().deleteMultiple(deleteRequest);
521
System.out.println("\nDeleted " + deleteResponse.getDeletedTraceIds().size() +
522
" old test traces");
523
}
524
}
525
}
526
```
527
528
## Query Patterns
529
530
### Finding Traces by Session
531
532
```java
533
GetTracesRequest sessionRequest = GetTracesRequest.builder()
534
.sessionId("session-123")
535
.orderBy("timestamp.asc") // String format, not Sort enum
536
.build();
537
538
Traces sessionTraces = client.trace().list(sessionRequest);
539
```
540
541
### Finding Observations by Parent
542
543
```java
544
GetObservationsRequest childRequest = GetObservationsRequest.builder()
545
.parentObservationId("parent-obs-123")
546
.build();
547
548
ObservationsViews children = client.observations().getMany(childRequest);
549
```
550
551
### Filtering by Environment and Version
552
553
```java
554
GetTracesRequest prodRequest = GetTracesRequest.builder()
555
.environment("production")
556
.version("v2.1.0")
557
.build();
558
559
Traces prodTraces = client.trace().list(prodRequest);
560
```
561
562
## Best Practices
563
564
1. **Use Pagination**: Always set appropriate page size limits for large result sets
565
2. **Filter by Date**: Use date range filters to limit query scope and improve performance
566
3. **Index on Tags**: Use tags for efficient filtering of traces by feature or category
567
4. **Session Grouping**: Group related traces using sessionId for workflow analysis
568
5. **Environment Separation**: Use environment field to separate production/staging/development data
569
6. **Cost Monitoring**: Regularly query ObservationsView to monitor LLM costs
570
7. **Error Tracking**: Filter by ObservationLevel.ERROR to find and analyze failures
571
8. **Deletion Caution**: Trace deletion is irreversible - use with care
572
573
## Related Documentation
574
575
- [Ingestion API](./ingestion.md) - Creating traces and observations
576
- [Scores](./scores.md) - Score management for traces and observations
577
- [Sessions](./sessions.md) - Session management and retrieval
578
- [Common Types](./common-types.md) - Shared type definitions
579
- [Pagination](./pagination.md) - Pagination utilities
580