x402sms
Guides

Raw HTTP / 402 flow

Use the API without an x402 SDK — for custom clients and other languages.

x402 is plain HTTP. You can implement the payment handshake in any language.

The handshake

POST /v1/numbers                      (no payment)
← 402, PAYMENT-REQUIRED: <base64>     (payment requirements)

  ... decode, sign a Permit2 authorization for `accepts[0]` ...

POST /v1/numbers
  PAYMENT-SIGNATURE: <base64>         (payment payload)
← 200 { id, number, accessToken }

1. Decode the requirements

The PAYMENT-REQUIRED header is base64 JSON:

{
  "x402Version": 2,
  "resource": { "url": "https://api.sms-x402.xyz/v1/numbers" },
  "accepts": [
    {
      "scheme": "upto",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "1941139",
      "payTo": "0xeC73B5405F8511AD20EBE1E4de223DA1e49727ab",
      "maxTimeoutSeconds": 1800,
      "extra": {
        "assetTransferMethod": "permit2",
        "facilitatorAddress": "0xB2Bd...371B",
        "name": "USD Coin",
        "version": "2"
      }
    }
  ],
  "extensions": { "bazaar": { "info": { "input": ..., "output": ... } } }
}
  • asset — USDC on Base
  • amount — maximum authorization in atomic units (6 decimals)
  • payTo — where the money goes on settlement
  • extra.facilitatorAddress — the Permit2 spender you authorize

2. Sign the payment (upto / Permit2)

For upto, the payload is an EIP-712 Permit2 PermitTransferFrom signature authorizing facilitatorAddress to pull up to amount USDC from your address, with a signature deadline no later than maxTimeoutSeconds from now. The reference implementation is @x402/evm upto/client — port it or wrap it.

3. Send the payload

Base64-encode and retry:

{
  "x402Version": 2,
  "accepted": { "...": "the requirements you accepted (echo them back)" },
  "payload": { "signature": "0x...", "permit2Authorization": { "..." : "..." } }
}

Header: PAYMENT-SIGNATURE: <base64 of the above>.

4. Settlement receipt

When your poll delivers the code, the response carries PAYMENT-RESPONSE: <base64 SettleResponse> — the on-chain receipt (tx hash, settled amount, payer). If no SMS ever arrives you will simply never see this header, and no transaction ever touches your wallet.

Error responses

StatusMeaning
402Payment required (first call) or verification failed
400Invalid body, or accepted requirements mismatch (scheme/network/asset/payTo/amount)
409No numbers available right now
502Temporary service or payment-network error — safe to retry

On this page