← Back to Home

API Documentation

Integrate Apocha receipts into your application

Authentication: Most endpoints use x402 payment protocol. Include X-Payment header with your USDC payment signature, and X-Wallet-Address for subscription verification.
Time Limit: Receipts must be minted within 48 hours of the original transaction for contemporaneous record-keeping.
CARF Compliance: All receipts include DTIF codes (Digital Token Identifier) for CARF and 1099-DA tax reporting. Each attribute is marked as chain-verified or self-reported.
Production Infrastructure: Receipts are minted as compressed NFTs via Metaplex Bubblegum. Metadata is permanently stored on Arweave via Irys. Subscriptions are verified on-chain via Helius DAS API (cached for 1 hour).
Reliable Minting: All mints go through a persistent queue with automatic retries (up to 3 attempts). Payment is verified immediately - if minting fails, it retries automatically. Failed mints can be manually retried via admin endpoints.
Data Persistence: All receipts are stored in a persistent SQLite database. This ensures duplicate prevention survives server restarts and provides fast lookups. The on-chain NFT and Arweave metadata remain the immutable source of truth.
Privacy: Payer jurisdiction is detected via IP for tax compliance but is never stored in the on-chain NFT. This data is kept in the private database and only visible to sellers when viewing their receipts. Payers never see location data in their wallet.

Core Endpoints

POST /mint

Mint a CARF-compliant receipt NFT for a transaction. Requires x402 payment (0.1% of transaction, min $0.10, max $5) for transactions over $1, unless you have an active subscription. Transaction must be within 48 hours.

curl -X POST https://api.apocha.cc/mint \
  -H "Content-Type: application/json" \
  -H "X-Payment: <payment_signature>" \
  -H "X-Wallet-Address: <your_wallet>" \
  -H "X-Wallet-Signature: <ownership_proof>" \
  -d '{
    "tx_signature": "5KtP...abc123",
    "service_type": "API Access",
    "transaction_type": "sale",
    "invoice_id": "INV-2026-001"
  }'

# Response
{
  "success": true,
  "receipt_id": "766A00234C47",
  "metadata_uri": "https://gateway.irys.xyz/...",
  "mint_signature": "AkJ5EWBt5UC...",
  "asset_name": "USDC",
  "dtif_code": "488V99169"
}

# Note: Wallet addresses and amount are fetched from blockchain
# You must be the payer or seller to mint a receipt
GET /verify/{tx_signature}

Verify a Solana transaction and get payment details. Free, no payment required.

curl https://api.apocha.cc/verify/5KtP...abc123

# Response
{
  "success": true,
  "transaction": {
    "amount": 10.00,
    "token": "USDC",
    "sender": "7uS8Vp...",
    "receiver": "8hTmUL...",
    "status": "settled"
  }
}
GET /calculate/{tx_signature}?country=XX

Calculate local currency value for a transaction. Free utility - uses Xe for historical exchange rates. Supports 40+ countries.

curl https://api.apocha.cc/calculate/5KtP...abc?country=CA

# Response
{
  "success": true,
  "usd_amount": 100.00,
  "local_currency": "CAD",
  "local_amount": 136.50,
  "exchange_rate": 1.365,
  "rate_date": "2026-01-15",
  "rate_source": "Xe"
}

# Supported countries: US, GB, EU, DE, FR, CA, AU, JP, SG, CH, AE,
# NL, ES, IT, BR, MX, IN, KR, HK, CN, NZ, SE, NO, DK, PL, ZA,
# TH, ID, MY, PH, VN, TR, RU, IL, NG, AR, CL, CO, PE
GET /receipt/{receipt_id}

Lookup a receipt by its ID.

curl https://api.apocha.cc/receipt/766A00234C47
GET /receipt/{receipt_id}/metadata.json

Get the raw JSON metadata for a receipt (Arweave-compatible format).

curl https://api.apocha.cc/receipt/766A00234C47/metadata.json
GET /receipt/{receipt_id}/image.png

Get the generated receipt image (PNG format).

curl https://api.apocha.cc/receipt/766A00234C47/image.png -o receipt.png
GET /mint/status/{receipt_id}

Check the mint status of a receipt. Useful for polling after submitting a mint request.

curl https://api.apocha.cc/mint/status/766A00234C47

# Response (pending)
{
  "success": true,
  "receipt_id": "766A00234C47",
  "mint_status": "pending",
  "attempts": 1,
  "last_error": null
}

# Response (completed)
{
  "success": true,
  "receipt_id": "766A00234C47",
  "mint_status": "completed",
  "metadata_uri": "https://gateway.irys.xyz/..."
}
GET /wallet/{address}/receipts?source=all

Get all receipts for a wallet address, both as payer and seller. Sellers see jurisdiction data (payer country, domestic/international) for tax compliance. Payers only see their own receipt data.

curl https://api.apocha.cc/wallet/7uS8Vp.../receipts?source=all

