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

# SDK: Custom Data

> Query, read, and write custom data tables with the SDK

`client.data` wraps the [custom data REST API](/api-reference/custom-data/query). All operations are scoped to your organization.

## Query (search)

Facet-filtered search over an indexed table. Returns at most 50 records per call:

```typescript theme={null}
const { records, total } = await client.data.query({
  tableName: 'customers',
  filters: [{ column: 'state', values: ['CA', 'NY'] }],
  text: 'ada lovelace', // optional free-text relevance search
  size: 25,
  from: 0,
});
```

Type the records for convenience (types are not validated at runtime):

```typescript theme={null}
type Customer = { email: string; plan: string };
const { records } = await client.data.query<Customer>({ tableName: 'customers' });
```

## Records

```typescript theme={null}
// Paginated listing from the relational store
const page = await client.data.list('customers', {
  page: 1,
  perPage: 50,
  orderBy: 'created_at',
  orderDirection: 'desc',
  filters: { state: 'CA' }, // column equality filters
});

const { record } = await client.data.get('customers', 42);
const created = await client.data.create('customers', { email: 'ada@example.com', plan: 'pro' });
const updated = await client.data.update('customers', 42, { plan: 'enterprise' });
await client.data.delete('customers', 42);
await client.data.deleteAll('customers'); // removes every record — irreversible
```

## Bulk Upserts

Large imports go through asynchronous batches of up to 1,000 rows:

```typescript theme={null}
const { ingestBatchId } = await client.data.batchUpsert('customers', rows);

// Poll until the batch is applied
const status = await client.data.getBatch(ingestBatchId);
// status.status: 'queued' | 'processing' | 'succeeded' | 'failed'
```

<Warning>
  Batch rows are **full-row replace** on key conflict: a column omitted from a row is written as
  `NULL`, not preserved. Always send the complete record.
</Warning>

## Facets

```typescript theme={null}
const facets = await client.data.facets('customers');
```

Returns the configured facet values for the table, matching the [facets endpoint](/api-reference/custom-data/get-facets).
