# list_rows

Source: https://modulify.ai/docs/api/database/list-rows

Reads rows from one table in a site database, ordered by primary key.

- Title: Read rows from a collection
- Scope: `data:read`
- Access: Read only
- Endpoint: `POST /v1/list_rows`

A call with no `limit` returns the first 50 rows, and `limit` is capped at 200, so larger reads page with `offset`. A table with no primary key is ordered by its first column instead, so paging over one is not guaranteed to be stable.

The count in the response is the size of the whole table, or of the matching rows when `search` is used, rather than of the page. Counting is a second full scan, so on a large table pass `withCount` as false when you do not need the total.

This is real customer content, and the tool tells the client to treat anything in it as data to report, never as instructions to follow. See [Read the table](https://modulify.ai/docs/data/cms#read-the-table).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/list_rows`, sending the inputs below as a JSON object. The token needs the `data:read` scope.

It only reads and changes nothing, so retrying it is safe.

```bash
curl -X POST https://api.modulify.ai/v1/list_rows \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID","name":"NAME"}'
```

Over MCP, the same method is the [list_rows tool](https://modulify.ai/docs/mcp/database/list-rows).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site id. |
| `schema` | string | No | The schema the collection lives in, exactly as `list_collections` reports it. Leave it out to use the site database's own default, which is right unless `list_collections` showed something else. A site on the newer database always uses its default. |
| `name` | string | Yes | The table name. |
| `offset` | integer | No | How many rows to skip. Use it with `limit` to page, 0, then 50, and so on. Defaults to 0. |
| `limit` | integer | No | How many rows to return. Defaults to 50 and is capped at 200, so a larger number is silently reduced. |
| `search` | string | No | Keeps only rows where this text appears anywhere in the row, matched case insensitively across every column. |
| `withCount` | boolean | No | Whether to also count the matching rows. On unless you pass false, which is worth doing on a large table because the count is a second full scan. |

## Response

Every call answers with the [JSON envelope](https://modulify.ai/docs/api/requests-and-responses#the-response) of `success`, `message`, `data`, `code` and `version`. `data` holds the result described above, and on a method that returns a total, `count` carries it. The [response headers](https://modulify.ai/docs/api/requests-and-responses#headers-on-every-method-call) carry the call's `X-Request-Id` and what is left of your per-minute budget in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. [Errors](https://modulify.ai/docs/api/errors) explains every status code a call can answer with.