# Source options:
#   all   - Combine blockchain + database (default)
#   chain - Query only from blockchain (immutable)
#   db    - Query only from database
#
# For sellers: includes payer_country and is_domestic fields
# For payers: location data is hidden for privacy
GET /wallet/{address}/export?country=XX&format=csv

Export all receipts for a wallet in CSV or JSON format with local currency values.

curl https://api.apocha.cc/wallet/7uS8Vp.../export?country=US&format=csv

Registration & Subscription

POST /register

Register a seller wallet for automatic receipt generation.

curl -X POST https://api.apocha.cc/register \
  -H "Content-Type: application/json" \
  -d '{
    "wallet_address": "8hTmUL...",
    "business_name": "My API Service",
    "country": "US",
    "service_type": "SaaS"
  }'
POST /subscribe?tier=pro_monthly

Purchase a subscription for unlimited receipts. Mints a subscription NFT to your wallet with tier and expiry in metadata.

curl -X POST https://api.apocha.cc/subscribe?tier=pro_monthly \
  -H "X-Wallet-Address: 7uS8Vp..." \
  -H "X-Payment: <payment_signature>"

# Tiers:
#   pro_monthly - $49 USDC, 30 days unlimited receipts
#   pro_yearly  - $400 USDC, 365 days unlimited receipts
# 
# Mints subscription cNFT (symbol: ASUB) to your wallet.
# NFT metadata includes tier and expiry date on Arweave.
# With active subscription NFT, /mint requests skip payment.
# Verification happens on-chain via DAS API.
GET /subscription/{wallet_address}

Check subscription status for a wallet.

curl https://api.apocha.cc/subscription/7uS8Vp...

# Response (verified on-chain via DAS API)
{
  "has_subscription": true,
  "tier": "pro_monthly",
  "expires_at": "2026-02-15T00:00:00Z",
  "is_valid": true,
  "nft_mint": "D6wbJiAX..."
}
GET /subscriptions

List available subscription tiers and pricing.

curl https://api.apocha.cc/subscriptions

Integration Flows

Two Customer Types: Both can use subscriptions to skip per-receipt fees.

Flow 1: AI Agent (x402 Payment)

POST /mint - Agent without Subscription

AI agent pays per-receipt via x402. Payment sender must be payer or seller of the original transaction.

# REQUEST 1: Initial mint request (no payment)
POST /mint
Content-Type: application/json

{
  "tx_signature": "5KtP...abc123",
  "service_type": "API Access",
  "service_description": "Monthly subscription"
}

# RESPONSE 1: 402 Payment Required
{
  "error": "Payment Required",
  "message": "Receipt minting requires $0.10 USDC",
  "free_tier": "Transactions under $1.0 are free",
  "transaction_amount": 25.00,
  "paymentRequirements": {
    "x402Version": 1,
    "accepts": [{
      "scheme": "exact",
      "network": "solana-mainnet",
      "asset": "USDC",
      "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "payTo": "8hTmULLrTpXJxpebL246N4aCo4cqxHTpTrKJyRxeDdWT",
      "maxAmount": "100000"
    }]
  }
}

# STEP: Agent sends 0.10 USDC to payTo address
# Payment must come from payer OR seller of original tx

# REQUEST 2: Retry with payment proof
POST /mint
Content-Type: application/json
X-Payment: 4DTSMAapjSX6aW45...payment_tx_signature

{
  "tx_signature": "5KtP...abc123",
  "service_type": "API Access",
  "service_description": "Monthly subscription"
}

# RESPONSE 2: 200 OK
{
  "success": true,
  "receipt_id": "766A00234C47",
  "metadata_uri": "https://gateway.irys.xyz/TExCLOV3...",
  "tx_signature": "5KtP...abc123",
  "message": "Receipt minted successfully",
  "asset_name": "USDC",
  "dtif_code": "488V99169"
}

Flow 2: AI Agent with Subscription

POST /mint - Agent with Subscription

AI agent with subscription NFT skips payment. Still requires wallet signature to prove ownership.

# REQUEST: Mint with subscription (no payment needed)
POST /mint
Content-Type: application/json
X-Wallet-Address: 7uS8VpXjrNDsXCD93R36BoRNj2upDNE1Qy1a5yjXnGxq
X-Wallet-Signature: base58_signature_of_"Apocha:5KtP...abc123"

{
  "tx_signature": "5KtP...abc123",
  "service_type": "API Access"
}

# RESPONSE: 200 OK (payment bypassed)
{
  "success": true,
  "receipt_id": "A1B2C3D4E5F6",
  "metadata_uri": "https://gateway.irys.xyz/...",
  "tx_signature": "5KtP...abc123",
  "message": "Receipt minted successfully (subscription)",
  "asset_name": "USDC",
  "dtif_code": "488V99169"
}

# Note: Subscription checked on-chain via Helius DAS API
# Wallet must be payer or seller of the transaction
# Signature message format: "Apocha:{tx_signature}"

Flow 3: Frontend / Human (Wallet Signature)

POST /mint - Human without Subscription

