Agent Versions

Set or replace a staged rollout

Starts serving two archived versions side by side: canary_percent of traffic gets canary_version, the rest gets stable_version.

Assignment is deterministic — it hashes the actor behind the request's session (falling back to the session itself), so one end user never flip-flops between configs mid-conversation. Requests with neither are split randomly.

While a release is active the agent's live columns act as a draft: further edits archive new versions but do not disturb either side of the running split. End the rollout with promote or abort.

put/v1/projects/{project_id}/agents/{agent_id}/release

Request

  • Base URL: https://api.naturali.ai
  • URL: https://api.naturali.ai/v1/projects/{project_id}/agents/{agent_id}/release
  • 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

Request body

stable_versioninteger required

An existing version to serve as the baseline

canary_versioninteger required

An existing version to trial. Must differ from stable_version.

canary_percentinteger required

Percentage of traffic to assign to canary_version

promotion_gatestring nullable

Eval to gate promotion on. It must belong to this project and evaluate this agent; anything else is a 400. Omit it, or send null, for a rollout that can be promoted at will.

Example request

{
  "stable_version": 3,
  "canary_version": 4,
  "canary_percent": 20,
  "promotion_gate": "eval_V1StGXR8Z5jdHi6B"
}

Response

The agent, with its active release set

idstring

Public ID of the agent

project_idstring

Public ID of the owning project

ai_provider_idstring nullable

Public ID of the pinned AI provider. Null when the agent resolves its model through model_route_id instead.

model_route_idstring nullable

Public ID of the model route that resolves this agent's completion model. Null when the agent pins a provider through ai_provider_id. Mutually exclusive with ai_provider_id and model.

namestring nullable

Display name

instructionsstring nullable

System instructions guiding behavior

modelstring nullable

Model identifier

max_stepsinteger nullable

Maximum agent loop steps before stopping. The budget bounds a turn: a generation that pauses at requires_action and resumes after submit-tool-outputs continues the same turn and spends what is left of it, so a turn that arrives with nothing left completes with stop_reason: "max_steps" instead of calling the model again.

tool_choiceunknown
stop_conditionsobject[] nullable

Conditions that end the agent's work early, on top of max_steps — turn-scoped (has_tool_call) or chain-scoped (max_chain_generations). See the create request body for the accepted shapes.

active_tool_idsstring[] nullable

Subset of the bound tools that are active

guardrail_idsstring[] nullable

Guardrails attached at the agent scope, governing every tool call the agent makes.

step_rulesobject[] nullable

Per-step overrides of tool_choice and active_tool_ids. Steps are numbered from the first step of the turn, and that numbering spans a requires_action pause — a rule fires once per turn, not once per resumption.

boundary_policyobject nullable

Allowed/denied runtime actions

temperaturenumber nullable

Sampling temperature

output_schemaobject nullable

JSON Schema describing the structured object the model must return. When set, non-streaming generations constrain output to this schema and the parsed value is returned as output.object. The schema is enforced on the way back, not just sent to the model: an object that violates it fails the generation with 502 OUTPUT_SCHEMA_VALIDATION_FAILED, naming the violated field. Constraints beyond required/type (minLength, enum, pattern, minItems) are honored and are what reject a structurally valid but degenerate answer. See the Structured Output section in the Agents module docs.

max_context_messagesinteger nullable

Maximum number of recent messages to include in the context window sent to the model. When null, all messages are included.

max_output_tokensinteger nullable

Maximum number of tokens the model may generate per step of a turn. A response that reaches it stops with stop_reason length. Null leaves the model's default.

single_session_per_actorboolean

When true, only one open session per actor_id is allowed for this agent. Creating a second open session for the same actor returns 409.

trace_content_mode'full' | 'none' | 'null' nullable

Agent-scope zero-retention setting. null (the default) inherits the project's trace_content_mode; none means this agent's trace and generation content is never persisted. An agent may tighten a storing project to none but cannot loosen a none project back to full.

on_approval_expiry'terminate' | 'react' | 'null' nullable

What happens when one of this agent's held tool calls expires un-approved. null (the default) and terminate end the chain there — the expired approval, its approvals.expired event and the auto-filed approval_expired exception are the whole record. react spawns a continuation that reports the staleness to the agent, for an agent that acts on it.

versioninteger

Current config version. Starts at 1 and increments on every write that changes the config; each increment archives the new config as an AgentVersion. A write that changes nothing leaves it untouched.

created_atstring date-time
updated_atstring date-time

Example response

{
  "id": "agent_V1StGXR8Z5jdHi6B",
  "tool_bindings": [
    {
      "tool_id": "tool_V1StGXR8Z5jdHi6B"
    }
  ],
  "knowledge_config": {
    "tags": {
      "team": "finance",
      "env": "prod"
    }
  },
  "max_output_tokens": 1024,
  "reasoning": {
    "effort": "low"
  },
  "version": 3,
  "active_release": {
    "stable_version": 3,
    "canary_version": 4,
    "canary_percent": 20,
    "promotion_gate": "eval_V1StGXR8Z5jdHi6B"
  }
}

Changes

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