Skip to main content
OnDB uses the x402 payment protocol for cost handling. When a write or read operation requires payment, the server returns a 402 response with a payment quote. The SDK handles this automatically via the payment callback.

How Pricing Works

Costs are determined server-side based on:
FactorDescription
Data sizeAmount of data being stored (KB)
Indexed fieldsNumber and type of indexes on the collection
Price indexesValue-based pricing via write/read price indexes
Creator premiumsRevenue sharing with content creators

Inspecting Costs via Payment Callback

The payment callback receives an X402Quote with full cost details:
const result = await client.store(
  { collection: 'users', data: [{ name: 'Alice' }] },
  async (quote) => {
    // Inspect the cost before paying
    console.log('Total cost:', quote.totalCost, quote.tokenSymbol);
    console.log('Amount (raw):', quote.amountRaw);
    console.log('Pay to:', quote.brokerAddress);
    console.log('Network:', quote.network);
    console.log('Chain:', quote.chainType);
    console.log('Expires:', new Date(quote.expiresAt * 1000));

    // Process payment
    const txHash = await processPayment(quote);
    return { txHash, network: quote.network, sender: walletAddress, chainType: quote.chainType, paymentMethod: 'native' };
  },
  true
);

Estimating Batch Costs

For batch operations, the payment callback is invoked once for the entire batch. The quote reflects the total cost:
const records = generateRecords(1000);

const result = await client.store(
  { collection: 'batch_data', data: records },
  async (quote) => {
    console.log(`Batch of ${records.length} records:`);
    console.log(`  Total cost: ${quote.totalCost} ${quote.tokenSymbol}`);
    console.log(`  Per record: ~${(quote.totalCost / records.length).toFixed(6)} ${quote.tokenSymbol}`);

    const txHash = await processPayment(quote);
    return { txHash, network: quote.network, sender: walletAddress, chainType: quote.chainType, paymentMethod: 'native' };
  },
  true
);

Retention Costs

Use getRetentionCost() to estimate ongoing storage costs for your collections:
const costs = await client.getRetentionCost();

console.log('Total monthly cost:', costs.total_monthly_cost, 'USDC');
console.log('Projected next month:', costs.projected_next_month_cost, 'USDC');

for (const col of costs.collections) {
  console.log(`  ${col.collection}: ${col.monthly_cost} USDC/month (${col.size_kb} KB)`);
}

Next Steps

Write Payments

Execute payments

PriceIndex

Value-based pricing