{"openapi":"3.1.0","info":{"title":"x402card Virtual Cards and Freeland eSIM API","version":"0.3.1","description":"Wallet-native x402 commerce API for virtual card issuance and funding plus prepaid Freeland travel eSIM purchase with private installation delivery.","contact":{"name":"x402card security contact","email":"security@x402card.org","url":"https://x402card.org/security/"},"x-products":["virtual_card","prepaid_travel_esim"],"x-guidance":"For a virtual card, POST /api/card/purchase with a stable idempotencyKey; the Base USDC payer becomes the owner and credentials still require fresh owner authentication. To fund an existing active card, POST /api/card/topup with amountUsdCents and a stable idempotencyKey; the payer must own the active card and funding is asynchronous. For a travel eSIM, read GET /api/esim/plans, then POST /api/esim/purchase with the selected planId and a stable idempotencyKey. These routes return an x402 v2 challenge before payment. Submit PAYMENT-SIGNATURE at most once and recover ambiguous responses with the same idempotency key."},"servers":[{"url":"https://api.x402card.org"}],"paths":{"/health":{"get":{"summary":"Liveness check","responses":{"200":{"description":"Database-backed liveness"}}}},"/ready":{"get":{"summary":"Deep production readiness","responses":{"200":{"description":"Ready"},"503":{"description":"Not ready"}}}},"/mcp":{"get":{"summary":"MCP endpoint descriptor","responses":{"200":{"description":"MCP descriptor"}}},"post":{"summary":"MCP Streamable HTTP JSON-RPC endpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response"},"202":{"description":"Notification accepted"}}}},"/api/agent":{"get":{"summary":"Machine-readable agent contract","responses":{"200":{"description":"Agent contract"}}}},"/api/openapi.json":{"get":{"summary":"OpenAPI document","responses":{"200":{"description":"OpenAPI 3.1 document"}}}},"/api/config":{"get":{"summary":"Public runtime config","responses":{"200":{"description":"Network, card, fee, and limit config"}}}},"/api/events":{"post":{"summary":"Accept a privacy-safe first-party product event","description":"Event names and properties are allowlisted. Wallet addresses, IP addresses, user agents, tokens, signatures, PAN and CVV are never accepted as raw event fields.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["eventId","eventName","visitorId"],"properties":{"eventId":{"type":"string","format":"uuid"},"eventName":{"type":"string"},"visitorId":{"type":"string","format":"uuid"},"path":{"type":"string"},"properties":{"type":"object"}},"additionalProperties":false}}}},"responses":{"202":{"description":"Event accepted"},"400":{"description":"Event rejected by schema"}}}},"/api/admin/activity":{"get":{"summary":"Aggregated product and operational activity report","security":[{"bearerAuth":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":90,"default":7}}],"responses":{"200":{"description":"Aggregate activity without raw identifiers"},"401":{"description":"Unauthorized"}}}},"/api/admin/activity/prune":{"post":{"summary":"Delete expired product events immediately","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Deleted row count"},"401":{"description":"Unauthorized"}}}},"/api/auth/challenge":{"post":{"summary":"Create wallet sign-in challenge","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"properties":{"address":{"type":"string"},"preferredMessageSchemes":{"type":"array","items":{"type":"string","enum":["eip191","eip712"]}}}}}}},"responses":{"200":{"description":"Challenge message"}}}},"/api/auth/verify":{"post":{"summary":"Verify wallet signature and mint x402card session","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address","signature"],"properties":{"address":{"type":"string"},"intentId":{"type":"string","format":"uuid"},"messageScheme":{"type":"string","enum":["eip191","eip712"]},"message":{"type":"string"},"signature":{"type":"string"}}}}}},"responses":{"200":{"description":"Bearer token"},"401":{"description":"Invalid signature"}}}},"/api/auth/session":{"get":{"summary":"Inspect the current wallet-bound session without exposing its bearer","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Wallet, scopes and expiry"},"401":{"description":"Missing, expired or revoked session"}}}},"/api/cards":{"get":{"summary":"List owner cards","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Cards"},"401":{"description":"Missing or invalid session"}}},"post":{"summary":"Return existing owner card; unpaid public card issue is blocked","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Existing card"},"409":{"description":"Paid card issue is required"},"503":{"description":"Card issue is paused"}}}},"/api/cards/{id}/balance":{"get":{"summary":"Read the owner card balance directly from VALUT","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current VALUT card balance"},"401":{"description":"Missing or invalid session"},"404":{"description":"Card not found"},"409":{"description":"Card is not active"}}}},"/api/cards/{id}/reveal-challenge":{"post":{"summary":"Create a fresh owner credential-reveal challenge","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"preferredMessageSchemes":{"type":"array","items":{"type":"string","enum":["eip191","eip712"]}}}}}}},"responses":{"200":{"description":"Single-use challenge intent"}}}},"/api/cards/{id}/reveal":{"post":{"summary":"Verify a fresh owner signature and reveal card credentials","description":"Sensitive response. Agent clients should deliver it through a secure local presenter and exclude it from model context.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"No-store sensitive credential response"},"401":{"description":"Invalid, expired or consumed challenge"}}}},"/api/card-issue/orders":{"post":{"summary":"Create or recover an idempotent paid x402 order for first card issue","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Required for new agent clients; optional temporarily for the legacy browser.","schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"Card issue order with payable_url"},"409":{"description":"Card already exists or card BIN unavailable"},"503":{"description":"Card issue paused or VALUT float unavailable"}}}},"/api/card/discovery":{"get":{"summary":"Return the virtual-card direct x402 purchase contract","responses":{"200":{"description":"Machine-readable payment, payer-ownership, issuance, and credential contract"}}}},"/api/card/purchase":{"post":{"summary":"Issue a wallet-owned virtual card directly with x402","description":"Public agent marketplace entrypoint. The Base USDC payment payer becomes the card owner. Issuance is asynchronous and credentials require fresh owner authentication.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["idempotencyKey"],"properties":{"idempotencyKey":{"type":"string","minLength":1,"maxLength":200,"description":"Stable caller-generated key. Reuse it after an ambiguous response."}},"additionalProperties":false},"example":{"idempotencyKey":"agent-card-purchase-001"}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"25.00"},"protocols":[{"x402":{}}]},"responses":{"200":{"description":"Settled card-issue order with queued asynchronous issuance"},"402":{"description":"Payment Required"},"409":{"description":"Card already exists, terms changed, or order is no longer payable"},"503":{"description":"Card issue, provider BIN, workers, or backing float are unavailable"}}}},"/api/card/topup/discovery":{"get":{"summary":"Return the separate direct card top-up x402 contract","responses":{"200":{"description":"Machine-readable limits, fee, active-card ownership, payment and funding contract"}}}},"/api/card/topup":{"post":{"summary":"Top up an existing wallet-owned active card directly with x402","description":"Public agent marketplace entrypoint. The Base USDC payer must own an active card. The server selects that card; funding is asynchronous and the current load fee applies.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["idempotencyKey"],"properties":{"amountUsdCents":{"type":"integer","minimum":2500,"maximum":25000,"default":2500,"description":"Gross USDC payment in integer USD cents. Omit to use the current configured default."},"idempotencyKey":{"type":"string","minLength":1,"maxLength":200,"description":"Stable caller-generated key. Reuse it after an ambiguous response."}},"additionalProperties":false},"example":{"amountUsdCents":2500,"idempotencyKey":"agent-card-topup-001"}}}},"x-payment-info":{"price":{"mode":"dynamic","currency":"USD","min":"25.00","max":"250.00"},"protocols":[{"x402":{}}]},"responses":{"200":{"description":"Settled funding order with queued asynchronous card top-up"},"402":{"description":"Payment Required"},"409":{"description":"Active card missing, terms changed, idempotency conflict, or order is no longer payable"},"503":{"description":"Funding worker, provider BIN, treasury reconciliation, or backing float is unavailable"}}}},"/api/esim/discovery":{"get":{"summary":"Return the Freeland eSIM agent purchase contract","responses":{"200":{"description":"Machine-readable catalog, payment, ownership, and fulfillment contract"}}}},"/api/esim/ready":{"get":{"summary":"eSIM-only readiness without unrelated card or treasury gates","responses":{"200":{"description":"Database, x402, and eSIM fulfillment are ready"},"503":{"description":"At least one eSIM purchase dependency is not ready"}}}},"/api/esim/plans":{"get":{"summary":"List Freeland eSIM plans priced in Base USDC","parameters":[{"name":"countryCode","in":"query","schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"type","in":"query","schema":{"type":"string","enum":["country","region"]}}],"responses":{"200":{"description":"Public plan catalog without supplier identity or cost"}}}},"/api/esim/purchase":{"post":{"summary":"Buy a Freeland prepaid travel eSIM directly with x402","description":"Public agent marketplace entrypoint. The payment payer becomes the eSIM owner. Omit planId to select the cheapest currently available plan.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["idempotencyKey"],"properties":{"planId":{"type":"string","description":"Live plan id from GET /api/esim/plans. Omit to buy the cheapest available plan."},"idempotencyKey":{"type":"string","minLength":1,"maxLength":200,"description":"Stable caller-generated key. Reuse it after an ambiguous response."}},"additionalProperties":false},"example":{"idempotencyKey":"agent-esim-purchase-001"}}}},"x-payment-info":{"price":{"mode":"dynamic","currency":"USD","min":"0.01","max":"250.00"},"protocols":[{"x402":{}}]},"responses":{"200":{"description":"Settled eSIM order with inline credentials when fulfillment completes within the bounded wait, plus a private delivery-token continuation fallback"},"402":{"description":"Payment Required"},"409":{"description":"Plan terms changed or order is no longer payable"},"503":{"description":"Purchase or fulfillment is paused"}}}},"/api/esim/orders":{"post":{"summary":"Create or recover an idempotent Freeland eSIM x402 order","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"eSIM order with Base USDC payment requirements"},"503":{"description":"Purchase or fulfillment is paused"}}}},"/api/esim/orders/{orderId}":{"get":{"summary":"Get owner eSIM order without installation secrets","description":"Use the order-scoped delivery token returned by the paid purchase, or a wallet-authenticated owner session.","security":[{"esimDeliveryToken":[]},{"bearerAuth":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order status"},"404":{"description":"Order not found"}}}},"/api/esim/orders/{orderId}/credentials":{"get":{"summary":"Decrypt and return the fulfilled eSIM profile to its wallet owner","description":"Sensitive no-store response. Use the order-scoped delivery token returned by the paid purchase, or a wallet-authenticated owner session. QR/LPA material is encrypted at rest and excluded from generic order responses and logs.","security":[{"esimDeliveryToken":[]},{"bearerAuth":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Owner-only ICCID and installation material"},"404":{"description":"Order not found for this wallet"},"409":{"description":"Order is not fulfilled"}}}},"/api/admin/auth-challenges/retention":{"get":{"summary":"Inspect privacy/security challenge retention status","security":[{"adminToken":[]}],"responses":{"200":{"description":"Retention status and stale row count"}}}},"/api/admin/auth-challenges/prune":{"post":{"summary":"Prune expired auth challenges in bounded batches","security":[{"adminToken":[]}],"responses":{"200":{"description":"Deleted row count"}}}},"/api/orders":{"get":{"summary":"List owner orders","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active"]}}],"responses":{"200":{"description":"Orders"},"401":{"description":"Missing or invalid session"}}},"post":{"summary":"Create payable x402 order","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"oneOf":[{"type":"number"},{"type":"string"}]},"amountUsdCents":{"type":"integer"},"resource":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Order with payable_url"},"401":{"description":"Missing or invalid session"}}}},"/api/orders/{orderId}":{"get":{"summary":"Get owner order","security":[{"bearerAuth":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order"},"404":{"description":"Order not found"}}}},"/api/orders/{orderId}/pay":{"post":{"summary":"Submit x402 payment signature directly","security":[{"bearerAuth":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["paymentSignature"],"properties":{"paymentSignature":{"type":"string"}}}}}},"responses":{"200":{"description":"Settlement/funding result"},"402":{"description":"Payment rejected"}}}},"/api/admin/card-issue-fee/jobs":{"get":{"summary":"List card issue platform-fee jobs","security":[{"adminToken":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["queued","processing","succeeded","failed","operator_review"]}}],"responses":{"200":{"description":"Fee jobs"},"401":{"description":"Invalid admin token"}}}},"/api/admin/card-issue-fee/jobs/{id}/reconcile":{"post":{"summary":"Read and reconcile one VALUT withdrawal without replaying the mutation","security":[{"adminToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Reconciled job"},"404":{"description":"Fee job not found"}}}},"/api/admin/card-issue-fee/jobs/{id}/retry":{"post":{"summary":"Create a versioned retry only after provider-confirmed FAILED","security":[{"adminToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":500}}}}}},"responses":{"200":{"description":"Retry queued"},"400":{"description":"Missing idempotency key or reason"},"409":{"description":"Provider failure is not confirmed"}}}},"/pay/{orderId}":{"get":{"summary":"Public x402 payable endpoint","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paid/funding result"},"402":{"description":"PAYMENT-REQUIRED header with x402 requirements"}}},"post":{"summary":"Public x402 payable endpoint","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paid/funding result"},"402":{"description":"PAYMENT-REQUIRED header with x402 requirements"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"esimDeliveryToken":{"type":"apiKey","in":"header","name":"X-Esim-Delivery-Token","description":"Private order-scoped capability returned only by a successful paid eSIM purchase."},"adminToken":{"type":"http","scheme":"bearer","description":"Operator ADMIN_TOKEN"}}}}