List invoices
Returns a paginated list of all invoices of the company. The list contains invoice headers without positions — use the details endpoint to retrieve the full positions list.
Request
GET /api/oauth/v2/resource/invoices
Header
| Header | Value |
|---|---|
Authorization | Bearer {access_token} |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
offset | integer | No | Start position (default: 0, min: 0) |
limit | integer | No | Number of results (default: 50, min: 1, max: 200) |
view | string | No | Response format: default (default) or slim (slim response) |
createdSince | string (ISO 8601) | No | Only invoices created at or after this timestamp (createdAt >=) |
createdUntil | string (ISO 8601) | No | Only invoices created at or before this timestamp (createdAt <=) |
updatedSince | string (ISO 8601) | No | Only invoices modified at or after this timestamp (updatedAt >=). Newly created invoices are included, because the modification timestamp is set on creation. |
updatedUntil | string (ISO 8601) | No | Only invoices modified at or before this timestamp (updatedAt <=) |
Note: For a sync,
updatedSincealone is enough — it covers new and modified invoices.
Note: Formats, time zones, sorting, cursor strategy, and the
meta.totaltrap work the same across all filters. See Incremental Sync.For invoices, the residual risk of pagination also shows up when an invoice is deleted during the run.
Note on deletions: Invoices do not carry a deletion timestamp. There is no
deletedSincehere. A deleted invoice disappears from this list and from the details endpoint without the sync learning about it.An invoice your client has cached therefore stays there indefinitely. Detecting deletions needs a periodic full sync instead. Fetch all invoices without a timestamp filter and compare them against your set.
Response
Success (200 OK)
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"sequence": 42,
"formattedSequence": "RE-2026-0042",
"name": "Invoice for Anna Muster",
"status": "open",
"net": 100.00,
"subTotal": 110.00,
"gross": 110.00,
"discount": 0.00,
"outstandingBalance": 110.00,
"invoicingDate": "2026-06-01",
"paidAt": null,
"timeForPayment": "2026-06-15",
"isFullyPaid": false,
"visible": true,
"comment": null,
"customer": {
"id": "f0e1d2c3-b4a5-6789-fedc-ba9876543210",
"firstName": "Anna",
"lastName": "Muster"
},
"createdAt": "2026-06-01T09:30:00+02:00",
"updatedAt": "2026-06-05T14:10:00+02:00"
}
],
"meta": {
"total": 128,
"offset": 0,
"limit": 50
}
}Response fields
| Field | Type | Description |
|---|---|---|
data | Array | List of invoices |
data[].id | string (UUID) | Unique ID of the invoice |
data[].sequence | integer | null | Sequential invoice number |
data[].formattedSequence | string | null | Formatted invoice number |
data[].name | string | null | Name of the invoice |
data[].status | string | null | Invoice status |
data[].net | number | null | Net amount |
data[].subTotal | number | null | Subtotal |
data[].gross | number | null | Gross amount |
data[].discount | number | null | Discount amount |
data[].outstandingBalance | number | null | Outstanding balance |
data[].invoicingDate | string | null | Invoice date (YYYY-MM-DD) |
data[].paidAt | string | null | Payment date (YYYY-MM-DD) |
data[].timeForPayment | string | null | Payment due date (YYYY-MM-DD) |
data[].isFullyPaid | boolean | Fully paid |
data[].visible | boolean | Invoice visible |
data[].comment | string | null | Comment on the invoice |
data[].customer | object | null | Assigned customer |
data[].customer.id | string (UUID) | Customer ID |
data[].customer.firstName | string | First name |
data[].customer.lastName | string | Last name |
data[].createdAt | string (ISO 8601) | null | Creation timestamp |
data[].updatedAt | string (ISO 8601) | null | Last modification timestamp |
meta.total | integer | Total number of invoices |
meta.offset | integer | Current start position |
meta.limit | integer | Number of returned entries |
Slim response (?view=slim)
With view=slim, the endpoint returns a slim response with less data per invoice. Without the parameter, the response stays unchanged.
If view is given more than once, the last value wins — ?view=default&view=slim returns the slim response.
The slim response contains:
id, sequence, formattedSequence, status, net, subTotal, gross, discount, outstandingBalance, invoicingDate, paidAt, isFullyPaid, customer (id only), createdAt, updatedAt
References like customer appear in the slim response as an object with only id, without the other fields. name, timeForPayment, visible, and comment are omitted.
Note: Currently only the slim response returns
createdAtandupdatedAt— the default response doesn't include these fields yet.
Warning: Don't use
updatedAton invoices as a cursor for incremental sync right now. The value isn't reliably set on every change yet, so a change could slip past the cursor unnoticed. For a complete sync, a periodic full sync is required for now.
Example: view=slim
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"sequence": 42,
"formattedSequence": "RE-2026-0042",
"status": "open",
"net": 100.00,
"subTotal": 110.00,
"gross": 110.00,
"discount": 0.00,
"outstandingBalance": 110.00,
"invoicingDate": "2026-06-01",
"paidAt": null,
"isFullyPaid": false,
"customer": {
"id": "f0e1d2c3-b4a5-6789-fedc-ba9876543210"
},
"createdAt": "2026-05-20T09:12:00+02:00",
"updatedAt": "2026-06-01T14:03:00+02:00"
}
],
"meta": {
"total": 128,
"offset": 0,
"limit": 50
}
}curl -X GET "https://my.offisy.at/api/oauth/v2/resource/invoices?offset=0&limit=50&view=default&createdSince=beispiel&createdUntil=beispiel&updatedSince=2026-04-15T10%3A00%3A00&updatedUntil=2026-04-15T10%3A00%3A00" \
-H "Authorization: Bearer {access_token}"Possible errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid value for view (valid values: default, slim) |
| 400 | validation_error | A timestamp filter contains an invalid value |
| 401 | invalid_client | Invalid or missing access token |
| 403 | insufficient_scope | Scope invoices not present |