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

# Fetch Dataset

> Retrieve paginated, redacted rows for a single dataset

A single endpoint serves both initial and incremental loads. The shape of each element in `rows[]` depends on the dataset — see the [per-dataset pages](/api-reference/exports/datasets/d07-borrower-payments) for the field-by-field reference. Every response also carries pagination and meta blocks that tell you how to fetch the next page and how your filter was interpreted.

## Request

### Endpoint

```
GET {{base_url}}/lenders/{{lenderPublicId}}/exports/{{sectionCode}}/{{datasetCode}}
```

<Tabs>
  <Tab title="Production">
    `https://v3-api.cleargrid.ai/admin/v3`
  </Tab>

  <Tab title="Staging">
    `https://stage-v3-api.cleargrid.ai/admin/v3`
  </Tab>
</Tabs>

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token obtained from the [Lender Login](/api-reference/authentication/lender-login) endpoint. Format: `Bearer <access_token>`.
</ParamField>

### Path parameters

<ParamField path="lenderPublicId" type="string" required>
  Your lender public ID. Must equal the `lenderId` encoded in the JWT, otherwise the request returns `403`.
</ParamField>

<ParamField path="sectionCode" type="string" required>
  One of `S1`–`S5`. See the [catalog endpoint](/api-reference/exports/endpoints/catalog).
</ParamField>

<ParamField path="datasetCode" type="string" required>
  One of `D01`–`D26` (with gaps). See the [catalog endpoint](/api-reference/exports/endpoints/catalog).
</ParamField>

### Query parameters

<ParamField query="since" type="string (ISO-8601)">
  Inclusive lower bound (`>=`) on the dataset's cursor field. Omit for an initial load.
</ParamField>

<ParamField query="until" type="string (ISO-8601)">
  Exclusive upper bound (`<`) on the dataset's cursor field. Omit to read up to "now".
</ParamField>

<ParamField query="cursor" type="string">
  Opaque next-page token from the previous response's `body.pagination.nextCursor`. Omit on the first page. Treat as opaque — see [Pagination](/api-reference/exports/pagination).
</ParamField>

<ParamField query="limit" type="integer" default="500">
  Page size. Range: `1`–`1000`. Values outside the range are clamped.
</ParamField>

<ParamField query="sort" type="string" default="asc">
  Sort direction on the cursor field. One of `asc` or `desc`.
</ParamField>

<ParamField query="includeTotal" type="boolean" default="false">
  When `true`, runs an extra query and adds `pagination.total` (the filter-wide row count, independent of cursor/limit). For `via` datasets (e.g. `D21`, `D22`, `D23`) a time window — `since` and/or `until` — is required, otherwise `total` is `null` with `totalNote: "window_required"`. Large counts are capped (`totalExact: false`, `totalNote: "capped"`) and the query is time-bounded (`total: null`, `totalNote: "timeout"`).
</ParamField>

### Example requests

```bash theme={null}
# Initial load — walk forward until nextCursor is null
curl -X GET \
  "https://stage-v3-api.cleargrid.ai/admin/v3/lenders/${LENDER}/exports/S2/D07?limit=500" \
  -H "Authorization: Bearer <token>"

# Incremental — only rows updated since last sync
curl -X GET \
  "https://stage-v3-api.cleargrid.ai/admin/v3/lenders/${LENDER}/exports/S2/D07?since=2026-05-22T10:00:00Z&limit=500" \
  -H "Authorization: Bearer <token>"

# Continuing pagination — pass nextCursor back
curl -X GET \
  "https://stage-v3-api.cleargrid.ai/admin/v3/lenders/${LENDER}/exports/S2/D07?cursor=eyJ1Ijoi...&limit=500" \
  -H "Authorization: Bearer <token>"

# Page + filter-wide total
curl -X GET \
  "https://stage-v3-api.cleargrid.ai/admin/v3/lenders/${LENDER}/exports/S2/D07?since=2026-05-01T00:00:00Z&limit=500&includeTotal=true" \
  -H "Authorization: Bearer <token>"
```

## Response

