developer docs
Two transports, one product. Pick REST if you're wiring a backend; pick MCP if you're building an agent.
Not a developer? Add cartapi to your AI assistant at /install — no code required.
endpoints
ACP = Agentic Commerce Protocol. Pending Stripe Shared Payment Tokens.
auth
REST
$ curl https://api.cartapi.io/v1/countries \ -H "Authorization: Bearer $CARTAPI_KEY"
Per-key rate limits. Request a key: [email protected].
MCP
Currently open (no auth). OAuth in flight — once shipped, unauthenticated sessions keep read-only tools; authenticated sessions unlock order history, refunds, and saved defaults. Same URL, additive.
MCP tools
Streamable HTTP transport, protocol version 2024-11-05.
REST endpoints
category, country, validity_days, min_data_gb, data_unlimited, sort
GET /v1/products/:id product detail
GET /v1/countries supported countries
POST /v1/checkout/session create a Stripe Checkout session, returns URL for the buyer
GET /v1/orders/:id order status + fulfillment payload
POST /v1/webhooks/stripe Stripe webhook receiver (server-to-server)
GET /v1/health DB + every provider adapter
hello world
Top up a Nigerian mobile number with $10, end to end.
# 1. search $ curl "https://api.cartapi.io/v1/products/search?category=topup&country=NG" \ -H "Authorization: Bearer $CARTAPI_KEY" # 2. create a checkout session for the chosen SKU $ curl -X POST https://api.cartapi.io/v1/checkout/session \ -H "Authorization: Bearer $CARTAPI_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "product_id": "topup_reloadly_ng_mtn_10usd", "phone_number": "+2348012345678", "success_url": "https://your.app/order/success", "cancel_url": "https://your.app/order/cancel" }' # 3. user pays at checkout.url, then poll the order $ curl https://api.cartapi.io/v1/orders/ord_abc123 \ -H "Authorization: Bearer $CARTAPI_KEY"
conventions
idempotency
Every mutation accepts an Idempotency-Key header. Same key + same body = same response, safe against agent retries.
consent
cartapi never receives, stores, or replays payment credentials. Every charge is signed by the user — through a Stripe Checkout URL they click, or an ACP payment token their wallet issues.
neutral catalog
Search returns every matching SKU across every provider. Sort is a parameter, not a ranking cartapi imposes: price_asc (default), price_desc, data_desc, validity_desc, value.
fulfillment
Instant. Fulfillment payload (QR, activation code, credentials) is included in the order response — poll GET /v1/orders/:id or handle the Stripe webhook.
categories
phone_number.
esim Airalo · Nomad — 219 countries. MobileMatter on the way.
gift_card Reloadly — 156 countries, 305+ brands (Amazon, Xbox, PlayStation, Steam, Netflix, Uber). Region-locked per SKU.
vpn VPNResellers (roadmap).
insurance Cover Genius, Battleface (roadmap).
gamekey CodesWholesale (roadmap).
machine-readable
LLM crawlers should read /llms.txt. Programmatic
clients receive JSON from / when the request includes
Accept: application/json.