Skip to content

Recipe

Listing incoming invoices

Read the supplier invoices (expenses) received by your company, paginated and filtered, from /1/expenses/.

Beginner~25 min5 steps

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:

bash
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:

json
{
  "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:

bash
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:

ParameterExampleWhat it returns
date_fieldcreated, fulfilled_at, due_atWhich date field to filter on
from_date2026-06-01From this date onwards
is_approvedtrue / falseApproved items
needs_reviewtrueItems awaiting review
invoice_number2026/001By invoice number
ordering-created, gross_amountOrdering (- is descending)

4. A pagination helper in Node.js

Following the next URL lets you walk the whole list without holding it in memory:

ts
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:

json
{
  "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

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.