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

# Query rows

> Read a database's rows with filters and sorts.

Reads a list of rows. Trashed and archived rows are left out by default. With no sort, the most recently created rows come first.

This endpoint has its own rate limit of about 3 requests per second per integration. See [Rate limits](https://developers.bottari.ai/limits/rate-limits.md).

**Authorization** `string` *required*

`Bearer <token>`. See [Tokens](https://developers.bottari.ai/auth/tokens.md).

**Bottari-Version** `string`

Optional. Only `2026-03-11` is accepted. Without it, the current version is used. A different value returns 400.

**id** `string` *required*

The data source ID. Use the database ID.

**filter\_properties** `string[]`

Property names or IDs to include. An unknown property returns 400.

**filter** `object`

See [Filters and sorts](https://developers.bottari.ai/api-reference/filters.md).

**sorts** `object[]`

See [Sorts](https://developers.bottari.ai/api-reference/filters.md#sorts).

**start\_cursor** `string`

`next_cursor` from the previous response. See [Read every row](#read-every-row).

**page\_size** `number` (default: 100)

1 to 100.

**in\_trash** `boolean`

If `true`, returns trashed rows that aren't archived.

**is\_archived** `boolean`

If `true`, returns archived rows that aren't in the trash. With `in_trash` and `is_archived` both `true`, returns rows that are both trashed and archived.

**result\_type** `string`

Only `page` is accepted.

**results** `object[]`

`page` objects. See [Property values](https://developers.bottari.ai/api-reference/property-values.md).

**next\_cursor** `string | null`

The cursor for the next set.

**has\_more** `boolean`

`true` if there's more.

**type** `string`

Always `page_or_data_source`.

## Read every row

Query results have no limit on the total number of rows. If `has_more` is `true`, send `next_cursor` as `start_cursor` and repeat until `has_more` is `false`.

Send the same `filter`, `sorts`, `in_trash`, and `is_archived` with every page, with keys in the same order. Only `start_cursor` and `page_size` can change. Otherwise the cursor returns 400.

```bash theme={null}
curl https://api.bottari.ai/v1/data_sources/exampleDb001/query \
  -X POST \
  -H "Authorization: Bearer $BOTTARI_TOKEN" \
  -H "Bottari-Version: 2026-03-11" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "property": "Team", "select": { "equals": "Ops" } },
    "sorts": [{ "timestamp": "created_time", "direction": "descending" }],
    "start_cursor": "eyJxIjoiZXhhbXBsZSJ9"
  }'
```

## Errors

| Status | `code` | Cause |
| - | - | - |
| 400 | `validation_error` | An unknown body key, a wrong filter or sort, a cursor sent without the same `filter`, `sorts`, `in_trash`, and `is_archived`, or an unknown `filter_properties` value. |
| 404 | `object_not_found` | The database doesn't exist, isn't connected, or is in the trash. |
| 429 | `rate_limited` | You went over a rate limit. |

See [Common rules](https://developers.bottari.ai/api-reference/overview.md#errors) for shared errors.

```bash curl theme={null}
curl "https://api.bottari.ai/v1/data_sources/exampleDb001/query?filter_properties=title&filter_properties=exampleFld01" \
  -X POST \
  -H "Authorization: Bearer $BOTTARI_TOKEN" \
  -H "Bottari-Version: 2026-03-11" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "property": "Team",
      "select": {
        "equals": "Ops"
      }
    },
    "sorts": [
      {
        "timestamp": "created_time",
        "direction": "descending"
      }
    ],
    "page_size": 10
  }'
```

```json 200 theme={null}
{
  "object": "list",
  "results": [
    {
      "object": "page",
      "id": "exampleRow01",
      "created_time": "2026-01-15T02:30:00.000Z",
      "last_edited_time": "2026-01-15T03:10:00.000Z",
      "created_by": {
        "object": "user",
        "id": "11111111-1111-4111-8111-111111111111"
      },
      "last_edited_by": {
        "object": "user",
        "id": "11111111-1111-4111-8111-111111111111"
      },
      "in_trash": false,
      "cover": null,
      "icon": null,
      "parent": {
        "type": "data_source_id",
        "data_source_id": "exampleDb001",
        "database_id": "exampleDb001"
      },
      "is_archived": false,
      "is_locked": false,
      "properties": {
        "Name": {
          "id": "title",
          "type": "title",
          "title": [
            {
              "type": "text",
              "text": {
                "content": "Review January orders",
                "link": null
              },
              "annotations": {
                "bold": false,
                "italic": false,
                "strikethrough": false,
                "underline": false,
                "code": false,
                "color": "default"
              },
              "plain_text": "Review January orders",
              "href": null
            }
          ]
        },
        "Team": {
          "id": "exampleFld01",
          "type": "select",
          "select": {
            "id": "exampleOpt01",
            "name": "Ops",
            "color": "blue"
          }
        }
      },
      "url": "https://app.bottari.ai/t/exampleTeam1/p/exampleRow01",
      "public_url": null
    }
  ],
  "next_cursor": "eyJxIjoiZXhhbXBsZSJ9",
  "has_more": true,
  "type": "page_or_data_source",
  "page_or_data_source": {},
  "request_id": "33333333-3333-4333-8333-333333333333"
}
```

```json 400 theme={null}
{
  "object": "error",
  "status": 400,
  "code": "validation_error",
  "message": "body failed validation: body.start_cursor should be a valid cursor for this query.",
  "request_id": "33333333-3333-4333-8333-333333333333"
}
```


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