Developer guide

Practical integration for api.archonia.org. JSON in, JSON out. Errors look like {"error":"…","detail":"…"}.

What Ax402 does

  • Catalog List sellable SKUs with price and fulfillment mode.
  • Quotes / orders Price a SKU, challenge with HTTP 402 + USDC details, verify the on-chain transfer.
  • Fulfillment After payment: issue metered API access, notify your webhook, or record-only.
  • Metering Authorization: Bearer … against /v1/meter, /v1/balance, /v1/usage.

Ax402 does not manage inventory, shipping labels, or carriers. Physical goods are paid here; you fulfill after the webhook.

1. List products

curl -s https://api.archonia.org/store/products

Useful fields per SKU: slug, price, billing_model (credits | quota | one_shot), fulfillment_mode (metered_access | webhook | none), product_kind, credits/quota fields.

Example seed SKUs: api-credits-100, api-quota-1k-month, coffee-1kg.

2. Create a quote

curl -s -X POST https://api.archonia.org/store/quotes \
  -H "Content-Type: application/json" \
  -d '{"product_id":"api-credits-100","quantity":1}'

Response includes quote_id, unit_price, total_price, currency, and valid_until_epoch (about one hour).

3. Start an order → HTTP 402

curl -s -i -X POST https://api.archonia.org/store/orders \
  -H "Content-Type: application/json" \
  -d '{"quote_id":"QUOTE_ID"}'

402 Payment Required body:

{
  "network": "base_sepolia",
  "token": "USDC",
  "amount": "5",
  "recipient_address": "0x…"
}

The same payload is also returned base64-encoded in the PAYMENT-REQUIRED header (x402-style). Send that USDC amount on Base (currently Base Sepolia for testnet) to recipient_address.

4. Complete with the tx hash

curl -s -X POST https://api.archonia.org/store/orders \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "QUOTE_ID",
    "email": "[email protected]",
    "payment_data": { "hash": "0x…64 hex chars…" }
  }'

Ax402 verifies the receipt on-chain (successful status, USDC Transfer to the recipient, amount within 0.01). Reused hashes → 409 payment_already_used.

Metered SKU → 201

{
  "order_id": "R…",
  "status": "confirmed",
  "access": {
    "api_key": "yog_…",
    "customer_id": "cus_…",
    "billing_model": "credits",
    "credits_granted": 100
  }
}

Store api_key immediately — it is shown once; only a hash is kept server-side.

Webhook SKU → 201

Include ship_to when the product requires it. Response includes fulfillment.status of notified or notify_failed (the order is still paid either way).

5. Metered API usage

Auth header: Authorization: Bearer yog_…

# Balance
curl -s https://api.archonia.org/v1/balance \
  -H "Authorization: Bearer $API_KEY"

# Consume units
curl -s -X POST https://api.archonia.org/v1/meter \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"units":1,"idempotency_key":"call-abc-123"}'

# Usage history
curl -s "https://api.archonia.org/v1/usage?limit=20" \
  -H "Authorization: Bearer $API_KEY"
  • Default units is 1; credits charged = units
  • Replay the same idempotency_key → success without double-charging
  • Insufficient credits / quota → 402
  • Bad or missing key → 401

Top up by completing another credit/quota order with the existing Bearer key. Rotate or revoke with POST /v1/keys/rotate and POST /v1/keys/revoke. Export usage via /v1/usage/export?format=json|csv.

6. Merchant webhooks

Configured per product at onboarding: HTTPS webhook_url, optional HMAC secret, and requires_ship_to when an address is required.

{
  "event": "order.paid",
  "order_id": "R…",
  "sku": "coffee-1kg",
  "quantity": 2,
  "total_price": 36,
  "currency": "USD",
  "email": "[email protected]",
  "ship_to": { "name": "…", "line1": "…", "city": "…", "postal": "…", "country": "…" },
  "tx_hash": "0x…"
}

Signature header: X-YogAI-Signature: sha256=<hex> — HMAC-SHA256 of the raw request body with your webhook secret. Respond quickly with 2xx.

Mode After USDC verify
metered_access Create customer, API key, credits/quota
webhook Persist order + ship_to; POST signed order.paid
none Record paid order only

Common error codes

Code HTTP Meaning
unauthorized 401 Missing or invalid Bearer key
insufficient_credits / quota_exceeded 402 Meter blocked
invalid_payment 400 On-chain verify failed
payment_already_used 409 Tx hash reused
quote_expired 410 Quote past valid_until_epoch
product_not_fulfillable 422 Bad or missing product config
invalid_input 400 Bad body (e.g. missing ship_to)