Repository navigation
Ingestion
The Ingestion resource lets you send traces, spans, and generations to Langfuse. Every call sends immediately to the API -- no buffering or flushing required.
$ingestion = $langfuse->ingestion();The environment is set on the Langfuse constructor and applied to all ingestion events automatically.
| Object | Description | Created from |
|---|---|---|
| Trace | Root of an observation tree. Represents a single request or workflow. | $ingestion->trace() |
| Span | Groups related work within a trace. Can be nested. |
$trace->span() or $span->span()
|
| Generation | Represents an LLM call. |
$trace->generation() or $span->generation()
|
All objects expose an $id property and their $traceId. Context IDs (traceId, parentObservationId) are threaded automatically when using the fluent API.
A trace is the root of every observation tree.
$trace = $ingestion->trace(
name: 'handle-request',
userId: 'user-456',
sessionId: 'session-789',
input: 'What is the weather?',
metadata: ['source' => 'api'],
tags: ['production'],
);
echo $trace->id; // auto-generated UUID$traceId is optional. If omitted, a UUID v4 is generated automatically. You can also provide your own:
$trace = $ingestion->trace(
name: 'handle-request',
traceId: 'my-custom-trace-id',
);$trace->update(
output: 'It is 22 degrees and sunny.',
metadata: ['duration_ms' => 1234],
);| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Name of the trace |
traceId |
?string |
No | Custom ID, auto-generated if omitted |
sessionId |
?string |
No | Group traces by session |
userId |
?string |
No | Associate with a user |
input |
array|string|null |
No | Input data |
output |
array|string|null |
No | Output data |
metadata |
?array |
No | Arbitrary metadata |
tags |
?array |
No | List of tags |
Spans group related work within a trace. They can be nested to any depth.
$span = $trace->span(name: 'web-search-batch');$childSpan = $span->span(name: 'single-search');traceId and parentObservationId are set automatically.
$span->update(
output: ['results' => 3],
endTime: date('c'),
);$generation = $span->generation(
name: 'summarize',
input: 'Summarize the search results',
output: 'Here is a summary...',
model: 'gpt-4o',
);| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Name of the span |
spanId |
?string |
No | Custom ID, auto-generated if omitted |
input |
array|string|null |
No | Input data |
output |
array|string|null |
No | Output data |
startTime |
?string |
No | ISO 8601 timestamp, defaults to now |
endTime |
?string |
No | ISO 8601 timestamp |
metadata |
?array |
No | Arbitrary metadata |
Generations represent LLM calls. Create them from a trace or a span.
$generation = $trace->generation(
name: 'llm-call',
input: ['messages' => [['role' => 'user', 'content' => 'Hello']]],
output: 'Hi there!',
model: 'gpt-4o',
modelParameters: ['temperature' => 0.7],
promptName: 'greeting',
promptVersion: 1,
);$generation = $span->generation(
name: 'summarize-call',
input: 'Summarize this text',
output: 'Summary text here.',
model: 'gpt-4o',
);$generation->update(
output: 'Updated response',
metadata: ['tokens' => 150],
endTime: date('c'),
);| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Name of the generation |
input |
array|string |
Yes | Input sent to the LLM |
output |
array|string |
Yes | Output from the LLM |
generationId |
?string |
No | Custom ID, auto-generated if omitted |
model |
?string |
No | Model name (e.g. gpt-4o) |
modelParameters |
?array |
No | Parameters like temperature, max_tokens |
promptName |
?string |
No | Link to a Langfuse prompt |
promptVersion |
?int |
No | Version of the linked prompt |
metadata |
?array |
No | Arbitrary metadata |
startTime |
?string |
No | ISO 8601 timestamp, defaults to now |
endTime |
?string |
No | ISO 8601 timestamp |
$ingestion = $langfuse->ingestion();
// 1. Create the trace
$trace = $ingestion->trace(
name: 'handle-request',
userId: 'user-789',
input: 'What is the weather?',
);
// 2. Create a span for a batch of work
$span = $trace->span(name: 'search-batch');
// 3. Nested child span
$child = $span->span(name: 'weather-api-call');
$child->update(output: ['temp' => 22], endTime: date('c'));
// 4. LLM generation nested under the span
$span->generation(
name: 'summarize',
input: 'Summarize weather data',
output: 'It is 22 degrees and sunny.',
model: 'gpt-4o',
);
// 5. Close the span
$span->update(output: ['answer' => 'It is 22 degrees.'], endTime: date('c'));
// 6. Update the trace with the final output
$trace->update(output: 'It is 22 degrees and sunny.');This produces the following observation tree in Langfuse:
handle-request (trace)
└── search-batch (span)
├── weather-api-call (span)
└── summarize (generation)
You can also use Ingestion directly without the fluent objects:
// Send any event type
$ingestion->send('trace-create', [
'id' => 'my-trace-id',
'name' => 'my-trace',
'timestamp' => Ingestion::now(),
'environment' => 'production',
]);| Method | Returns | Description |
|---|---|---|
Ingestion::uuid() |
string |
Generate a UUID v4 |
Ingestion::now() |
string |
Current UTC timestamp with milliseconds |