Agents

Run an agent generation

Sends messages to the agent, resolves its tools, and runs the AI model loop. Background by default: returns 202 Accepted with a generation_id to poll via GET /v1/projects/{project_id}/generations/{generation_id}. Pass ?wait=true to block and receive the result inline, where client tools pause the generation and return requires_action. Streaming (stream: true) implies waiting. Pass idempotency_key to make a retry safe: a request whose key is already claimed runs nothing and answers 202 with the generation the key names.

A credential scoped to a project the agent is shared with, through an accepted share, runs it in that project: on the publisher's configuration, recorded, metered and governed in the grantee project.

post/v1/projects/{project_id}/agents/{agent_id}/generate

Request

  • Base URL: https://api.naturali.ai
  • URL: https://api.naturali.ai/v1/projects/{project_id}/agents/{agent_id}/generate
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://api.naturali.ai/authorize, token URL https://api.naturali.ai/token, scopes: mcp:access)

Path parameters

agent_idstring required
Example:agent_V1StGXR8Z5jdHi6B

Agent public ID

Query parameters

waitboolean

When omitted or false (default), the generation runs in the background and 202 Accepted is returned immediately with a generation_id to poll. Pass true to block until the generation settles and receive the result. Mutually exclusive with stream: true. An MCP tool call always waits.

Headers

Idempotency-Keystring

The request's deduplication key. Equivalent to idempotency_key in the request body; sending both with different values is 400 VALIDATION_FAILED. A non-empty string of at most 255 characters.

Request body

streamboolean

When true the response is an SSE stream

trace_idstring

Optional trace ID to group generations. Each generation appends its own steps to the trace's steps object, and step_count covers them all.

parent_trace_idstring nullable

The trace ID of the parent agent generation that triggered this one (for agent-to-agent calls)

root_trace_idstring nullable

The trace ID of the root generation in the call chain; if omitted, this generation is the root

max_call_depthinteger

Maximum nested agent-call depth; 0 short-circuits with a depth-guard response

tool_contextobject nullable

Key-value pairs forwarded as X-Naturali-Context-<key> headers on every http and mcp tool call in this generation. The header name is the deployment's configured context prefix (X-Naturali-Context- by default) plus the key verbatim — no character is re-cased. Keys are never case-converted — they round-trip exactly as sent. An invalid or colliding key is rejected with 400 INVALID_TOOL_CONTEXT_KEY.

action_idstring

Logical action label recorded on the generation's usage meter, so spend can be rolled up per action (e.g. an A/B/C/D operating action).

guardrail_contextobject nullable

Caller-supplied guardrail context (the context.* namespace guard and class expressions read at tool-dispatch time). Free-form and never interpreted by the platform; a guardrail may combine it with a context_tool per its context_mode. See the guardrails module.

metadataNullableMetadataBag nullable

A MetadataBag on a request field where null is meaningful: a full-replacement update that clears the bag. A record whose bag is unset leaves the field out.

idempotency_keystring

Deduplication key, unique within the project, that makes a retry of an at-least-once delivery or an ambiguous failure safe. The first request under a key runs the generation; any later request carrying it runs nothing and answers 202 with the generation the key names, whatever state it has reached — including a retry that arrives while the original is still running. The key is claimed by the generation record for as long as the record exists.

Every other body field except stream is the request the key names: reusing a key with any of them changed, or on another agent of the project, is 409 IDEMPOTENCY_KEY_REUSED. stream and wait say how the caller receives the generation, not what it is, so a retry may flip them.

Example request

{
  "metadata": {
    "author": "John",
    "revision": 2
  },
  "idempotency_key": "discord-1287654321098765432",
  "knowledge_config": {
    "tags": {
      "team": "finance",
      "env": "prod"
    }
  }
}

Response

Generation result or SSE stream (only when ?wait=true or stream: true)

idstring required

Public ID of the generation

trace_idstring required

Public ID of the trace for this generation

status'completed' | 'requires_action' required

Generation status

ai_provider_idstring nullable

Public ID of the AI provider that served output.model — the target a model route picked, or the agent's pinned provider. A model string alone does not identify its provider: two providers in one project can serve byte-identical model names, so this is what makes the value safe to map back to a name a gateway in front of this runtime publishes. Null when the generation resolved no serving provider.

Example response

{
  "id": "gen_V1StGXR8Z5jdHi6B",
  "trace_id": "trace_V1StGXR8Z5jdHi6B",
  "ai_provider_id": "aip_V1StGXR8Z5jdHi6B"
}

Changes

No recorded changes to this operation across all 1 revision of this API.