Products
GET /v1/products
Section titled “GET /v1/products”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
sku | query | string | No | Exact SKU match |
limit | query | integer | No | Page size, 1-200 (default 50) |
cursor | query | string | No | Opaque cursor from meta.nextCursor |
Request exampleNo request body
curl https://api.rieckflow.com/v1/products \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/products");{ "data": [ { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "sku": "CONSULTING", "name": "Consulting", "unitPriceOere": 125000, "vatRateBps": 2500, "vatExemptionReason": null, "account": 1010, "active": true, "accountingId": null, "createdAt": "2026-08-04T09:32:11Z" } ], "meta": { "nextCursor": null }}200 Success envelopeapplication/json
Response fields 6
| Field | Type | Description |
|---|---|---|
data[].id | uuid | Stable product id. |
data[].sku | string | Your unique item number. |
data[].unitPriceOere | integer | Default unit price in øre. |
data[].vatRateBps | integer | VAT rate in basis points. |
data[].active | boolean | Whether the product can be used on new invoices. |
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/products
Section titled “POST /v1/products”Request body fields 10
| Field | Type | Required | Description |
|---|---|---|---|
sku | string | Yes | Field in the request payload. |
name | string | Yes | Human-readable name. |
unitPriceOere | integer | Yes | Unit price in integer øre. |
vatRateBps | integer | No | VAT rate in basis points. 2500 means 25%. |
vatExemptionReason | string | No | Required legal reason when the VAT rate is zero. |
accountId | string | No | Field in the request payload. |
account | integer | No | Field in the request payload. |
categoryId | string | No | Field in the request payload. |
unit | string | No | Field in the request payload. |
costPriceOere | integer | No | Field in the request payload. |
Request exampleapplication/json
curl -X POST https://api.rieckflow.com/v1/products \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "sku": "…", "name": "Acme ApS", "unitPriceOere": 125000, "vatRateBps": 2500, "accountId": "9b2f1c1e-…" }'const svar = await rieck.request("POST", "/v1/products", { body: { "sku": "…", "name": "Acme ApS", "unitPriceOere": 125000, "vatRateBps": 2500, "accountId": "9b2f1c1e-…" },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "sku": "CONSULTING", "name": "Consulting", "unitPriceOere": 125000, "vatRateBps": 2500, "vatExemptionReason": null, "account": 1010, "active": true, "accountingId": null, "createdAt": "2026-08-04T09:32:11Z" }}201 Success envelopeapplication/json
Response fields 5
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable product id. |
data.sku | string | Your unique item number. |
data.unitPriceOere | integer | Default unit price in øre. |
data.vatRateBps | integer | VAT rate in basis points. |
data.active | boolean | Whether the product can be used on new invoices. |
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": { "sku": { "type": "string", "minLength": 1, "maxLength": 60 }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "unitPriceOere": { "type": "integer", "minimum": 0, "maximum": 100000000000 }, "vatRateBps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "vatExemptionReason": { "anyOf": [ { "type": "string", "enum": [ "ML13", "OMVENDT", "EU_VARE", "EKSPORT" ] }, { "type": "null" } ] }, "accountId": { "anyOf": [ { "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)$" }, { "type": "null" } ] }, "account": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 999999999 }, { "type": "null" } ] }, "categoryId": { "anyOf": [ { "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)$" }, { "type": "null" } ] }, "unit": { "anyOf": [ { "type": "string", "enum": [ "STK", "TIME", "DAG", "M", "M2", "M3", "KG", "LITER", "KM", "SAET" ] }, { "type": "null" } ] }, "costPriceOere": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 100000000000 }, { "type": "null" } ] } }, "required": [ "sku", "name", "unitPriceOere" ], "additionalProperties": false}GET /v1/products/{productId}
Section titled “GET /v1/products/{productId}”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request exampleNo request body
curl https://api.rieckflow.com/v1/products/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/products/9b2f1c1e-…");{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "sku": "CONSULTING", "name": "Consulting", "unitPriceOere": 125000, "vatRateBps": 2500, "vatExemptionReason": null, "account": 1010, "active": true, "accountingId": null, "createdAt": "2026-08-04T09:32:11Z" }}200 Success envelopeapplication/json
Response fields 5
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable product id. |
data.sku | string | Your unique item number. |
data.unitPriceOere | integer | Default unit price in øre. |
data.vatRateBps | integer | VAT rate in basis points. |
data.active | boolean | Whether the product can be used on new invoices. |
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 | product_not_found | The product does not exist or belongs to another organisation. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
PATCH /v1/products/{productId}
Section titled “PATCH /v1/products/{productId}”| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body fields 11
| Field | Type | Required | Description |
|---|---|---|---|
sku | string | No | Field in the request payload. |
name | string | No | Human-readable name. |
unitPriceOere | integer | No | Unit price in integer øre. |
vatRateBps | integer | No | VAT rate in basis points. 2500 means 25%. |
vatExemptionReason | string | No | Required legal reason when the VAT rate is zero. |
accountId | string | No | Field in the request payload. |
account | integer | No | Field in the request payload. |
categoryId | string | No | Field in the request payload. |
unit | string | No | Field in the request payload. |
costPriceOere | integer | No | Field in the request payload. |
active | boolean | No | Whether the resource is active. |
Request exampleapplication/json
curl -X PATCH https://api.rieckflow.com/v1/products/9b2f1c1e-… \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme ApS", "unitPriceOere": 125000, "vatRateBps": 2500 }'const svar = await rieck.request("PATCH", "/v1/products/9b2f1c1e-…", { body: { "name": "Acme ApS", "unitPriceOere": 125000, "vatRateBps": 2500 },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "sku": "CONSULTING", "name": "Consulting", "unitPriceOere": 125000, "vatRateBps": 2500, "vatExemptionReason": null, "account": 1010, "active": true, "accountingId": null, "createdAt": "2026-08-04T09:32:11Z" }}200 Success envelopeapplication/json
Response fields 5
| Field | Type | Description |
|---|---|---|
data.id | uuid | Stable product id. |
data.sku | string | Your unique item number. |
data.unitPriceOere | integer | Default unit price in øre. |
data.vatRateBps | integer | VAT rate in basis points. |
data.active | boolean | Whether the product can be used on new invoices. |
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 | product_not_found | The product 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": { "sku": { "type": "string", "minLength": 1, "maxLength": 60 }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "unitPriceOere": { "type": "integer", "minimum": 0, "maximum": 100000000000 }, "vatRateBps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "vatExemptionReason": { "anyOf": [ { "type": "string", "enum": [ "ML13", "OMVENDT", "EU_VARE", "EKSPORT" ] }, { "type": "null" } ] }, "accountId": { "anyOf": [ { "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)$" }, { "type": "null" } ] }, "account": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 999999999 }, { "type": "null" } ] }, "categoryId": { "anyOf": [ { "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)$" }, { "type": "null" } ] }, "unit": { "anyOf": [ { "type": "string", "enum": [ "STK", "TIME", "DAG", "M", "M2", "M3", "KG", "LITER", "KM", "SAET" ] }, { "type": "null" } ] }, "costPriceOere": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 100000000000 }, { "type": "null" } ] }, "active": { "type": "boolean" } }, "additionalProperties": false}GET /v1/accounts
Section titled “GET /v1/accounts”Request exampleNo request body
curl https://api.rieckflow.com/v1/accounts \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/accounts");{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "accountNumber": 1010, "name": "Consulting revenue", "active": true, "createdAt": "2026-08-04T09:32:11Z" }}200 Success envelopeapplication/json
Possible errors 4
| 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. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/accounts
Section titled “POST /v1/accounts”Request body fields 5
| Field | Type | Required | Description |
|---|---|---|---|
accountNumber | string | Yes | Field in the request payload. |
name | string | Yes | Human-readable name. |
accountType | string | No | Field in the request payload. |
vatRateBps | integer | No | VAT rate in basis points. 2500 means 25%. |
vatExemptionReason | string | No | Required legal reason when the VAT rate is zero. |
Request exampleapplication/json
curl -X POST https://api.rieckflow.com/v1/accounts \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "…", "name": "Acme ApS", "accountType": "omsaetning" }'const svar = await rieck.request("POST", "/v1/accounts", { body: { "accountNumber": "…", "name": "Acme ApS", "accountType": "omsaetning" },});{ "data": { "id": "9b2f1c1e-6b87-4d9b-91a0-47c8d72b8440", "accountNumber": 1010, "name": "Consulting revenue", "active": true, "createdAt": "2026-08-04T09:32:11Z" }}201 Success envelopeapplication/json
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": { "accountNumber": { "type": "string", "minLength": 1, "maxLength": 20 }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "accountType": { "default": "omsaetning", "type": "string", "enum": [ "omsaetning", "vareforbrug", "kapacitet", "finans", "aktiv", "passiv" ] }, "vatRateBps": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 10000 }, { "type": "null" } ] }, "vatExemptionReason": { "anyOf": [ { "type": "string", "enum": [ "ML13", "OMVENDT", "EU_VARE", "EKSPORT" ] }, { "type": "null" } ] } }, "required": [ "accountNumber", "name" ], "additionalProperties": false}GET /v1/product-categories
Section titled “GET /v1/product-categories”The whole tree in one response — a catalogue has tens of categories, not thousands, so there is no cursor.
Request exampleNo request body
curl https://api.rieckflow.com/v1/product-categories \ -H "Authorization: Bearer $RIECK_API_KEY"const svar = await rieck.request("GET", "/v1/product-categories");{ "data": {}}200
level is 1 for a top-level category and 2 for a subcategory; productCount counts products in that category only.application/jsonPossible errors 4
| 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. |
| 429 | rate_limited | The organisation’s rate budget is exhausted. |
POST /v1/product-categories
Section titled “POST /v1/product-categories”The tree is exactly two levels deep: pass parentId for a subcategory, omit it for a top-level one. A parentId that is itself a subcategory is rejected with 422 — the rule is enforced in the database, not restated here.
Request body fields 3
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable name. |
parentId | string | No | Field in the request payload. |
sortOrder | integer | No | Field in the request payload. |
Request exampleapplication/json
curl -X POST https://api.rieckflow.com/v1/product-categories \ -H "Authorization: Bearer $RIECK_API_KEY" \ -H "Idempotency-Key: order-2041" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme ApS", "parentId": "9b2f1c1e-…" }'const svar = await rieck.request("POST", "/v1/product-categories", { body: { "name": "Acme ApS", "parentId": "9b2f1c1e-…" },});{ "data": {}}201 Success envelopeapplication/json
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": { "name": { "type": "string", "minLength": 1, "maxLength": 80 }, "parentId": { "anyOf": [ { "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)$" }, { "type": "null" } ] }, "sortOrder": { "anyOf": [ { "type": "integer", "minimum": 0, "maximum": 9999 }, { "type": "null" } ] } }, "required": [ "name" ], "additionalProperties": false}