Session lifecycle
A TAP session has three phases: open, stream, settle.
Open
The consumer POSTs the prompt to the producer's URL with no payment. The producer:
- Tokenizes the prompt with its declared
tokenizer_id. - Returns HTTP 402 with
X-PAYMENT-REQUIREMENTScarrying:input_price_microandoutput_price_micro(per-token, asymmetric)tokenizer_id(so the consumer can re-tokenize locally)input_token_countandprepaid_input_micro = input_token_count × input_price_micromax_unpaid,trailing_buffer,duration,dispute_secs,grace_ms,pause_timeout_ms
The consumer then:
- Re-tokenizes the prompt locally with the same
tokenizer_id. If the count disagrees with the producer'sinput_token_count, abort — tokenizers are deterministic, so any mismatch implies misbehaviour (§5.3.7). - Builds an
open_channelSolana transaction depositingdeposit_microUSDC into the channel PDA, lockingprepaid_input_microon-chain as the settlement floor. - POSTs that transaction to the producer with
X-PAYMENT. - Receives
X-PAYMENT-RESPONSEwith the channel ID once the transaction confirms.
Stream
The producer runs prefill and starts emitting output tokens via SSE.
Each token is one data: event. As tokens flow:
- The consumer accumulates output, runs the configured evaluator after
each chunk, and signs an incrementing
CommitMessageevery K tokens. Each commit'scumulative_paid = prepaid_input + (output tokens × output_price). - The producer holds the latest accepted commit. K is auto-tuned by the consumer SDK (AIMD, like TCP congestion control).
Settle
When the stream ends — gracefully or via halt — the producer submits the
latest commit to the on-chain settle instruction. The program:
- Verifies the Ed25519 signature against the channel's session key (via the Ed25519Program sibling instruction).
- Enforces
prepaid_input ≤ cumulative_paid ≤ deposit. - Records the latest accepted state and opens the dispute window.
After the dispute window (configurable, default 30s) elapses, either
party calls close, which actually moves USDC: cumulative_paid to
the producer, the rest back to the consumer. One on-chain
transaction per session (or per N sessions in a reused channel —
see Channel reuse).