Payment Sessions
Session tokens for high-frequency requests, with settlement batched on-chain. Planned for general availability.
Why sessions exist
At high request rates, per-request payment stops being practical, even with an active subscription. An LLM inference agent making 500 API calls a minute cannot afford an on-chain transaction for each one: the latency adds hundreds of milliseconds per call, and the fees quickly exceed the value of the requests.
Sessions decouple authorization from the request path. The agent commits a budget up front, the Facilitator settles the underlying charges in batches, and each individual request carries near-zero payment overhead.
How sessions work
1. Agent calls agent.openSession({ provider, budget, ttl })
2. Scribe Finance Facilitator verifies the agent has sufficient balance
3. Facilitator issues a short-lived Session Token (JWT, TTL: 5-60 min)
4. Agent attaches the Session Token to each request header
5. Service validates the token against the Facilitator (sub-millisecond)
6. Facilitator batches on-chain settlements periodically
7. On session expiry: final settlement executed, unused balance returned
For the service, validating a session is an inexpensive token check (no on-chain query per request), so payment adds effectively nothing to request latency.
Session Token lifecycle
| Phase | Description |
|---|---|
| Open | The agent commits a budget; the Facilitator locks the funds and issues a token. |
| Active | Requests flow while the Facilitator meters spend against the committed budget. |
| Expired | The TTL elapses or the agent closes the session; final settlement runs on-chain. |
| Settled | All charges are final on-chain and the unused budget is back in the agent’s wallet. |
Planned API
Opening a session (agent)
const session = await agent.openSession({
provider: "https://api.inference.com",
budget: 10_000_000, // 10 USDG session budget
ttl: 3600, // 1 hour
});
// Make high-frequency calls through the session
const response = await session.get("/v1/completions", {
body: { prompt: "..." },
});
// Closing early triggers settlement and returns the unused budget
await session.close();
Accepting sessions (provider)
app.use("/v1", scribefinance.sessionGate({
facilitatorUrl: "https://facilitator.scribefinance.org",
}));
The sessionGate middleware reads the X-ScribeFinance-Session header on every request and validates it against the Facilitator. Nothing touches the chain per request.
On-chain auditability
Batching applies to per-request charges, not to the record. The final settlement is a normal on-chain transaction, so any observer can verify what a session paid in total, its duration, and its parties; the transaction memo field carries the session ID. The chain remains the source of truth.
Where sessions fit
Sessions earn their keep in:
- LLM inference agents issuing completions calls in rapid succession
- Real-time data feed consumers
- Multi-step agent workflows that fan out many sub-calls to one provider
- Any workload where per-request latency matters
For lower request rates, one-time payments and subscriptions are the simpler choice, and they are available today.