Lists are returned in pages. Pass limit and offset, and read has_more and next_offset from the response; next_offset is null on the last page.
| List | limit |
|---|---|
| Journal entries, attachments, bank lines, products, invoices, contacts | 1 to 500, default 100 |
| Ledger entries | 1 to 1000, default 1000 |
A limit or offset out of range returns 400 invalid_request, except on invoices and contacts, which bring it within range.
{
"contacts": [
{ "id": "550e8400-e29b-41d4-a716-446655440001", "name": "Acme ApS" },
{ "id": "550e8400-e29b-41d4-a716-446655440002", "name": "Brdr. Hansen I/S" }
],
"has_more": true,
"next_offset": 2
}Keep the same filters and pass next_offset as offset until has_more is false:
async function* allContacts() {
let offset = 0;
while (offset !== null) {
const response = await fetch(`https://api.numina.app/v1/contacts?limit=500&offset=${offset}`, {
headers: { Authorization: `Bearer ${process.env.NUMINA_API_KEY}` },
});
const page = await response.json();
yield* page.contacts;
offset = page.has_more ? page.next_offset : null;
}
}The chart of accounts, VAT codes and accounting years are short and come back in one response, as do the balance reports.