Sessions

Fork a session

Branches a new session from a point in this session's history: same context, different continuation.

The fork gets its own conversation whose messages reference the same documents as the parent rather than copying them, so there is one stored copy of the content and a retention purge erases it from both. Recorded tool results ride along on those messages and are replayed as model input on the fork's next turn — forking never re-invokes a tool, so exploring a "what if" cannot send an email or charge a card a second time. The consequence to accept is that a forked turn sees the tool data as it was, not as it is now.

The fork is created inert: auto_generate is false and no generation is triggered. Drive it with the normal message and generate endpoints. The fork has no actor — attach one only if the branch is meant to be driven by the same end user, since single_session_per_actor agents allow one open session per actor.

post/v1/projects/{project_id}/sessions/{session_id}/fork

Request

  • Base URL: https://api.naturali.ai
  • URL: https://api.naturali.ai/v1/projects/{project_id}/sessions/{session_id}/fork
  • 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

session_idstring required
Example:sess_V1StGXR8Z5jdHi6B

Session public ID

Request body

fork_at_positioninteger

The parent conversation position to branch after. Messages at positions 0..N are carried into the fork. Omit it to branch at the tip (the whole history).

agent_idstring

Agent the fork runs against. Defaults to the parent session's agent; overriding it is the point of forking — same context, a different agent or agent version. Must belong to the same project as the session being forked.

namestring

Optional name for the forked session

tagsTagBag

Key-value labels on a resource. A flat object of string values — an array, a nested object or a number is rejected with 400 VALIDATION_FAILED, never coerced. Keys are opaque and stored verbatim, so cost_center and costCenter are two different tags. Matched by JSONB containment wherever tags are read: the ?tags= filter and knowledge search.

Keys beginning system. are reserved: the platform writes them to record which conversation, actor, agent and role a row came from, and a write naming one is refused with 400 RESERVED_TAG_KEY. They are read and filtered like any other tag.

The bag is bounded, because every pair reaches the IAM context of every access check on the resource: at most 50 keys, each key at most 128 characters and each value at most 256. A write past a bound — including a merge that would grow the stored bag past the key count — is 400 VALIDATION_FAILED with meta.limit naming the bound it crossed. system.* keys are the platform's and do not count against the 50.

tool_contextobject nullable

Overrides the parent's tool_context on the fork. Omit it and the fork inherits the parent's, so the branch is faithful to the run it came from.

Example request

{
  "fork_at_position": 7,
  "agent_id": "agent_V1StGXR8Z5jdHi6B",
  "name": "retry with stricter system prompt",
  "tags": {
    "team": "finance",
    "env": "prod"
  }
}

Response

Fork created

idstring

Session public ID

agent_idstring

Agent public ID, kept after a shared agent is deleted by its owner.

conversation_idstring

Underlying conversation public ID

status'open' | 'closed' | 'expired'
namestring nullable
actor_idstring nullable

Public ID of the user actor, or null when the session was created without one

tagsTagBag

Key-value labels on a resource. A flat object of string values — an array, a nested object or a number is rejected with 400 VALIDATION_FAILED, never coerced. Keys are opaque and stored verbatim, so cost_center and costCenter are two different tags. Matched by JSONB containment wherever tags are read: the ?tags= filter and knowledge search.

Keys beginning system. are reserved: the platform writes them to record which conversation, actor, agent and role a row came from, and a write naming one is refused with 400 RESERVED_TAG_KEY. They are read and filtered like any other tag.

The bag is bounded, because every pair reaches the IAM context of every access check on the resource: at most 50 keys, each key at most 128 characters and each value at most 256. A write past a bound — including a merge that would grow the stored bag past the key count — is 400 VALIDATION_FAILED with meta.limit naming the bound it crossed. system.* keys are the platform's and do not count against the 50.

auto_generateboolean

When true, automatically triggers generation after each user message (if no generation is in progress).

generating_atstring date-time nullable

Timestamp when the current generation started, or null if not generating.

created_atstring date-time
updated_atstring date-time
inactivity_ttl_secondsinteger

Number of seconds of inactivity after which the session expires. 0 means the session never expires.

message_delay_secondsinteger nullable

Number of seconds to wait after the last user message before sending to the LLM. Acts as a debounce: each new message resets the timer. null or absent means no delay (immediate processing).

max_context_messagesinteger nullable

Maximum number of recent conversation messages sent to the model on each generation. Takes precedence over the agent's max_context_messages; null defers to it. A fork keeps its parent's value.

last_activity_atstring date-time nullable

Timestamp of the last activity on the session (message added or response generated).

forked_from_session_idstring nullable

Public ID of the session this one was forked from, or null when it was not forked. Also null once that parent is deleted — a fork survives its parent and keeps its own history.

forked_from_positioninteger nullable

The parent conversation position this session branched after, or null when it is not a fork or was forked at the tip.

Example response

{
  "id": "sess_V1StGXR8Z5jdHi6B",
  "agent_id": "agent_V1StGXR8Z5jdHi6B",
  "conversation_id": "conv_V1StGXR8Z5jdHi6B",
  "status": "open",
  "name": "Support chat",
  "actor_id": "actor_V1StGXR8Z5jdHi6B",
  "tags": {
    "team": "finance",
    "env": "prod"
  },
  "inactivity_ttl_seconds": 300,
  "message_delay_seconds": 3,
  "max_context_messages": 20,
  "forked_from_session_id": "sess_V1StGXR8Z5jdHi6B",
  "forked_from_position": 7
}

Changes

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