Rails
Plain HTTP

REST API

The same settlement rail as x402, described as a plain OpenAPI 3.1 document for any HTTP client that isn't speaking MCP or A2A. One endpoint, Celo-only, machine-readable.

POST/api/pay/x402

Settles a real-world bill payment. The caller pays in a supported Celo stablecoin; on confirmed settlement, AbaPay vends the underlying service and returns the result. Price is dynamic — it equals the live value of the bill, plus any applicable service fee and a flat $0.001 x402 facilitator fee, so there is no fixed catalog price for this resource.

Request body

FieldTypeDescription
serviceIDstringVTpass service identifier, e.g. "mtn", "ikeja-electric"
serviceCategorystringAIRTIME | DATA | ELECTRICITY | CABLE | BANK | EDUCATION
networkstringProvider name, e.g. MTN, IKEJA-ELECTRIC, DSTV
billersCodestringPhone number, meter number, or smartcard/IUC number
nairaAmountnumberBill amount in NGN — the source of truth for pricing
tokenstring"USDC", "USD₮", or "USA₮" — all three implement EIP-3009 on Celo; an unrecognized value falls back to USDC
blockchainstring"CELO" — this site's rails are Celo-only
wallet_addressstringThe paying wallet, cross-checked against the signed authorization

Responses

200Settled

Bill vended, or queued for background processing.

402Payment Required

Standard x402 challenge — see /agents/x402.

200 response body
{
  "success": true,
  "status": "SUCCESS",
  "purchased_code": null,
  "units": null,
  "request_id": "req_...",
  "tx_hash": "0x91a3...4f2c"
}

Try it — live

Edit the bill, hit send — a probe against production with no payment attached returns a 402 challenge naming the live price. Nothing here moves money.

{
  "serviceID": "mtn",
  "serviceCategory": "AIRTIME",
  "network": "MTN",
  "billersCode": "08012345678",
  "nairaAmount": 1000,
  "token": "USDC",
  "blockchain": "CELO",
  "wallet_address": "0xYourAgentWallet"
}

Try it — curl

A GET or probing POST with no payment attached returns a valid 402 challenge — the endpoint is always live for discovery, no credential required to see the price. CORS is open on this endpoint (see the live panel above), so this also works straight from browser JS, not just curl.

curl -X POST https://agents.abapays.com/api/pay/x402 \
  -H "Content-Type: application/json" \
  -d '{"serviceID":"mtn","serviceCategory":"AIRTIME","network":"MTN","billersCode":"08012345678","nairaAmount":1000,"token":"USDC","blockchain":"CELO","wallet_address":"0xYourAgentWallet"}'

Full machine-readable spec: openapi.json. For the signed retry that actually settles it, see /agents/x402 or abapay-sdk. Every error code this endpoint can return: /agents/errors.