Payment Sessions
High-frequency session tokens with batch on-chain settlement. Coming in general availability.
The problem sessions solve
One-time payments and even active subscriptions have a practical ceiling for high-frequency use cases. Consider an LLM inference agent that makes 500 API calls in a minute. Processing an on-chain transaction per request would add hundreds of milliseconds of latency and cost more in fees than the requests themselves are worth.
Payment sessions decouple the payment authorization from individual request processing. The agent commits a budget upfront; the Facilitator batches the underlying settlements; the agent pays near-zero overhead per request.
How sessions work
1. Agent calls agent.openSession({ provider, budget, ttl })
2. Recur 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
From the service’s perspective, session validation is a lightweight token check — not an on-chain query. This keeps per-request latency near zero.
Session Token lifecycle
| Phase | Description |
|---|---|
| Open | Agent commits budget; Facilitator issues token. Funds are locked. |
| Active | Agent makes requests. Facilitator tracks spend against committed budget. |
| Expired | TTL elapses or agent closes session. Final settlement executed on-chain. |
| Settled | All charges finalized on-chain. Unused budget returned to agent wallet. |
Planned API
Opening a session (agent)
const session = await agent.openSession({
provider: "https://api.inference.com",
budget: 10_000_000, // 10 USDC session budget
ttl: 3600, // 1 hour
});
// Use the session for high-frequency calls
const response = await session.get("/v1/completions", {
body: { prompt: "..." },
});
// Close early to settle and reclaim unused budget
await session.close();
Accepting sessions (provider)
app.use("/v1", recur.sessionGate({
facilitatorUrl: "https://facilitator.recurprotocol.com",
}));
The sessionGate middleware validates the X-Recur-Session header on each request. No on-chain call is made per request — only the Facilitator is queried.
On-chain auditability
Even though per-request settlements are batched, the final settlement is a standard on-chain transaction. Any observer can verify the total amount paid in a session, the session duration, and the parties involved. The session ID is recorded in the transaction memo field.
Use cases
Sessions are particularly well-suited for:
- LLM inference agents making rapid completions calls
- Real-time data feed consumers
- Multi-step agent workflows with many sub-calls to the same provider
- Any workload where per-request latency matters
For workloads with lower frequency, one-time payments and subscriptions are simpler and available now.