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

# Query records

> Read bounded results and inspect the query plan.

## Query rows

Use the structured query model for most requests. It supports:

* bounded pagination;
* field projection;
* nested `and`, `or`, and `not` filters;
* sorting, grouping, and distinct selection;
* type-aware casts;
* supported joins and common table expressions on surfaces that explicitly allow them.

```js theme={null}
const result = await api.getDatabaseData('orders', {
  fields: ['orderId', 'customerId', 'total', 'status'],
  filter: {
    and: [
      { field: 'status', op: 'eq', value: 'READY' },
      { field: 'total', op: 'gte', value: 100, filterType: 'number' },
    ],
  },
  sort: { createdAt: 'DESC' },
  take: 100,
});
```

This returns up to 100 ready orders with totals of at least 100, newest first. Show it as a bounded page in the UI. For a full scan, follow the returned paging contract and use a stable order. See [bounded reads](https://docs.revoengine.com/patterns/bounded-data.md).

### Platform API read paths

The generated Platform API exposes two complementary read operations:

| Operation | Use it for |
| - | - |
| [Get Database data](https://docs.revoengine.com/api-reference/databases/get-database-data.md) | Query-string filtering, projection, sorting, joins, casts, pagination, and count. An explicit `take` is validated up to 10,000; larger values are rejected rather than silently treated as 10,000. |
| [Query Database data with a request body](https://docs.revoengine.com/api-reference/databases/query-database-data-with-a-request-body.md) | A structured JSON query when nested filters, joins, expressions, or casts are awkward to encode in a URL. Joined Tables are authorization-checked independently. |

Both return `data`, `results`, and `next`, plus `total` only when count is requested. The body-based query does not publish a larger guaranteed page ceiling. Keep pages bounded and prefer keyset-like business filters for large data sets instead of increasing `skip` indefinitely.

### Preview a read plan

Use `debug: true` on `api.getDatabaseData` to inspect the complete estimated read
plan before fetching records. `count: true` also previews the count plan. The
result contains `debug.explain` and optional `debug.countExplain`; it contains no
records or pagination result. Omit `debug` to fetch records normally.

```javascript theme={null}
const diagnostic = await api.getDatabaseData('orders', {
  fields: ['orderId'],
  filter: { field: 'status', op: 'eq', value: 'OPEN' },
  take: 100,
  debug: true,
});
console.log(diagnostic.debug.explain.join('\n'));
```

This option retains normal data access checks and query validation. Use it on
`getDatabaseData`, rather than row, count or walk helpers. An unsupported data
source rejects the diagnostic request without running the read.

Continue with [databases](https://docs.revoengine.com/operate/databases.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.