<Tabs>
  <Tab title="200 — Success">
    Example using `D07` (Borrower Payments). `nextCursor` is non-null, so there are more pages to fetch.

    ```json theme={null}
    {
      "code": 200,
      "message": "Dataset retrieved successfully",
      "body": {
        "section": { "code": "S2", "name": "Payments & Settlements" },
        "dataset": { "code": "D07", "name": "Borrower Payments" },
        "rows": [
          {
            "public_id": "b1f4c2e0-9a73-4d21-8c54-7e2a1d9b0f31",
            "amount": 75000,
            "settled_amount": 75000,
            "payment_type": "PAID_TO_LENDER",
            "payment_status": "SUCCESS",
            "is_settled": true,
            "paid_before_submission": false,
            "paid_date": "2026-05-18T08:12:44.000Z",
            "failure_reason": null,
            "created_at": "2026-05-18T08:12:45.221Z",
            "updated_at": "2026-05-18T08:30:02.108Z"
          },
          {
            "public_id": "c92a7d18-4f60-4bb2-9e1a-3d6c8b0f5a22",
            "amount": 120000,
            "settled_amount": 0,
            "payment_type": "PAID_TO_LENDER",
            "payment_status": "PENDING",
            "is_settled": false,
            "paid_before_submission": false,
            "paid_date": "2026-05-20T13:45:10.000Z",
            "failure_reason": null,
            "created_at": "2026-05-20T13:45:11.004Z",
            "updated_at": "2026-05-20T13:45:11.004Z"
          },
          {
            "public_id": "e07b3a55-21cd-4f88-bb09-6a4e2c1d77f0",
            "amount": 45000,
            "settled_amount": 0,
            "payment_type": "PAID_TO_LENDER",
            "payment_status": "FAILED",
            "is_settled": false,
            "paid_before_submission": false,
            "paid_date": null,
            "failure_reason": "INSUFFICIENT_FUNDS",
            "created_at": "2026-05-21T09:02:33.512Z",
            "updated_at": "2026-05-21T09:05:18.900Z"
          }
        ],
        "pagination": {
          "limit": 500,
          "returned": 3,
          "nextCursor": "eyJ1IjoiMjAyNi0wNS0yMVQwOTowNToxOC45MDBaIiwiaSI6IjY2NGExYjJjM2Q0ZTVmNjA3MTgyOTNhNCJ9"
        },
        "meta": {
          "schemaVersion": "v1",
          "cursorField": "updated_at",
          "sort": "asc",
          "since": null,
          "until": null,
          "tenantPathKind": "direct",
          "readFrom": "secondary"
        }
      },
      "errors": []
    }
    ```
  </Tab>

  <Tab title="200 — Last page (nextCursor null)">
    Same shape, but `nextCursor` is `null` — there are no more pages for this filter.

    ```json theme={null}
    {
      "code": 200,
      "message": "Dataset retrieved successfully",
      "body": {
        "section": { "code": "S2", "name": "Payments & Settlements" },
        "dataset": { "code": "D07", "name": "Borrower Payments" },
        "rows": [
          {
            "public_id": "f81c0d44-77ba-49e3-a012-5b9d3e6c4481",
            "amount": 30000,
            "settled_amount": 30000,
            "payment_type": "PAID_TO_LENDER",
            "payment_status": "SUCCESS",
            "is_settled": true,
            "paid_before_submission": true,
            "paid_date": "2026-05-22T11:00:00.000Z",
            "failure_reason": null,
            "created_at": "2026-05-22T11:00:01.330Z",
            "updated_at": "2026-05-22T11:00:01.330Z"
          }
        ],
        "pagination": {
          "limit": 500,
          "returned": 1,
          "nextCursor": null
        },
        "meta": {
          "schemaVersion": "v1",
          "cursorField": "updated_at",
          "sort": "asc",
          "since": "2026-05-22T10:00:00Z",
          "until": null,
          "tenantPathKind": "direct",
          "readFrom": "secondary"
        }
      },
      "errors": []
    }
    ```
  </Tab>

  <Tab title="200 — Success (with totals)">
    Response when `includeTotal=true` is passed. `pagination` gains `total` and `totalExact`, and `meta.schemaVersion` is present.

    ```json theme={null}
    {
      "code": 200,
      "message": "Dataset retrieved successfully",
      "body": {
        "section": { "code": "S2", "name": "Payments & Settlements" },
        "dataset": { "code": "D07", "name": "Borrower Payments" },
        "rows": [ /* ...allowlisted row objects... */ ],
        "pagination": {
          "limit": 500,
          "returned": 500,
          "nextCursor": "eyJ1Ijoi...",
          "total": 12483,
          "totalExact": true
        },
        "meta": {
          "schemaVersion": "v1",
          "cursorField": "updated_at",
          "sort": "asc",
          "since": "2026-05-01T00:00:00Z",
          "until": null,
          "tenantPathKind": "direct",
          "readFrom": "secondary"
        }
      },
      "errors": []
    }
    ```
  </Tab>

  <Tab title="200 — Success (total: capped)">
    For very large result sets the count short-circuits at a server-side cap and is reported as a lower bound.

    ```json theme={null}
    "pagination": {
      "limit": 500,
      "returned": 500,
      "nextCursor": "eyJ1Ijoi...",
      "total": 10000000,
      "totalExact": false,
      "totalNote": "capped"
    }
    ```
  </Tab>

  <Tab title="200 — Success (total: timeout)">
    If the count query exceeds its wall-clock budget, only the count fails — `rows` and `nextCursor` are unaffected.

    ```json theme={null}
    "pagination": {
      "limit": 500,
      "returned": 12,
      "nextCursor": null,
      "total": null,
      "totalExact": false,
      "totalNote": "timeout"
    }
    ```
  </Tab>

  <Tab title="200 — Success (total: window required, via)">
    For `via` (TIER 2) datasets such as `D21`/`D22`/`D23`, `includeTotal` requires a time window (`since` and/or `until`). Without one, the count is refused.

    ```json theme={null}
    "pagination": {
      "limit": 500,
      "returned": 500,
      "nextCursor": "eyJ1Ijoi...",
      "total": null,
      "totalExact": false,
      "totalNote": "window_required"
    }
    ```
  </Tab>

  <Tab title="400 — (not applicable)">
    The export endpoints do not return dedicated `400` validation errors. A malformed `cursor` surfaces as a `500`; see the [Errors reference](/api-reference/exports/errors#invalid-cursor).
  </Tab>

  <Tab title="401 — Unauthorized">
    ```json theme={null}
    {
      "success": false,
      "message": "Access denied. Invalid token.",
      "requestId": "req_3d5b8a0f1e62"
    }
    ```
  </Tab>

  <Tab title="403 — Lender mismatch">
    ```json theme={null}
    {
      "success": false,
      "message": "Lender ID mismatch",
      "requestId": "req_6b2f9d3a7c14"
    }
    ```
  </Tab>

  <Tab title="404 — Unknown section">
    ```json theme={null}
    {
      "success": false,
      "message": "Unknown section",
      "requestId": "req_c8e1a5f2b903"
    }
    ```
  </Tab>

  <Tab title="404 — Unknown dataset">
    ```json theme={null}
    {
      "success": false,
      "message": "Unknown dataset",
      "requestId": "req_47d9b0c3e1a8"
    }
    ```
  </Tab>

  <Tab title="404 — Dataset unavailable">
    ```json theme={null}
    {
      "success": false,
      "message": "Dataset D04 is listed in the catalog but not available for export at this time.",
      "requestId": "req_92a4c7e0d3b1"
    }
    ```
  </Tab>
</Tabs>

## Response fields

<ResponseField name="body.section" type="object">
  The section this dataset belongs to.

  <Expandable title="section">
    <ResponseField name="code" type="string">Section code (`S1`–`S5`).</ResponseField>
    <ResponseField name="name" type="string">Friendly section name.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="body.dataset" type="object">
  The dataset that was fetched.

  <Expandable title="dataset">
    <ResponseField name="code" type="string">Dataset code (e.g. `D07`).</ResponseField>
    <ResponseField name="name" type="string">Friendly dataset name.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="body.rows" type="array">
  The page of rows. Each element is a redacted document whose shape depends on the dataset — see the [per-dataset pages](/api-reference/exports/datasets/d07-borrower-payments). May be empty.
</ResponseField>

<ResponseField name="body.pagination" type="object">
  Pagination state for this page.

  <Expandable title="pagination">
    <ResponseField name="limit" type="integer">The effective page size used (after clamping to `1`–`1000`).</ResponseField>
    <ResponseField name="returned" type="integer">Number of rows in this response. For `via` datasets this can be less than `limit` even when more data exists — keep paging until `nextCursor` is `null`.</ResponseField>
    <ResponseField name="nextCursor" type="string | null">Opaque token for the next page, or `null` at the end of data.</ResponseField>
    <ResponseField name="total" type="integer | null">Filter-wide row count. Present only when `includeTotal=true`.</ResponseField>
    <ResponseField name="totalExact" type="boolean">Whether `total` is exact. Present only when `includeTotal=true`; `false` when the count was capped.</ResponseField>
    <ResponseField name="totalNote" type="string">Present only when applicable: `"capped"`, `"timeout"`, or `"window_required"`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="body.meta" type="object">
  Echo of how the request was interpreted.

  <Expandable title="meta">
    <ResponseField name="schemaVersion" type="string">Response-shape version anchor. `"v1"` today; additive changes stay on v1, breaking changes land at a new path (`/exports/v2/...`).</ResponseField>
    <ResponseField name="cursorField" type="string">The timestamp field paginated on (`updated_at`, `created_at`, or `communicated_at`).</ResponseField>
    <ResponseField name="sort" type="string">`asc` or `desc`.</ResponseField>
    <ResponseField name="since" type="string | null">The inclusive lower bound applied, or `null`.</ResponseField>
    <ResponseField name="until" type="string | null">The exclusive upper bound applied, or `null`.</ResponseField>
    <ResponseField name="tenantPathKind" type="string">`"direct"` (constant page size) or `"via"` (variable page size — joined through a parent collection).</ResponseField>
    <ResponseField name="readFrom" type="string">Which connection served the data read: `"secondary"` (replica) when configured, otherwise `"primary"`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errors" type="array">
  Always an empty array on success.
</ResponseField>

<Note>
  The contents of each `rows[]` element vary by dataset. For the exact field list, masking, and a sample row, open the matching [per-dataset page](/api-reference/exports/datasets/d07-borrower-payments).
</Note>

***

<Snippet file="snippets/support-info.mdx" />