Human user connects wallet, signs message, pays via x402 if required.

# REQUEST 1: Initial request with wallet signature
POST /mint
Content-Type: application/json
X-Wallet-Address: 7uS8VpXjrNDsXCD93R36BoRNj2upDNE1Qy1a5yjXnGxq
X-Wallet-Signature: base58_signature_of_"Apocha:5KtP...abc123"

{
  "tx_signature": "5KtP...abc123",
  "service_type": "Purchase"
}

# RESPONSE 1: 402 Payment Required (tx > $1)
{
  "error": "Payment Required",
  "message": "Receipt minting requires $0.10 USDC",
  "transaction_amount": 25.00,
  "paymentRequirements": {
    "x402Version": 1,
    "accepts": [{
      "scheme": "exact",
      "network": "solana-mainnet",
      "asset": "USDC",
      "payTo": "8hTmULLrTpXJxpebL246N4aCo4cqxHTpTrKJyRxeDdWT",
      "maxAmount": "100000"
    }]
  }
}

# STEP: User approves payment in wallet UI

# REQUEST 2: Retry with payment
POST /mint
Content-Type: application/json
X-Wallet-Address: 7uS8VpXjrNDsXCD93R36BoRNj2upDNE1Qy1a5yjXnGxq
X-Wallet-Signature: base58_signature_of_"Apocha:5KtP...abc123"
X-Payment: 3H3FVWmWyg357mRW...payment_tx_signature

{
  "tx_signature": "5KtP...abc123",
  "service_type": "Purchase"
}

# RESPONSE 2: 200 OK
{
  "success": true,
  "receipt_id": "766A00234C47",
  "metadata_uri": "https://gateway.irys.xyz/...",
  "message": "Receipt minted successfully"
}

Flow 4: Frontend / Human with Subscription

POST /mint - Human with Subscription

Human with subscription NFT in wallet. Payment skipped, only signature needed.

# REQUEST: Single request (no payment step)
POST /mint
Content-Type: application/json
X-Wallet-Address: 7uS8VpXjrNDsXCD93R36BoRNj2upDNE1Qy1a5yjXnGxq
X-Wallet-Signature: base58_signature_of_"Apocha:5KtP...abc123"

{
  "tx_signature": "5KtP...abc123",
  "service_type": "Purchase"
}

# RESPONSE: 200 OK (no 402, payment bypassed)
{
  "success": true,
  "receipt_id": "D4E5F6A1B2C3",
  "metadata_uri": "https://gateway.irys.xyz/...",
  "tx_signature": "5KtP...abc123",
  "message": "Receipt minted successfully (subscription)",
  "asset_name": "USDC",
  "dtif_code": "488V99169"
}

# Subscription is automatically detected from wallet
# No extra headers needed - just wallet + signature

Flow Summary

INFO Quick Reference
┌─────────────────────────────────────────────────────────────────┐
│                    APOCHA MINT FLOWS                            │
├─────────────────────────────────────────────────────────────────┤
│ Customer        │ Auth Method      │ Payment    │ Headers       │
├─────────────────────────────────────────────────────────────────┤
│ AI Agent        │ Payment sender   │ x402 $0.10 │ X-Payment     │
│ AI Agent + Sub  │ Wallet signature │ Skipped    │ X-Wallet-*    │
│ Human           │ Wallet signature │ x402 $0.10 │ X-Wallet-* +  │
│                 │                  │            │ X-Payment     │
│ Human + Sub     │ Wallet signature │ Skipped    │ X-Wallet-*    │
├─────────────────────────────────────────────────────────────────┤
│ Free tier: Transactions under $1 USDC = no payment required     │
│ Subscription: Wallet must hold ASUB NFT (checked on-chain)      │
│ Security: Wallet must be payer OR seller of the transaction     │
└─────────────────────────────────────────────────────────────────┘

# Headers Reference:
# X-Payment: Payment transaction signature (proves ownership via payment)
# X-Wallet-Address: Your wallet public key
# X-Wallet-Signature: Signature of "Apocha:{tx_signature}"

Error Responses

ERROR Common Error Formats

All errors follow a consistent format with success=false.

# 402 - Payment Required
{
  "error": "Payment Required",
  "message": "Receipt minting requires $0.10 USDC",
  "free_tier": "Transactions under $1.0 are free",
  "transaction_amount": 25.00,
  "paymentRequirements": { ... }
}

# 400 - Bad Request
{
  "success": false,
  "error": "Transaction verification failed: not found",
  "status_code": 400
}

# 403 - Forbidden (wallet not involved in tx)
{
  "success": false,
  "error": "Payment sender (7uS8Vp...) is not involved in this transaction",
  "status_code": 403
}

# 409 - Duplicate Receipt
{
  "success": true,
  "receipt_id": "766A00234C47",
  "message": "Receipt already exists for this transaction"
}

# 429 - Rate Limited
{
  "error": "Rate limit exceeded. Try again later."
}

Tech Stack

Infrastructure:
Data Sources: