API Documentation

CheckPoint is a self-hosted x402 facilitator for Base. Integrate payments in 5 minutes.

Quickstart

0

Install the SDK (optional)

bash
npm install @x402-checkpoint/sdk
typescript
import { CheckPointClient } from '@x402-checkpoint/sdk';

const client = new CheckPointClient();
const health = await client.health();
1

Server: Return 402 with payment requirements

typescript
// When client requests paid resource
res.status(402).json({
  x402Version: 2,
  payTo: "0xYourWallet",
  amount: "10000",           // 0.01 USDC (6 decimals)
  network: "eip155:8453",    // Base Mainnet
  asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  facilitator: "https://checkpoint-pied.vercel.app"
});
2

Client: Sign EIP-3009 authorization

typescript
import { signTypedData } from 'viem/accounts';

const authorization = {
  from: clientWallet,
  to: payTo,
  value: BigInt(amount),
  validAfter: 0n,
  validBefore: BigInt(Math.floor(Date.now() / 1000) + 3600),
  nonce: `0x${crypto.randomBytes(32).toString('hex')}`
};

const signature = await wallet.signTypedData({
  domain: { name: 'USDC', version: '2', chainId: 8453, verifyingContract: asset },
  types: { TransferWithAuthorization: [...] },
  primaryType: 'TransferWithAuthorization',
  message: authorization
});
3

Server: Verify and settle

typescript
// Verify payment
const verifyRes = await fetch('https://checkpoint-pied.vercel.app/api/v2/x402/verify', {
  method: 'POST',
  body: JSON.stringify({ paymentPayload, paymentRequirements })
});
const { valid } = await verifyRes.json();

if (valid) {
  // Settle payment (USDC transfers client → you)
  await fetch('https://checkpoint-pied.vercel.app/api/v2/x402/settle', {
    method: 'POST',
    body: JSON.stringify({ paymentPayload, paymentRequirements })
  });
  
  // Serve resource
  res.json({ data: "your content" });
}

◎ Solana Integration

CheckPoint supports Solana via the SPL Token delegate pattern. Network IDs: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp (Mainnet) or solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 (Devnet)

1

One-Time: Setup Delegate Approval

Payers must approve CheckPoint as a delegate for their USDC tokens.

typescript
import { fetchDelegateSetup, SOLANA_NETWORKS } from '@x402-checkpoint/sdk';

const setup = await fetchDelegateSetup({
  facilitatorUrl: 'https://checkpoint-pied.vercel.app',
  payer: wallet.publicKey.toBase58(),
  network: SOLANA_NETWORKS.DEVNET,
  amount: '1000000000', // 1000 USDC
});

// Build and submit approve transaction
const transaction = new Transaction().add(
  new TransactionInstruction({
    programId: new PublicKey(setup.instruction.programId),
    keys: setup.instruction.keys.map(k => ({
      pubkey: new PublicKey(k.pubkey),
      isSigner: k.isSigner,
      isWritable: k.isWritable,
    })),
    data: Buffer.from(setup.instruction.data, 'base64'),
  })
);
await wallet.sendTransaction(transaction, connection);
2

Create and Sign Payment Authorization

typescript
import {
  createSolanaAuthorization,
  signSolanaPayment,
  createSolanaPaymentPayload,
  SOLANA_NETWORKS,
} from '@x402-checkpoint/sdk';

// Create authorization
const authorization = createSolanaAuthorization({
  from: wallet.publicKey.toBase58(),
  to: 'MerchantWalletPubkey',
  amount: '1000000', // 1 USDC
  timeoutSeconds: 3600,
});

// Sign with wallet adapter
const signature = await signSolanaPayment(
  authorization,
  async (msg) => await wallet.signMessage(msg)
);

// Create payment payload
const paymentPayload = createSolanaPaymentPayload({
  authorization,
  signature,
  network: SOLANA_NETWORKS.DEVNET,
});
3

Verify and Settle

typescript
const paymentRequirements = {
  scheme: 'exact',
  network: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
  amount: '1000000',
  asset: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // Devnet USDC
  payTo: 'MerchantWalletPubkey',
  maxTimeoutSeconds: 3600,
};

