Injects a turn into the session as the chosen participant.
The run is queued; the reply arrives on the stream / messages endpoints. The participant must already be bound to the session's agent — an unbound sender is dropped and filed as an access request. On a sandbox session the participant is optional. Omitted, the turn speaks as the session's recorded participant, or else as the caller's own test customer: an external contact with no real channel, created and bound to the agent on first use. A non-draft turn on an agent that has never been deployed is a 400, since there is no published version to run. A session that records its participant — a fork's customer, a widget's visitor, or the test customer once an unnamed turn has run — speaks as that one only. Naming anyone else is a 409: the turn would start a second, empty conversation inside this one. The operator of a takeover rehearsed on the session is the exception, since that turn is relayed to the customer. `revisionPolicy: PROPOSAL` with a `recommendationId` runs that card's change, made to the deployed release in memory — what approving the card would deploy — without saving anything. Agent admins only (403); 409 when the card has no change waiting or the live agent already has it. 503 means the turn was <b>deferred</b>, not lost: participant resolution faulted, so admission could not be decided and nothing was enqueued. On a provider webhook this asks for a redelivery; here the caller is the widget, so it must be told to retry rather than sit waiting on a stream that will never produce a reply.
Authorization
Bearer JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token.
In: header
Path Parameters
The session id returned by open.
The tenant identifier
The participant to speak as and the turn text.
The participant to speak as. Optional on a sandbox session: omitted, the turn speaks as the session's recorded participant (a fork's subject), or else as the caller's own test customer — an external contact with no real channel, created and bound to the agent on first use.
uuidOptional per-turn async-execution-mode override (sandbox debug console). Forces this run's async tools (consult / approval / delegate) to await or background, winning over each step's deployed AsyncExecution.Mode for this turn only — so an operator can exercise the suspend-and-answer loop without redeploying the agent. Omitted (or UNSPECIFIED) = no override: the deployed step config applies (current behavior). Honoured only for sandbox sessions; nothing is persisted to the agent.
"UNSPECIFIED" | "AGENT_DECIDES" | "FORCE_AWAIT" | "FORCE_BACKGROUND"Which body of the agent's code this turn runs: the deployed release (default, unchanged
behaviour), the caller's own draft, or a recommendation card's change
(FruxonRevisionPolicy.Proposal, with SendFruxonTurnRequest.RecommendationId).
FruxonRevisionPolicy.Draft is what closes the edit-then-test loop — without it,
seeing whether a fix works means publishing it to every real customer first — and
PROPOSAL does the same for a change a review proposed. 400 when the caller has no draft
for the agent, and sandbox sessions only. See FruxonChannel.FruxonRevisionPolicy.
"UNSPECIFIED" | "PUBLISHED" | "DRAFT" | "PROPOSAL"Hold every tool call that changes something until the operator confirms it, for this turn. Sandbox sessions only.
The sandbox hard-blocks channel sends and memory writes, and simulates every connection with no sandbox saved unless SendFruxonTurnRequest.SandboxRouting chooses Live for it. What can still change something real is a connection chosen Live, and a built-in that acts on the workspace itself. This is the guard for those. Only a call that reaches production is held: not a read — a confirmation queue nobody reads is worse than none — and not a write the run sends to the simulator or a vendor sandbox. Each held call suspends the run on the ordinary human-approval gate and surfaces on the console's existing approval card, naming the arguments and why the call reaches production.
How to route a connection the agent uses on this run, by connection id: SIMULATED, READ_THROUGH,
or NONE — shown as Live, which reaches the connection with its production credentials. Sandbox sessions
only (a Live session is refused). A connection left out is simulated unless it has a sandbox saved: a sandbox
session never reaches production through an integration unless you choose Live for it. Nothing is saved on
the connection.
The reply style to run this turn with instead of the agent's active one: {"version": 3} for a
particular version (a draft under review, say), or {"off": true} for none — send the same message
both ways to compare. Sandbox sessions only (a Live session is refused): a real conversation always gets
the reply style an admin activated. A version the agent does not have runs with none.
Stream the reply as it is written, as PARTIAL frames on the session stream, instead of
only the whole REPLY at the end. Sandbox sessions only — a Live session already
streams, since a web caller has no other transport back.
Off by default. A conversation turn against a real agent runs for tens of seconds, and a
reader watching a spinner for that long cannot tell a working run from a wedged one. The cost
of asking is that partials are drafts: the run can still end silent, parked or failed, so a
client that opts in must take the text back when no REPLY follows the terminal frame.
Frames are bus-only and never persisted; the reply row remains the transcript.
With revisionPolicy: DRAFT, run the caller's draft of this published revision rather than
whichever draft the session would pick. The studio sends the revision it is open on; 0 is
the draft of an agent that has never been deployed. 400 when the caller has no draft of it, and
when sent without DRAFT.
int64With revisionPolicy: DRAFT, the draft version the caller last saw. 409 when the draft has
moved on since, so a test never runs a head its author has not seen. Omit to run the draft as it
stands (the console, which has no editor state to assert). 400 when sent without DRAFT.
int64With revisionPolicy: PROPOSAL, the recommendation card whose change this run makes to the
deployed release, in memory — what approving the card would deploy. Required with
PROPOSAL, 400 without it. Agent admins only (403); 409 when the card has no change waiting,
or the live agent already has it; 400 when the change cannot be made yet, with the reason.
uuidFiles this message carries, as references to storage the caller has already uploaded to
(POST storage) — the same upload the studio's single-run path makes.
They land on InboundMessage.Attachments, where a real customer's photo or PDF lands, so the run sees what it would see in production: a screenshot with no caption stays an unstated request, and the tools that read a file get one to read. Without this a turn could only ever carry words, and anything the agent does because of an attachment was untestable.
Response Body
curl -X POST "https://api.fruxon.com/v1/tenants/string/fruxon/sessions/string/turns" \ -H "Content-Type: application/json" \ -d '{}'{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}