One-time payment over x402

Paying once is x402 in its simplest form. The agent has no account with the service, has never spoken to it, and holds no relationship with it when the first request goes out.

Agent                    Service API              Opus Protocol Facilitator        Robinhood Chain
  |                           |                          |                    |
  |-- GET /v1/data ---------->|                          |                    |
  |                           |                          |                    |
  |<-- 402 + payment terms ---|                          |                    |
  |    { scheme, amount,      |                          |                    |
  |      token, payTo, memo } |                          |                    |
  |                           |                          |                    |
  |-- POST /authorize ----------------------------------------->|             |
  |   { signedPayment }       |                          |                    |
  |                           |                          |-- submit TX ------->|
  |                           |                          |                    |
  |                           |                          |<-- TX confirmed ----|
  |<-- payment proof ---------|--------------------------|                    |
  |                           |                          |                    |
  |-- GET /v1/data ---------->|                          |                    |
  |   X-PAYMENT: <proof>      |                          |                    |
  |                           |-- verify proof --------->|                    |
  |                           |<-- valid ----------------|                    |
  |<-- 200 OK + data ---------|                          |                    |

From the agent’s point of view, all of this is one agent.pay() call. The SDK walks through every step on its behalf.

Subscription signup

Subscribing records a standing authorization on-chain. After that, the agent attaches a subscription id to its requests rather than a payment, and there is no payment work left for it to do per request.

Agent                    Service API              Opus Protocol Facilitator        Robinhood Chain
  |                           |                          |                    |
  |-- GET /v1/data ---------->|                          |                    |
  |                           |                          |                    |
  |<-- 402 + plan terms ------|                          |                    |
  |    { planId, amount,      |                          |                    |
  |      interval, token }    |                          |                    |
  |                           |                          |                    |
  |-- agent.subscribe({ planId }) ------------------->   |                    |
  |   (SDK creates subscription account on-chain)        |                    |
  |                                                      |-- create sub TX -->|
  |                                                      |-- first billing -->|
  |                                                      |<-- confirmed ------|
  |<-- subscription.id -----------------------------------|                    |
  |                           |                          |                    |
  |-- GET /v1/data ---------->|                          |                    |
  |   X-OpusProtocol-Sub: <sub.id>   |                          |                    |
  |                           |-- verify on-chain ------>|                    |
  |                           |<-- ACTIVE ---------------|                    |
  |<-- 200 OK + data ---------|                          |                    |
  |                           |                          |                    |
  |    [30 days later]        |                          |                    |
  |                           |-- auto-collect --------->|                    |
  |                           |                          |-- billing TX ----->|
  |                           |                          |<-- confirmed ------|

Renewal happens without the agent’s involvement: at every billing cycle the charge is collected and recorded on the chain automatically.

Agent-to-agent payment

The protocol draws no line between a service operated by a human and one operated by an agent. A specialist agent can publish a plan, put a payment gate in front of its API, and charge orchestrator agents over the same subscription rails. This is the groundwork for an economy in which agents purchase capabilities from one another.

Orchestrator Agent          Specialist Agent              Robinhood Chain
  |                               |                          |
  |-- POST /analyze (legal doc) ->|                          |
  |                               |                          |
  |<-- 402 + plan terms ----------|                          |
  |                               |                          |
  |-- subscribe to specialist --->|                          |
  |                               |-- create sub TX -------->|
  |                               |<-- confirmed ------------|
  |                               |                          |
  |-- POST /analyze (legal doc) ->|                          |
  |   X-OpusProtocol-Sub: <sub.id>       |                          |
  |<-- 200 OK + analysis result --|                          |
  |                               |                          |
  |    [monthly]                  |                          |
  |                               |-- auto-collect --------->|
  |                               |<-- confirmed ------------|

As the seller, the specialist works with the Provider SDK the same way any service does: publish a plan, put up the payment gate, and collect.

Metered billing flow

Usage-based pricing works by having the agent subscribe to a plan and attach an allowance, which sets the budget for its metered overage.

Agent                    Service API
  |                           |
  |-- subscribe with overage ->|
  |   { planId, maxOverage: 20 USDG }
  |
  |   [creates Subscription + Allowance on-chain]
  |
  |-- POST /v1/process ------->|
  |<-- 200 OK (1k tokens used) |
  |                            |-- deductAllowance(500_000)
  |
  |-- POST /v1/process ------->|
  |<-- 200 OK (2k tokens used) |
  |                            |-- deductAllowance(1_000_000)
  |
  |    [allowance exhausted]   |
  |                            |
  |-- POST /v1/process ------->|
  |<-- 402 (overage cap hit) --|

Once the cap is hit, the service answers with 402. That tells the agent to raise its overage ceiling or move up to a bigger plan.

Error states

Error Cause Resolution
InsufficientFunds Not enough USDG in the agent’s wallet Top up the wallet with USDG
SubscriptionNotActive The subscription has been paused or cancelled Renew it or create a new subscription
AllowanceExhausted The spend cap has been used up Increase the cap or wait until the cycle resets
InvalidPaymentProof The Facilitator rejected the proof The SDK retries on its own; if failures continue, check Facilitator status
PlanDeprecated The plan is closed to new subscriptions Switch to the provider’s current plan