Skip to main content
Runs one agent turn and streams the result back as Anthropic-style server-sent events.
Examples below use DataGen Cloud (https://api.datagen.dev). Self-hosted installs replace that host with their own server — http://10.0.0.42:3001/api/agents/invoice-agent/v1/messages — and everything else is identical. See Base URL.

Request body

Other Anthropic fields (max_tokens, temperature, tools, …) are accepted and ignored.

metadata

metadata.builder runs the turn against the agent builder’s working tree (storage-backed agents only, requires Admin or Builder) and metadata.test marks a new conversation as a hidden test run. Both back the DataGen web UI; they are not intended for external integrations.

Writing to a connected repository

API-key calls are read-only by default. For an agent backed by a connected repository, the agent clones and reads the repo but never writes back, unless you explicitly ask it to. To let a turn commit its work:
With read_only: false, a turn that changes any file ends with git add -A, a commit authored by datagen-agent, and a push to the repository’s default branch — not to a scratch branch. Send it only for integrations whose whole purpose is to modify the repository, and consider pointing the agent at a repo whose default branch is protected.
Storage-backed agents have no repository and never push. Their working files are restored fresh for each turn and are not written back; the durable output of a turn is whatever the agent writes to its outputs directory, which is published to the workspace store.

Attachments

Base64 only — no data: prefix. Filenames are sanitized to a safe basename and de-duplicated. Malformed entries and anything past the caps are dropped silently, so validate client-side if a missing file would be a silent failure for you. Attachments are never committed to a connected repo.

Response

200 OK, Content-Type: text/event-stream, plus an X-Conversation-Id response header — capture it when you didn’t supply your own id.
Block types. text, thinking (with a following signature_delta), and — when stream_tool_calls is on — tool_use (with input_json_delta) and tool_result (carrying tool_use_id, content, is_error). The tool_result block is a DataGen extension; generic Anthropic clients ignore it. Granularity. Blocks arrive whole, not token by token: each is content_block_start + one full content_block_delta + content_block_stop. index is a running counter for the turn. Termination. The stream ends at message_stop — there is no data: [DONE] sentinel. Usage. message_delta.usage carries input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens, and the DataGen-specific total_cost_usd for the turn.
A failure after the stream opens arrives as an SSE error event on an already-200 response: event: error data: {"error":{"type":"api_error","message":"…"}}. Check for error events, not just the HTTP status.

Examples

extra_body (Python) and the cast on metadata (TypeScript) exist because the SDKs type metadata as Anthropic’s {user_id} object. The field is passed through to DataGen untouched.

Reading the stream without an SDK


Model-routed variant

If you’d rather select the agent by model string than by URL path:
with "model": "datagen-agent--data-agent" (or a bare agent slug). Useful when a client only lets you configure one base URL and switches agents through its model picker. Everything else is identical.