// Verify
const verifyRes = await fetch('https://checkpoint-pied.vercel.app/api/v2/x402/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ paymentPayload, paymentRequirements }),
});
const { valid, payer, amount } = await verifyRes.json();

if (valid) {
  // Settle - USDC transfers from payer to merchant
  const settleRes = await fetch('https://checkpoint-pied.vercel.app/api/v2/x402/settle', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ paymentPayload, paymentRequirements }),
  });
  const { success, txHash } = await settleRes.json();
  console.log('Settlement TX:', txHash);
}

Solana Network Constants

typescript
// Network IDs (CAIP-2)
const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';
const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';

// USDC Mint Addresses
const MAINNET_USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const DEVNET_USDC = '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU';

Required Dependencies

bash
npm install @x402-checkpoint/sdk @solana/web3.js @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-wallets

Test Tokens (Devnet)

Before testing, get these tokens:

Delegate Approval

Users must approve CheckPoint as a delegate before payments can be settled. Use our delegate approval page or integrate the component into your app.

Authentication

Core payment endpoints (verify/settle) require no authentication. Admin endpoints require an API key or master key.

bash
# Create API key (requires FACILITATOR_MASTER_KEY)
curl -X POST https://checkpoint-pied.vercel.app/api/keys \
  -H "Authorization: Bearer YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ownerId": "merchant1", "scopes": ["payments:read"]}'

Payments

POST/api/v2/x402/verify

Verify a signed payment before serving content. No auth required.

cURL

bash
curl -X POST https://checkpoint-pied.vercel.app/api/v2/x402/verify \
  -H "Content-Type: application/json" \
  -d '{"paymentPayload": {...}, "paymentRequirements": {...}}'

Request Body

