> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ondb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Storage

> Store JSON documents with built-in monetization

OnDB stores JSON documents with verifiable storage and automatic payment handling.

## How It Works

The SDK automatically handles payment responses internally. When you pass a payment callback as the second parameter to `store()`, the SDK:

1. Attempts the store operation
2. If the server requires payment, the SDK invokes your callback with the payment quote
3. Your callback executes the payment and returns the result
4. The SDK automatically retries the store operation with the payment proof

You do NOT need to catch payment errors or make a second API call - the SDK handles the entire flow.

## Store with Payment Callback

```typescript theme={null}
// Store with payment callback
const result = await client.store(
  {
    collection: 'posts',
    data: [{
      title: 'My First Post',
      content: 'Stored on blockchain!',
      author: 'alice'
    }]
  },
  // Payment callback - SDK invokes this when server requires payment
  async (quote) => {
    const txHash = await processPayment(quote);

    return {
      txHash,
      network: quote.network,
      sender: walletAddress,
      chainType: quote.chainType,
      paymentMethod: 'native'
    };
  },
  true // waitForConfirmation
);

// SDK automatically retried with payment proof - result contains confirmed data
console.log(`Confirmed at block ${result.block_height}`);
```

## Wait for Confirmation

The `waitForConfirmation` option ensures data is confirmed on-chain before returning:

```typescript theme={null}
// Without confirmation (returns immediately with ticket)
const quick = await client.store(
  { collection: 'products', data: products },
  paymentCallback,
  false  // Returns immediately
);

console.log('Task ticket:', quick.ticket_id);

// Check status later
const status = await client.getTaskStatus(quick.ticket_id);
console.log('Status:', status.status);

// With confirmation (waits for blockchain)
const confirmed = await client.store(
  { collection: 'products', data: products },
  paymentCallback,
  true  // Waits for on-chain confirmation
);

console.log('Data confirmed at height:', confirmed.block_height);
```

## Payment Methods

OnDB supports multiple payment methods:

### Method 1: Payment Callback (Recommended)

```typescript theme={null}
await client.store(
  { collection: 'data', data: [{ content: 'example' }] },
  async (quote) => {
    const txHash = await processPayment(quote);
    return { txHash, network: quote.network, sender: walletAddress, chainType: quote.chainType, paymentMethod: 'native' };
  },
  true
);
```

### Method 2: Auto-Pay (Agent Key)

```typescript theme={null}
// With an Agent Key, payment is automatic -- no callback needed
const agent = createClient({
  endpoint: 'https://api.ondb.io',
  appId: 'my_agent_app',
  agentKey: 'app_a3f9...'  // Key must have Pay permission
});

await agent.store({
  collection: 'target_app::data',
  data: [{ content: 'example' }]
});
```

### Method 3: Pre-paid via Callback

```typescript theme={null}
const paymentTxHash = 'ABC123...'; // Already paid

await client.store(
  { collection: 'data', data: [{ content: 'example' }] },
  async (quote) => ({
    txHash: paymentTxHash,
    network: quote.network,
    sender: walletAddress,
    chainType: quote.chainType,
    paymentMethod: 'native'
  }),
  true
);
```

## Storage Model

OnDB uses an append-only storage model. See [Immutability](/concepts/immutability) for details on how creates, updates, and deletes work under the hood, as well as data retention policies.

## Next Steps

<CardGroup cols={2}>
  <Card title="Payment Flows" icon="credit-card" href="/concepts/payment-flows">
    Deep dive into payment options
  </Card>

  <Card title="Query Builder" icon="magnifying-glass" href="/querying/query-builder">
    Query your stored data
  </Card>
</CardGroup>
