Recipe
Listing incoming invoices
Read the supplier invoices (expenses) received by your company, paginated and filtered, from /1/expenses/.
Prerequisites
- A working authenticated integration (see: Authenticating API requests)
- At least one expense recorded in the company
1. Basic listing
Incoming (supplier) invoices live among the expenses. The basic listing returns a paginated response:
curl -sS "https://api.quick.riport.co.hu/1/expenses/?page_size=50" \
-H "Authorization: Token $QUICK_API_TOKEN"The trailing slash is required
Endpoints are valid with a trailing slash (/1/expenses/, not /1/expenses).
2. Pagination
The response has a count / next / previous / results shape. The next URL gives you the following page — follow it until it becomes null:
{
"count": 128,
"next": "https://api.quick.riport.co.hu/1/expenses/?page=2&page_size=50",
"previous": null,
"results": [ /* ... */ ]
}You can also page directly with the page and page_size parameters.
3. Filtering by date and state
date_field selects the date field the from_date filter applies to, and ordering sets the order:
curl -sS "https://api.quick.riport.co.hu/1/expenses/?date_field=created&from_date=2026-06-01&ordering=-created&page_size=100" \
-H "Authorization: Token $QUICK_API_TOKEN"Common filters:
| Parameter | Example | What it returns |
|---|---|---|
date_field | created, fulfilled_at, due_at | Which date field to filter on |
from_date | 2026-06-01 | From this date onwards |
is_approved | true / false | Approved items |
needs_review | true | Items awaiting review |
invoice_number | 2026/001 | By invoice number |
ordering | -created, gross_amount | Ordering (- is descending) |
4. A pagination helper in Node.js
Following the next URL lets you walk the whole list without holding it in memory:
export async function* listExpenses(params: Record<string, string> = {}) {
const qs = new URLSearchParams({ page_size: "100", ...params });
let url: string | null = `https://api.quick.riport.co.hu/1/expenses/?${qs}`;
while (url) {
const res = await fetch(url, {
headers: { Authorization: `Token ${process.env.QUICK_API_TOKEN}` },
});
if (!res.ok) throw new Error(`QUiCK ${res.status}`);
const page = await res.json();
for (const item of page.results) yield item;
url = page.next;
}
}5. What an item contains
An expense also returns the partner data denormalised, so listing needs no separate partner lookup:
{
"id": 90231,
"partner": 5501,
"partner_name": "Example Supplier Ltd.",
"partner_tax_number": "12345678-2-42",
"invoice_number": "2026/001",
"fulfilled_at": "2026-06-14",
"due_at": "2026-06-28",
"paid_status": 1,
"accounting_status": "pending",
"has_artifact": true
}Values of paid_status: 1 — unpaid, 2 — paid, 3 — instalment.
Related endpoints
- GET/v1/invoices
Related terms
Common pitfalls
Assuming cursor-based pagination
The QUiCK Public API is page-number based: you page with `page` and `page_size`, and the response has a `count`/`next`/`previous`/`results` shape. There is no `cursor` or `next_cursor` field.
Dropping the trailing slash
`/1/expenses` (without the trailing `/`) may redirect or return 404. Always call the form with the trailing slash.
Fetching every page at once
For large companies this leads to timeouts and 429s. Iterate along the `next` URL and process page by page.