json
{
  "paymentPayload": {
    "x402Version": 2,
    "resource": {
      "url": "https://api.example.com/premium/data",
      "description": "Premium API endpoint",
      "mimeType": "application/json"
    },
    "accepted": {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "10000",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "maxTimeoutSeconds": 60
    },
    "payload": {
      "signature": "0xa1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d41b",
      "authorization": {
        "from": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD00",
        "to": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
        "value": "10000",
        "validAfter": "0",
        "validBefore": "1999999999",
        "nonce": "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "10000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "maxTimeoutSeconds": 60
  }
}

Response

json
{
  "valid": true,
  "payer": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD00",
  "payee": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "amount": "10000",
  "nonce": "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "simulationPassed": true
}
POST/api/v2/x402/settle

Execute on-chain USDC transfer. Requires prior verification.

cURL

bash
curl -X POST https://checkpoint-pied.vercel.app/api/v2/x402/settle \
  -H "Content-Type: application/json" \
  -d '{"paymentPayload": {...}, "paymentRequirements": {...}}'

Response

json
{
  "success": true,
  "network": "eip155:8453",
  "txHash": "0x...",
  "blockNumber": 12345678,
  "gasUsed": "85000"
}
GET/api/payments

Query payment history. Requires payments:read scope.

cURL

bash
curl https://checkpoint-pied.vercel.app/api/payments \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

json
{
  "payments": [
    {
      "id": "pay_...",
      "payer": "0x...",
      "payee": "0x...",
      "amount": "10000",
      "status": "settled",
      "txHash": "0x...",
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ],
  "total": 1
}

Discovery

GET/api/discovery

Browse registered services. Public, no auth required.

cURL

bash
curl https://checkpoint-pied.vercel.app/api/discovery

Response

json
{
  "services": [
    {
      "id": "svc_...",
      "name": "AI Analysis API",
      "description": "GPT-powered analysis",
      "url": "https://api.example.com",
      "pricing": { "model": "per_request", "amount": "10000" },
      "categories": ["AI", "Analysis"]
    }
  ]
}
POST/api/discovery

Register your service. Requires discovery:write scope.

cURL

bash
curl -X POST https://checkpoint-pied.vercel.app/api/discovery \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My AI Service", ...}'

Request Body

json
{
  "name": "My AI Service",
  "description": "Description of service",
  "url": "https://api.myservice.com",
  "paymentEndpoint": "/v1/analyze",
  "networks": ["eip155:8453"],
  "pricing": {
    "model": "per_request",
    "amount": "10000",
    "currency": "USDC"
  },
  "categories": ["AI"]
}

Response

json
{
  "id": "svc_...",
  "name": "My AI Service",
  "status": "active"
}

Admin

POST/api/keys

Create API key. Requires master key.

cURL

bash
curl -X POST https://checkpoint-pied.vercel.app/api/keys \
  -H "Authorization: Bearer YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ownerId": "merchant1", "scopes": ["payments:read"]}'

Request Body

json
{
  "ownerId": "merchant1",
  "scopes": ["payments:read", "webhooks:write"],
  "label": "Production Key"
}

Response

json
{
  "id": "key_...",
  "key": "cp_live_...",          // Only shown once!
  "prefix": "cp_live_abc",
  "scopes": ["payments:read", "webhooks:write"]
}
POST/api/webhooks

Configure webhook. Requires webhooks:write scope.

cURL

bash
curl -X POST https://checkpoint-pied.vercel.app/api/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://...", "events": ["payment.settled"]}'

Request Body

json
{
  "url": "https://your-server.com/webhook",
  "events": ["payment.verified", "payment.settled", "payment.failed"]
}

Response

json
{
  "id": "wh_...",
  "url": "https://your-server.com/webhook",
  "secret": "whsec_...",        // For HMAC verification
  "events": ["payment.verified", "payment.settled"]
}
GET/api/health

Health check. Public, no auth required.

cURL

bash
curl https://checkpoint-pied.vercel.app/api/health

Response

json
{
  "status": "healthy",
  "version": "1.0.0",
  "redis": { "connected": true },
  "networks": [
    { "id": "eip155:8453", "name": "Base", "status": "connected" }
  ]
}

Error Codes

All possible error codes returned by CheckPoint API endpoints.

Verification Errors

CodeDescriptionSolution
INVALID_SIGNATUREEIP-712 signature verification failedCheck signature creation matches USDC domain
AUTHORIZATION_EXPIREDvalidBefore timestamp passedRe-sign with new validBefore
AUTHORIZATION_NOT_YET_VALIDvalidAfter not yet reachedWait or use validAfter: 0
INSUFFICIENT_BALANCEPayer lacks USDCFund payer wallet
AMOUNT_MISMATCHAuthorization amount wrongMatch amount to requirements
PAYEE_MISMATCHAuthorization payee wrongMatch payee to requirements
NONCE_ALREADY_USEDReplay attack preventedGenerate new random nonce
SIMULATION_FAILEDOn-chain simulation failedCheck contract state

Settlement Errors

CodeDescriptionSolution
VERIFICATION_REQUIREDMust verify firstCall /verify before /settle
NONCE_ALREADY_SETTLEDPayment already processedCheck receipt by txHash
SETTLEMENT_IN_PROGRESSAnother attempt runningWait and check status
TRANSACTION_FAILEDTX submission failedRetry with new nonce
TRANSACTION_REVERTEDTX reverted on-chainCheck balance/allowance
INSUFFICIENT_GASFacilitator needs ETHFund facilitator wallet

Error Handling

typescript
import { CheckPointClient, CheckPointError } from '@x402-checkpoint/sdk';

const checkpoint = new CheckPointClient();

try {
  const result = await checkpoint.verify({
    paymentPayload: { ... },
    paymentRequirements: { ... }
  });
} catch (error) {
  if (error instanceof CheckPointError) {
    switch (error.code) {
      case 'INSUFFICIENT_BALANCE':
        console.log('Payer needs more USDC');
        break;
      case 'AUTHORIZATION_EXPIRED':
        console.log('Need to re-sign with new validBefore');
        break;
      case 'NONCE_ALREADY_USED':
        console.log('Generate new nonce and re-sign');
        break;
      default:
        console.log('Error:', error.message);
    }
    
    // Check retryability
    if (error.isRetryable) {
      // 5xx errors or network issues - can retry
    }
  }
}

Retry Logic

The SDK automatically retries on network errors and 5xx responses with exponential backoff:

typescript
const checkpoint = new CheckPointClient({
  retry: {
    maxRetries: 3,      // Maximum attempts
    baseDelay: 1000,    // Initial delay (ms)
    maxDelay: 10000     // Max delay cap (ms)
  }
});