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

# Pagination

> Traverse Onlyform collections with opaque cursors.

List endpoints use cursor pagination. Cursor pagination remains stable when records are added while you are traversing a collection.

## Paginated endpoints

* `GET /v1/workspaces`
* `GET /v1/forms`
* `GET /v1/forms/{formId}/submissions`

## Request a page

Use `limit` to control the page size. The default is 20 and the maximum is 100.

```bash theme={null}
curl "https://api.onlyform.com/v1/forms?limit=50" \
  --header "X-API-Key: $ONLYFORM_API_KEY"
```

The response includes an `items` array and pagination metadata:

```json theme={null}
{
  "items": [],
  "page": {
    "has_more": true,
    "next_cursor": "eyJpZCI6IjUwN2Yx..."
  }
}
```

## Request the next page

When `page.has_more` is `true`, pass `page.next_cursor` back unchanged:

```bash theme={null}
curl "https://api.onlyform.com/v1/forms?limit=50&cursor=eyJpZCI6IjUwN2Yx..." \
  --header "X-API-Key: $ONLYFORM_API_KEY"
```

Continue until `has_more` is `false` and `next_cursor` is `null`.

<Warning>
  Cursors are opaque. Do not decode, edit, construct, or persist assumptions about their contents.
</Warning>

An invalid cursor returns `422 INVALID_CURSOR`.

## JavaScript example

```javascript theme={null}
const baseUrl = 'https://api.onlyform.com'
let cursor

do {
  const url = new URL('/v1/forms', baseUrl)
  url.searchParams.set('limit', '100')
  if (cursor) url.searchParams.set('cursor', cursor)

  const response = await fetch(url, {
    headers: {
      'X-API-Key': process.env.ONLYFORM_API_KEY,
    },
  })

  if (!response.ok) {
    const error = await response.json()
    throw new Error(`${error.code}: ${error.message} (${error.request_id})`)
  }

  const body = await response.json()
  for (const form of body.items) {
    console.log(form.id, form.name)
  }

  cursor = body.page.has_more ? body.page.next_cursor : undefined
} while (cursor)
```

## Submission date filters

The submissions list also accepts `since` and `until` as ISO 8601 timestamps.

```bash theme={null}
curl "https://api.onlyform.com/v1/forms/507f1f77bcf86cd799439011/submissions?since=2026-07-01T00:00:00Z&until=2026-08-01T00:00:00Z" \
  --header "X-API-Key: $ONLYFORM_API_KEY"
```
