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 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}}
https://v3-api.cleargrid.ai/admin/v3
https://stage-v3-api.cleargrid.ai/admin/v3
Bearer token obtained from the Lender Login endpoint. Format: Bearer <access_token>.
Path parameters
Your lender public ID. Must equal the lenderId encoded in the JWT, otherwise the request returns 403.
Query parameters
Inclusive lower bound (>=) on the dataset’s cursor field. Omit for an initial load.
Exclusive upper bound (<) on the dataset’s cursor field. Omit to read up to “now”.
Opaque next-page token from the previous response’s body.pagination.nextCursor. Omit on the first page. Treat as opaque — see Pagination .
Page size. Range: 1–1000. Values outside the range are clamped.
Sort direction on the cursor field. One of asc or desc.
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").
Example requests
# 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
200 — Success
200 — Last page (nextCursor null)
200 — Success (with totals)
200 — Success (total: capped)
200 — Success (total: timeout)
200 — Success (total: window required, via)
400 — (not applicable)
401 — Unauthorized
403 — Lender mismatch
404 — Unknown section
404 — Unknown dataset
404 — Dataset unavailable
Example using D07 (Borrower Payments). nextCursor is non-null, so there are more pages to fetch. {
"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" : []
}
Same shape, but nextCursor is null — there are no more pages for this filter. {
"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" : []
}
Response when includeTotal=true is passed. pagination gains total and totalExact, and meta.schemaVersion is present. {
"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" : []
}
For very large result sets the count short-circuits at a server-side cap and is reported as a lower bound. "pagination" : {
"limit" : 500 ,
"returned" : 500 ,
"nextCursor" : "eyJ1Ijoi..." ,
"total" : 10000000 ,
"totalExact" : false ,
"totalNote" : "capped"
}
If the count query exceeds its wall-clock budget, only the count fails — rows and nextCursor are unaffected. "pagination" : {
"limit" : 500 ,
"returned" : 12 ,
"nextCursor" : null ,
"total" : null ,
"totalExact" : false ,
"totalNote" : "timeout"
}
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. "pagination" : {
"limit" : 500 ,
"returned" : 500 ,
"nextCursor" : "eyJ1Ijoi..." ,
"total" : null ,
"totalExact" : false ,
"totalNote" : "window_required"
}
The export endpoints do not return dedicated 400 validation errors. A malformed cursor surfaces as a 500; see the Errors reference . {
"success" : false ,
"message" : "Access denied. Invalid token." ,
"requestId" : "req_3d5b8a0f1e62"
}
{
"success" : false ,
"message" : "Lender ID mismatch" ,
"requestId" : "req_6b2f9d3a7c14"
}
{
"success" : false ,
"message" : "Unknown section" ,
"requestId" : "req_c8e1a5f2b903"
}
{
"success" : false ,
"message" : "Unknown dataset" ,
"requestId" : "req_47d9b0c3e1a8"
}
{
"success" : false ,
"message" : "Dataset D04 is listed in the catalog but not available for export at this time." ,
"requestId" : "req_92a4c7e0d3b1"
}
Response fields
The section this dataset belongs to.
The dataset that was fetched.
The page of rows. Each element is a redacted document whose shape depends on the dataset — see the per-dataset pages . May be empty.
Pagination state for this page. The effective page size used (after clamping to 1–1000).
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.
Opaque token for the next page, or null at the end of data.
Filter-wide row count. Present only when includeTotal=true.
Whether total is exact. Present only when includeTotal=true; false when the count was capped.
Present only when applicable: "capped", "timeout", or "window_required".
Echo of how the request was interpreted. Response-shape version anchor. "v1" today; additive changes stay on v1, breaking changes land at a new path (/exports/v2/...).
The timestamp field paginated on (updated_at, created_at, or communicated_at).
The inclusive lower bound applied, or null.
The exclusive upper bound applied, or null.
"direct" (constant page size) or "via" (variable page size — joined through a parent collection).
Which connection served the data read: "secondary" (replica) when configured, otherwise "primary".
Always an empty array on success.
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 .
Need Help? Our support team is available Monday-Friday, 9 AM - 6 PM GST. Reach out at support@cleargrid.co or visit our help center.