Invoices
GET /v1/invoices
Section titled “GET /v1/invoices”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
status | query | string | No | draft | issued | paid | overdue | collections |
customerId | query | string | No | Filter by customer |
externalReference | query | string | No | Exact match on your own reference |
limit | query | integer | No | Page size, 1-200 (default 50) |
cursor | query | string | No | Opaque cursor from meta.nextCursor |
curl https://api.rieckflow.com/v1/invoices \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices");{ "data": [ { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" } ], "meta": { "nextCursor": null }}Response fields 9
| Field | Type | Description |
|---|---|---|
data[].id | uuid | Stable invoice id. |
data[].invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data[].status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data[].grossOere | integer | Invoice total including VAT. |
data[].paidOere | integer | Total registered payments. |
data[].balanceOere | integer | Amount still owed now. |
data[].collectionsCaseId | uuid | null | Collection case created from this invoice. |
data[].externalReference | string | null | Your reconciliation reference. |
meta.nextCursor | `string | null` |
Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_cursor | The cursor is malformed, expired or belongs to another list shape. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/invoices
Section titled “POST /v1/invoices”Creates a draft — or with ?issue=true / ?send=true the whole chain (inline customer does find-or-create and requires customers:write). Issue = number + hash-locked PDF, atomically.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
issue | query | string | No | true = issue in the same transaction |
send | query | string | No | true = issue and send (send outcome in meta.send — never rolls back the invoice) |
Request body fields 41
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | No | The customer this resource belongs to. |
customer | object | No | Create or find the customer inline instead of sending customerId. |
customer.type | string | Yes | Resource-specific type. |
customer.name | string | Yes | Human-readable name. |
customer.cvr | string | No | Danish CVR number for a company. |
customer.vatNumber | string | No | Foreign VAT number for a non-Danish company. |
customer.address | object | No | Postal address used on documents. |
customer.address.street | string | No | Street and house number. |
customer.address.postalCode | string | No | Postal code. |
customer.address.city | string | No | City. |
customer.address.country | string | No | ISO country code or country name. |
customer.email | string | No | E-mail used for delivery and contact. |
customer.phone | string | No | Customer or contact phone number. |
customer.contactPerson | string | No | Named contact at the customer. |
customer.language | string | No | Language used for customer-facing documents. |
customer.externalReference | string | No | Your stable reference for reconciliation and idempotent imports. |
customer.metadata | object | No | Your own string key/value data. Never used for Rieck business logic. |
lines | object[] | Yes | Invoice or subscription line items. |
lines[].itemNumber | string | No | Your own item number printed on the invoice. |
lines[].description | string | Yes | Human-readable description. |
lines[].descriptionDetails | string | No | Optional detail printed below the line description. |
lines[].quantity | number | Yes | Positive quantity for this line. |
lines[].unitPriceOere | integer | Yes | Unit price in integer øre. |
lines[].vatRateBps | integer | No | VAT rate in basis points. 2500 means 25%. |
lines[].vatExemptionReason | string | No | Required legal reason when the VAT rate is zero. |
lines[].discount | object | No | Optional line-level percentage or amount discount. |
lines[].discount.type | string | Yes | Resource-specific type. |
lines[].discount.value | integer | Yes | Field in the request payload. |
lines[].accountId | string | No | Field in the request payload. |
lines[].unit | string | No | Field in the request payload. |
currency | string | No | Field in the request payload. |
dueDate | string | No | Due date in YYYY-MM-DD format. |
paymentTermsDays | integer | No | Number of days from issue date until payment is due. |
customerReference | string | No | The customer’s reference printed on the invoice. |
requisitionNumber | string | No | Field in the request payload. |
accountingCost | string | No | Field in the request payload. |
senderReference | string | No | Your reference printed on the invoice. |
message | string | No | Free-text message printed in the document footer. |
heading | string | No | Custom document heading. |
externalReference | string | No | Your stable reference for reconciliation and idempotent imports. |
metadata | object | No | Your own string key/value data. Never used for Rieck business logic. |
curl -X POST https://api.rieckflow.com/v1/invoices \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "lines": [ { "description": "Consulting", "quantity": 1, "unitPriceOere": 125000, "vatRateBps": 2500 } ], "customer": { "type": "company", "name": "Acme ApS", "cvr": "12345678", "email": "ap@acme.example" }, "dueDate": "2026-08-15" }'const svar = await rieck.request("POST", "/v1/invoices", { body: { "lines": [ { "description": "Consulting", "quantity": 1, "unitPriceOere": 125000, "vatRateBps": 2500 } ], "customer": { "type": "company", "name": "Acme ApS", "cvr": "12345678", "email": "ap@acme.example" }, "dueDate": "2026-08-15" },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" }}Response fields 8
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable invoice id. |
data.invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data.status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data.grossOere | integer | Invoice total including VAT. |
data.paidOere | integer | Total registered payments. |
data.balanceOere | integer | Amount still owed now. |
data.collectionsCaseId | uuid | null | Collection case created from this invoice. |
data.externalReference | string | null | Your reconciliation reference. |
Possible errors 9
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 400 | invalid_request | The request body or parameter failed validation. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 413 | payload_too_large | The JSON or uploaded file exceeds this endpoint’s size limit. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
Request body — fuldt JSON Schema
{ "type": "object", "properties": { "customerId": { "type": "string", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, "customer": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "person", "company" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "cvr": { "anyOf": [ { "type": "string", "pattern": "^\\d{8}$" }, { "type": "null" } ] }, "vatNumber": { "anyOf": [ { "type": "string", "maxLength": 20 }, { "type": "null" } ] }, "address": { "anyOf": [ { "type": "object", "properties": { "street": { "type": "string", "maxLength": 200 }, "postalCode": { "type": "string", "maxLength": 10 }, "city": { "type": "string", "maxLength": 100 }, "country": { "type": "string", "maxLength": 100 } }, "additionalProperties": false }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string", "maxLength": 254 }, { "type": "null" } ] }, "phone": { "anyOf": [ { "type": "string", "maxLength": 30 }, { "type": "null" } ] }, "contactPerson": { "anyOf": [ { "type": "string", "maxLength": 200 }, { "type": "null" } ] }, "language": { "anyOf": [ { "type": "string", "enum": [ "da", "en" ] }, { "type": "null" } ] }, "externalReference": { "anyOf": [ { "type": "string", "minLength": 1, "maxLength": 200 }, { "type": "null" } ] }, "metadata": { "anyOf": [ { "type": "object", "propertyNames": { "type": "string", "minLength": 1, "maxLength": 40 }, "additionalProperties": { "type": "string", "maxLength": 500 } }, { "type": "null" } ] } }, "required": [ "type", "name" ], "additionalProperties": false }, "lines": { "minItems": 1, "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "itemNumber": { "type": "string", "minLength": 1, "maxLength": 60 }, "description": { "type": "string", "minLength": 1, "maxLength": 500 }, "descriptionDetails": { "type": "string", "maxLength": 500 }, "quantity": { "type": "number", "exclusiveMinimum": 0, "maximum": 999999 }, "unitPriceOere": { "type": "integer", "minimum": 0, "maximum": 100000000000 }, "vatRateBps": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "vatExemptionReason": { "anyOf": [ { "type": "string", "enum": [ "ML13", "OMVENDT", "EU_VARE", "EKSPORT" ] }, { "type": "null" } ] }, "discount": { "anyOf": [ { "type": "object", "properties": { "type": { "type": "string", "enum": [ "percent", "amount" ] }, "value": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "type", "value" ], "additionalProperties": false }, { "type": "null" } ] }, "accountId": { "anyOf": [ { "type": "string", "maxLength": 100 }, { "type": "null" } ] }, "unit": { "anyOf": [ { "type": "string", "maxLength": 20 }, { "type": "null" } ] } }, "required": [ "description", "quantity", "unitPriceOere" ], "additionalProperties": false } }, "currency": { "default": "DKK", "type": "string", "const": "DKK" }, "dueDate": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }, "paymentTermsDays": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 365 }, { "type": "null" } ] }, "customerReference": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "requisitionNumber": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "accountingCost": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "senderReference": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "message": { "anyOf": [ { "type": "string", "maxLength": 2000 }, { "type": "null" } ] }, "heading": { "anyOf": [ { "type": "string", "maxLength": 60 }, { "type": "null" } ] }, "externalReference": { "anyOf": [ { "type": "string", "minLength": 1, "maxLength": 200 }, { "type": "null" } ] }, "metadata": { "anyOf": [ { "type": "object", "propertyNames": { "type": "string", "minLength": 1, "maxLength": 40 }, "additionalProperties": { "type": "string", "maxLength": 500 } }, { "type": "null" } ] } }, "required": [ "lines" ], "additionalProperties": false}GET /v1/invoices/{invoiceId}
Section titled “GET /v1/invoices/{invoiceId}”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…");{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" }}Response fields 8
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable invoice id. |
data.invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data.status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data.grossOere | integer | Invoice total including VAT. |
data.paidOere | integer | Total registered payments. |
data.balanceOere | integer | Amount still owed now. |
data.collectionsCaseId | uuid | null | Collection case created from this invoice. |
data.externalReference | string | null | Your reconciliation reference. |
Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
PUT /v1/invoices/{invoiceId}
Section titled “PUT /v1/invoices/{invoiceId}”Full replacement of a DRAFT (issued invoices are immutable).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Request body fields 25
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | The customer this resource belongs to. |
lines | object[] | Yes | Invoice or subscription line items. |
lines[].itemNumber | string | No | Your own item number printed on the invoice. |
lines[].description | string | Yes | Human-readable description. |
lines[].descriptionDetails | string | No | Optional detail printed below the line description. |
lines[].quantity | number | Yes | Positive quantity for this line. |
lines[].unitPriceOere | integer | Yes | Unit price in integer øre. |
lines[].vatRateBps | integer | No | VAT rate in basis points. 2500 means 25%. |
lines[].vatExemptionReason | string | No | Required legal reason when the VAT rate is zero. |
lines[].discount | object | No | Optional line-level percentage or amount discount. |
lines[].discount.type | string | Yes | Resource-specific type. |
lines[].discount.value | integer | Yes | Field in the request payload. |
lines[].accountId | string | No | Field in the request payload. |
lines[].unit | string | No | Field in the request payload. |
currency | string | No | Field in the request payload. |
dueDate | string | No | Due date in YYYY-MM-DD format. |
paymentTermsDays | integer | No | Number of days from issue date until payment is due. |
customerReference | string | No | The customer’s reference printed on the invoice. |
requisitionNumber | string | No | Field in the request payload. |
accountingCost | string | No | Field in the request payload. |
senderReference | string | No | Your reference printed on the invoice. |
message | string | No | Free-text message printed in the document footer. |
heading | string | No | Custom document heading. |
externalReference | string | No | Your stable reference for reconciliation and idempotent imports. |
metadata | object | No | Your own string key/value data. Never used for Rieck business logic. |
curl -X PUT https://api.rieckflow.com/v1/invoices/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "customerId": "9b2f1c1e-…", "lines": [ { "description": "Consulting", "quantity": 1, "unitPriceOere": 125000, "vatRateBps": 2500 } ], "dueDate": "2026-08-15", "customerReference": "crm-9001" }'const svar = await rieck.request("PUT", "/v1/invoices/9b2f1c1e-…", { body: { "customerId": "9b2f1c1e-…", "lines": [ { "description": "Consulting", "quantity": 1, "unitPriceOere": 125000, "vatRateBps": 2500 } ], "dueDate": "2026-08-15", "customerReference": "crm-9001" },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" }}Response fields 8
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable invoice id. |
data.invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data.status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data.grossOere | integer | Invoice total including VAT. |
data.paidOere | integer | Total registered payments. |
data.balanceOere | integer | Amount still owed now. |
data.collectionsCaseId | uuid | null | Collection case created from this invoice. |
data.externalReference | string | null | Your reconciliation reference. |
Possible errors 11
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 400 | invalid_request | The request body or parameter failed validation. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 413 | payload_too_large | The JSON or uploaded file exceeds this endpoint’s size limit. |
| 422 | invoice_not_editable | The invoice can no longer be edited. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
Request body — fuldt JSON Schema
{ "type": "object", "properties": { "customerId": { "type": "string", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, "lines": { "minItems": 1, "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "itemNumber": { "type": "string", "minLength": 1, "maxLength": 60 }, "description": { "type": "string", "minLength": 1, "maxLength": 500 }, "descriptionDetails": { "type": "string", "maxLength": 500 }, "quantity": { "type": "number", "exclusiveMinimum": 0, "maximum": 999999 }, "unitPriceOere": { "type": "integer", "minimum": 0, "maximum": 100000000000 }, "vatRateBps": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "vatExemptionReason": { "anyOf": [ { "type": "string", "enum": [ "ML13", "OMVENDT", "EU_VARE", "EKSPORT" ] }, { "type": "null" } ] }, "discount": { "anyOf": [ { "type": "object", "properties": { "type": { "type": "string", "enum": [ "percent", "amount" ] }, "value": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "type", "value" ], "additionalProperties": false }, { "type": "null" } ] }, "accountId": { "anyOf": [ { "type": "string", "maxLength": 100 }, { "type": "null" } ] }, "unit": { "anyOf": [ { "type": "string", "maxLength": 20 }, { "type": "null" } ] } }, "required": [ "description", "quantity", "unitPriceOere" ], "additionalProperties": false } }, "currency": { "default": "DKK", "type": "string", "const": "DKK" }, "dueDate": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }, "paymentTermsDays": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 365 }, { "type": "null" } ] }, "customerReference": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "requisitionNumber": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "accountingCost": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "senderReference": { "anyOf": [ { "type": "string", "maxLength": 140 }, { "type": "null" } ] }, "message": { "anyOf": [ { "type": "string", "maxLength": 2000 }, { "type": "null" } ] }, "heading": { "anyOf": [ { "type": "string", "maxLength": 60 }, { "type": "null" } ] }, "externalReference": { "anyOf": [ { "type": "string", "minLength": 1, "maxLength": 200 }, { "type": "null" } ] }, "metadata": { "anyOf": [ { "type": "object", "propertyNames": { "type": "string", "minLength": 1, "maxLength": 40 }, "additionalProperties": { "type": "string", "maxLength": 500 } }, { "type": "null" } ] } }, "required": [ "customerId", "lines" ], "additionalProperties": false}DELETE /v1/invoices/{invoiceId}
Section titled “DELETE /v1/invoices/{invoiceId}”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl -X DELETE https://api.rieckflow.com/v1/invoices/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041"const svar = await rieck.request("DELETE", "/v1/invoices/9b2f1c1e-…");Possible errors 9
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 422 | invoice_not_editable | The invoice can no longer be edited. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/invoices/{invoiceId}/issue
Section titled “POST /v1/invoices/{invoiceId}/issue”Assigns the next number in the unbroken series and locks the PDF.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl -X POST https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/issue \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041"const svar = await rieck.request("POST", "/v1/invoices/9b2f1c1e-…/issue");{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" }}Response fields 8
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable invoice id. |
data.invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data.status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data.grossOere | integer | Invoice total including VAT. |
data.paidOere | integer | Total registered payments. |
data.balanceOere | integer | Amount still owed now. |
data.collectionsCaseId | uuid | null | Collection case created from this invoice. |
data.externalReference | string | null | Your reconciliation reference. |
Possible errors 10
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 422 | invoice_already_issued | The invoice has already been issued. |
| 422 | invoice_not_editable | The invoice can no longer be edited. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/invoices/{invoiceId}/send
Section titled “POST /v1/invoices/{invoiceId}/send”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl -X POST https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/send \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041"const svar = await rieck.request("POST", "/v1/invoices/9b2f1c1e-…/send");{ "data": { "status": "sent" }}Possible errors 10
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 422 | customer_email_missing | The invoice cannot be sent because the customer has no e-mail. |
| 422 | invoice_not_editable | The invoice can no longer be edited. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
GET /v1/invoices/{invoiceId}/pdf
Section titled “GET /v1/invoices/{invoiceId}/pdf”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/pdf \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…/pdf");Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
GET /v1/invoices/{invoiceId}/attachments
Section titled “GET /v1/invoices/{invoiceId}/attachments”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/attachments \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…/attachments");{ "data": [ { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "filename": "timesheet-july.pdf", "mime": "application/pdf", "sizeBytes": 48211, "sendWithInvoice": true, "sha256": "2f9d81c01fd0d9c06ad98c34a58c4f81a03544151fbca8fb18bcd9eeccab8474", "createdAt": "2026-08-04T09:32:11Z" } ]}Response fields 4
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable attachment id. |
data.filename | string | Original file name. |
data.sendWithInvoice | boolean | Whether the file is included when the invoice is sent. |
data.sha256 | string | SHA-256 digest of the immutable stored bytes. |
Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/invoices/{invoiceId}/attachments
Section titled “POST /v1/invoices/{invoiceId}/attachments”Base64 in JSON, max 10 MB. Every byte is malware-scanned before storage; a rejected file returns 422 malware_detected. Attachments are INSERT-ONLY — they cannot be edited or removed, because documentation that can be changed afterwards is not documentation. Allowed before and after issuing; only sendWithInvoice attachments present at send time go out with the e-mail.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Request body fields 4
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | Field in the request payload. |
data | string | Yes | Field in the request payload. |
mime | string | Yes | Field in the request payload. |
sendWithInvoice | boolean | No | Field in the request payload. |
curl -X POST https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/attachments \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "filename": "…", "data": "…", "mime": "application/pdf", "sendWithInvoice": true }'const svar = await rieck.request("POST", "/v1/invoices/9b2f1c1e-…/attachments", { body: { "filename": "…", "data": "…", "mime": "application/pdf", "sendWithInvoice": true },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "filename": "timesheet-july.pdf", "mime": "application/pdf", "sizeBytes": 48211, "sendWithInvoice": true, "sha256": "2f9d81c01fd0d9c06ad98c34a58c4f81a03544151fbca8fb18bcd9eeccab8474", "createdAt": "2026-08-04T09:32:11Z" }}Response fields 4
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable attachment id. |
data.filename | string | Original file name. |
data.sendWithInvoice | boolean | Whether the file is included when the invoice is sent. |
data.sha256 | string | SHA-256 digest of the immutable stored bytes. |
Possible errors 10
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 400 | invalid_request | The request body or parameter failed validation. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 413 | payload_too_large | The JSON or uploaded file exceeds this endpoint’s size limit. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
Request body — fuldt JSON Schema
{ "type": "object", "properties": { "filename": { "type": "string", "minLength": 1, "maxLength": 255 }, "data": { "type": "string", "minLength": 1 }, "mime": { "type": "string", "enum": [ "application/pdf", "image/png", "image/jpeg", "image/webp" ] }, "sendWithInvoice": { "default": true, "type": "boolean" } }, "required": [ "filename", "data", "mime" ], "additionalProperties": false}GET /v1/invoices/{invoiceId}/attachments/{attachmentId}
Section titled “GET /v1/invoices/{invoiceId}/attachments/{attachmentId}”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes | |
attachmentId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/attachments/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…/attachments/9b2f1c1e-…");Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
GET /v1/invoices/{invoiceId}/timeline
Section titled “GET /v1/invoices/{invoiceId}/timeline”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/timeline \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…/timeline");{ "data": [ { "kind": "issued", "at": "2026-08-04T09:34:20Z" } ]}Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
GET /v1/invoices/{invoiceId}/einvoicing
Section titled “GET /v1/invoices/{invoiceId}/einvoicing”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/einvoicing \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/invoices/9b2f1c1e-…/einvoicing");{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "invoiceNumber": 1042, "type": "invoice", "status": "issued", "customerId": "467a0d8d-b9b2-4df3-bf7b-17d649442890", "issuedDate": "2026-08-04", "dueDate": "2026-08-18", "netOere": 125000, "vatOere": 31250, "grossOere": 156250, "paidOere": 0, "creditedOere": 0, "reminderFeeOere": 0, "balanceOere": 156250, "reminderCount": 0, "collectionsCaseId": null, "externalReference": "order-2041", "metadata": null, "createdAt": "2026-08-04T09:32:11Z" }}status queued | sent | failed | rejected, recipientEndpoint, transportReference, failureReason, and the receiving system’s own responseCode/responseMessage/respondedAt. ⚠️ rejected arrives AFTER sent, sometimes hours later — GET /v1/dispatches only tells you we handed the document to the access point, so an invoice the recipient’s system threw out reads “sent” there forever. Subscribe to einvoice.failed rather than polling. ⚠️ The document itself is never returned: the access point signs it with its own certificate. documentHash is the sha256 of exactly the UBL we sent, so you can prove the content without holding it.application/jsonResponse fields 8
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable invoice id. |
data.invoiceNumber | integer | null | Sequential number. Null while the invoice is a draft. |
data.status | draft | issued | paid | overdue | collections | Stored lifecycle status. |
data.grossOere | integer | Invoice total including VAT. |
data.paidOere | integer | Total registered payments. |
data.balanceOere | integer | Amount still owed now. |
data.collectionsCaseId | uuid | null | Collection case created from this invoice. |
data.externalReference | string | null | Your reconciliation reference. |
Possible errors 5
| HTTP | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/invoices/{invoiceId}/collect
Section titled “POST /v1/invoices/{invoiceId}/collect”The bridge: creates a collection case from the invoice. §9b prerequisites are enforced.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
curl -X POST https://api.rieckflow.com/v1/invoices/9b2f1c1e-…/collect \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041"const svar = await rieck.request("POST", "/v1/invoices/9b2f1c1e-…/collect");{ "data": { "caseId": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "activated": true, "replayed": false }}Possible errors 8
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_idempotency_key | Idempotency-Key is missing or malformed. |
| 401 | invalid_api_key | The API key is missing, invalid, expired or revoked. |
| 403 | api_not_included | The organisation’s plan does not include API access. |
| 403 | insufficient_scope | The key does not have the required scope. |
| 404 | invoice_not_found | The invoice does not exist or belongs to another organisation. |
| 409 | idempotency_conflict | The same key was used with a different request. |
| 409 | idempotency_in_progress | The same operation is currently being processed. Retry later. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |