Status code 402 has been in the HTTP spec since 1997 with the label "Payment Required" and no defined behaviour. It's finally getting one, and the reason is boring in a good way: software that runs without a person nearby needs a way to pay for things.
I work at MyOTP.App. We sell OTP delivery, and this year we started answering 402 to agents that run out of credits. Here's what that means with the crypto vocabulary taken out.
The problem it solves
An agent is building or running an app for someone. It needs to send a verification SMS. It has an API key with zero credits. Today the flow stops, a human is paged, they open a dashboard, enter a card, and the agent resumes an hour later. Every API that charges money has this cliff.
What a 402 flow looks like
The client calls the API. The server answers 402 with a header describing what it will accept: an amount, a currency, and one or more ways to pay. The client pays using one of them, gets a receipt, and repeats the request with the receipt attached. The server verifies the receipt and serves the request. No checkout page, no form, no session.
The protocol we use is Stripe's Machine Payments Protocol, and it's the "one or more ways" part that makes it usable outside crypto. Our 402 offers two:
- A card, through a Stripe Link wallet the agent's owner authorised once. The agent presents a scoped, time-limited token, not the card number.
- USDC, a dollar-pegged stablecoin, for agents that hold a wallet and no card.
The client picks whichever it has. The API doesn't care.
What ours looks like
POST https://api.myotp.app/v1/topup
Content-Type: application/json
{"credits": 100}
402 Payment Required
WWW-Authenticate: Payment ... (two offers: card via Stripe, USDC on Tempo)
Pay, retry with the receipt, get:
200 OK
{"credits_added": 100, "balance": 115, "amount_usd": "2.00"}
The numbers: $0.02 a credit, 25 credits minimum because that's Stripe's card floor, 50,000 maximum per call. Cards are capped at $100 per account per rolling day, and over that the 402 offers USDC only. That cap is the fraud control. Stolen cards get tested against APIs like ours, and a low daily ceiling makes us not worth the effort.
Why an agent should use it instead of asking a human
Because the human isn't there. That's the whole reason. The agent registers an account with one call, gets a key, and the first time it hits zero balance it gets a 402 and pays. Our MCP server exposes this as get_topup_quote and top_up_credits, and the CLI as myotp topup, so most agents never see the raw protocol.
What it isn't
It's not a subscription. Each 402 is one payment for one top-up. It's not a way to bypass Stripe's rules, since Stripe is the one processing the card. And it's not anonymous: the account behind the key has an email, and card top-ups need that email confirmed.
Should you add it to your API
If your API is called by software that runs unattended and your smallest sale is under a few dollars, yes, and it's a few hundred lines with Stripe's SDK. If your customers are humans with a dashboard, the checkout page you already have is fine.
Disclosure again: I work at MyOTP.App. The contract for our endpoint is public and the MCP server and CLI are open source at brntech/myotp-agentkit.
Top comments (0)