Skip to content

Modes

A Mode sets how a Verb runs and when the caller hears back; try stores nothing, send returns at once, and do waits for the finished Action.

A Mode is how a caller invokes a Verb: try, send or do. It decides whether the call is recorded and when the caller hears back.

Three Modes

ModeRecordedThe caller getsHTTP status
tryNoThe result or the error it would hit, at once200
sendYesA pending Action, at once, with its URL in Location202
doYesThe finished Action and its result200

try runs every check and computes the result, then stores nothing. It suits lookups and previews: a tax estimate, a domain check, the refund a caller would get.

send records the Action and returns before the work starts. It suits work measured in minutes or days, such as a contract review that a credentialed human finishes.

do records the Action and holds the call until it ends. The caller writes straight-line code and gets the result, or the reason there is none.

Defaults and choices

Each Verb declares a default Mode and the Modes a caller may choose, and its reference lists both. Order.refund defaults to do, because the caller wants the refunded Order back.

A call that names a Mode the Verb does not accept returns mode-not-allowed. A Verb that accepts only send never blocks a caller, whatever the caller asks.

Choosing a Mode on each Interface

clauseclear.com is a Services-as-Software business that reviews vendor contracts for small firms. An agent reviews each contract, and a licensed attorney signs off. Its client places Orders in send Mode and moves on:

Text
Order a contract review and tell me when it is done.

The SDK also takes the Mode as an option: $.Order.place(input, { mode: 'send' }). Over MCP, the do tool's name is fixed, and the Mode still belongs to the call inside it.

A send caller learns the outcome by reading the Action at Location, or by subscribing to its Events through a Watch or a stream.

Try as a preview

try on a Verb that writes is a dry run. The caller sees the record it would get, or the problem it would hit, and nothing changes.

TypeScript
const preview = await $.try.Order.refund({ order: 'order_7', amount: { amount: 120, currency: 'USD' }, reason: 'Review missed the deadline' })

On the API, GET on a Verb's route is the same preview. Agents preview every write that moves money, then commit with do.

What the caller waits through

A recorded call creates an Action that starts pending and settles done, failed, canceled or refused. Actions explains each status and each reason an Action waits.

The Mode decides only how much of that wait the caller sits through. A do caller holds the connection until the Action settles; a send caller reads the outcome later. The clauseclear review, Order.deliver, waits as awaitingWorker until the attorney claims its Task, which can take hours.

A one-way Verb, such as a refund, also waits out its delay window as awaitingTime. Nobody has to approve it: when the window closes, it runs. A refund over a Limit waits instead on an Approval.

In the SDK, a do call rejects when its Action ends failed, refused or canceled. To get the final Action whatever its status, await .settled:

TypeScript
const action = await $.Order.refund({ order: 'order_7', reason: 'Review missed the deadline' }).settled
if (action.status === 'refused') console.log(action.error?.fix)

Safe to repeat

Send an Idempotency-Key with every recorded call. A repeat after a dropped connection returns the first Action instead of starting a second.

Every call, in every Mode, emits a usage Event that billing reads, so a billed call is never sampled. Streaming, batching and scheduling change how results arrive or when work runs; they are not Modes.

Next