# Pagination

Two endpoints return long lists. A provider's plans page by `offset`; a plan's providers page by `cursor`. Every other endpoint returns its whole answer at once.

Source: https://inplan.io/docs/pagination · Updated 2026-10-30

## A provider's plans: offset and limit

`GET /v1/providers/{npi}/plans` takes `limit` (default 500, at most 2,000) and `offset` (default 0). `total` counts every plan that matches your filters. `next_offset` is the `offset` for the next page, and `null` on the last page.

curl:

```bash
curl https://api.inplan.io/v1/providers/1184617268/plans \
  -H "Authorization: Bearer $INPLAN_KEY" \
  -G -d year=2026 -d limit=2
```

JavaScript:

```javascript
const url = new URL("https://api.inplan.io/v1/providers/1184617268/plans");
url.search = new URLSearchParams({ year: "2026", limit: "2" });

const res = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.INPLAN_KEY}` },
});
const body = await res.json();
console.log(body.data.total, body.data.next_offset);
```

Python:

```python
import os, requests

res = requests.get(
    "https://api.inplan.io/v1/providers/1184617268/plans",
    params={"year": "2026", "limit": "2"},
    headers={"Authorization": f"Bearer {os.environ['INPLAN_KEY']}"},
    timeout=10,
)
body = res.json()
print(body["data"]["total"], body["data"]["next_offset"])
```

Response (200 OK · shortened):

```json
{
  "data": {
    "npi": "1184617268",
    "provider_states": [
      "OH"
    ],
    "filters": {
      "market": null,
      "state": null,
      "year": 2026
    },
    "total": 46,
    "counts": {
      "aca": 46,
      "ma": 0
    },
    "offset": 0,
    "limit": 2,
    "next_offset": 2,
    "plans": [
      {
        "market": "aca",
        "plan_id": "29276OH0970001",
        "plan_year": 2026,
        "plan_name": "Anthem Bronze Pathway 10600 ($0 Virtual PCP + $0 Select Drugs)",
        "network_tiers": [
          "PARTICIPATING"
        ],
        "source": {
          "type": "insurer_directory",
          "as_of": "2026-07-27"
        }
      },
      {
        "market": "aca",
        "plan_id": "29276OH0970002",
        "plan_year": 2026,
        "plan_name": "Anthem Heart Healthy Bronze Pathway 6000 ($0 Virtual PCP + $0 Select Drugs)",
        "network_tiers": [
          "PARTICIPATING"
        ],
        "source": {
          "type": "insurer_directory",
          "as_of": "2026-07-27"
        }
      }
    ]
  }
}
```

## A plan's providers: cursors

`GET /v1/plans/{plan_id}/providers` (Growth and above) takes `limit` (default 50, at most 100). Pass `page.next_cursor` from one response as `cursor` in the next request, unchanged, until it is `null`. A cursor belongs to one plan and plan year.

Response (200 OK · page 1):

```json
{
  "data": {
    "page": {
      "limit": 2,
      "rows_scanned": 2,
      "scanned_through": 2,
      "max_depth": 5000,
      "next_cursor": "eyJvIjoyLCJ5IjoyMDI2LCJwIjoiMjkyNzZPSDA5NzAwMDEifQ"
    }
  }
}
```

With filters (`state`, `zip`, `radius`, `specialty`), a page can hold fewer than `limit` providers, even none, while `next_cursor` is not `null`. Keep following the cursor. Paging reads up to `page.max_depth` (5,000) listings of a plan; past that the API answers `400 depth_limit`. Narrow the filters, or ask about data files for whole plan networks.

## Paging errors

| Type | When |
| --- | --- |
| `invalid_cursor` | The cursor was changed, or belongs to another plan. |
| `depth_limit` | Paging reached `max_depth` listings for this plan. |
| `invalid_request` | `limit` or `offset` is not a whole number in range. |
