Skip to content

Pagination

Every list endpoint returns one page at a time:

{
"data": [
{ "id": "01a1412b-ae38-7c39-8c71-16d2b5dfc472", "type": "invoice", "status": "authorized", "...": "..." },
{ "id": "01a14116-1c50-73e7-8aab-349c93e541da", "type": "invoice", "status": "authorized", "...": "..." }
],
"pagination": { "nextCursor": "MDFhMTQxMTYtMWM1MC03M2U3LThhYWItMzQ5YzkzZTU0MWRh", "hasMore": true }
}
  • limit sets the page size: 1 to 100, 20 by default.
  • When hasMore is true, ask for the next page with cursor set to nextCursor. On the last page hasMore is false and nextCursor is null.
  • The cursor is opaque: pass it back exactly as you got it, together with the same filters. A cursor that is not valid gets 422 validation_failed with the field error invalid_format on cursor.
  • Single resources (GET /v1/documents/{id}) are returned as they are, without this envelope.
Terminal window
curl "https://api.flashpi.com.ec/v1/documents?status=authorized&limit=100&cursor=MDFhMTQxMTYtMWM1MC03M2U3LThhYWItMzQ5YzkzZTU0MWRh" \
-H "Authorization: Bearer $FLASHPI_API_KEY"
List Order Filters
GET /v1/documents Newest first issuerId, type, status, issueDateFrom, issueDateTo, counterpartyId, accessKey
GET /v1/events Newest first type, issuerId, documentId, certificateId
GET /v1/issuers Newest first
GET /v1/issuers/{issuerId}/certificates Newest first
GET /v1/webhook-endpoints Newest first
GET /v1/webhook-endpoints/{endpointId}/deliveries Newest first status, eventType, eventId
GET /v1/issuers/{issuerId}/establishments By code
GET .../establishments/{establishmentId}/emission-points By code

Newest first means by creation: every ID is a UUIDv7, which starts with its creation time. Items created while you page through a newest-first list appear before the first page, so they never shift the pages you are reading.

type Page<T> = { data: T[]; pagination: { nextCursor: string | null; hasMore: boolean } }
export async function* listDocuments(apiKey: string, filters: Record<string, string> = {}) {
let cursor: string | null = null
do {
const query = new URLSearchParams({ ...filters, limit: '100' })
if (cursor) query.set('cursor', cursor)
const response = await fetch(`https://api.flashpi.com.ec/v1/documents?${query}`, {
headers: { Authorization: `Bearer ${apiKey}` },
})
if (!response.ok) throw new Error(`Flashpi answered ${response.status}`)
const page = (await response.json()) as Page<{ id: string; status: string }>
yield* page.data
cursor = page.pagination.hasMore ? page.pagination.nextCursor : null
} while (cursor)
}
for await (const document of listDocuments(process.env.FLASHPI_API_KEY ?? '', { status: 'failed' })) {
console.log(document.id, document.status)
}