---
title: "Generation ingest API | Grafana Cloud documentation"
description: "Export generation and workflow step data through HTTP or gRPC."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Generation ingest API

The generation ingest API receives structured generation and workflow step data from Agent Observability SDKs. It supports both HTTP and gRPC transports.

## Before you begin

- Agent Observability is enabled on your Grafana Cloud stack.
- You have the Agent Observability API URL, instance ID, and Grafana Cloud access policy token. Refer to [Use Agent Observability on Grafana Cloud](/docs/grafana-cloud/observe-and-act/agent-observability/get-started/grafana-cloud/#collect-credentials-from-grafana-cloud) for setup steps.
- Your producer can assign stable generation IDs so retries are idempotent.

## Endpoints

Expand table

| Transport | Endpoint                                                 |
|-----------|----------------------------------------------------------|
| HTTP      | `POST /api/v1/generations:export`                        |
| gRPC      | `agento11y.v1.GenerationIngestService.ExportGenerations` |

## Workflow step endpoints

Use workflow step endpoints to export non-LLM execution nodes in an agentic workflow. Workflow steps are linked to generations and appear in the conversation graph and detail view.

Expand table

| Transport | Endpoint                                                     |
|-----------|--------------------------------------------------------------|
| HTTP      | `POST /api/v1/workflow-steps:export`                         |
| gRPC      | `agento11y.v1.WorkflowStepIngestService.ExportWorkflowSteps` |

## Authentication

Use the Grafana Cloud instance ID and Grafana Cloud access policy token you collected from Agent Observability. HTTP requests without valid credentials receive `401 Unauthorized`. gRPC requests without valid credentials receive `Unauthenticated`.

## Request body

Each request contains an array of generation objects. Key fields:

Expand table

| Field                   | Required | Description                                                                                         |
|-------------------------|----------|-----------------------------------------------------------------------------------------------------|
| `id`                    | Yes      | Unique, stable generation identifier assigned by your producer.                                     |
| `conversation_id`       | Yes      | Groups generations into a conversation thread.                                                      |
| `model.provider`        | Yes      | LLM provider name, for example, `openai`.                                                           |
| `model.name`            | Yes      | Model name, for example, `gpt-4o`.                                                                  |
| `mode`                  | No       | `SYNC` or `STREAM`. Default: `SYNC`.                                                                |
| `agent_name`            | No       | Agent identifier for catalog tracking.                                                              |
| `agent_version`         | No       | SDK-declared version label. Set this for agent catalog versions and per-version Performance charts. |
| `effective_version`     | No       | SDK-supplied catalog key. Must match `sha256:<64 lowercase hex>` when set.                          |
| `system_prompt`         | No       | System prompt text.                                                                                 |
| `input`                 | No       | Array of input messages.                                                                            |
| `output`                | No       | Array of output messages.                                                                           |
| `tools`                 | No       | Array of tool definitions.                                                                          |
| `usage`                 | No       | Token usage breakdown.                                                                              |
| `timestamps`            | No       | Start, first token, and end timestamps.                                                             |
| `metadata`              | No       | Key-value metadata pairs.                                                                           |
| `tags`                  | No       | String tags for filtering.                                                                          |
| `trace_id`              | No       | OpenTelemetry trace ID.                                                                             |
| `span_id`               | No       | OpenTelemetry span ID.                                                                              |
| `parent_generation_ids` | No       | List of upstream generation IDs for multi-agent dependency tracking.                                |

Generation and conversation IDs are opaque strings, not necessarily UUIDs. You can use IDs that contain reserved URL characters, for example, `session/customer-support/42`. Keep the original value in the export payload and reuse each generation ID when retrying its export.

## Message parts

Messages can use the `system`, `user`, `assistant`, or `tool` role. Put model instructions in the top-level `system_prompt` field when your SDK or framework exposes one. If your producer represents instructions as chat history instead, send them as `system` role input messages. Evaluation targets and prompt-template variables read the top-level `system_prompt` field first, then fall back to text from `system` role input messages when that field is empty.

Message parts can contain `text`, `thinking`, `tool_call`, `tool_result`, or `media`. Use `media` for image or video prompt and response content. A `media` part stores content metadata plus a `url` value. Depending on the producer and content-capture mode, the URL may be a data URL, a same-origin URL, or an opaque reference URI. Metadata-only capture can preserve the media part and metadata while stripping the URL payload.

## Token usage fields

Expand table

| Field                      | Description                         |
|----------------------------|-------------------------------------|
| `input_tokens`             | Tokens in the request.              |
| `output_tokens`            | Tokens in the response.             |
| `cache_read_input_tokens`  | Tokens served from cache.           |
| `cache_write_input_tokens` | Tokens written to cache.            |
| `reasoning_tokens`         | Tokens used for reasoning/thinking. |

## Tool definitions

Expand table

| Field               | Description                        |
|---------------------|------------------------------------|
| `name`              | Tool name.                         |
| `description`       | Tool description.                  |
| `type`              | Tool type.                         |
| `input_schema_json` | JSON schema for tool input.        |
| `deferred`          | Whether the tool is lazily loaded. |

## Response

The response contains per-generation results:

Expand table

| Field           | Description                          |
|-----------------|--------------------------------------|
| `generation_id` | The generation ID.                   |
| `accepted`      | Whether the generation was accepted. |
| `error`         | Error message if rejected.           |

Partial success is supported — some generations may be accepted while others are rejected. Validation and duplicate errors are descriptive. Internal failures use `internal server error; error_id=<id>` in the existing `error` field, with one shared ID for internal failures in the batch.

When Agent Observability can’t persist one or more generations because the store is temporarily unavailable, the generation ingest API returns a retryable transport status instead of a successful partial response. HTTP requests receive `503 Service Unavailable`. gRPC requests receive `Unavailable`. Retry the same batch; generation IDs make accepted items idempotent, and duplicate items are treated as successful no-ops.

## Workflow step request body

Each workflow step request contains an array of workflow step objects. Key fields:

Expand table

| Field                   | Required | Description                                   |
|-------------------------|----------|-----------------------------------------------|
| `id`                    | Yes      | Unique workflow step identifier.              |
| `conversation_id`       | Yes      | Conversation that contains the workflow step. |
| `step_name`             | No       | Human-readable workflow node name.            |
| `agent_name`            | No       | Agent or component that executed the step.    |
| `agent_version`         | No       | SDK-declared version label.                   |
| `parent_step_ids`       | No       | Upstream workflow step IDs for graph edges.   |
| `linked_generation_ids` | No       | LLM generation IDs executed inside this step. |
| `input_state`           | No       | Structured input state for the step.          |
| `output_state`          | No       | Structured output state for the step.         |
| `started_at`            | No       | Step start timestamp.                         |
| `ended_at`              | No       | Step completion timestamp.                    |
| `tags`                  | No       | String tags for filtering and grouping.       |
| `metadata`              | No       | Key-value metadata pairs.                     |
| `error`                 | No       | Error details if the workflow step failed.    |

Workflow steps don’t replace generations. Send generations for LLM calls and workflow steps for the surrounding orchestration.

## Multi-agent dependency tracking

The `parent_generation_ids` field lets you declare parent-child relationships between generations. Set it to the list of generation IDs whose output the current generation consumes. Agent Observability uses these links to build a dependency DAG and propagate quality signals — if an upstream generation fails evaluation, all downstream dependents are flagged.

For example, in an orchestrator that spawns agents A, B, and C where C depends on A and B:

- A: `parent_generation_ids` = `[]`
- B: `parent_generation_ids` = `[]`
- C: `parent_generation_ids` = `["<A_GENERATION_ID>", "<B_GENERATION_ID>"]`

## Agent version computation

Agent Observability resolves an effective agent version as `sha256:<64 lowercase hex>` for agent catalog queries. If `effective_version` is set, Agent Observability validates and uses that SDK-supplied catalog key. If it is omitted or blank and `agent_version` is set, Agent Observability derives the catalog key from the declared `agent_version`. If both are omitted, Agent Observability computes a fallback key from the system prompt. The resolved effective version is projection-only and doesn’t modify the stored generation payload.

Set `agent_version` when you want catalog, Quality, and Performance views to compare declared releases. The agent catalog can compute an effective version without it, but Performance charts join Prometheus metrics by the SDK-emitted `gen_ai.agent.version` label.

## Next steps

- [Browse and debug conversations](/docs/grafana-cloud/observe-and-act/agent-observability/observe-and-troubleshoot/conversations)
- [Instrument agent dependencies and workflows](/docs/grafana-cloud/observe-and-act/agent-observability/instrumentation/agent-dependencies-and-workflows)
