Multi-tenant SaaS REST API for Raccoon, the agentic cloud ERP for small and medium businesses: business partners, products, invoices, files and tax. Authentication uses JWT Bearer tokens.
/resource/v{n}/{objects}.{ "_id", "_class", "_name" }. Only _id is required on input; _name
is a read-only display label the API composes on output.DELETE responses are always 204 No Content with an empty body —
including soft-deletes, cancellations, and "reset to default" semantics.
Clients that need the post-deletion state must re-fetch.| admin_email required | string <email> |
| admin_password required | string <password> >= 8 characters |
| admin_first_name required | string non-empty |
| admin_last_name required | string non-empty |
required | object (RegisterAddress) Address block on the registration payload. Used by the post- registration seed (Phase D) to build the starter Company and sample customers. Tax IDs (VAT, legal/tax registration, IBAN) are NOT accepted on the form and are not seeded either — neither is required to issue an invoice, and a private person or small business may have none of them. The user adds real values in Settings → Companies if and when they have them. |
| invite_code required | string [ 1 .. 40 ] characters A registration invite, issued by a Raccoon administrator. Registration is closed without one. Matched case-insensitively and ignoring whitespace; an unknown, revoked, expired or used-up code is rejected with 422. |
| company_name | string or null non-empty The business's legal/trading name. Optional — a sole trader who sells
under their own name omits it, and the tenant, its starter Company and
the seeded letterhead are all named
" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| user_id required | string |
| access_token required | string |
| refresh_token required | string |
| token_type required | string |
| expires_in required | integer |
| auth_source required | string Enum: "login" "api_key" Indicates how this session was authenticated. |
{- "company_name": "Acme GmbH",
- "admin_email": "admin@acme.de",
- "admin_password": "pa$$word",
- "admin_first_name": "Jane",
- "admin_last_name": "Doe",
- "address": {
- "street_line_1": "Friedrichstr. 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "10117",
- "country_code": "DE"
}, - "invite_code": "RCCN-7K3P-QX92"
}{- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "user_id": "usr_def456",
- "access_token": "string",
- "refresh_token": "string",
- "token_type": "Bearer",
- "expires_in": 900,
- "auth_source": "login"
}string <email> | |
| password | string <password> |
| api_key | string Raw API key string ( |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| user_id required | string |
| access_token required | string |
| refresh_token required | string |
| token_type required | string |
| expires_in required | integer |
| auth_source required | string Enum: "login" "api_key" Indicates how this session was authenticated. |
{- "email": "user@example.com",
- "password": "pa$$word",
- "api_key": "string"
}{- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "user_id": "usr_def456",
- "access_token": "string",
- "refresh_token": "string",
- "token_type": "Bearer",
- "expires_in": 900,
- "auth_source": "login"
}| refresh_token required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| user_id required | string |
| access_token required | string |
| refresh_token required | string |
| token_type required | string |
| expires_in required | integer |
| auth_source required | string Enum: "login" "api_key" Indicates how this session was authenticated. |
{- "refresh_token": "string"
}{- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "user_id": "usr_def456",
- "access_token": "string",
- "refresh_token": "string",
- "token_type": "Bearer",
- "expires_in": 900,
- "auth_source": "login"
}Always returns 200 regardless of whether email matches a
registered, active user — this prevents callers from using the
response to enumerate registered accounts.
| email required | string <email> |
{- "email": "user@example.com"
}{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}Single-use: the token is invalidated on first use whether or not the password update succeeds. On success, every outstanding refresh token for the user is revoked.
| token required | string The signed, single-use token from the reset-link email. |
| new_password required | string <password> >= 8 characters |
{- "token": "string",
- "new_password": "pa$$word"
}{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}Returns the API keys owned by the authenticated user (never another user's keys). The bcrypt hash is never returned — only safe metadata.
required | Array of objects (ApiKeyResponse) |
| next_token required | string or null |
{- "items": [
- {
- "key_id": "a1b2c3d4e5f6",
- "name": "CI deploy key",
- "created_at": 1748815200,
- "last_used_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}The raw key string is returned in the key field exactly once and
cannot be recovered. Only a bcrypt hash of the secret portion (salt
embedded) is persisted.
Forbidden when the calling session was itself authenticated with an
API key (auth_source == "api_key") — preventing privilege chaining.
An API key inherits the privileges of the owning user, so the role of
the resulting session matches the user's role.
| name required | string [ 1 .. 100 ] characters |
| key_id required | string |
| key required | string The raw key string in the form |
| name required | string |
| created_at required | integer |
Reference (object) or null Reference to the user who created the key. |
{- "name": "CI deploy key"
}{- "key_id": "a1b2c3d4e5f6",
- "key": "rccn_a1b2c3d4e5f6_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
- "name": "CI deploy key",
- "created_at": 1748815200,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| key_id required | string Short identifier embedded in the raw key string. |
| key_id required | string Short identifier embedded in the raw key string. |
| name required | string |
| created_at required | integer Unix epoch seconds. |
| last_used_at | integer or null Unix epoch seconds of the most recent successful exchange of this
API key for a JWT pair at |
Reference (object) or null Reference to the user who created the key. Carries the user display name denormalized at creation time. Null when the creator could not be resolved. |
{- "key_id": "a1b2c3d4e5f6",
- "name": "CI deploy key",
- "created_at": 1748815200,
- "last_used_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}The owner-facing audit surface. Returns every API key in the calling
tenant, whoever owns it, each carrying a user reference to its
owner. Owner role required — administrators manage only their own
keys, through /resource/v1/api-keys.
Keys are never minted here: an owner cannot create a key on another user's behalf.
required | Array of objects (TenantApiKeyResponse) |
| next_token required | string or null |
{- "items": [
- {
- "key_id": "a1b2c3d4e5f6",
- "name": "CI deploy key",
- "created_at": 1748815200,
- "last_used_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "user": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}Revokes the key regardless of which user owns it — the route an owner
uses to cut off a departed colleague's credential. The revocation is
published as an api_key deletion event, so the audit trail records
the acting owner.
| key_id required | string Short identifier embedded in the raw key string. |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| partner_type | string Enum: "person" "company" |
| status | string Enum: "active" "inactive" |
| q | string non-empty Full-text search term. When provided, the endpoint delegates to the
shared search index (matches across name/title/email/identifier
fields, tenant-scoped) and returns the matching entities in the
same response shape as the unfiltered list. Pagination ( |
required | Array of any (BusinessPartnerResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp",
- "partner_type": "person",
- "first_name": "Jane",
- "last_name": "Doe",
- "type_id": "string",
- "status": "active",
- "language": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "data": { },
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "vat_partner_type": "b2c",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| partner_type required | string |
| first_name required | string non-empty |
| last_name required | string non-empty |
| phone | string |
| mobile | string |
string <email> | |
Array of objects (EmailAddress) All e-mail addresses linked to this partner. Send | |
| website | string <uri> |
| notes | string |
| customer_number | string The tenant's own reference for this partner (DIN 5008 Kundennummer), copied onto the documents it is billed on. |
| status | string Default: "active" Enum: "active" "inactive" |
| language | string [ 2 .. 5 ] characters Default: "en" |
| discount_percent | number [ 0 .. 100 ] Default: 0 Per-partner discount applied to product list prices on Order-to-Cash documents. Defaults to 0 (no discount). 0 % is semantically the "no override" state. |
| payment_due_days | integer or null >= 0 Calendar days from order date to payment due date. |
Reference (object) or null Reference to the BP's preferred invoice (billing) address. Must
point at an address belonging to this BP that has
| |
Reference (object) or null Like | |
Reference (object) or null Like | |
Reference (object) or null Optional tenant-defined sales channel this partner belongs to.
| |
| vat_partner_type | string Default: "b2c" Enum: "b2c" "b2b" "public_authority" Buyer kind, and the first input to VAT regime resolution. |
| type_id | string [ 1 .. 100 ] characters The business-partner-class tenant type this partner is created under. Every partner has one. Omitted, the partner is created under the tenant's default business-partner type; that is a 422 when the tenant has several and marks none of them default. |
| schema_version | string or null Type version. Omitted = latest. |
object Custom field values keyed by section field IDs. | |
| salutation | string |
| salutation_code | string Enum: "frau" "herr" "divers" "mme" "m" "ms" "mr" "mx" Machine-readable salutation feeding a future formal-greeting helper (deferred Phase 3 invoice-text epic). |
| date_of_birth | string <date> |
| gender | string Enum: "male" "female" "other" "unknown" |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| partner_type required | string |
| first_name required | string |
| last_name required | string |
| type_id required | string The tenant type this partner was created under. |
| status required | string Enum: "active" "inactive" |
| language required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | object Type-specific custom-field data; |
required | Array of objects (EmailAddress) All e-mail addresses linked to this partner (including login users) |
| vat_partner_type required | string Enum: "b2c" "b2b" "public_authority" Buyer kind for VAT regime resolution. The VAT-ID itself is a
|
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | object
|
{- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "email": "user@example.com",
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "notes": "string",
- "customer_number": "string",
- "status": "active",
- "language": "de",
- "discount_percent": 10,
- "payment_due_days": 30,
- "preferred_invoice_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_shipping_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_service_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "vat_partner_type": "b2c",
- "type_id": "customer",
- "schema_version": "string",
- "data": { },
- "partner_type": "person",
- "salutation": "Ms.",
- "salutation_code": "ms",
- "first_name": "Jane",
- "last_name": "Doe",
- "date_of_birth": "1985-03-15",
- "gender": "male"
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp",
- "partner_type": "person",
- "first_name": "Jane",
- "last_name": "Doe",
- "type_id": "string",
- "status": "active",
- "language": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "data": { },
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "vat_partner_type": "b2c",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| partner_type required | string |
| first_name required | string |
| last_name required | string |
| type_id required | string The tenant type this partner was created under. |
| status required | string Enum: "active" "inactive" |
| language required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | object Type-specific custom-field data; |
required | Array of objects (EmailAddress) All e-mail addresses linked to this partner (including login users) |
| vat_partner_type required | string Enum: "b2c" "b2b" "public_authority" Buyer kind for VAT regime resolution. The VAT-ID itself is a
|
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | object
|
{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp",
- "partner_type": "person",
- "first_name": "Jane",
- "last_name": "Doe",
- "type_id": "string",
- "status": "active",
- "language": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "data": { },
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "vat_partner_type": "b2c",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| phone | string |
| mobile | string |
string <email> | |
Array of objects (EmailAddress) Replaces the partner's whole e-mail list. | |
| website | string <uri> |
| notes | string |
| customer_number | string |
| status | string Enum: "active" "inactive" |
| language | string |
| salutation | string |
| first_name | string |
| last_name | string |
| date_of_birth | string <date> |
| gender | string Enum: "male" "female" "other" "unknown" |
| company_name | string |
| legal_form | string |
| tax_id | string |
| vat_partner_type | string Enum: "b2c" "b2b" "public_authority" |
| commercial_register_number | string |
| type_id | string or null |
| schema_version | string or null |
object | |
| discount_percent | number [ 0 .. 100 ] |
| payment_due_days | integer or null >= 0 |
Reference (object) or null | |
Reference (object) or null | |
Reference (object) or null | |
Reference (object) or null Tenant-defined sales channel, or null to unassign. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| partner_type required | string |
| first_name required | string |
| last_name required | string |
| type_id required | string The tenant type this partner was created under. |
| status required | string Enum: "active" "inactive" |
| language required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | object Type-specific custom-field data; |
required | Array of objects (EmailAddress) All e-mail addresses linked to this partner (including login users) |
| vat_partner_type required | string Enum: "b2c" "b2b" "public_authority" Buyer kind for VAT regime resolution. The VAT-ID itself is a
|
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | object
|
{- "phone": "string",
- "mobile": "string",
- "email": "user@example.com",
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "notes": "string",
- "customer_number": "string",
- "status": "active",
- "language": "string",
- "salutation": "string",
- "first_name": "string",
- "last_name": "string",
- "date_of_birth": "2019-08-24",
- "gender": "male",
- "company_name": "string",
- "legal_form": "string",
- "tax_id": "string",
- "vat_partner_type": "b2c",
- "commercial_register_number": "string",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "discount_percent": 100,
- "payment_due_days": 0,
- "preferred_invoice_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_shipping_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_service_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp",
- "partner_type": "person",
- "first_name": "Jane",
- "last_name": "Doe",
- "type_id": "string",
- "status": "active",
- "language": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "data": { },
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "vat_partner_type": "b2c",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| phone | string |
| mobile | string |
string <email> | |
Array of objects (EmailAddress) Replaces the partner's whole e-mail list. | |
| website | string <uri> |
| notes | string |
| customer_number | string |
| status | string Enum: "active" "inactive" |
| language | string |
| salutation | string |
| first_name | string |
| last_name | string |
| date_of_birth | string <date> |
| gender | string Enum: "male" "female" "other" "unknown" |
| company_name | string |
| legal_form | string |
| tax_id | string |
| vat_partner_type | string Enum: "b2c" "b2b" "public_authority" |
| commercial_register_number | string |
| type_id | string or null |
| schema_version | string or null |
object | |
| discount_percent | number [ 0 .. 100 ] |
| payment_due_days | integer or null >= 0 |
Reference (object) or null | |
Reference (object) or null | |
Reference (object) or null | |
Reference (object) or null Tenant-defined sales channel, or null to unassign. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| partner_type required | string |
| first_name required | string |
| last_name required | string |
| type_id required | string The tenant type this partner was created under. |
| status required | string Enum: "active" "inactive" |
| language required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | object Type-specific custom-field data; |
required | Array of objects (EmailAddress) All e-mail addresses linked to this partner (including login users) |
| vat_partner_type required | string Enum: "b2c" "b2b" "public_authority" Buyer kind for VAT regime resolution. The VAT-ID itself is a
|
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | object
|
{- "phone": "string",
- "mobile": "string",
- "email": "user@example.com",
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "notes": "string",
- "customer_number": "string",
- "status": "active",
- "language": "string",
- "salutation": "string",
- "first_name": "string",
- "last_name": "string",
- "date_of_birth": "2019-08-24",
- "gender": "male",
- "company_name": "string",
- "legal_form": "string",
- "tax_id": "string",
- "vat_partner_type": "b2c",
- "commercial_register_number": "string",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "discount_percent": 100,
- "payment_due_days": 0,
- "preferred_invoice_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_shipping_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "preferred_service_address": {
- "_id": "prod_fd74a5ce31b6"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp",
- "partner_type": "person",
- "first_name": "Jane",
- "last_name": "Doe",
- "type_id": "string",
- "status": "active",
- "language": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "data": { },
- "email_addresses": [
- {
- "email_id": "email_5a3b4079",
- "email": "billing@example.com",
- "label": "billing",
- "is_primary": false,
- "is_invoicing": false,
- "is_confirmed": false,
- "confirmed_at": 1746144000
}
], - "vat_partner_type": "b2c",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Creates a user account linked to the business partner and sets its business_partner_role. Restricted to the tenant owner. Only person-type partners without existing login access are eligible.
| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| email required | string <email> |
| password required | string <password> >= 8 characters |
| role | string Default: "administrator" Value: "administrator" |
| user_id required | string |
| business_partner_id required | string |
| role required | string Value: "administrator" |
| email required | string <email> |
| business_partner_role required | string Value: "administrator" |
{- "email": "user@example.com",
- "password": "pa$$word",
- "role": "administrator"
}{- "user_id": "string",
- "business_partner_id": "string",
- "role": "administrator",
- "email": "user@example.com",
- "business_partner_role": "administrator"
}Deactivates the linked user account and clears the partner's business_partner_role. Restricted to the tenant owner. The owner's own login cannot be revoked.
| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}The products most recently billed to this partner, newest first and capped. Read off the partner's own invoice line items, so it reflects what was actually billed rather than a separately maintained list. Empty for a partner with no invoice history.
| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
required | Array of objects (ProductResponse) |
| next_token required | string or null |
{- "items": [
- {
- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
required | Array of objects (AddressResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "addr_a1b2c3",
- "_class": "address",
- "_name": "Acme Corp",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "city": "string",
- "country_code": "st",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| street_line_1 required | string non-empty |
| city required | string non-empty |
| country_code required | string = 2 characters ISO 3166-1 alpha-2 country code |
| label | string Free-text structural label (e.g. "HQ", "Munich warehouse"). Purely descriptive — has no behaviour. |
| is_invoice_address | boolean Default: false When true, this address is eligible to fill the |
| is_shipping_address | boolean Default: false When true, this address is eligible to fill the |
| is_service_address | boolean Default: false When true, this address is eligible to fill the |
| street_line_2 | string |
| state_province | string |
| postal_code | string |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| is_invoice_address required | boolean |
| is_shipping_address required | boolean |
| is_service_address required | boolean |
| street_line_1 required | string |
| city required | string |
| country_code required | string = 2 characters |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
{- "label": "HQ",
- "is_invoice_address": false,
- "is_shipping_address": false,
- "is_service_address": false,
- "street_line_1": "Musterstraße 1",
- "street_line_2": "Apt 2B",
- "city": "Berlin",
- "state_province": "Berlin",
- "postal_code": "10115",
- "country_code": "DE"
}{- "_id": "addr_a1b2c3",
- "_class": "address",
- "_name": "Acme Corp",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "city": "string",
- "country_code": "st",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| address_id required | string Example: addr_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| is_invoice_address required | boolean |
| is_shipping_address required | boolean |
| is_service_address required | boolean |
| street_line_1 required | string |
| city required | string |
| country_code required | string = 2 characters |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
{- "_id": "addr_a1b2c3",
- "_class": "address",
- "_name": "Acme Corp",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "city": "string",
- "country_code": "st",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| address_id required | string Example: addr_a1b2c3d4e5f6 |
| label | string |
| is_invoice_address | boolean |
| is_shipping_address | boolean |
| is_service_address | boolean |
| street_line_1 | string |
| street_line_2 | string |
| city | string |
| state_province | string |
| postal_code | string |
| country_code | string = 2 characters |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| is_invoice_address required | boolean |
| is_shipping_address required | boolean |
| is_service_address required | boolean |
| street_line_1 required | string |
| city required | string |
| country_code required | string = 2 characters |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
{- "label": "string",
- "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "street_line_2": "string",
- "city": "string",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "st"
}{- "_id": "addr_a1b2c3",
- "_class": "address",
- "_name": "Acme Corp",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "city": "string",
- "country_code": "st",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| address_id required | string Example: addr_a1b2c3d4e5f6 |
| label | string |
| is_invoice_address | boolean |
| is_shipping_address | boolean |
| is_service_address | boolean |
| street_line_1 | string |
| street_line_2 | string |
| city | string |
| state_province | string |
| postal_code | string |
| country_code | string = 2 characters |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| is_invoice_address required | boolean |
| is_shipping_address required | boolean |
| is_service_address required | boolean |
| street_line_1 required | string |
| city required | string |
| country_code required | string = 2 characters |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
{- "label": "string",
- "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "street_line_2": "string",
- "city": "string",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "st"
}{- "_id": "addr_a1b2c3",
- "_class": "address",
- "_name": "Acme Corp",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_invoice_address": true,
- "is_shipping_address": true,
- "is_service_address": true,
- "street_line_1": "string",
- "city": "string",
- "country_code": "st",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| address_id required | string Example: addr_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| project_id | string Example: project_id=prj_a1b2c3d4e5f6 Filter products by project ID |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| q | string non-empty Full-text search term. When provided, the endpoint delegates to the
shared search index (matches across name/title/email/identifier
fields, tenant-scoped) and returns the matching entities in the
same response shape as the unfiltered list. Pagination ( |
required | Array of objects (ProductResponse) |
| next_token required | string or null |
{- "items": [
- {
- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| name required | string [ 1 .. 200 ] characters |
Reference (object) or null Optional project to assign this product to | |
Reference (object) or null Optional tenant-defined sales channel to assign this product to | |
| type_id | string [ 1 .. 100 ] characters The product-class tenant type this product is created under. Every product has one. Omitted, the product is created under the tenant's default product type; that is a 422 when the tenant has several and marks none of them default. |
| schema_version | string [ 1 .. 50 ] characters |
object | |
| stocking_unit_of_measure | string or null <= 20 characters Overrides the product type's |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category. Optional on input — defaults to the product type's |
Array of objects (ProductPriceInput) Inline price entries. Single-price mode ( |
| _id required | string |
| _class required | string Value: "product" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| schema_version required | string |
| name required | string |
required | object |
| stocking_unit_of_measure required | string or null <= 20 characters Overrides the product type's |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category. The per-invoice rate is resolved from it. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | Array of objects (ProductSaveWarning) |
Reference (object) or null Project this product belongs to, null if unassigned | |
Reference (object) or null Sales channel this product belongs to, null if unassigned | |
Array of objects (ProductPrice) Inline price entries. Empty array when no price has been assigned.
Single-price mode = 0 or 1 entries, no scoping fields populated.
Multi-dim mode (any |
{- "project": {
- "_id": "prod_fd74a5ce31b6"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "prices": [
- {
- "_id": "string",
- "_class": "price",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
]
}{- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "warnings": [
- {
- "code": "prices.by_country_missing_vat_category",
- "field": "prices",
- "message": "string"
}
]
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string Value: "product" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| schema_version required | string |
| name required | string |
required | object |
| stocking_unit_of_measure required | string or null <= 20 characters Overrides the product type's |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category. The per-invoice rate is resolved from it. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
Reference (object) or null Project this product belongs to, null if unassigned | |
Reference (object) or null Sales channel this product belongs to, null if unassigned | |
Array of objects (ProductPrice) Inline price entries. Empty array when no price has been assigned.
Single-price mode = 0 or 1 entries, no scoping fields populated.
Multi-dim mode (any |
{- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
| name | string [ 1 .. 200 ] characters |
object | |
Reference (object) or null Sales channel to assign, or null to unassign | |
| stocking_unit_of_measure | string or null <= 20 characters Stocking-unit override for this product. Omit to leave it unchanged; send |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category. Omit or null to leave unchanged. |
| type_id | string or null |
| schema_version | string or null |
Array of objects or null (ProductPriceInput) Omit (or |
| _id required | string |
| _class required | string Value: "product" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| schema_version required | string |
| name required | string |
required | object |
| stocking_unit_of_measure required | string or null <= 20 characters Overrides the product type's |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category. The per-invoice rate is resolved from it. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
required | Array of objects (ProductSaveWarning) |
Reference (object) or null Project this product belongs to, null if unassigned | |
Reference (object) or null Sales channel this product belongs to, null if unassigned | |
Array of objects (ProductPrice) Inline price entries. Empty array when no price has been assigned.
Single-price mode = 0 or 1 entries, no scoping fields populated.
Multi-dim mode (any |
{- "name": "string",
- "data": { },
- "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "type_id": "string",
- "schema_version": "string",
- "prices": [
- {
- "_id": "string",
- "_class": "price",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
]
}{- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "warnings": [
- {
- "code": "prices.by_country_missing_vat_category",
- "field": "prices",
- "message": "string"
}
]
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
Reference (object) or null Project reference to assign, or null to unassign |
| _id required | string |
| _class required | string Value: "product" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| schema_version required | string |
| name required | string |
required | object |
| stocking_unit_of_measure required | string or null <= 20 characters Overrides the product type's |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category. The per-invoice rate is resolved from it. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
Reference (object) or null Project this product belongs to, null if unassigned | |
Reference (object) or null Sales channel this product belongs to, null if unassigned | |
Array of objects (ProductPrice) Inline price entries. Empty array when no price has been assigned.
Single-price mode = 0 or 1 entries, no scoping fields populated.
Multi-dim mode (any |
{- "project": {
- "_id": "prod_fd74a5ce31b6"
}
}{- "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prd_a1b2c3d4e5f6",
- "_class": "product",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "type_id": "toy",
- "schema_version": "1.0.0",
- "name": "My Product",
- "data": { },
- "stocking_unit_of_measure": "string",
- "vat_category": "H",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_at": 1672531200,
- "updated_at": 1672531200,
- "project": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "prices": [
- {
- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}
], - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Sub-resource sugar over the parent Product update. Single-price mode
accepts at most one row across the product's lifetime — adding a
second one returns 422 until the relevant pricing_config flag is
enabled on the product type. Scoping fields (country_codes,
channel, …) are rejected unless their gating flag is on.
The row is new by definition, so a body carrying _id is a 422 —
the server assigns price ids. To change an existing row, address
its own URL.
| product_id required | string Example: prd_a1b2c3d4e5f6 |
required | object (MonetaryAmountInput) Request-side counterpart of Responses always carry |
| _id | string or null Optional; server generates a |
| _class | string or null Enum: "price" null Accepted on input but ignored — the server always assigns "price". |
| tax_mode | string or null Enum: "net" "gross" null |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null |
| country_codes | Array of strings[ items = 2 characters ] |
Reference (object) or null | |
| valid_from | string or null <date> |
| valid_to | string or null <date> |
| is_campaign | boolean Default: false |
MonetaryAmountInput (object) or null | |
number or string Default: 1 | |
| unit_of_measure | string Default: "EA" |
| compute | object or null |
| priority | integer Default: 0 |
| _id required | string |
| _class required | string Value: "price" |
required | object
|
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| tax_mode required | string Enum: "net" "gross" |
| vat_category required | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category override for this row. Null inherits the Product-level |
| country_codes required | Array of strings[ items = 2 characters ] ISO 3166-1 alpha-2 codes. Empty = any. Gated by |
required | Reference (object) or null Reference to a tenant-defined Channel. Null = applies to any channel. Gated by |
| valid_from required | string or null <date> ISO calendar date (YYYY-MM-DD), inclusive. Gated by |
| valid_to required | string or null <date> |
| is_campaign required | boolean Default: false Gated by |
required | MonetaryAmount (object) or null |
| min_quantity required | number Default: 1 Volume-tier breakpoint. Gated by |
| unit_of_measure required | string Default: "EA" |
| compute required | object or null Reserved for |
| priority required | integer Default: 0 Tie-breaker; higher wins. Always available. |
{- "_id": "string",
- "_class": "price",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}{- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}A price is an object with an id, so it answers at its own URL —
the one every row carries as _links.self. 404 when this product
does not hold that row, including when it belongs to another
product.
| product_id required | string Example: prd_a1b2c3d4e5f6 |
| price_id required | string Example: prc_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string Value: "price" |
required | object
|
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| tax_mode required | string Enum: "net" "gross" |
| vat_category required | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category override for this row. Null inherits the Product-level |
| country_codes required | Array of strings[ items = 2 characters ] ISO 3166-1 alpha-2 codes. Empty = any. Gated by |
required | Reference (object) or null Reference to a tenant-defined Channel. Null = applies to any channel. Gated by |
| valid_from required | string or null <date> ISO calendar date (YYYY-MM-DD), inclusive. Gated by |
| valid_to required | string or null <date> |
| is_campaign required | boolean Default: false Gated by |
required | MonetaryAmount (object) or null |
| min_quantity required | number Default: 1 Volume-tier breakpoint. Gated by |
| unit_of_measure required | string Default: "EA" |
| compute required | object or null Reserved for |
| priority required | integer Default: 0 Tie-breaker; higher wins. Always available. |
{- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}Full replace: the body is the new row contents; the price_id
stays with the row across the swap so downstream snapshots
(invoice lines, change logs) keep their back-link. A body _id
that disagrees with the URL is a 422 rather than being silently
overridden.
| product_id required | string Example: prd_a1b2c3d4e5f6 |
| price_id required | string Example: prc_a1b2c3d4e5f6 |
required | object (MonetaryAmountInput) Request-side counterpart of Responses always carry |
| _id | string or null Optional; server generates a |
| _class | string or null Enum: "price" null Accepted on input but ignored — the server always assigns "price". |
| tax_mode | string or null Enum: "net" "gross" null |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null |
| country_codes | Array of strings[ items = 2 characters ] |
Reference (object) or null | |
| valid_from | string or null <date> |
| valid_to | string or null <date> |
| is_campaign | boolean Default: false |
MonetaryAmountInput (object) or null | |
number or string Default: 1 | |
| unit_of_measure | string Default: "EA" |
| compute | object or null |
| priority | integer Default: 0 |
| _id required | string |
| _class required | string Value: "price" |
required | object
|
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| tax_mode required | string Enum: "net" "gross" |
| vat_category required | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category override for this row. Null inherits the Product-level |
| country_codes required | Array of strings[ items = 2 characters ] ISO 3166-1 alpha-2 codes. Empty = any. Gated by |
required | Reference (object) or null Reference to a tenant-defined Channel. Null = applies to any channel. Gated by |
| valid_from required | string or null <date> ISO calendar date (YYYY-MM-DD), inclusive. Gated by |
| valid_to required | string or null <date> |
| is_campaign required | boolean Default: false Gated by |
required | MonetaryAmount (object) or null |
| min_quantity required | number Default: 1 Volume-tier breakpoint. Gated by |
| unit_of_measure required | string Default: "EA" |
| compute required | object or null Reserved for |
| priority required | integer Default: 0 Tie-breaker; higher wins. Always available. |
{- "_id": "string",
- "_class": "price",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}{- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}Body is an arbitrary subset of ProductPrice fields. The service merges
the patch into the existing row, re-validates the result as a
ProductPriceInput, and re-runs the prices-array validators (scoping
guard, currency consistency, scoping-tuple uniqueness). A body
_id that disagrees with the URL is a 422.
| product_id required | string Example: prd_a1b2c3d4e5f6 |
| price_id required | string Example: prc_a1b2c3d4e5f6 |
| property name* additional property | any |
| _id required | string |
| _class required | string Value: "price" |
required | object
|
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| tax_mode required | string Enum: "net" "gross" |
| vat_category required | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null ONIX List 62 VAT category override for this row. Null inherits the Product-level |
| country_codes required | Array of strings[ items = 2 characters ] ISO 3166-1 alpha-2 codes. Empty = any. Gated by |
required | Reference (object) or null Reference to a tenant-defined Channel. Null = applies to any channel. Gated by |
| valid_from required | string or null <date> ISO calendar date (YYYY-MM-DD), inclusive. Gated by |
| valid_to required | string or null <date> |
| is_campaign required | boolean Default: false Gated by |
required | MonetaryAmount (object) or null |
| min_quantity required | number Default: 1 Volume-tier breakpoint. Gated by |
| unit_of_measure required | string Default: "EA" |
| compute required | object or null Reserved for |
| priority required | integer Default: 0 Tie-breaker; higher wins. Always available. |
{ }{- "_id": "prc_a1b2c3d4e5f6",
- "_class": "price",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_mode": "net",
- "vat_category": "H",
- "country_codes": [
- "st"
], - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "is_campaign": false,
- "compare_at_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "min_quantity": 1,
- "unit_of_measure": "EA",
- "compute": { },
- "priority": 0
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
| price_id required | string Example: prc_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockLocationResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "stl_a1b2c3d4e5f6",
- "_class": "stock_location",
- "_name": "Acme Corp",
- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}| name required | string [ 1 .. 140 ] characters |
| location_type | string Default: "warehouse" Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| description | string or null |
| is_default | boolean Default: false Mark this location as the tenant default. At most one location per tenant is the default; setting it here clears the flag on any previous default. The tenant's first location is made the default automatically. |
| is_active | boolean Default: true |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| name required | string |
| location_type required | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| is_default required | boolean |
| is_active required | boolean |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
| description | string or null |
{- "name": "Shop",
- "location_type": "shop",
- "description": "string",
- "is_default": false,
- "is_active": true
}{- "_id": "stl_a1b2c3d4e5f6",
- "_class": "stock_location",
- "_name": "Acme Corp",
- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_location_id required | string Example: stl_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| name required | string |
| location_type required | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| is_default required | boolean |
| is_active required | boolean |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
| description | string or null |
{- "_id": "stl_a1b2c3d4e5f6",
- "_class": "stock_location",
- "_name": "Acme Corp",
- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_location_id required | string Example: stl_a1b2c3d4e5f6 |
| name | string [ 1 .. 140 ] characters |
| location_type | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| description | string or null |
| is_default | boolean |
| is_active | boolean |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| name required | string |
| location_type required | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| is_default required | boolean |
| is_active required | boolean |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
| description | string or null |
{- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true
}{- "_id": "stl_a1b2c3d4e5f6",
- "_class": "stock_location",
- "_name": "Acme Corp",
- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_location_id required | string Example: stl_a1b2c3d4e5f6 |
| name | string [ 1 .. 140 ] characters |
| location_type | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| description | string or null |
| is_default | boolean |
| is_active | boolean |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| name required | string |
| location_type required | string Enum: "shop" "store_room" "vehicle" "warehouse" "other" |
| is_default required | boolean |
| is_active required | boolean |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
| description | string or null |
{- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true
}{- "_id": "stl_a1b2c3d4e5f6",
- "_class": "stock_location",
- "_name": "Acme Corp",
- "name": "string",
- "location_type": "shop",
- "description": "string",
- "is_default": true,
- "is_active": true,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}Rejected with 409 when the location is the tenant default (reassign first) or still holds stock.
| stock_location_id required | string Example: stl_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| product_id required | string |
| stock_location_id required | string |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockMovementResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| movement_type required | string Enum: "opening" "receipt" "issue" "adjustment" opening/receipt add stock (positive quantity_delta, unit_cost required); issue removes stock (negative); adjustment is a signed correction. count and transfer have their own endpoints. |
| quantity_delta required | number Signed quantity change; must be non-zero. |
MonetaryAmountInput (object) or null Required on opening/receipt so weighted-average cost recomputes. | |
| reason | string or null |
| dedupe_key | string or null [ 1 .. 128 ] characters Optional. A second write with the same key within the tenant does not create a second row. The existing movement is returned unchanged. |
| effective_at | integer or null Business date (unix seconds); defaults to now. |
| _id required | string |
| _class required | string |
| _name required | string The movement type and its signed quantity, e.g. "receipt +20". |
| movement_type required | string Enum: "opening" "receipt" "issue" "transfer" "adjustment" "count" |
| quantity_delta required | number |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| dedupe_key required | string or null |
| effective_at required | integer |
required | Reference (object) or null The offer or invoice this movement fulfils (a dispatch line). |
| document_line_item_id required | string or null |
required | Reference (object) or null The receipt, stocktake or dispatch that posted this movement. |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
Reference (object) or null | |
MonetaryAmount (object) or null | |
| balance_after | number or null |
| reason | string or null |
{- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0
}{- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}Supply the absolute counted quantity; the service posts a count movement for the difference from the current on-hand.
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| counted_quantity required | number >= 0 Absolute counted quantity; the service posts the variance. |
| reason | string or null |
| dedupe_key | string or null [ 1 .. 128 ] characters Optional. A second write with the same key within the tenant does not create a second row. The existing movement is returned unchanged. |
| effective_at | integer or null |
| _id required | string |
| _class required | string |
| _name required | string The movement type and its signed quantity, e.g. "receipt +20". |
| movement_type required | string Enum: "opening" "receipt" "issue" "transfer" "adjustment" "count" |
| quantity_delta required | number |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| dedupe_key required | string or null |
| effective_at required | integer |
required | Reference (object) or null The offer or invoice this movement fulfils (a dispatch line). |
| document_line_item_id required | string or null |
required | Reference (object) or null The receipt, stocktake or dispatch that posted this movement. |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
Reference (object) or null | |
MonetaryAmount (object) or null | |
| balance_after | number or null |
| reason | string or null |
{- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "counted_quantity": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0
}{- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}Emits an issue on the source and a receipt on the destination in one transaction, carrying the source's average cost across.
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| quantity required | number > 0 |
| reason | string or null |
| dedupe_key | string or null [ 1 .. 128 ] characters Optional. A second write with the same key within the tenant does not create a second row. The existing movement is returned unchanged. |
| effective_at | integer or null |
required | object (StockMovementResponse) |
required | object (StockMovementResponse) |
{- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "from_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "to_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "quantity": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0
}{- "source": {
- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}, - "destination": {
- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
}| product_id required | string |
| stock_location_id | string Omit to get the product's total on-hand across all locations; supply to scope the series to one location. |
required | Array of objects |
{- "series": [
- {
- "at": 0,
- "balance": 0,
- "movement_type": "string",
- "quantity_delta": 0,
- "stock_movement_id": "string",
- "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "reason": "string",
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
]
}| product_id required | string |
| stock_location_id | string |
required | Array of objects (StockLevelResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "prd_abc.stl_xyz",
- "_class": "stock_level",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "on_hand": 0,
- "reserved": 0,
- "available": 0,
- "average_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reorder_point": 0,
- "stocking_unit_of_measure": "string",
- "last_counted_at": 0,
- "last_count": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| reorder_point | number or null >= 0 |
| _id required | string Composite id "{product_id}.{stock_location_id}". |
| _class required | string |
| on_hand required | number |
| reserved required | number |
| available required | number Computed on-hand minus reserved (never stored). |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object Backend-computed on_hand x average_cost. |
| stocking_unit_of_measure required | string |
| last_counted_at required | integer or null The business date of the last stocktake that counted this level. |
required | Reference (object) or null The stocktake that last counted this level. |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
| reorder_point | number or null |
{- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "reorder_point": 0
}{- "_id": "prd_abc.stl_xyz",
- "_class": "stock_level",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "on_hand": 0,
- "reserved": 0,
- "available": 0,
- "average_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reorder_point": 0,
- "stocking_unit_of_measure": "string",
- "last_counted_at": 0,
- "last_count": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_location_id | string |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockReceiptResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "srct_a1b2c3d4e5f6",
- "_class": "stock_receipt",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_receipt_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "quantity": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}Lines post first, keyed {dedupe_key}:{line dedupe_key} so a retried
sheet replays already-posted lines as no-ops; the header is written
once every line landed. When a line fails the response is a 422 whose
details.lines carries every line's outcome and no header is written.
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| dedupe_key required | string [ 1 .. 64 ] characters Required. A second write with the same key within the tenant does not create a second row. The existing sheet is returned unchanged, every line |
required | Array of objects (StockReceiptLineCreate) [ 1 .. 500 ] items |
| effective_at | integer or null Business date (unix seconds); defaults to now. |
| reference | string or null The supplier's delivery-note number, as given. |
| note | string or null |
| _id required | string |
| _class required | string |
| _name required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| reference required | string or null |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockReceiptLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | Array of objects (StockReceiptLineResult) The outcome per line of this post. |
{- "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "dedupe_key": "string",
- "lines": [
- {
- "dedupe_key": "string",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "quantity": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "effective_at": 0,
- "reference": "string",
- "note": "string"
}{- "_id": "srct_a1b2c3d4e5f6",
- "_class": "stock_receipt",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_receipt_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "quantity": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "lines_result": [
- {
- "dedupe_key": "string",
- "line_id": "string",
- "status": "posted",
- "error": "string"
}
]
}| stock_receipt_id required | string |
| _id required | string |
| _class required | string |
| _name required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| reference required | string or null |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockReceiptLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
{- "_id": "srct_a1b2c3d4e5f6",
- "_class": "stock_receipt",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_receipt_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "quantity": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_location_id | string |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockCountResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "stc_a1b2c3d4e5f6",
- "_class": "stock_count",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_count_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "expected": 0,
- "counted": 0,
- "variance": 0,
- "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}Every line's variance is measured against the ledger balance as of
the count date, so a backdated count does not undo movements posted
since. Lines whose counted figure matches post no movement but stay
on the sheet. Lines post first, keyed {dedupe_key}:{line dedupe_key},
so a retried sheet replays; the sheet is written once every line
landed, and every counted level is stamped last_counted_at.
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| dedupe_key required | string [ 1 .. 64 ] characters Required. A second write with the same key within the tenant does not create a second row. The existing sheet is returned unchanged, every line |
required | Array of objects (StockCountLineCreate) [ 1 .. 500 ] items |
| effective_at | integer or null The count date (unix seconds); defaults to now. Variances are measured against the ledger as of this date. |
| note | string or null |
| _id required | string |
| _class required | string |
| _name required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockCountLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | Array of objects (StockCountLineResult) |
{- "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "dedupe_key": "string",
- "lines": [
- {
- "dedupe_key": "string",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "counted": 0
}
], - "effective_at": 0,
- "note": "string"
}{- "_id": "stc_a1b2c3d4e5f6",
- "_class": "stock_count",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_count_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "expected": 0,
- "counted": 0,
- "variance": 0,
- "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "lines_result": [
- {
- "dedupe_key": "string",
- "line_id": "string",
- "status": "posted",
- "error": "string"
}
]
}| stock_count_id required | string |
| _id required | string |
| _class required | string |
| _name required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockCountLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
{- "_id": "stc_a1b2c3d4e5f6",
- "_class": "stock_count",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_count_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "expected": 0,
- "counted": 0,
- "variance": 0,
- "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| document_id | string Only dispatches shipped against this offer or invoice; the response then also carries shipped_by_line. |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockDispatchResponse) |
| next_token required | string or null |
object Present when filtered by document_id — quantity already shipped per document line, across every dispatch. |
{- "items": [
- {
- "_id": "sdp_a1b2c3d4e5f6",
- "_class": "stock_dispatch",
- "_name": "string",
- "dispatch_number": "string",
- "status": "draft",
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "recipient_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_dispatch_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "description": "string",
- "quantity": 0,
- "unit_code": "string",
- "unit_label": "string",
- "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string",
- "shipped_by_line": {
- "property1": 0,
- "property2": 0
}
}From an accepted offer or an invoice (any status but cancelled), or
on its own. Every tracked line posts an issue movement keyed
{dedupe_key}:{line dedupe_key} naming the customer document and the
dispatch; a draft invoice's reservation is lowered in the same write.
Untracked lines are skipped and reported. The header is written once
every line landed and numbered on the tenant's delivery-note series.
| dedupe_key required | string [ 1 .. 64 ] characters Required. A second write with the same key within the tenant does not create a second row. The existing sheet is returned unchanged, every line |
required | Array of objects (StockDispatchLineCreate) [ 1 .. 500 ] items |
Reference (object) or null The accepted offer or the invoice being shipped. Omit for a standalone dispatch. | |
Reference (object) or null Recipient of a standalone dispatch. | |
Reference (object) or null The location the goods leave from; defaults to the tenant default. | |
| effective_at | integer or null |
| reference | string or null A customer order or waybill number. |
| note | string or null |
| _id required | string |
| _class required | string |
| _name required | string The dispatch number once posted. |
| dispatch_number required | string |
| status required | string Enum: "draft" "posted" |
required | Reference (object) or null |
required | Reference (object) or null |
| recipient_name required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| reference required | string or null |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockDispatchLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | Array of objects (StockDispatchLineResult) |
{- "source_document": {
- "_id": "prod_fd74a5ce31b6"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}, - "dedupe_key": "string",
- "lines": [
- {
- "dedupe_key": "string",
- "document_line_item_id": "string",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "quantity": 0,
- "stock_location": {
- "_id": "prod_fd74a5ce31b6"
}
}
], - "effective_at": 0,
- "reference": "string",
- "note": "string"
}{- "_id": "sdp_a1b2c3d4e5f6",
- "_class": "stock_dispatch",
- "_name": "string",
- "dispatch_number": "string",
- "status": "draft",
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "recipient_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_dispatch_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "description": "string",
- "quantity": 0,
- "unit_code": "string",
- "unit_label": "string",
- "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "lines_result": [
- {
- "dedupe_key": "string",
- "line_id": "string",
- "status": "posted",
- "error": "string"
}
]
}| stock_dispatch_id required | string |
| _id required | string |
| _class required | string |
| _name required | string The dispatch number once posted. |
| dispatch_number required | string |
| status required | string Enum: "draft" "posted" |
required | Reference (object) or null |
required | Reference (object) or null |
| recipient_name required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| effective_at required | integer |
| reference required | string or null |
| note required | string or null |
| dedupe_key required | string |
required | Array of objects (StockDispatchLine) |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
{- "_id": "sdp_a1b2c3d4e5f6",
- "_class": "stock_dispatch",
- "_name": "string",
- "dispatch_number": "string",
- "status": "draft",
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "recipient_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "reference": "string",
- "note": "string",
- "dedupe_key": "string",
- "lines": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "dedupe_key": "string",
- "_id": "string",
- "_class": "stock_dispatch_line",
- "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "description": "string",
- "quantity": 0,
- "unit_code": "string",
- "unit_label": "string",
- "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_movement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
required | Array of objects (StockDispatchDocumentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "sddoc_a1b2c3d4e5f6789012345",
- "_class": "stock_dispatch_document",
- "stock_dispatch_id": "sdp_a1b2c3d4e5f6",
- "document_type": "delivery_note",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Writes the document in pdf_pending and publishes the event the generator subscribes to. The dispatch must be posted; a posted dispatch already has one requested for it.
| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
| document_type | string (StockDispatchDocumentType) Value: "delivery_note" One artefact today, the rendered delivery note. |
| _id required | string |
| _class required | string |
| stock_dispatch_id required | string |
| document_type required | string (StockDispatchDocumentType) Value: "delivery_note" One artefact today, the rendered delivery note. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF; |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "document_type": "delivery_note"
}{- "_id": "sddoc_a1b2c3d4e5f6789012345",
- "_class": "stock_dispatch_document",
- "stock_dispatch_id": "sdp_a1b2c3d4e5f6",
- "document_type": "delivery_note",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
| stock_dispatch_document_id required | string Example: sddoc_a1b2c3d4e5f6789012345 |
| _id required | string |
| _class required | string |
| stock_dispatch_id required | string |
| document_type required | string (StockDispatchDocumentType) Value: "delivery_note" One artefact today, the rendered delivery note. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF; |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "_id": "sddoc_a1b2c3d4e5f6789012345",
- "_class": "stock_dispatch_document",
- "stock_dispatch_id": "sdp_a1b2c3d4e5f6",
- "document_type": "delivery_note",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Setting file on a pdf_pending document moves it to pdf_ready. Idempotent: replaying on an already-attached document returns the PDF it already has. Setting status to pdf_pending re-requests the render of a failed document.
| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
| stock_dispatch_document_id required | string Example: sddoc_a1b2c3d4e5f6789012345 |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
| status | string Value: "pdf_pending" |
| _id required | string |
| _class required | string |
| stock_dispatch_id required | string |
| document_type required | string (StockDispatchDocumentType) Value: "delivery_note" One artefact today, the rendered delivery note. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF; |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "file": {
- "_id": "prod_fd74a5ce31b6"
}, - "status": "pdf_pending"
}{- "_id": "sddoc_a1b2c3d4e5f6789012345",
- "_class": "stock_dispatch_document",
- "stock_dispatch_id": "sdp_a1b2c3d4e5f6",
- "document_type": "delivery_note",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
| stock_dispatch_document_id required | string Example: sddoc_a1b2c3d4e5f6789012345 |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
| status | string Value: "pdf_pending" |
| _id required | string |
| _class required | string |
| stock_dispatch_id required | string |
| document_type required | string (StockDispatchDocumentType) Value: "delivery_note" One artefact today, the rendered delivery note. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF; |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "file": {
- "_id": "prod_fd74a5ce31b6"
}, - "status": "pdf_pending"
}{- "_id": "sddoc_a1b2c3d4e5f6789012345",
- "_class": "stock_dispatch_document",
- "stock_dispatch_id": "sdp_a1b2c3d4e5f6",
- "document_type": "delivery_note",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| stock_dispatch_id required | string Example: sdp_a1b2c3d4e5f6 |
| stock_dispatch_document_id required | string Example: sddoc_a1b2c3d4e5f6789012345 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}One timeline across the three applied stock documents. Capped at 200 rows; truncated says when the filters should narrow. counts gives the rows per kind after the location, date and search filters so a kind filter chip can show its count.
| kind | string (StockDocumentKind) Enum: "stock_receipt" "stock_count" "stock_dispatch" |
| stock_location_id | string |
| from | string <date> ISO date, inclusive, on |
| to | string <date> ISO date, inclusive, on |
| q | string Matches the dispatch number, the receipt reference, the recipient and the customer document number. |
required | Array of objects (StockDocumentRow) |
required | object (StockDocumentCounts) Rows per kind after the location, date and search filters, before the kind filter. |
| truncated required | boolean More than 200 rows matched; narrow the filters. |
{- "items": [
- {
- "_id": "string",
- "_class": "stock_receipt",
- "_name": "string",
- "number": "string",
- "counterparty": "string",
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "effective_at": 0,
- "created_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "line_count": 0,
- "units": 0,
- "value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "_links": {
- "self": "string"
}
}
], - "counts": {
- "stock_receipt": 0,
- "stock_count": 0,
- "stock_dispatch": 0
}, - "truncated": true
}Sorted for the overview page: negative available first, then rows at
or below their reorder point by shortfall, then the rest by product
and location name. Capped at 2,000 rows (stats.truncated) — narrow
by location past that. committed is what accepted offers still
claim per product, attributed to the level at the default location.
| stock_location_id | string |
| low_only | boolean |
required | Array of objects (StockSummaryRow) |
required | object (StockSummaryStats) |
{- "items": [
- {
- "_id": "prd_abc.stl_xyz",
- "_class": "stock_level",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "on_hand": 0,
- "reserved": 0,
- "available": 0,
- "average_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reorder_point": 0,
- "stocking_unit_of_measure": "string",
- "last_counted_at": 0,
- "last_count": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "committed": 0
}
], - "stats": {
- "total_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "mixed_currencies": true,
- "low_stock_count": 0,
- "committed_units": 0,
- "truncated": true
}
}Array of objects (StockLevelResponse) | |
object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
{- "items": [
- {
- "_id": "prd_abc.stl_xyz",
- "_class": "stock_level",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "on_hand": 0,
- "reserved": 0,
- "available": 0,
- "average_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reorder_point": 0,
- "stocking_unit_of_measure": "string",
- "last_counted_at": 0,
- "last_count": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "total_value": {
- "amount": 12.5,
- "currency": "EUR"
}
}| stock_location_id | string |
Array of objects (StockLevelResponse) |
{- "items": [
- {
- "_id": "prd_abc.stl_xyz",
- "_class": "stock_level",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "on_hand": 0,
- "reserved": 0,
- "available": 0,
- "average_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "stock_value": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reorder_point": 0,
- "stocking_unit_of_measure": "string",
- "last_counted_at": 0,
- "last_count": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
]
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (StockMovementResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "stm_a1b2c3d4e5f6",
- "_class": "stock_movement",
- "_name": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "stock_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "counterparty_location": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "movement_type": "opening",
- "quantity_delta": 0,
- "unit_cost": {
- "amount": 12.5,
- "currency": "EUR"
}, - "value_delta": {
- "amount": 12.5,
- "currency": "EUR"
}, - "average_cost_after": {
- "amount": 12.5,
- "currency": "EUR"
}, - "balance_after": 0,
- "reason": "string",
- "dedupe_key": "string",
- "effective_at": 0,
- "source_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "document_line_item_id": "string",
- "stock_document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string"
}| invoice_id required | string |
required | Array of objects (PaymentCollection) |
| total required | integer |
| page required | integer |
| page_size required | integer |
{- "items": [
- {
- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "total": 0,
- "page": 0,
- "page_size": 0
}Starts a collection on one of the tenant's rails and returns whatever the buyer needs in order to pay. The money settles into the tenant's own merchant account — Raccoon never holds it — and is booked against this invoice as an ordinary payment when the rail confirms.
Rejected with 422 when the rail is switched off, not offered in the tenant's country, or has no credentials yet.
| invoice_id required | string |
| rail_id required | string |
object (MonetaryAmount) Optional — defaults to the invoice's open balance. Must be in the invoice's own currency, which makes a mismatch structurally unreachable rather than a 422 the buyer meets holding their phone. | |
| phone_number | string <= 20 characters Where to push the request, for a rail that asks a phone rather than
showing a code — required for such a rail, ignored by the rest. A
Kenyan number is accepted in any form a tenant types it ( |
| dedupe_key | string [ 1 .. 64 ] characters Optional. A second write with the same key within the tenant does not create a second row. The collection already started is returned unchanged; the rail is asked once. |
| stub_behaviour | string Enum: "succeed" "pending" "fail" Drives the stub adapter through a state a real rail would take minutes to reach. Ignored once a rail has a real adapter. |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| rail_id required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| reference required | string What the buyer's payment will actually carry back, and — on a rail that
cannot confirm itself — the only thing tying the money to this invoice
when it lands. A rail that mints a structured reference (an ISO 11649
|
| status required | string Enum: "pending" "succeeded" "failed" "expired" "cancelled"
|
required | object What the buyer needs in order to pay — |
| provider_reference required | string or null The rail's own receipt, once it has one. |
| stub_behaviour required | string or null |
| expires_at required | integer or null |
| settled_at required | integer or null |
| failure_reason required | string or null |
required | Reference (object) or null The payment this collection booked, once it settled. |
| dedupe_key required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
{- "rail_id": "girocode",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "phone_number": "0712345678",
- "dedupe_key": "string",
- "stub_behaviour": "succeed"
}{- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}| invoice_id required | string |
| collection_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| rail_id required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| reference required | string What the buyer's payment will actually carry back, and — on a rail that
cannot confirm itself — the only thing tying the money to this invoice
when it lands. A rail that mints a structured reference (an ISO 11649
|
| status required | string Enum: "pending" "succeeded" "failed" "expired" "cancelled"
|
required | object What the buyer needs in order to pay — |
| provider_reference required | string or null The rail's own receipt, once it has one. |
| stub_behaviour required | string or null |
| expires_at required | integer or null |
| settled_at required | integer or null |
| failure_reason required | string or null |
required | Reference (object) or null The payment this collection booked, once it settled. |
| dedupe_key required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
{- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}The buyer walked away, or chose another rail. A settled collection cannot be cancelled — the money is already booked.
| invoice_id required | string |
| collection_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| rail_id required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| reference required | string What the buyer's payment will actually carry back, and — on a rail that
cannot confirm itself — the only thing tying the money to this invoice
when it lands. A rail that mints a structured reference (an ISO 11649
|
| status required | string Enum: "pending" "succeeded" "failed" "expired" "cancelled"
|
required | object What the buyer needs in order to pay — |
| provider_reference required | string or null The rail's own receipt, once it has one. |
| stub_behaviour required | string or null |
| expires_at required | integer or null |
| settled_at required | integer or null |
| failure_reason required | string or null |
required | Reference (object) or null The payment this collection booked, once it settled. |
| dedupe_key required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
{- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}Books the money through the ordinary allocation path, so the invoice gets a payment exactly as if a human had recorded it.
Gated to service identities and superusers only — deliberately stricter than its sibling routes, because a forged settlement is money rather than provenance. Repeated delivery is expected on every rail researched and books once.
| invoice_id required | string |
| collection_id required | string |
| provider_reference required | string The rail's own receipt (an M-Pesa code, a Pix txid). |
object (MonetaryAmount) Optional — defaults to what the collection asked for. |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| rail_id required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| reference required | string What the buyer's payment will actually carry back, and — on a rail that
cannot confirm itself — the only thing tying the money to this invoice
when it lands. A rail that mints a structured reference (an ISO 11649
|
| status required | string Enum: "pending" "succeeded" "failed" "expired" "cancelled"
|
required | object What the buyer needs in order to pay — |
| provider_reference required | string or null The rail's own receipt, once it has one. |
| stub_behaviour required | string or null |
| expires_at required | integer or null |
| settled_at required | integer or null |
| failure_reason required | string or null |
required | Reference (object) or null The payment this collection booked, once it settled. |
| dedupe_key required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
{- "provider_reference": "string",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}{- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}Completes the instruction on a collection whose rail had to ask a
provider for it. A rail whose adapter runs in process fills this in
before the start request returns and is refused here; a remote one
leaves the collection at state: requesting until its worker reports
back through this route.
Send failure_reason instead of a payload when the provider refused
the request, so the collection closes rather than waiting for a code
that is never coming. One of the two is required: a body carrying
neither is a 422, because it would leave the collection waiting with
an empty artefact and no reason given.
Gated to service identities and superusers only, for the same reason as its sibling: this writes what a buyer is shown, so a forged instruction is a code pointing at somebody else's account.
| invoice_id required | string |
| collection_id required | string |
| payload | string <= 4096 characters The rail's own artefact — for PayPal, the approval link the QR encodes. |
object What the screen shows beside the code, rendered as given. | |
| expires_in_seconds | integer or null [ 1 .. 86400 ] How long the artefact is good for, when the provider says. |
| failure_reason | string or null <= 500 characters Sent instead of a payload when the provider refused. Closes the collection rather than leaving it waiting for a code. |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| rail_id required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| reference required | string What the buyer's payment will actually carry back, and — on a rail that
cannot confirm itself — the only thing tying the money to this invoice
when it lands. A rail that mints a structured reference (an ISO 11649
|
| status required | string Enum: "pending" "succeeded" "failed" "expired" "cancelled"
|
required | object What the buyer needs in order to pay — |
| provider_reference required | string or null The rail's own receipt, once it has one. |
| stub_behaviour required | string or null |
| expires_at required | integer or null |
| settled_at required | integer or null |
| failure_reason required | string or null |
required | Reference (object) or null The payment this collection booked, once it settled. |
| dedupe_key required | string or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
{- "payload": "string",
- "display": {
- "property1": "string",
- "property2": "string"
}, - "expires_in_seconds": 1,
- "failure_reason": "string"
}{- "_id": "pcl_9f2c1a4b7e05",
- "_class": "string",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "rail_id": "mpesa_push",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reference": "string",
- "status": "pending",
- "instruction": {
- "property1": "string",
- "property2": "string"
}, - "provider_reference": "string",
- "stub_behaviour": "string",
- "expires_at": 0,
- "settled_at": 0,
- "failure_reason": "string",
- "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "dedupe_key": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| status | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| payment_status | string Enum: "unpaid" "partially_paid" "paid" Filter on the settlement axis. Independent of |
| business_partner_id | string |
| type_id | string |
| offer_id | string Only the invoices raised from this offer. One offer can produce several invoices, so this is how they are listed — the offer keeps no list of its own. |
| q | string non-empty Full-text search term. When provided, the endpoint delegates to the
shared search index (matches across name/title/email/identifier
fields, tenant-scoped) and returns the matching entities in the
same response shape as the unfiltered list. Pagination ( |
required | Array of objects (InvoiceResponse) |
| next_token required | string or null |
{- "items": [
- {
- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
ReferenceValue (object) or null Issuing Company (EN 16931 BG-7 Seller). Auto-resolved from the tenant's invoice-company config when omitted on create. Per the no-bare-id rule (architecture.md#Embedded References) the wire shape is the full Reference object. | |
Reference (object) or null Optional tenant-defined sales channel selected for this invoice. Snapshotted on the invoice. | |
| issue_date | string or null <date> |
| due_date | string or null <date> |
| tax_point_date | string or null <date> EN 16931 BT-7 — value-added-tax point date. |
| actual_delivery_date | string or null <date> EN 16931 BT-72 — actual delivery date. |
| document_type_code | string or null Enum: "380" "381" "384" "386" "326" null EN 16931 BT-3 (UNCL 1001). 380=commercial invoice, 381=credit note, 384=corrected invoice, 386=prepayment invoice, 326=partial invoice. |
| currency | string or null = 3 characters |
| buyer_reference | string or null EN 16931 BT-10. Often the buyer's PO number or Leitweg-ID. |
| purchase_order_reference | string or null EN 16931 BT-13. |
| contract_reference | string or null EN 16931 BT-12. |
| project_reference | string or null EN 16931 BT-11. |
| subject | string or null What the invoice is about, printed as its subject line. |
InvoicePeriod (object) or null | |
InvoiceBillingReference (object) or null | |
| buyer_name | string or null EN 16931 BT-44 — buyer name. Defaults to the partner's company/full name. |
| buyer_legal_registration_id | string or null EN 16931 BT-47. |
| buyer_identifier | string or null EN 16931 BT-46 — party identifier (GLN, DUNS, etc.). |
| buyer_customer_number | string or null The buyer's customer number with the seller (DIN 5008 Kundennummer). Defaults to the business partner's. |
| buyer_vat_id | string or null EN 16931 BT-48. |
| buyer_vat_id_type | string or null EN 16931 VAT scheme of |
InvoicePartyContact (object) or null | |
InvoiceElectronicAddress (object) or null | |
InvoicePayee (object) or null | |
| payment_means_code | string or null EN 16931 BT-81 (UNCL 4461). Defaults from tenant config. |
| payment_terms_text | string or null EN 16931 BT-20. |
InvoicePaymentTerms (object) or null Structured skonto / late-payment block. Additive to BT-20
| |
| remittance_information | string or null EN 16931 BT-83 — payment reference / Verwendungszweck. |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings Default: [] EN 16931 BT-22 — invoice notes (0..n). Each entry is rendered as its own paragraph below the totals. The author handles translation; the renderer prints what is supplied. |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| type_id | string [ 1 .. 100 ] characters The invoice-class tenant type this invoice is created under. Every invoice has one. It decides the letterhead, the numbering and the payment defaults. Omitted, the invoice is created under the tenant's default invoice type; that is a 422 when the tenant has several and marks none of them default. |
| schema_version | string or null |
object Default: {} | |
object Optional. When omitted, the server snapshots the partner's preferred
addresses for each slot declared by the invoice type. When supplied,
the slot keys must be a subset of the invoice type's |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "tax_point_date": "2019-08-24",
- "actual_delivery_date": "2019-08-24",
- "document_type_code": "380",
- "currency": "EUR",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "preceding_invoice": {
- "preceding_invoice_number": "string",
- "preceding_invoice_issue_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_means_code": "string",
- "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [ ],
- "vat_aggregation": "horizontal",
- "type_id": "standard_invoice",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}{"status": "finalized"} issues the invoice: it refreshes the seller
snapshot, re-rates VAT at the time of supply, stamps the number from
the tenant's numbering schema in the same atomic write, and hands the
PDF off to the document generator. A finalize carries no other field
changes — save the edits first — and only a draft can be finalized.
paid is refused: an invoice becomes paid by recording a payment
against it.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
Reference (object) or null | |
ReferenceValue (object) or null Re-pick the issuing Company. Validated against the tenant's per-doc-type allowed list. Only editable while the invoice is in draft. Per the no-bare-id rule the wire shape is the full Reference object. | |
Reference (object) or null Re-pick the sales channel, or null to clear. Only editable while the invoice is in draft. | |
| issue_date | string <date> |
| due_date | string <date> |
| dunning_level | integer >= 0 Dunning escalation level (0 = none, 1..N = reminder ladder step). |
| tax_point_date | string <date> |
| actual_delivery_date | string <date> |
| document_type_code | string Enum: "380" "381" "384" "386" "326" |
| currency | string = 3 characters |
| buyer_reference | string |
| purchase_order_reference | string |
| contract_reference | string |
| project_reference | string |
| subject | string or null |
object (InvoicePeriod) Invoice-level invoicing period (EN 16931 BG-14). | |
object (InvoiceBillingReference) Preceding-invoice reference (EN 16931 BG-3 / BT-25 / BT-26). | |
| buyer_name | string |
| buyer_legal_registration_id | string |
| buyer_identifier | string |
| buyer_customer_number | string or null |
| buyer_vat_id | string |
| buyer_vat_id_type | string EN 16931 VAT scheme of |
object (InvoicePartyContact) Contact group (EN 16931 BG-6 / BG-9). | |
object (InvoiceElectronicAddress) Electronic address (EN 16931 BT-34 / BT-49). | |
object (InvoicePayee) Third-party payee (EN 16931 BG-10). Populated only when the party receiving payment differs from the seller (e.g. factoring). | |
| payment_means_code | string |
| payment_terms_text | string |
InvoicePaymentTerms (object) or null | |
| remittance_information | string |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings or null Replaces the persisted list. |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| status | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| type_id | string or null |
| schema_version | string or null |
object | |
object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2019-08-24",
- "due_date": "2019-08-24",
- "dunning_level": 0,
- "tax_point_date": "2019-08-24",
- "actual_delivery_date": "2019-08-24",
- "document_type_code": "380",
- "currency": "str",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "preceding_invoice": {
- "preceding_invoice_number": "string",
- "preceding_invoice_issue_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_means_code": "string",
- "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [
- "string"
], - "vat_aggregation": "horizontal",
- "status": "draft",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}{"status": "finalized"} issues the invoice: it refreshes the seller
snapshot, re-rates VAT at the time of supply, stamps the number from
the tenant's numbering schema in the same atomic write, and hands the
PDF off to the document generator. A finalize carries no other field
changes — save the edits first — and only a draft can be finalized.
paid is refused: an invoice becomes paid by recording a payment
against it.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
Reference (object) or null | |
ReferenceValue (object) or null Re-pick the issuing Company. Validated against the tenant's per-doc-type allowed list. Only editable while the invoice is in draft. Per the no-bare-id rule the wire shape is the full Reference object. | |
Reference (object) or null Re-pick the sales channel, or null to clear. Only editable while the invoice is in draft. | |
| issue_date | string <date> |
| due_date | string <date> |
| dunning_level | integer >= 0 Dunning escalation level (0 = none, 1..N = reminder ladder step). |
| tax_point_date | string <date> |
| actual_delivery_date | string <date> |
| document_type_code | string Enum: "380" "381" "384" "386" "326" |
| currency | string = 3 characters |
| buyer_reference | string |
| purchase_order_reference | string |
| contract_reference | string |
| project_reference | string |
| subject | string or null |
object (InvoicePeriod) Invoice-level invoicing period (EN 16931 BG-14). | |
object (InvoiceBillingReference) Preceding-invoice reference (EN 16931 BG-3 / BT-25 / BT-26). | |
| buyer_name | string |
| buyer_legal_registration_id | string |
| buyer_identifier | string |
| buyer_customer_number | string or null |
| buyer_vat_id | string |
| buyer_vat_id_type | string EN 16931 VAT scheme of |
object (InvoicePartyContact) Contact group (EN 16931 BG-6 / BG-9). | |
object (InvoiceElectronicAddress) Electronic address (EN 16931 BT-34 / BT-49). | |
object (InvoicePayee) Third-party payee (EN 16931 BG-10). Populated only when the party receiving payment differs from the seller (e.g. factoring). | |
| payment_means_code | string |
| payment_terms_text | string |
InvoicePaymentTerms (object) or null | |
| remittance_information | string |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings or null Replaces the persisted list. |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| status | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| type_id | string or null |
| schema_version | string or null |
object | |
object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2019-08-24",
- "due_date": "2019-08-24",
- "dunning_level": 0,
- "tax_point_date": "2019-08-24",
- "actual_delivery_date": "2019-08-24",
- "document_type_code": "380",
- "currency": "str",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "preceding_invoice": {
- "preceding_invoice_number": "string",
- "preceding_invoice_issue_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_means_code": "string",
- "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [
- "string"
], - "vat_aggregation": "horizontal",
- "status": "draft",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}A finalized invoice carrying live payment allocations returns 409. Void the allocations first, then cancel it.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}The callback half of clearance. In Kenya, Nigeria, India and Brazil the
tax authority must mint an artefact — an IRN, control number,
cryptographic stamp or QR — before the document is a valid invoice at
all, and Nigeria's turnaround is measured in hours. So the call to
the authority never happens in a request: finalize hands off, a
per-country worker service does the talking, and the answer arrives
here, exactly as the VAT-ID validator reports an identifier
validation.
Called by a worker holding a service identity, not by a user.
status is never touched by this endpoint. Clearance lives on its own
axis so a clearance worker and the dunning worker are not two writers
on one field.
Cleared is terminal. A repeated cleared returns the unchanged
invoice; a rejected after a cleared is a 409. At-least-once
delivery must not let message ordering decide whether an invoice is
valid.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| status required | string Enum: "cleared" "rejected" |
| scheme | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which regime is reporting, as a code — never an authority name and never a display label. Optional on the wire so an adapter written against the original callback contract keeps working, and immutable once recorded: a result naming a different regime than the one already on the invoice is refused with 409 rather than applied, because which regime cleared a document is a fact about the document and two regimes claiming one invoice is a routing bug upstream. |
| reference | string or null |
| stamp | string or null |
| qr | string or null |
| error | string or null Why the authority refused. Expected whenever |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "status": "cleared",
- "scheme": "ke_kra_etims",
- "reference": "IRN-2026-000123",
- "stamp": "string",
- "qr": "string",
- "error": "string"
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}One row per send attempt per channel, newest first — the answer to "has this invoice gone out, where to, and when".
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
required | Array of objects (CorrespondenceResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Sending creates a correspondence row: two sends are two rows, which is why this is a creation and not a status change on the invoice.
The send itself is performed by an event-driven worker, so a 202
means "accepted for sending", not "sent" — poll
GET /resource/v1/invoices/{invoice_id}/correspondence (or the row's
_links.self) until status leaves queued.
The invoice must have left draft (it needs its number and frozen
seller snapshot), and the business partner must have an email
address — the one flagged for invoicing, else the primary one, else
the only one. The invoice's own status is unchanged by a send;
correspondence rows are the record of what went out.
Sending an invoice that already went out sends it again and creates a
second row. The only 409 is a send still in flight: while a row on
the same channel is queued, a repeat is the same send twice, not a
second one.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| channel required | string (CorrespondenceChannel) Value: "email" Channel a document is sent over. |
| acknowledge_uncleared | boolean Default: false Send even though the invoice has not been cleared by the tax authority.
Staying compliant is the tenant's own legal responsibility, so an
uncleared send is warned about (409 with |
{- "channel": "email",
- "acknowledge_uncleared": false
}{- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}The row's own _links.self. Poll it while status is queued to learn whether the send succeeded.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| correspondence_id required | string Example: cor_a1b2c3d4e5f6789012345 |
| _id required | string |
| _class required | string |
required | object (Reference) The document this message is about — an invoice or an offer. |
| channel required | string (CorrespondenceChannel) Value: "email" Channel a document is sent over. |
| purpose required | string (CorrespondencePurpose) Enum: "invoice" "reminder" "offer" What went out. |
| status required | string (CorrespondenceStatus) Enum: "queued" "sent" "failed" Lifecycle state. A send starts at |
| recipient required | string Resolved destination for this channel — for |
| message required | string or null The approved reminder text sent in the body, for a |
required | Reference (object) or null The PDF file that actually went out. |
required | Reference (object) or null The stored outbound message. Null until the worker links it, including the interval after message creation but before linking. Once linked, it remains available whether sending succeeds or fails. |
| sent_at required | integer or null Unix seconds the channel accepted the message; |
| failure_reason required | string or null Channel error code for a |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object
|
required | ReferenceValue (object) or null |
{- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Replaces the invoice's address snapshots with the current preferred
(primary) addresses from the linked business partner, for every slot
declared on the invoice type. The frontend calls this after the user
confirms a "Update addresses to {new partner}'s defaults?" prompt
triggered by a business-partner change. Only allowed while the invoice
is in draft.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}The same rows the invoice itself returns in line_items, at the URL
the invoice advertises as _links.line_items. Unpaginated —
next_token is always null — because a line array is bounded by what
fits on one invoice.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
required | Array of objects (InvoiceLineItemResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "next_token": "string"
}Sub-resource sugar over the parent invoice update: the invoice's
totals and VAT breakdown are recomputed and one DynamoDB item is
written, as if the whole line_items array had been sent.
Draft only. An invoice that has been finalized or cancelled answers 422 — an issued invoice is the legal record and its content is frozen.
The line is new by definition, so a body carrying _id is a 422 —
the server assigns line ids. To change an existing line, address its
own URL.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| description required | string non-empty |
required | number or string (Decimal) |
| _id | string The id of a line already on this invoice, when the intent is to edit
that line rather than add one. Omit it to add a line — the server
assigns the id. An |
(Decimal (Decimal (number) or Decimal (string))) or null Optional. Filled by the resolver when | |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null Which tax band this line falls in. Omit it — the default — to
inherit the product's category, then the tenant's
The rate itself is never accepted on input — it is always derived from the band, the countries involved and the date. Which bands a country has varies, so a client offering them as a choice should read the effective set for the buyer's country rather than assume a fixed list. |
Reference (object) or null Reference to the catalog product whose price should be applied to
this line. When set without an explicit | |
| unit_code | string or null [ 1 .. 3 ] characters ^[A-Za-z0-9]{1,3}$ UN/ECE Recommendation 20 unit of measure (EN 16931 BT-130). Omit it
to get |
InvoiceItemClassification (object) or null |
| _id required | string |
| _class required | string Value: "line_item" |
required | object
|
| description required | string |
required | number or string (Decimal) |
required | number or string (Decimal) |
| tax_mode required | string Enum: "net" "gross" Whether |
| vat_regime required | string Enum: "domestic_vat" "intra_eu_reverse_charge" "intra_eu_oss" "intra_eu_origin_b2c" "third_country_export" "destination_sales_tax" "exempt" The VAT regime the resolver picked at issue time. Snapshotted — a historical invoice keeps the treatment that applied when it was issued, even after the countries involved change bloc membership. |
| vat_country required | string or null = 2 characters ISO 3166-1 alpha-2 country whose VAT regime applied. |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category resolved for this line. |
| vat_category_source required | string Enum: "line" "product" "tenant_default" Where the category came from — a deliberate per-line choice, the product's default, or the tenant's. Recorded so an audit can tell a chosen band from an inherited one without re-deriving anything. |
required | number or string (Decimal) |
| vat_legal_note required | string or null Localised note the invoice must print for this regime (e.g. the reverse-charge or export wording), in the tenant's language with English as the fallback. Null when the regime needs no note. |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | Reference (object) or null Back-link to the catalog product the line was priced from, when applicable. |
| resolved_price_id required | string or null Id of the ProductPrice row the resolver chose, when the line was priced by
the multi-dimension resolver. Always null in single-price mode and
when the caller supplied an explicit |
| unit_code required | string [ 1 .. 3 ] characters ^[A-Z0-9]{1,3}$ UN/ECE Rec 20 unit of measure (BT-130). Never null — a line with no
unit is not exportable, so the default |
| unit_label required | string
Empty for |
required | InvoiceItemClassification (object) or null |
| seller_item_identifier required | string or null The seller's own article number (BT-155), snapshotted from the
product's |
required | InvoiceStandardItemIdentifier (object) or null Snapshotted from the product's |
required | Array of objects (PrintedIdentifier) The numbers this line prints beside its description, snapshotted from
the product's primary identifiers when the line was written. Which
ones print is the product type's decision ( |
{- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}{- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}A line is an object with an id, so it answers at its own URL — the one
every line carries as _links.self. 404 when this invoice does not
hold that line, including when it belongs to another invoice.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| line_item_id required | string Example: li_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string Value: "line_item" |
required | object
|
| description required | string |
required | number or string (Decimal) |
required | number or string (Decimal) |
| tax_mode required | string Enum: "net" "gross" Whether |
| vat_regime required | string Enum: "domestic_vat" "intra_eu_reverse_charge" "intra_eu_oss" "intra_eu_origin_b2c" "third_country_export" "destination_sales_tax" "exempt" The VAT regime the resolver picked at issue time. Snapshotted — a historical invoice keeps the treatment that applied when it was issued, even after the countries involved change bloc membership. |
| vat_country required | string or null = 2 characters ISO 3166-1 alpha-2 country whose VAT regime applied. |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category resolved for this line. |
| vat_category_source required | string Enum: "line" "product" "tenant_default" Where the category came from — a deliberate per-line choice, the product's default, or the tenant's. Recorded so an audit can tell a chosen band from an inherited one without re-deriving anything. |
required | number or string (Decimal) |
| vat_legal_note required | string or null Localised note the invoice must print for this regime (e.g. the reverse-charge or export wording), in the tenant's language with English as the fallback. Null when the regime needs no note. |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | Reference (object) or null Back-link to the catalog product the line was priced from, when applicable. |
| resolved_price_id required | string or null Id of the ProductPrice row the resolver chose, when the line was priced by
the multi-dimension resolver. Always null in single-price mode and
when the caller supplied an explicit |
| unit_code required | string [ 1 .. 3 ] characters ^[A-Z0-9]{1,3}$ UN/ECE Rec 20 unit of measure (BT-130). Never null — a line with no
unit is not exportable, so the default |
| unit_label required | string
Empty for |
required | InvoiceItemClassification (object) or null |
| seller_item_identifier required | string or null The seller's own article number (BT-155), snapshotted from the
product's |
required | InvoiceStandardItemIdentifier (object) or null Snapshotted from the product's |
required | Array of objects (PrintedIdentifier) The numbers this line prints beside its description, snapshotted from
the product's primary identifiers when the line was written. Which
ones print is the product type's decision ( |
{- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}Full replace: the body is the new content of the line, and the line id
stays with it across the swap so the URL survives. A body _id that
disagrees with the URL is a 422 rather than being silently overridden.
A PUT restates the line, so an explicit unit_price is read as net
unless the line names a product — the same reading a create gets. Use
PATCH to edit a gross-quoted line without restating its basis.
Draft only; see POST.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| line_item_id required | string Example: li_a1b2c3d4e5f6 |
| description required | string non-empty |
required | number or string (Decimal) |
| _id | string The id of a line already on this invoice, when the intent is to edit
that line rather than add one. Omit it to add a line — the server
assigns the id. An |
(Decimal (Decimal (number) or Decimal (string))) or null Optional. Filled by the resolver when | |
| vat_category | string or null Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" null Which tax band this line falls in. Omit it — the default — to
inherit the product's category, then the tenant's
The rate itself is never accepted on input — it is always derived from the band, the countries involved and the date. Which bands a country has varies, so a client offering them as a choice should read the effective set for the buyer's country rather than assume a fixed list. |
Reference (object) or null Reference to the catalog product whose price should be applied to
this line. When set without an explicit | |
| unit_code | string or null [ 1 .. 3 ] characters ^[A-Za-z0-9]{1,3}$ UN/ECE Recommendation 20 unit of measure (EN 16931 BT-130). Omit it
to get |
InvoiceItemClassification (object) or null |
| _id required | string |
| _class required | string Value: "line_item" |
required | object
|
| description required | string |
required | number or string (Decimal) |
required | number or string (Decimal) |
| tax_mode required | string Enum: "net" "gross" Whether |
| vat_regime required | string Enum: "domestic_vat" "intra_eu_reverse_charge" "intra_eu_oss" "intra_eu_origin_b2c" "third_country_export" "destination_sales_tax" "exempt" The VAT regime the resolver picked at issue time. Snapshotted — a historical invoice keeps the treatment that applied when it was issued, even after the countries involved change bloc membership. |
| vat_country required | string or null = 2 characters ISO 3166-1 alpha-2 country whose VAT regime applied. |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category resolved for this line. |
| vat_category_source required | string Enum: "line" "product" "tenant_default" Where the category came from — a deliberate per-line choice, the product's default, or the tenant's. Recorded so an audit can tell a chosen band from an inherited one without re-deriving anything. |
required | number or string (Decimal) |
| vat_legal_note required | string or null Localised note the invoice must print for this regime (e.g. the reverse-charge or export wording), in the tenant's language with English as the fallback. Null when the regime needs no note. |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | Reference (object) or null Back-link to the catalog product the line was priced from, when applicable. |
| resolved_price_id required | string or null Id of the ProductPrice row the resolver chose, when the line was priced by
the multi-dimension resolver. Always null in single-price mode and
when the caller supplied an explicit |
| unit_code required | string [ 1 .. 3 ] characters ^[A-Z0-9]{1,3}$ UN/ECE Rec 20 unit of measure (BT-130). Never null — a line with no
unit is not exportable, so the default |
| unit_label required | string
Empty for |
required | InvoiceItemClassification (object) or null |
| seller_item_identifier required | string or null The seller's own article number (BT-155), snapshotted from the
product's |
required | InvoiceStandardItemIdentifier (object) or null Snapshotted from the product's |
required | Array of objects (PrintedIdentifier) The numbers this line prints beside its description, snapshotted from
the product's primary identifiers when the line was written. Which
ones print is the product type's decision ( |
{- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}{- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}Body is an arbitrary subset of InvoiceLineItemCreate fields. The service
overlays the patch onto the stored line, re-validates the result and
rebuilds the line, then recomputes the invoice's totals and VAT
breakdown. A body _id that disagrees with the URL is a 422.
The line keeps the tax basis it was quoted in: patching the quantity of a gross-quoted line does not re-read its price as net.
Draft only; see POST.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| line_item_id required | string Example: li_a1b2c3d4e5f6 |
| property name* additional property | any |
| _id required | string |
| _class required | string Value: "line_item" |
required | object
|
| description required | string |
required | number or string (Decimal) |
required | number or string (Decimal) |
| tax_mode required | string Enum: "net" "gross" Whether |
| vat_regime required | string Enum: "domestic_vat" "intra_eu_reverse_charge" "intra_eu_oss" "intra_eu_origin_b2c" "third_country_export" "destination_sales_tax" "exempt" The VAT regime the resolver picked at issue time. Snapshotted — a historical invoice keeps the treatment that applied when it was issued, even after the countries involved change bloc membership. |
| vat_country required | string or null = 2 characters ISO 3166-1 alpha-2 country whose VAT regime applied. |
| vat_category required | string Enum: "H" "S" "R" "R2" "T" "Z" "EXEMPT" ONIX List 62 VAT category resolved for this line. |
| vat_category_source required | string Enum: "line" "product" "tenant_default" Where the category came from — a deliberate per-line choice, the product's default, or the tenant's. Recorded so an audit can tell a chosen band from an inherited one without re-deriving anything. |
required | number or string (Decimal) |
| vat_legal_note required | string or null Localised note the invoice must print for this regime (e.g. the reverse-charge or export wording), in the tenant's language with English as the fallback. Null when the regime needs no note. |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | number or string (Decimal) |
required | Reference (object) or null Back-link to the catalog product the line was priced from, when applicable. |
| resolved_price_id required | string or null Id of the ProductPrice row the resolver chose, when the line was priced by
the multi-dimension resolver. Always null in single-price mode and
when the caller supplied an explicit |
| unit_code required | string [ 1 .. 3 ] characters ^[A-Z0-9]{1,3}$ UN/ECE Rec 20 unit of measure (BT-130). Never null — a line with no
unit is not exportable, so the default |
| unit_label required | string
Empty for |
required | InvoiceItemClassification (object) or null |
| seller_item_identifier required | string or null The seller's own article number (BT-155), snapshotted from the
product's |
required | InvoiceStandardItemIdentifier (object) or null Snapshotted from the product's |
required | Array of objects (PrintedIdentifier) The numbers this line prints beside its description, snapshotted from
the product's primary identifiers when the line was written. Which
ones print is the product type's decision ( |
{ }{- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}Recomputes the invoice's totals and VAT breakdown. Draft only; see POST.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| line_item_id required | string Example: li_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| status | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" |
| business_partner_id | string |
| type_id | string |
required | Array of objects (OfferResponse) |
| next_token required | string or null |
{- "items": [
- {
- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "off_a1b2c3d4e5f6",
- "_class": "offer",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "currency": "EUR",
- "line_items": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "_id": "li_c4e4c8320982",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "language": "de",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "offer_number": "AN-2026-0001",
- "valid_until": "2019-08-24",
- "supersedes": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "accepted_at": 0,
- "rejected_at": 0
}
], - "next_token": "string"
}required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
ReferenceValue (object) or null Issuing Company (EN 16931 BG-7 Seller). Auto-resolved from the tenant's invoice-company config when omitted on create. Per the no-bare-id rule (architecture.md#Embedded References) the wire shape is the full Reference object. | |
Reference (object) or null Optional tenant-defined sales channel selected for this offer. Snapshotted on the offer. | |
| issue_date | string or null <date> |
| currency | string or null = 3 characters |
| buyer_reference | string or null EN 16931 BT-10. Often the buyer's PO number or Leitweg-ID. |
| purchase_order_reference | string or null EN 16931 BT-13. |
| contract_reference | string or null EN 16931 BT-12. |
| project_reference | string or null EN 16931 BT-11. |
| subject | string or null What the offer is about, printed as its subject line. |
InvoicePeriod (object) or null | |
| buyer_name | string or null EN 16931 BT-44 — buyer name. Defaults to the partner's company/full name. |
| buyer_legal_registration_id | string or null EN 16931 BT-47. |
| buyer_identifier | string or null EN 16931 BT-46 — party identifier (GLN, DUNS, etc.). |
| buyer_customer_number | string or null The buyer's customer number with the seller (DIN 5008 Kundennummer). Defaults to the business partner's. |
| buyer_vat_id | string or null EN 16931 BT-48. |
| buyer_vat_id_type | string or null EN 16931 VAT scheme of |
InvoicePartyContact (object) or null | |
InvoiceElectronicAddress (object) or null | |
InvoicePayee (object) or null | |
| payment_terms_text | string or null EN 16931 BT-20. |
InvoicePaymentTerms (object) or null Structured skonto / late-payment block. Additive to BT-20
| |
| remittance_information | string or null EN 16931 BT-83 — payment reference / Verwendungszweck. |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings Default: [] EN 16931 BT-22 — invoice notes (0..n). Each entry is rendered as its own paragraph below the totals. The author handles translation; the renderer prints what is supplied. |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| type_id | string [ 1 .. 100 ] characters The offer-class tenant type this offer is created under. Every offer has one. It decides the letterhead and the payment defaults. Omitted, the offer is created under the tenant's default offer type; that is a 422 when the tenant has several and marks none of them default. |
| schema_version | string or null |
object Default: {} | |
object Optional. When omitted, the server snapshots the partner's preferred
addresses for each slot declared by the offer type. When supplied,
the slot keys must be a subset of the offer type's | |
| valid_until | string <date> Last day the quoted price stands. Defaults to issue_date + the tenant's offer.default_validity_days. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the offer number, or id while still a draft). |
required | object
|
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" |
| issue_date required | string <date> |
| currency required | string |
required | Array of objects (OfferLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| language required | string The language the offer is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the offer leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 notes (0..n), printed on the offer. |
| type_id required | string The tenant type this offer was created under. |
required | object |
required | object Snapshotted address per slot the offer type declared. Slot
keys are a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| offer_number required | string Empty ("") until the offer is finalized. Offer numbers are not gap-free. |
| valid_until required | string or null <date> |
required | Reference (object) or null The offer this one replaces, when it is a revision. |
| accepted_at required | integer or null Unix seconds. |
| rejected_at required | integer or null Unix seconds. |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...), stored on the record itself. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this offer, null if none. | |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2026-05-01",
- "currency": "EUR",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [ ],
- "vat_aggregation": "horizontal",
- "type_id": "standard_offer",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}, - "valid_until": "2019-08-24"
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "off_a1b2c3d4e5f6",
- "_class": "offer",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "currency": "EUR",
- "line_items": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "_id": "li_c4e4c8320982",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "language": "de",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "offer_number": "AN-2026-0001",
- "valid_until": "2019-08-24",
- "supersedes": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "accepted_at": 0,
- "rejected_at": 0
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
required | Array of objects (OfferDocumentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "odoc_a1b2c3d4e5f6789012345",
- "_class": "offer_document",
- "offer_id": "off_a1b2c3d4e5f6",
- "document_type": "offer",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Writes the document in pdf_pending and publishes the event the generator subscribes to. The offer must have been finalized: a draft has no number, and a document with no number on it is not one to put in front of a customer.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
| document_type | string (OfferDocumentType) Value: "offer" The kind of document. One today: the rendered offer PDF. It is an enum rather than a free string so a second artefact arrives as a deliberate change rather than by a caller inventing a value. |
| _id required | string |
| _class required | string |
| offer_id required | string |
| document_type required | string (OfferDocumentType) Value: "offer" The kind of document. One today: the rendered offer PDF. It is an enum rather than a free string so a second artefact arrives as a deliberate change rather than by a caller inventing a value. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "document_type": "offer"
}{- "_id": "odoc_a1b2c3d4e5f6789012345",
- "_class": "offer_document",
- "offer_id": "off_a1b2c3d4e5f6",
- "document_type": "offer",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
| offer_document_id required | string Example: odoc_a1b2c3d4e5f6789012345 |
| _id required | string |
| _class required | string |
| offer_id required | string |
| document_type required | string (OfferDocumentType) Value: "offer" The kind of document. One today: the rendered offer PDF. It is an enum rather than a free string so a second artefact arrives as a deliberate change rather than by a caller inventing a value. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "_id": "odoc_a1b2c3d4e5f6789012345",
- "_class": "offer_document",
- "offer_id": "off_a1b2c3d4e5f6",
- "document_type": "offer",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Setting file on a pdf_pending document moves it to pdf_ready. Idempotent: replaying on an already-attached document returns the PDF it already has. Setting status to pdf_pending re-requests the render of a failed document.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
| offer_document_id required | string Example: odoc_a1b2c3d4e5f6789012345 |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
| status | string Value: "pdf_pending" Set to |
| _id required | string |
| _class required | string |
| offer_id required | string |
| document_type required | string (OfferDocumentType) Value: "offer" The kind of document. One today: the rendered offer PDF. It is an enum rather than a free string so a second artefact arrives as a deliberate change rather than by a caller inventing a value. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "file": {
- "_id": "prod_fd74a5ce31b6"
}, - "status": "pdf_pending"
}{- "_id": "odoc_a1b2c3d4e5f6789012345",
- "_class": "offer_document",
- "offer_id": "off_a1b2c3d4e5f6",
- "document_type": "offer",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
| offer_document_id required | string Example: odoc_a1b2c3d4e5f6789012345 |
object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only | |
| status | string Value: "pdf_pending" Set to |
| _id required | string |
| _class required | string |
| offer_id required | string |
| document_type required | string (OfferDocumentType) Value: "offer" The kind of document. One today: the rendered offer PDF. It is an enum rather than a free string so a second artefact arrives as a deliberate change rather than by a caller inventing a value. |
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "file": {
- "_id": "prod_fd74a5ce31b6"
}, - "status": "pdf_pending"
}{- "_id": "odoc_a1b2c3d4e5f6789012345",
- "_class": "offer_document",
- "offer_id": "off_a1b2c3d4e5f6",
- "document_type": "offer",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
| offer_document_id required | string Example: odoc_a1b2c3d4e5f6789012345 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}One row per send attempt per channel, newest first — the answer to "has this offer gone out, where to, and when".
| offer_id required | string Example: off_a1b2c3d4e5f6 |
required | Array of objects (CorrespondenceResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}The same sub-resource the invoice has, mounted on the offer: sending creates a correspondence row, so two sends are two rows.
The send itself is performed by an event-driven worker, so a 202
means "accepted for sending", not "sent" — poll
GET /resource/v1/offers/{offer_id}/correspondence (or the row's
_links.self) until status leaves queued.
The offer must have left draft (it needs its number and frozen
seller snapshot), and the business partner must have an email
address. The offer's own status is unchanged by a send — the rows
are the record of what went out, which is also what tells a reopened
offer whether it was ever sent.
The only 409 is a send still in flight: while a row on the same
channel is queued, a repeat is the same send twice, not a second
one.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
| channel required | string (CorrespondenceChannel) Value: "email" Channel a document is sent over. |
| acknowledge_uncleared | boolean Default: false Send even though the invoice has not been cleared by the tax authority.
Staying compliant is the tenant's own legal responsibility, so an
uncleared send is warned about (409 with |
{- "channel": "email",
- "acknowledge_uncleared": false
}{- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}The row's own _links.self. Poll it while status is queued to learn whether the send succeeded.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
| correspondence_id required | string Example: cor_a1b2c3d4e5f6789012345 |
| _id required | string |
| _class required | string |
required | object (Reference) The document this message is about — an invoice or an offer. |
| channel required | string (CorrespondenceChannel) Value: "email" Channel a document is sent over. |
| purpose required | string (CorrespondencePurpose) Enum: "invoice" "reminder" "offer" What went out. |
| status required | string (CorrespondenceStatus) Enum: "queued" "sent" "failed" Lifecycle state. A send starts at |
| recipient required | string Resolved destination for this channel — for |
| message required | string or null The approved reminder text sent in the body, for a |
required | Reference (object) or null The PDF file that actually went out. |
required | Reference (object) or null The stored outbound message. Null until the worker links it, including the interval after message creation but before linking. Once linked, it remains available whether sending succeeds or fails. |
| sent_at required | integer or null Unix seconds the channel accepted the message; |
| failure_reason required | string or null Channel error code for a |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object
|
required | ReferenceValue (object) or null |
{- "_id": "cor_a1b2c3d4e5f6789012345",
- "_class": "correspondence",
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "channel": "email",
- "purpose": "invoice",
- "status": "queued",
- "recipient": "billing@example.com",
- "attachment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "email_message": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "sent_at": 0,
- "failure_reason": "string",
- "message": "string",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Accepting and invoicing are two acts: accepting is a status change and creates nothing, and the production or fulfilment flow sits between the two. One offer routinely becomes several invoices — a deposit and a final, or one per milestone — or none at all, so this may be called more than once and the offer is never mutated. The prices and terms the customer accepted are copied over exactly. VAT is re-rated at creation against the invoice date and the buyer, so a rate that has moved or a VAT-ID validated since the offer was written is reflected on the invoice.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
| line_item_ids | Array of strings Bill only these positions. Omitted, the whole offer is billed. |
| type_id | string Raise the invoice under this invoice type. Omitted, the tenant's default invoice type is used. Must be a type of entity class |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the invoice number, or id while still a draft). |
required | object
|
| invoice_number required | string Empty ( |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "paid" "overdue" "cancelled" |
| issue_date required | string <date> |
| due_date required | string <date> |
| document_type_code required | string Enum: "380" "381" "384" "386" "326" |
| currency required | string |
required | Reference (object) or null The offer this invoice was raised from, null if none. One offer can produce several invoices — a deposit and a final, or one per milestone — so the link lives here and never as a list on the offer. |
| payment_means_code required | string |
required | Array of objects (InvoiceLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
| payment_status required | string Enum: "unpaid" "partially_paid" "paid" How much of the invoice has been settled — a second axis, derived from the recorded allocations and never accepted on input. It is deliberately separate from |
required | object (MonetaryAmount) Cash received against this invoice — the sum of its non-voided allocations. Backend-computed. Always carries the invoice currency, even at zero. |
required | object (MonetaryAmount) The part of the invoice its payments deliberately did not cover — withholding tax the customer remitted on the seller's behalf, an early-payment discount, bank charges. Backend-computed from the allocations' typed deductions. |
required | object (MonetaryAmount)
|
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| clearance_status required | string Enum: "not_required" "pending" "cleared" "rejected" Whether the tax authority has cleared this invoice — the third
axis, beside In a clearance market (Kenya, Nigeria, India, Brazil) the document is
not a valid invoice until the authority mints its artefact, so
Deliberately not a sixth |
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null Which fiscal-clearance regime engaged, as a code —
Null whenever Read-only, and written only by a clearance adapter through
|
| clearance_reference required | string or null The identity the authority minted — Nigeria's IRN, Kenya's Control Unit Invoice Number, India's IRN. Null until cleared. |
| clearance_stamp required | string or null Cryptographic signature where the authority issues one (Nigeria's CSID). Null where the regime issues none, and until cleared. |
| clearance_qr required | string or null QR payload the human-readable document must carry. Null until cleared. |
| cleared_at required | integer or null Unix seconds at which clearance was recorded. Null until cleared. |
| clearance_error required | string or null Why the authority refused, when |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the invoice totals. |
| language required | string The language the invoice is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the invoice leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 invoice notes (0..n). |
| type_id required | string The tenant type this invoice was created under. |
required | object |
required | object Snapshotted address per slot the invoice type declared. Slot keys are
a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this invoice, null if none. | |
| dunning_level | integer Dunning escalation level (0 = none, 1..N = reminder ladder step). |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "line_item_ids": [
- "string"
], - "type_id": "standard_invoice"
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "inv_a1b2c3d4e5f6",
- "_class": "invoice",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "documents": "string",
- "line_items": "string",
- "property1": "string",
- "property2": "string"
}, - "invoice_number": "2026-R-0042",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "offer": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "due_date": "2026-05-31",
- "dunning_level": 0,
- "document_type_code": "380",
- "currency": "EUR",
- "payment_means_code": "30",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "_class": "line_item",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "payment_status": "unpaid",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_version": 0,
- "clearance_status": "not_required",
- "language": "de",
- "clearance_scheme": "ke_kra_etims",
- "clearance_reference": "IRN-2026-000123",
- "clearance_stamp": "string",
- "clearance_qr": "string",
- "cleared_at": 0,
- "clearance_error": "string",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the offer number, or id while still a draft). |
required | object
|
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" |
| issue_date required | string <date> |
| currency required | string |
required | Array of objects (OfferLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| language required | string The language the offer is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the offer leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 notes (0..n), printed on the offer. |
| type_id required | string The tenant type this offer was created under. |
required | object |
required | object Snapshotted address per slot the offer type declared. Slot
keys are a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| offer_number required | string Empty ("") until the offer is finalized. Offer numbers are not gap-free. |
| valid_until required | string or null <date> |
required | Reference (object) or null The offer this one replaces, when it is a revision. |
| accepted_at required | integer or null Unix seconds. |
| rejected_at required | integer or null Unix seconds. |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...), stored on the record itself. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this offer, null if none. | |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "off_a1b2c3d4e5f6",
- "_class": "offer",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "currency": "EUR",
- "line_items": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "_id": "li_c4e4c8320982",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "language": "de",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "offer_number": "AN-2026-0001",
- "valid_until": "2019-08-24",
- "supersedes": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "accepted_at": 0,
- "rejected_at": 0
}Fields may be changed only while the offer is a draft — once finalized, the customer holds that document. Moving the status to finalized stamps the offer number in the same write, and asks for the offer PDF: the document row is created afterwards and rendered in the background, so it is not on the response and a failure there does not undo the finalize. sent only records that the finalized offer went out. rejected back to sent reopens a declined offer: it keeps the number and the document and only clears rejected_at.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
Reference (object) or null | |
ReferenceValue (object) or null Re-pick the issuing Company. Validated against the tenant's per-doc-type allowed list. Only editable while the offer is in draft. Per the no-bare-id rule the wire shape is the full Reference object. | |
Reference (object) or null Re-pick the sales channel, or null to clear. Only editable while the offer is in draft. | |
| issue_date | string <date> |
| currency | string = 3 characters |
| buyer_reference | string |
| purchase_order_reference | string |
| contract_reference | string |
| project_reference | string |
| subject | string or null |
object (InvoicePeriod) Invoice-level invoicing period (EN 16931 BG-14). | |
| buyer_name | string |
| buyer_legal_registration_id | string |
| buyer_identifier | string |
| buyer_customer_number | string or null |
| buyer_vat_id | string |
| buyer_vat_id_type | string EN 16931 VAT scheme of |
object (InvoicePartyContact) Contact group (EN 16931 BG-6 / BG-9). | |
object (InvoiceElectronicAddress) Electronic address (EN 16931 BT-34 / BT-49). | |
object (InvoicePayee) Third-party payee (EN 16931 BG-10). Populated only when the party receiving payment differs from the seller (e.g. factoring). | |
| payment_terms_text | string |
InvoicePaymentTerms (object) or null | |
| remittance_information | string |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings or null Replaces the persisted list. |
| status | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" Moving to |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| type_id | string or null |
| schema_version | string or null |
object | |
object | |
| valid_until | string <date> Last day the quoted price stands. Defaults to issue_date + the tenant's offer.default_validity_days. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the offer number, or id while still a draft). |
required | object
|
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" |
| issue_date required | string <date> |
| currency required | string |
required | Array of objects (OfferLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| language required | string The language the offer is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the offer leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 notes (0..n), printed on the offer. |
| type_id required | string The tenant type this offer was created under. |
required | object |
required | object Snapshotted address per slot the offer type declared. Slot
keys are a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| offer_number required | string Empty ("") until the offer is finalized. Offer numbers are not gap-free. |
| valid_until required | string or null <date> |
required | Reference (object) or null The offer this one replaces, when it is a revision. |
| accepted_at required | integer or null Unix seconds. |
| rejected_at required | integer or null Unix seconds. |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...), stored on the record itself. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this offer, null if none. | |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2019-08-24",
- "currency": "str",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [
- "string"
], - "status": "draft",
- "vat_aggregation": "horizontal",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}, - "valid_until": "2019-08-24"
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "off_a1b2c3d4e5f6",
- "_class": "offer",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "currency": "EUR",
- "line_items": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "_id": "li_c4e4c8320982",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "language": "de",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "offer_number": "AN-2026-0001",
- "valid_until": "2019-08-24",
- "supersedes": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "accepted_at": 0,
- "rejected_at": 0
}| offer_id required | string Example: off_a1b2c3d4e5f6 |
Reference (object) or null | |
ReferenceValue (object) or null Re-pick the issuing Company. Validated against the tenant's per-doc-type allowed list. Only editable while the offer is in draft. Per the no-bare-id rule the wire shape is the full Reference object. | |
Reference (object) or null Re-pick the sales channel, or null to clear. Only editable while the offer is in draft. | |
| issue_date | string <date> |
| currency | string = 3 characters |
| buyer_reference | string |
| purchase_order_reference | string |
| contract_reference | string |
| project_reference | string |
| subject | string or null |
object (InvoicePeriod) Invoice-level invoicing period (EN 16931 BG-14). | |
| buyer_name | string |
| buyer_legal_registration_id | string |
| buyer_identifier | string |
| buyer_customer_number | string or null |
| buyer_vat_id | string |
| buyer_vat_id_type | string EN 16931 VAT scheme of |
object (InvoicePartyContact) Contact group (EN 16931 BG-6 / BG-9). | |
object (InvoiceElectronicAddress) Electronic address (EN 16931 BT-34 / BT-49). | |
object (InvoicePayee) Third-party payee (EN 16931 BG-10). Populated only when the party receiving payment differs from the seller (e.g. factoring). | |
| payment_terms_text | string |
InvoicePaymentTerms (object) or null | |
| remittance_information | string |
Array of objects (InvoiceLineItemCreate) | |
| notes | Array of strings or null Replaces the persisted list. |
| status | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" Moving to |
| vat_aggregation | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| type_id | string or null |
| schema_version | string or null |
object | |
object | |
| valid_until | string <date> Last day the quoted price stands. Defaults to issue_date + the tenant's offer.default_validity_days. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label (the offer number, or id while still a draft). |
required | object
|
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| status required | string Enum: "draft" "finalized" "sent" "accepted" "rejected" "expired" "superseded" |
| issue_date required | string <date> |
| currency required | string |
required | Array of objects (OfferLineItemResponse) |
required | object (MonetaryAmount) EN 16931 BT-109 — sum of line nets, as a |
required | object (MonetaryAmount) EN 16931 BT-110. |
required | object (MonetaryAmount) EN 16931 BT-112. BT-115 (payable_amount) equals this until prepaid / rounding ships. |
required | Array of objects (InvoiceVatBreakdownLine) Per-VAT-rate breakdown (UStG §14). Server-computed by
|
| vat_aggregation required | string Enum: "horizontal" "vertical" How per-line VAT rolls up into the offer totals. |
| language required | string The language the offer is written in. Snapshotted from the business partner when the draft is created, refreshed on every draft save and frozen once the offer leaves draft; falls back to the tenant's default language when the partner has none. Always present. Read-only: it is not accepted on input. |
| notes required | Array of strings EN 16931 BT-22 notes (0..n), printed on the offer. |
| type_id required | string The tenant type this offer was created under. |
required | object |
required | object Snapshotted address per slot the offer type declared. Slot
keys are a subset of the type's |
| created_at required | integer |
| updated_at required | integer |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (ReferenceValue) Stored value for a field of type "reference" |
| offer_number required | string Empty ("") until the offer is finalized. Offer numbers are not gap-free. |
| valid_until required | string or null <date> |
required | Reference (object) or null The offer this one replaces, when it is a revision. |
| accepted_at required | integer or null Unix seconds. |
| rejected_at required | integer or null Unix seconds. |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...), stored on the record itself. |
ReferenceValue (object) or null Issuing Company (BG-7 Seller). Snapshotted onto the immutable
| |
Reference (object) or null Sales channel selected for this offer, null if none. | |
InvoicePaymentTerms (object) or null Structured BT-20 sub-block. |
{- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6"
}, - "issue_date": "2019-08-24",
- "currency": "str",
- "buyer_reference": "string",
- "purchase_order_reference": "string",
- "contract_reference": "string",
- "project_reference": "string",
- "subject": "string",
- "invoicing_period": {
- "start_date": "2019-08-24",
- "end_date": "2019-08-24"
}, - "buyer_name": "string",
- "buyer_legal_registration_id": "string",
- "buyer_identifier": "string",
- "buyer_customer_number": "string",
- "buyer_vat_id": "string",
- "buyer_vat_id_type": "string",
- "buyer_contact": {
- "name": "string",
- "phone": "string",
- "email": "string"
}, - "buyer_electronic_address": {
- "value": "string",
- "scheme_id": "string"
}, - "payee": {
- "name": "string",
- "identifier": "string",
- "legal_registration_id": "string"
}, - "payment_terms_text": "string",
- "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "remittance_information": "string",
- "line_items": [
- {
- "_id": "li_a1b2c3d4e5f6",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "vat_category": "H",
- "product": {
- "_id": "prod_fd74a5ce31b6"
}, - "unit_code": "HUR",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}
}
], - "notes": [
- "string"
], - "status": "draft",
- "vat_aggregation": "horizontal",
- "type_id": "string",
- "schema_version": "string",
- "data": { },
- "addresses": {
- "property1": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}, - "property2": {
- "source_address_id": "addr_a1b2c3",
- "street_line_1": "Musterstraße 1",
- "street_line_2": "string",
- "city": "Berlin",
- "state_province": "string",
- "postal_code": "string",
- "country_code": "DE"
}
}, - "valid_until": "2019-08-24"
}{- "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "off_a1b2c3d4e5f6",
- "_class": "offer",
- "_name": "Acme Corp",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "company": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "channel": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "draft",
- "issue_date": "2026-05-01",
- "currency": "EUR",
- "line_items": [
- {
- "item_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "_id": "li_c4e4c8320982",
- "description": "Consulting services",
- "quantity": 0,
- "unit_price": 0,
- "tax_mode": "net",
- "vat_regime": "domestic_vat",
- "vat_country": "st",
- "vat_category": "H",
- "vat_category_source": "line",
- "vat_rate_percent": 0,
- "vat_legal_note": "string",
- "unit_price_net": 0,
- "tax_amount": 0,
- "line_total": 0,
- "unit_code": "HUR",
- "unit_label": "h",
- "item_classification": {
- "code": "190590",
- "scheme_id": "HS"
}, - "seller_item_identifier": "SD-100",
- "standard_item_identifier": {
- "value": "4006381333931",
- "scheme_id": "0160"
}, - "product": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resolved_price_id": "string"
}
], - "tax_exclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_total": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "language": "de",
- "vat_breakdown": [
- {
- "rate": 0,
- "taxable_amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "vat_amount": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "vat_aggregation": "horizontal",
- "notes": [
- "string"
], - "payment_terms": {
- "skonto_percent": 0,
- "skonto_days": 0,
- "late_payment_notice": "string"
}, - "type_id": "string",
- "data": { },
- "addresses": {
- "property1": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}, - "property2": {
- "street_line_1": "string",
- "city": "string",
- "country_code": "st"
}
}, - "created_at": 1746144000,
- "updated_at": 1746144000,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "offer_number": "AN-2026-0001",
- "valid_until": "2019-08-24",
- "supersedes": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "accepted_at": 0,
- "rejected_at": 0
}Only a draft. A finalized offer is a document the customer holds — reject it or let it expire, which keeps the record of what was quoted.
| offer_id required | string Example: off_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}Voided allocations are included: they are kept as history and shown struck through, not filtered out.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
required | Array of objects (InvoicePaymentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "ipay_a1b2c3d4e5f6",
- "_class": "invoice_payment",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_deducted": 0,
- "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "is_voided": true,
- "voided_at": 0,
- "void_reason": "string",
- "dedupe_key": "string",
- "invoice_number": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "next_token": "string"
}This is what marks an invoice paid — PATCH {status: "paid"} is rejected. Supply payment to apply an existing payment, or new_payment to record and allocate in one transaction. Where the customer withheld tax or took a discount, pass the shortfall in deductions and the invoice still settles.
Rejections: invoice_payment.invoice_not_finalized (draft), invoice_payment.invoice_cancelled, invoice_payment.currency_mismatch, invoice_payment.exceeds_payment_remainder, invoice_payment.exceeds_open_balance — the excess deliberately stays unallocated on the payment as credit on account.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
required | Reference (object) or null Reference to an existing payment. Mutually exclusive with |
object or null | |
object (MonetaryAmountInput) Cash to apply. Omit to settle as much of the open balance as the payment's remainder covers, which is what the record-payment dialog wants. May not exceed either the invoice's | |
Array of objects (PaymentDeduction) Parts of the invoice this payment deliberately did not cover. The invoice settles on | |
| dedupe_key | string or null [ 1 .. 128 ] characters Optional. A second write with the same key within the tenant does not create a second row. The allocation already recorded is returned unchanged. |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (MonetaryAmount) The cash applied — what the bank actually credited. |
| amount_deducted required | number Sum of this allocation's deductions, as a bare number in the invoice's currency (the figure is only meaningful alongside |
required | Array of objects (PaymentDeduction) |
| is_voided required | boolean Voided allocations are kept, not deleted, so "who un-paid this invoice, and why" stays answerable. They are excluded from every balance and are shown struck through. |
| voided_at required | integer or null Unix epoch seconds |
| void_reason required | string or null |
| dedupe_key required | string or null |
| invoice_number required | string The invoice's number as it stood when the money was applied. It
duplicates Empty on rows written before this field existed; those fall back to reading the invoice. |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
required | object (InvoiceTotalsAfterAllocation) The invoice figures as recomputed by this write, echoed so no caller needs a follow-up GET — the record-payment dialog needs the new status and open balance the moment it closes. |
{- "payment": {
- "_id": "prod_fd74a5ce31b6"
}, - "new_payment": {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "QGH7K3MNOP",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "notes": "string",
- "dedupe_key": "string"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "dedupe_key": "string"
}{- "_id": "ipay_a1b2c3d4e5f6",
- "_class": "invoice_payment",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_deducted": 0,
- "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "is_voided": true,
- "voided_at": 0,
- "void_reason": "string",
- "dedupe_key": "string",
- "invoice_number": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "invoice_totals": {
- "payment_status": "unpaid",
- "status": "draft",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}
}
}Soft-void: the row is kept and excluded from every balance, so the audit trail survives. The invoice's balance walks back and its status reopens to finalized or overdue as its due date dictates. Deliberately not blocked on a dunned invoice — the commonest reason to unallocate is a payment matched to the wrong invoice, which is exactly the one that stopped being chased.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| invoice_payment_id required | string Example: ipay_a1b2c3d4e5f6 |
| void_reason | string or null Why the allocation was reversed. Recorded on the audit trail. |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (MonetaryAmount) The cash applied — what the bank actually credited. |
| amount_deducted required | number Sum of this allocation's deductions, as a bare number in the invoice's currency (the figure is only meaningful alongside |
required | Array of objects (PaymentDeduction) |
| is_voided required | boolean Voided allocations are kept, not deleted, so "who un-paid this invoice, and why" stays answerable. They are excluded from every balance and are shown struck through. |
| voided_at required | integer or null Unix epoch seconds |
| void_reason required | string or null |
| dedupe_key required | string or null |
| invoice_number required | string The invoice's number as it stood when the money was applied. It
duplicates Empty on rows written before this field existed; those fall back to reading the invoice. |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object |
required | object (InvoiceTotalsAfterAllocation) The invoice figures as recomputed by this write, echoed so no caller needs a follow-up GET — the record-payment dialog needs the new status and open balance the moment it closes. |
{- "void_reason": "string"
}{- "_id": "ipay_a1b2c3d4e5f6",
- "_class": "invoice_payment",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_deducted": 0,
- "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "is_voided": true,
- "voided_at": 0,
- "void_reason": "string",
- "dedupe_key": "string",
- "invoice_number": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "invoice_totals": {
- "payment_status": "unpaid",
- "status": "draft",
- "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_written_off": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}
}
}The payment's own view of its allocations, which is what the allocation screen needs. Voided rows are included.
| payment_id required | string Example: pay_a1b2c3d4e5f6 |
required | Array of objects (InvoicePaymentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "ipay_a1b2c3d4e5f6",
- "_class": "invoice_payment",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_deducted": 0,
- "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "is_voided": true,
- "voided_at": 0,
- "void_reason": "string",
- "dedupe_key": "string",
- "invoice_number": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "next_token": "string"
}Settles up to 50 invoices from one payment. Each row is its own transaction, applied in the order given, so the remainder is consumed top-down and one row's failure never rolls back the rows that succeeded.
Answers 200 even when some rows failed — results[] carries a per-row verdict with a machine-readable error_code, and allocated_count / failed_count say how the batch went. A 4xx over the whole request would deny allocations that really happened.
Request-level rejections (422): invoice_payment.no_allocations, invoice_payment.too_many_allocations.
| payment_id required | string Example: pay_a1b2c3d4e5f6 |
required | Array of objects (BulkAllocationRow) [ 1 .. 50 ] items |
required | Array of objects (BulkAllocationResult) |
| allocated_count required | integer |
| failed_count required | integer |
required | object (PaymentResponse) The payment with its recomputed |
{- "allocations": [
- {
- "invoice": {
- "_id": "prod_fd74a5ce31b6"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "dedupe_key": "string"
}
]
}{- "results": [
- {
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "is_allocated": true,
- "allocation": {
- "_id": "ipay_a1b2c3d4e5f6",
- "_class": "invoice_payment",
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_deducted": 0,
- "deductions": [
- {
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "reason": "early_payment_discount",
- "certificate_reference": "KRA-WHT-2026-00123",
- "note": "string"
}
], - "is_voided": true,
- "voided_at": 0,
- "void_reason": "string",
- "dedupe_key": "string",
- "invoice_number": "string",
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}, - "error_code": "string",
- "message": "string"
}
], - "allocated_count": 0,
- "failed_count": 0,
- "payment": {
- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
}Every invoice with an open balance that can still receive money — non-draft, non-cancelled — oldest due date first, with the payment's own currency first. Invoices in another currency are returned flagged rather than dropped: allocation refuses them, but an invoice the tenant can see in the invoice list must not vanish here unexplained.
| payment_id required | string Example: pay_a1b2c3d4e5f6 |
| business_partner_id | string Restrict candidates to one customer's invoices. |
required | Array of objects (AllocationCandidate) |
| next_token required | string or null Always null — the open set is returned in one read. |
| truncated required | boolean True when the tenant has more open invoices than one read returns. A capped list presented as complete is how money gets allocated against a picture that is missing invoices, so the cap is stated rather than implied. |
{- "items": [
- {
- "invoice": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "finalized",
- "due_date": "2019-08-24",
- "is_overdue": true,
- "currency": "EUR",
- "currency_matches": true,
- "tax_inclusive": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_paid": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_due": {
- "amount": 12.5,
- "currency": "EUR"
}
}
], - "next_token": "string",
- "truncated": true
}Newest first by paid_at. Filters are applied after the page is read, so a page can come back short while next_token is still set — keep following the token until it is null.
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| business_partner_id | string Only payments from this payer. |
| allocation_state | string (AllocationState) Enum: "unallocated" "partially_allocated" "allocated" Only payments in this allocation state. |
| method | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at_from | string <date> Inclusive lower bound on |
| paid_at_to | string <date> Inclusive upper bound on |
| reference | string Exact-match payment reference. Used to warn about a double-recorded payment; references are not unique, so this can legitimately return more than one row. |
| q | string non-empty Full-text search term. When provided, the endpoint delegates to the
shared search index (matches across name/title/email/identifier
fields, tenant-scoped) and returns the matching entities in the
same response shape as the unfiltered list. Pagination ( |
required | Array of objects (PaymentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "next_token": "string"
}Records money that arrived. It does not mark any invoice paid — allocate the payment to an invoice separately. Supplying dedupe_key makes the create idempotent: a repeat returns the payment already recorded rather than recording the money twice.
required | object (MonetaryAmountInput) The amount actually received, as it appears on the bank statement or payment confirmation. Must be greater than zero. Where the customer withheld tax, this is the net figure that arrived; the withheld part is recorded as a deduction on the allocation, not here. |
| method | string (PaymentMethod) Default: "bank_transfer" Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at | string <date> Date the money was received. Defaults to today (UTC). |
| reference | string or null <= 200 characters The reference the payer's rail produced — an M-Pesa confirmation code, a UPI UTR, a Pix EndToEndId, a NIP session id, or a SEPA statement narrative. Free text: the formats share no structure across markets, so nothing is validated. Sized for the longest real value (the 140-character SEPA remittance field). |
Reference (object) or null Optional — who paid. A payment may exist with no payer set. | |
| notes | string or null |
| dedupe_key | string or null [ 1 .. 64 ] characters Optional. A second write with the same key within the tenant does not create a second row. The payment already recorded is returned unchanged. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Backend-composed label. A payment has no name field, so this is the amount plus the rail's own reference — recognisable in a picker or an approval card. Read the |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) Backend-computed total applied to invoices. Maintained by the allocation transaction; never accepted on input. |
required | object (MonetaryAmount) Backend-computed remainder ( |
| allocation_state required | string (AllocationState) Enum: "unallocated" "partially_allocated" "allocated" How much of the payment has been applied to invoices. |
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| method required | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at required | string <date> |
| reference required | string or null |
| notes required | string or null |
| dedupe_key required | string or null |
required | Reference (object) or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object
|
{- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "QGH7K3MNOP",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "notes": "string",
- "dedupe_key": "string"
}{- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}| payment_id required | string Example: pay_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Backend-composed label. A payment has no name field, so this is the amount plus the rail's own reference — recognisable in a picker or an approval card. Read the |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) Backend-computed total applied to invoices. Maintained by the allocation transaction; never accepted on input. |
required | object (MonetaryAmount) Backend-computed remainder ( |
| allocation_state required | string (AllocationState) Enum: "unallocated" "partially_allocated" "allocated" How much of the payment has been applied to invoices. |
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| method required | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at required | string <date> |
| reference required | string or null |
| notes required | string or null |
| dedupe_key required | string or null |
required | Reference (object) or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object
|
{- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}| payment_id required | string Example: pay_a1b2c3d4e5f6 |
object (MonetaryAmountInput) Request-side counterpart of Responses always carry | |
| method | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at | string <date> |
| reference | string or null <= 200 characters |
Reference (object) or null | |
| notes | string or null |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Backend-composed label. A payment has no name field, so this is the amount plus the rail's own reference — recognisable in a picker or an approval card. Read the |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) Backend-computed total applied to invoices. Maintained by the allocation transaction; never accepted on input. |
required | object (MonetaryAmount) Backend-computed remainder ( |
| allocation_state required | string (AllocationState) Enum: "unallocated" "partially_allocated" "allocated" How much of the payment has been applied to invoices. |
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| method required | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at required | string <date> |
| reference required | string or null |
| notes required | string or null |
| dedupe_key required | string or null |
required | Reference (object) or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object
|
{- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "notes": "string"
}{- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}Payments are correctable in place. Lowering amount below amount_allocated is rejected with 422 — unallocate first.
| payment_id required | string Example: pay_a1b2c3d4e5f6 |
object (MonetaryAmountInput) Request-side counterpart of Responses always carry | |
| method | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at | string <date> |
| reference | string or null <= 200 characters |
Reference (object) or null | |
| notes | string or null |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Backend-composed label. A payment has no name field, so this is the amount plus the rail's own reference — recognisable in a picker or an approval card. Read the |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
required | object (MonetaryAmount) Backend-computed total applied to invoices. Maintained by the allocation transaction; never accepted on input. |
required | object (MonetaryAmount) Backend-computed remainder ( |
| allocation_state required | string (AllocationState) Enum: "unallocated" "partially_allocated" "allocated" How much of the payment has been applied to invoices. |
| allocation_version required | integer Optimistic-lock counter for the allocation transaction. Read-only; exposed so a client can tell two allocation states apart. |
| method required | string (PaymentMethod) Enum: "bank_transfer" "bank_deposit" "cash" "card" "cheque" "mobile_money" "pix" "upi" "boleto" "other" How the money arrived. This is metadata about a payment that already happened — Raccoon does not process card, mobile-money, Pix, UPI or boleto transactions. |
| paid_at required | string <date> |
| reference required | string or null |
| notes required | string or null |
| dedupe_key required | string or null |
required | Reference (object) or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | object
|
{- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6"
}, - "notes": "string"
}{- "_id": "pay_a1b2c3d4e5f6",
- "_class": "payment",
- "_name": "Acme Corp",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_allocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "amount_unallocated": {
- "amount": 12.5,
- "currency": "EUR"
}, - "allocation_state": "unallocated",
- "allocation_version": 0,
- "method": "bank_transfer",
- "paid_at": "2019-08-24",
- "reference": "string",
- "notes": "string",
- "dedupe_key": "string",
- "business_partner": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}Only a payment with no live allocations can be deleted; one that is allocated to an invoice returns 409. Unallocate it first.
| payment_id required | string Example: pay_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| q | string Narrows the list to statements whose file name or uploader contains this term, in any case. It matches what the row shows and nothing else — status and counts are not free text. The whole set is read before the filter runs, so a term that matches nothing answers with an empty list, never a short page. |
required | Array of objects (BankStatement) |
| next_token required | string or null Pass back as |
{- "items": [
- {
- "_id": "bstm_9f2c1a4b7e05",
- "_class": "string",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "awaiting_file",
- "credits_seen": 0,
- "credits_matched": 0,
- "credits_unmatched": 0,
- "debits_seen": 0,
- "failure_reason": "string",
- "processed_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "next_token": "string"
}Opens an import and answers with where to upload the camt.053/054 file. The statement is created first, so a file can never sit in storage with nothing recording that it should be read — upload the bytes to the returned URL and there is nothing further to call.
Reading the file is a worker's job: a statement is megabytes of XML and one write per entry, which is not work a request should hold open.
Each credit is matched to an open payment collection by the structured reference it carries — never by payer name, amount or date, because a wrong automatic match moves money against the wrong invoice. A credit that matches nothing becomes an unallocated payment for a human to place.
| file_name required | string |
| file_size required | integer Size in bytes. Refused above the registered cap for a statement. |
| mime_type required | string |
| _id required | string |
| _class required | string |
required | Reference (object) or null Null only in the window between the statement being opened and its file row being created — a crash in between leaves a visible statement rather than an orphaned upload. |
| status required | string Enum: "awaiting_file" "in_progress" "finished" "failed"
Written only by the worker, through |
| credits_seen required | integer |
| credits_matched required | integer Credits that carried a reference matching an open collection. |
| credits_unmatched required | integer Credits recorded as unallocated payments. Money that arrived with nothing to point it at is not an error — it is what the payments list is for. |
| debits_seen required | integer Outgoing entries kept from this file. They are stored as a record and nothing else — never matched, never a payment — so they are counted separately rather than folded into the credit tallies. |
| failure_reason required | string or null |
| processed_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | object |
required | object (PresignedPost) S3 presigned-POST form. The client must POST |
{- "file_name": "august-2026.xml",
- "file_size": 248000,
- "mime_type": "application/xml"
}{- "_id": "bstm_9f2c1a4b7e05",
- "_class": "string",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "awaiting_file",
- "credits_seen": 0,
- "credits_matched": 0,
- "credits_unmatched": 0,
- "debits_seen": 0,
- "failure_reason": "string",
- "processed_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "upload": {
- "fields": {
- "property1": "string",
- "property2": "string"
}, - "expires_at": 0
}
}| bank_statement_id required | string |
| _id required | string |
| _class required | string |
required | Reference (object) or null Null only in the window between the statement being opened and its file row being created — a crash in between leaves a visible statement rather than an orphaned upload. |
| status required | string Enum: "awaiting_file" "in_progress" "finished" "failed"
Written only by the worker, through |
| credits_seen required | integer |
| credits_matched required | integer Credits that carried a reference matching an open collection. |
| credits_unmatched required | integer Credits recorded as unallocated payments. Money that arrived with nothing to point it at is not an error — it is what the payments list is for. |
| debits_seen required | integer Outgoing entries kept from this file. They are stored as a record and nothing else — never matched, never a payment — so they are counted separately rather than folded into the credit tallies. |
| failure_reason required | string or null |
| processed_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | object |
{- "_id": "bstm_9f2c1a4b7e05",
- "_class": "string",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "awaiting_file",
- "credits_seen": 0,
- "credits_matched": 0,
- "credits_unmatched": 0,
- "debits_seen": 0,
- "failure_reason": "string",
- "processed_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}The worker says it has picked the file up, and later that it is done. Service-gated for the same reason as the entries callback: a forged status tells a tenant their money has been looked at when it has not.
The only writer of status. The counts arrive through the entries
callback and describe what was read; they do not decide what the
import is doing.
| bank_statement_id required | string |
| status required | string Enum: "in_progress" "finished" "failed" |
| _id required | string |
| _class required | string |
required | Reference (object) or null Null only in the window between the statement being opened and its file row being created — a crash in between leaves a visible statement rather than an orphaned upload. |
| status required | string Enum: "awaiting_file" "in_progress" "finished" "failed"
Written only by the worker, through |
| credits_seen required | integer |
| credits_matched required | integer Credits that carried a reference matching an open collection. |
| credits_unmatched required | integer Credits recorded as unallocated payments. Money that arrived with nothing to point it at is not an error — it is what the payments list is for. |
| debits_seen required | integer Outgoing entries kept from this file. They are stored as a record and nothing else — never matched, never a payment — so they are counted separately rather than folded into the credit tallies. |
| failure_reason required | string or null |
| processed_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | object |
{- "status": "in_progress"
}{- "_id": "bstm_9f2c1a4b7e05",
- "_class": "string",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "status": "awaiting_file",
- "credits_seen": 0,
- "credits_matched": 0,
- "credits_unmatched": 0,
- "debits_seen": 0,
- "failure_reason": "string",
- "processed_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}The worker parses; this endpoint books. Gated to service identities and superusers only — a forged credit is money, so it is held to the tier a payment provider's callback uses.
Reporting the same credit twice books nothing twice: the bank's own reference for the entry is the idempotency key, which is what makes importing overlapping statements safe.
| bank_statement_id required | string |
Array of objects (BankTransactionCreate) | |
| failure_reason | string or null |
required | Array of objects |
{- "transactions": [
- {
- "bank_reference": "string",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "booked_on": "2019-08-24",
- "direction": "credit",
- "remittance_information": "string",
- "counterparty_name": "string"
}
], - "failure_reason": "string"
}{- "results": [
- {
- "bank_reference": "string",
- "status": "matched",
- "direction": "credit",
- "collection_id": "string",
- "payment_id": "string",
- "detail": "string"
}
]
}| status | string Value: "unmatched"
|
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string The |
| statement_id | string Only the entries one imported file contained. The statement's own counts say how many there were; this is how to see them. |
| direction | string Enum: "credit" "debit"
|
required | Array of objects (BankTransaction) |
| next_token required | string or null Pass back as |
{- "items": [
- {
- "_id": "string",
- "_class": "string",
- "bank_reference": "string",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "booked_on": "string",
- "direction": "credit",
- "status": "matched",
- "remittance_information": "string",
- "counterparty_name": "string",
- "invoices": [
- {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
], - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "statement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}
], - "next_token": "string"
}A transaction is addressed by its bank reference rather than by its own id: that is the key it is stored under, and the one anything holding a credit already knows.
| bank_reference required | string |
| _id required | string |
| _class required | string |
| bank_reference required | string |
required | object (MonetaryAmount) A monetary value with an ISO 4217 currency code.
Precision contract
Client-side parsingStandard JSON parsers convert JSON numbers to IEEE-754 floats, which lose precision for arithmetic on decimals that aren't power-of-10 fractions. Pick the right tool for the job:
Client-side encoding for sub-cent valuesA client that produces a sub-cent amount with
For everyday cent-precision values, sending a JSON number is fine. |
| booked_on required | string |
| direction required | string Enum: "credit" "debit" Money in or money out. A |
| status required | string Enum: "matched" "unmatched" |
| remittance_information required | string or null |
| counterparty_name required | string or null |
required | Reference (object) or null |
required | Array of objects (Reference) The invoices this entry's money currently sits against, resolved
from the live allocations rather than stored when the entry was
booked — so a payment re-allocated or split afterwards answers with
where the money is now. Each Empty for a debit — outgoing money is kept as a record and never matched to an invoice — and for a credit whose allocations have all been voided. |
required | Reference (object) or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer |
| updated_at required | integer |
required | Reference (object) or null |
required | object |
{- "_id": "string",
- "_class": "string",
- "bank_reference": "string",
- "amount": {
- "amount": 12.5,
- "currency": "EUR"
}, - "booked_on": "string",
- "direction": "credit",
- "status": "matched",
- "remittance_information": "string",
- "counterparty_name": "string",
- "invoices": [
- {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
], - "payment": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "statement": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}
}The outside services this tenant can plug into: the ways their customers can pay an invoice from their phone, and the tax authorities that clear an invoice before it is valid. Which appear is derived from the tenant's country at read time, so a corrected market list reaches every tenant without a migration.
Every payment rail settles into the tenant's own merchant account — Raccoon never holds the funds. Connectors are switched on and off through their own tenant-config key, not here.
| kind | string Enum: "payment_rail" "clearance" Only connectors of this kind. |
required | Array of objects (Connector) |
| total required | integer |
| page required | integer |
| page_size required | integer |
{- "items": [
- {
- "connector_id": "mpesa_push",
- "kind": "payment_rail",
- "display_name": "M-Pesa request on the phone",
- "shape": "push",
- "reconciliation": "callback",
- "clearance_scheme": "ke_kra_etims",
- "enabled": true,
- "configured": true,
- "available_in_country": true,
- "config_fields": [
- {
- "field_id": "consumer_key",
- "label": {
- "en": "Consumer key",
- "de": "Consumer Key"
}, - "secret": true,
- "required": true,
- "help_text": {
- "property1": "string",
- "property2": "string"
}
}
], - "requirements": [
- {
- "requirement_id": "mpesa_push.buyer_phone",
- "source": "invoice_field",
- "input_kind": "phone"
}
], - "description": "string"
}
], - "total": 0,
- "page": 0,
- "page_size": 0
}Answers for any registered connector, including one not offered in the
tenant's country — available_in_country carries that rather than the
endpoint 404-ing, so a tenant who moved gets an explanation.
| connector_id required | string Example: girocode |
| connector_id required | string |
| kind required | string Enum: "payment_rail" "clearance" What this connector connects to. |
| display_name required | string |
| shape required | string or null Enum: "push" "qr" "link" null How the buyer meets a payment rail. Null for other kinds. |
| reconciliation required | string or null Enum: "callback" "matched" null
|
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null The regime a |
| enabled required | boolean This connector's own enable key in the tenant's config. |
| configured required | boolean Whether anything is left for the tenant to do before this connector can be used: true once every required configuration field is on file. A connector with no required field — nothing to hand over — is configured by default. A missing IBAN and a missing API key are the same answer. |
| available_in_country required | boolean Whether the tenant's own country is one of the connector's default markets — where it is listed, defaults on, and shows a "configure" call-to-action. A soft default, not a usability gate: a payment rail switched on and configured can be collected on from any country (a clearance connector stays country-gated for legality). |
required | Array of objects (ConnectorField) What the tenant supplies to configure this connector — credentials, an IBAN. The configure screen renders from this rather than carrying its own copy of every connector's fields, so adding a connector stays a backend change. Empty for a connector with nothing to configure. |
required | Array of objects (ConnectorRequirement) What the connector needs on each invoice before it can run — a buyer phone for a rail that pushes a request to one. Distinct from a configuration field: checked against the invoice at collection time rather than supplied once. Empty when the connector needs nothing beyond being configured. |
| description | string |
{- "connector_id": "mpesa_push",
- "kind": "payment_rail",
- "display_name": "M-Pesa request on the phone",
- "shape": "push",
- "reconciliation": "callback",
- "clearance_scheme": "ke_kra_etims",
- "enabled": true,
- "configured": true,
- "available_in_country": true,
- "config_fields": [
- {
- "field_id": "consumer_key",
- "label": {
- "en": "Consumer key",
- "de": "Consumer Key"
}, - "secret": true,
- "required": true,
- "help_text": {
- "property1": "string",
- "property2": "string"
}
}
], - "requirements": [
- {
- "requirement_id": "mpesa_push.buyer_phone",
- "source": "invoice_field",
- "input_kind": "phone"
}
], - "description": "string"
}Whether the tenant may use this connector at all — the first of the three axes, and a separate control from its credentials. A connector switched off leaves the surfaces that offer it; one switched on without credentials stays visible with something to do.
The connector owns its own switch rather than exposing the
tenant_config key behind it, so no caller has to name that key. The
key's own edit scope still decides who may flip it.
| connector_id required | string Example: girocode |
| enabled required | boolean |
| connector_id required | string |
| kind required | string Enum: "payment_rail" "clearance" What this connector connects to. |
| display_name required | string |
| shape required | string or null Enum: "push" "qr" "link" null How the buyer meets a payment rail. Null for other kinds. |
| reconciliation required | string or null Enum: "callback" "matched" null
|
| clearance_scheme required | string or null Enum: "ke_kra_etims" "ng_firs_mbs" "in_gstn_irp" "br_sefaz_nfe" null The regime a |
| enabled required | boolean This connector's own enable key in the tenant's config. |
| configured required | boolean Whether anything is left for the tenant to do before this connector can be used: true once every required configuration field is on file. A connector with no required field — nothing to hand over — is configured by default. A missing IBAN and a missing API key are the same answer. |
| available_in_country required | boolean Whether the tenant's own country is one of the connector's default markets — where it is listed, defaults on, and shows a "configure" call-to-action. A soft default, not a usability gate: a payment rail switched on and configured can be collected on from any country (a clearance connector stays country-gated for legality). |
required | Array of objects (ConnectorField) What the tenant supplies to configure this connector — credentials, an IBAN. The configure screen renders from this rather than carrying its own copy of every connector's fields, so adding a connector stays a backend change. Empty for a connector with nothing to configure. |
required | Array of objects (ConnectorRequirement) What the connector needs on each invoice before it can run — a buyer phone for a rail that pushes a request to one. Distinct from a configuration field: checked against the invoice at collection time rather than supplied once. Empty when the connector needs nothing beyond being configured. |
| description | string |
{- "enabled": true
}{- "connector_id": "mpesa_push",
- "kind": "payment_rail",
- "display_name": "M-Pesa request on the phone",
- "shape": "push",
- "reconciliation": "callback",
- "clearance_scheme": "ke_kra_etims",
- "enabled": true,
- "configured": true,
- "available_in_country": true,
- "config_fields": [
- {
- "field_id": "consumer_key",
- "label": {
- "en": "Consumer key",
- "de": "Consumer Key"
}, - "secret": true,
- "required": true,
- "help_text": {
- "property1": "string",
- "property2": "string"
}
}
], - "requirements": [
- {
- "requirement_id": "mpesa_push.buyer_phone",
- "source": "invoice_field",
- "input_kind": "phone"
}
], - "description": "string"
}Metadata only. No human tier can read a secret value back once saved:
the record carries it as ciphertext and never as plaintext. The one
route that returns the values is GET .../credentials/values, which is
callable by a registered service and by nobody else.
| connector_id required | string Example: mpesa_push |
| connector_id required | string |
| configured required | boolean Whether credentials are on file for this connector. |
object The connector's non-secret fields, as the tenant entered them. | |
| verified_at | integer or null When the credentials were last confirmed to work, as a unix timestamp. Null means they have not been checked — which is not the same as broken. |
| verification_error | string or null Why the last check failed, when it did. |
| updated_at | integer or null |
{- "connector_id": "mpesa_push",
- "configured": true,
- "hint": {
- "property1": "string",
- "property2": "string"
}, - "verified_at": 0,
- "verification_error": "string",
- "updated_at": 0
}Replaces the whole credential set and then checks that it works. The credentials belong to the tenant's own relationship with the provider or the tax authority — Raccoon uses them to act on the tenant's behalf, and never holds their money.
| connector_id required | string Example: mpesa_push |
required | object non-empty Field id to value. Every required field the connector declares must be present; optional ones may be included. Unknown fields, a missing required one, or a value that fails the field's format check are rejected. |
| connector_id required | string |
| configured required | boolean Whether credentials are on file for this connector. |
object The connector's non-secret fields, as the tenant entered them. | |
| verified_at | integer or null When the credentials were last confirmed to work, as a unix timestamp. Null means they have not been checked — which is not the same as broken. |
| verification_error | string or null Why the last check failed, when it did. |
| updated_at | integer or null |
{- "values": {
- "property1": "string",
- "property2": "string"
}
}{- "connector_id": "mpesa_push",
- "configured": true,
- "hint": {
- "property1": "string",
- "property2": "string"
}, - "verified_at": 0,
- "verification_error": "string",
- "updated_at": 0
}Removes the stored values immediately. The connector stays switched on and becomes unconfigured again, so it keeps its place in the list with something to do rather than disappearing.
| connector_id required | string Example: mpesa_push |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}Returns the plaintext credentials, and is the only route that does.
It exists because an adapter running outside the core cannot resolve them in process — a service may not import core code, and the stored values are ciphertext — so a clearance worker has no other way to authenticate its one call to the tax authority.
Callable only by a registered service: no administrator, owner or
ordinary user reaches it at any tier. Each service is additionally
pinned to the connectors it may resolve by the scope table in
middleware/service_auth.py, so a payment adapter cannot read a tax
authority's credentials or the reverse.
| connector_id required | string Example: nrs_mbs |
| connector_id required | string |
required | object Every field the connector declares, secret and non-secret alike. |
{- "connector_id": "nrs_mbs",
- "values": {
- "property1": "string",
- "property2": "string"
}
}Returns all document rows attached to the invoice. A document is a derived business document (invoice PDF, delivery slip, offer, …) generated asynchronously by a worker.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
required | Array of objects (DocumentResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "doc_a1b2c3d4e5f6789012345",
- "_class": "document",
- "invoice_id": "inv_a1b2c3d4e5f6",
- "document_type": "invoice",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Creates a document row in pdf_pending and emits a document.created event. The PDF generation worker subscribes and asynchronously attaches the rendered file — clients should poll the row until status flips to pdf_ready.
| invoice_id required | string Example: inv_a1b2c3d4e5f6 |
| document_type required | string (DocumentType) Enum: "invoice" "invoice_ubl" "delivery_slip" "pro_forma_invoice" "intermediate_receipt" The kind of business document this document represents.
|
| _id required | string |
| _class required | string |
| invoice_id required | string |
| document_type required | string (DocumentType) Enum: "invoice" "invoice_ubl" "delivery_slip" "pro_forma_invoice" "intermediate_receipt" The kind of business document this document represents.
|
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "document_type": "invoice"
}{- "_id": "doc_a1b2c3d4e5f6789012345",
- "_class": "document",
- "invoice_id": "inv_a1b2c3d4e5f6",
- "document_type": "invoice",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| invoice_id required | string |
| document_id required | string Example: doc_a1b2c3d4e5f67890 |
| _id required | string |
| _class required | string |
| invoice_id required | string |
| document_type required | string (DocumentType) Enum: "invoice" "invoice_ubl" "delivery_slip" "pro_forma_invoice" "intermediate_receipt" The kind of business document this document represents.
|
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "_id": "doc_a1b2c3d4e5f6789012345",
- "_class": "document",
- "invoice_id": "inv_a1b2c3d4e5f6",
- "document_type": "invoice",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Two mutable fields, file and status. Setting file on a pdf_pending document implicitly transitions it to pdf_ready. Setting status to pdf_pending moves a pdf_failed document back to pending and re-publishes the document.created event so the worker picks it up again — idempotent for an already-pending row. No other status is writable; the rest of the FSM is server-controlled. Used by the invoice-document-generator service to report a rendered PDF (per architecture.md § Async Workers — no internal API; a UI client could call it too). Requires admin/superuser role.
Idempotent: replaying on an already-attached document returns 200 with the existing row (the originally attached PDF is preserved).
Per architecture.md § Embedded References, only _id is required inside the file Reference; _class and _name are accepted and resolved server-side from the linked File row.
| invoice_id required | string |
| document_id required | string Example: doc_a1b2c3d4e5f67890 |
Reference (object) or null | |
| status | string Value: "pdf_pending" Set to |
| _id required | string |
| _class required | string |
| invoice_id required | string |
| document_type required | string (DocumentType) Enum: "invoice" "invoice_ubl" "delivery_slip" "pro_forma_invoice" "intermediate_receipt" The kind of business document this document represents.
|
| status required | string (DocumentStatus) Enum: "draft" "pdf_pending" "pdf_ready" "pdf_failed" Lifecycle state. New documents start at |
required | Reference (object) or null Reference to the rendered PDF. |
| template_version required | string |
| created_at required | integer |
| updated_at required | integer |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | ReferenceValue (object) or null |
{- "file": {
- "_id": "fil_a1b2c3d4e5f6",
- "_class": "file",
- "_name": "INV-2026-00001.pdf"
}
}{- "_id": "doc_a1b2c3d4e5f6789012345",
- "_class": "document",
- "invoice_id": "inv_a1b2c3d4e5f6",
- "document_type": "invoice",
- "status": "draft",
- "file": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "template_version": "1.0.0",
- "created_at": 0,
- "updated_at": 0,
- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}The shared mailbox, readable by every signed-in user of the tenant. Nothing here is filtered by user.
Bodies are never in a list response — they live in a sibling row and
are returned by the detail route. preview is the one line that makes
the list readable without them.
Every filter is applied after the query rather than by an index, so a
page can come back short — or empty — while next_token is still set.
Exhaustion is a null token, never a short page.
todo_counts rides this response so the queue's three sections can be
labelled from one call. It is tallied on the first page only and is
null on a continuation page: the headings do not change while
paging, and the tally walks the tenant's whole partition.
| direction | string Enum: "inbound" "outbound" |
| todo_kind | string (TodoKind) Enum: "action" "reply" "notice" Only messages of this kind. |
| todo_status | string (TodoStatus) Enum: "open" "done" Only messages anyone has, or has not, dealt with. |
| assignee | string Only the messages one person holds. A user id, |
| document_id | string Only messages about this invoice or offer. A post-query filter over the tenant's whole mailbox, so its cost grows with the mailbox rather than with the answer. |
| link_state | string Enum: "linked" "unlinked"
|
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (EmailMessageResponse) |
| next_token required | string or null |
required | TodoCounts (object) or null Tallied on the first page only, and |
| todo_counts_are_a_floor required | boolean or null The counting walk hit its row budget with rows left, so each count is at least what it says rather than exactly. False for any mailbox a tenant is likely to have, and |
{- "items": [
- {
- "_id": "eml_a1b2c3d4e5f6",
- "_class": "email_message",
- "_name": "string",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "direction": "inbound",
- "status": "received",
- "from_address": "string",
- "from_name": "string",
- "to": [
- "string"
], - "cc": [
- "string"
], - "subject": "string",
- "preview": "string",
- "message_id": "string",
- "in_reply_to": "string",
- "references": [
- "string"
], - "spf_verdict": "pass",
- "dkim_verdict": "pass",
- "dmarc_verdict": "pass",
- "blocked_remote_reference_count": 0,
- "attachment_count": 0,
- "attachments": [
- {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
], - "todo_kind": "action",
- "todo_status": "open",
- "assignee": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_at": 0,
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "failure_reason": "string",
- "document_link_source": "tag",
- "thread_token": "string",
- "raw_mime_key": "string",
- "raw_mime_expires_at": 0,
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}
], - "next_token": "string",
- "todo_counts": {
- "action": 0,
- "reply": 0,
- "notice": 0
}, - "todo_counts_are_a_floor": true
}Internal. Called by the mail worker holding a service identity, never by a tenant: a tenant token is refused with 403.
This is the only write on the message itself. The envelope, headers, verdicts, bodies and attachments are a record of what arrived or was sent, and a record the recipient can edit is not a record — so there is no tenant-facing POST, PUT or DELETE here at all, and the one tenant-facing PATCH takes the to-do and refuses every other key.
Two bounds are applied server-side rather than asserted by the caller:
the references chain is cut to 20 entries, and the bodies are
truncated to their inline caps with the full copy written to S3. Both
truncate and neither rejects — the message already arrived.
An inbound message must carry recipient, the envelope address it was
delivered to. The core resolves it against the alias claims and
refuses the message with 403 unless it belongs to the token's tenant,
so the tenant a message lands in is decided here and never by the
caller. Its sub-address tag becomes thread_token; an inbound caller
may not send one.
A thread — the tag, or the sender when there is none — may add 20
inbound messages per UTC day; past that the answer is 429 and the
worker drops the message. A dedupe_key seen before answers 200 with
the message it stored.
| direction required | string Enum: "inbound" "outbound" |
| status required | string Enum: "received" "sent" "failed" "queued" "quarantined" |
| from_address required | string <= 320 characters |
| from_name | string or null <= 320 characters |
| to | Array of strings <= 100 items |
| cc | Array of strings <= 100 items |
| subject | string <= 998 characters |
| preview | string or null <= 400 characters The one line the list shows. Derived from the plain-text body when omitted. |
| message_id | string or null <= 998 characters |
| in_reply_to | string or null <= 998 characters |
| references | Array of strings The References header chain. Kept to the first 20 entries — a long thread's chain runs to tens of kilobytes. |
| spf_verdict | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dkim_verdict | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dmarc_verdict | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
TodoKind (string) or null What the message is for. The only to-do field a writer may state; omitted, it follows the direction — | |
Reference (object) or null The invoice or offer this message is about. | |
| document_link_source | string (DocumentLinkSource) Enum: "tag" "header" "manual" "none" How the link to a document was made — from the reply-to thread token, from a mail header, by hand, or not at all. |
| thread_token | string or null <= 64 characters |
| raw_mime_key | string or null <= 1024 characters |
| raw_mime_expires_at | integer or null Unix seconds. Past this the API serves a null raw_mime_key. |
EmailBodyCreate (object) or null | |
| recipient | string or null <= 320 characters The envelope address the message was delivered to, not a header. Required on an inbound message; decides the tenant and the thread token, and is not stored. |
| dedupe_key | string or null [ 1 .. 128 ] characters Reserved together with the message. A second call with the same key answers 200 with the stored message. |
| _id required | string |
| _class required | string |
| _name required | string The subject line. |
required | object
|
| direction required | string Enum: "inbound" "outbound" |
| status required | string Enum: "received" "sent" "failed" "queued" "quarantined" |
| from_address required | string |
| from_name required | string or null |
| to required | Array of strings |
| cc required | Array of strings |
| subject required | string |
| preview required | string One line of the message, so the list reads without fetching bodies. |
| message_id required | string or null |
| in_reply_to required | string or null |
| references required | Array of strings |
| spf_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dkim_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dmarc_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| blocked_remote_reference_count required | integer |
| attachment_count required | integer
|
required | Array of objects (Reference) Always empty on a stored row: nothing can write it, because a file's parent is the message and the message is minted before any file exists. The detail response replaces it with the files actually parented on the message, which is the tenant-isolated fact. |
| todo_kind required | string (TodoKind) Enum: "action" "reply" "notice" What the message is for. |
| todo_status required | string (TodoStatus) Enum: "open" "done" Whether anyone has dealt with the message. Not a read flag — a shared queue needs one answer to "has anyone dealt with this", not one per person. An outbound message is |
required | Reference (object) or null Who has picked this message up, or null while nobody has. Never a permission: every signed-in user of the tenant can read, open, re-assign and complete any message whoever owns it. |
required | Reference (object) or null Who completed it. Null on an outbound message, which is |
| done_at required | integer or null Unix epoch seconds. |
required | Reference (object) or null |
| failure_reason required | string or null Why the channel refused an outbound message — the provider's own error code, not a translated sentence. |
| document_link_source required | string (DocumentLinkSource) Enum: "tag" "header" "manual" "none" How the link to a document was made — from the reply-to thread token, from a mail header, by hand, or not at all. |
| thread_token required | string or null |
| raw_mime_key required | string or null Null once the 90-day retention has passed, rather than a key whose object no longer exists. |
| raw_mime_expires_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
| _id required | string |
| _class required | string |
| _name required | string The subject line. |
required | object
|
| direction required | string Enum: "inbound" "outbound" |
| status required | string Enum: "received" "sent" "failed" "queued" "quarantined" |
| from_address required | string |
| from_name required | string or null |
| to required | Array of strings |
| cc required | Array of strings |
| subject required | string |
| preview required | string One line of the message, so the list reads without fetching bodies. |
| message_id required | string or null |
| in_reply_to required | string or null |
| references required | Array of strings |
| spf_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dkim_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dmarc_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| blocked_remote_reference_count required | integer |
| attachment_count required | integer
|
required | Array of objects (Reference) Always empty on a stored row: nothing can write it, because a file's parent is the message and the message is minted before any file exists. The detail response replaces it with the files actually parented on the message, which is the tenant-isolated fact. |
| todo_kind required | string (TodoKind) Enum: "action" "reply" "notice" What the message is for. |
| todo_status required | string (TodoStatus) Enum: "open" "done" Whether anyone has dealt with the message. Not a read flag — a shared queue needs one answer to "has anyone dealt with this", not one per person. An outbound message is |
required | Reference (object) or null Who has picked this message up, or null while nobody has. Never a permission: every signed-in user of the tenant can read, open, re-assign and complete any message whoever owns it. |
required | Reference (object) or null Who completed it. Null on an outbound message, which is |
| done_at required | integer or null Unix epoch seconds. |
required | Reference (object) or null |
| failure_reason required | string or null Why the channel refused an outbound message — the provider's own error code, not a translated sentence. |
| document_link_source required | string (DocumentLinkSource) Enum: "tag" "header" "manual" "none" How the link to a document was made — from the reply-to thread token, from a mail header, by hand, or not at all. |
| thread_token required | string or null |
| raw_mime_key required | string or null Null once the 90-day retention has passed, rather than a key whose object no longer exists. |
| raw_mime_expires_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
{- "direction": "inbound",
- "status": "received",
- "from_address": "string",
- "from_name": "string",
- "to": [
- "string"
], - "cc": [
- "string"
], - "subject": "string",
- "preview": "string",
- "message_id": "string",
- "in_reply_to": "string",
- "references": [
- "string"
], - "spf_verdict": "pass",
- "dkim_verdict": "pass",
- "dmarc_verdict": "pass",
- "todo_kind": "action",
- "document": {
- "_id": "prod_fd74a5ce31b6"
}, - "document_link_source": "tag",
- "thread_token": "string",
- "raw_mime_key": "string",
- "raw_mime_expires_at": 0,
- "body": {
- "body_text": "string",
- "body_html": "string"
}, - "recipient": "string",
- "dedupe_key": "string"
}{- "_id": "eml_a1b2c3d4e5f6",
- "_class": "email_message",
- "_name": "string",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "direction": "inbound",
- "status": "received",
- "from_address": "string",
- "from_name": "string",
- "to": [
- "string"
], - "cc": [
- "string"
], - "subject": "string",
- "preview": "string",
- "message_id": "string",
- "in_reply_to": "string",
- "references": [
- "string"
], - "spf_verdict": "pass",
- "dkim_verdict": "pass",
- "dmarc_verdict": "pass",
- "blocked_remote_reference_count": 0,
- "attachment_count": 0,
- "attachments": [
- {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
], - "todo_kind": "action",
- "todo_status": "open",
- "assignee": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_at": 0,
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "failure_reason": "string",
- "document_link_source": "tag",
- "thread_token": "string",
- "raw_mime_key": "string",
- "raw_mime_expires_at": 0,
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}Internal. Called by the inbound-mail worker with a token for the
system tenant, which holds the alias claims; any other tenant is
refused with 403. The address is split on its first +, the base is
case-folded and looked up in the claims. A released alias keeps
answering for as long as its claim is held.
404 for an address outside the mail domain, one the alias grammar does not admit, and one nobody holds — the worker drops all three. The address travels in the body so it never lands in an access log.
| address required | string [ 3 .. 320 ] characters |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| local_part required | string The claimed base, case-folded, without its tag. |
| tag required | string or null What followed the first |
{- "address": "string"
}{- "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "local_part": "string",
- "tag": "string"
}content_type and size are joined onto each attachment here because
the file rows are one read away on the server and cost a round trip
each from a browser.
body.body_html is sanitised before it is stored, but it still comes
from an untrusted sender. Render it as untrusted content.
| email_message_id required | string Example: eml_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string The subject line. |
required | object
|
| direction required | string Enum: "inbound" "outbound" |
| status required | string Enum: "received" "sent" "failed" "queued" "quarantined" |
| from_address required | string |
| from_name required | string or null |
| to required | Array of strings |
| cc required | Array of strings |
| subject required | string |
| preview required | string One line of the message, so the list reads without fetching bodies. |
| message_id required | string or null |
| in_reply_to required | string or null |
| references required | Array of strings |
| spf_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dkim_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dmarc_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| blocked_remote_reference_count required | integer |
| attachment_count required | integer
|
required | Array of objects Always empty on a stored row: nothing can write it, because a file's parent is the message and the message is minted before any file exists. The detail response replaces it with the files actually parented on the message, which is the tenant-isolated fact. |
| todo_kind required | string (TodoKind) Enum: "action" "reply" "notice" What the message is for. |
| todo_status required | string (TodoStatus) Enum: "open" "done" Whether anyone has dealt with the message. Not a read flag — a shared queue needs one answer to "has anyone dealt with this", not one per person. An outbound message is |
required | Reference (object) or null Who has picked this message up, or null while nobody has. Never a permission: every signed-in user of the tenant can read, open, re-assign and complete any message whoever owns it. |
required | Reference (object) or null Who completed it. Null on an outbound message, which is |
| done_at required | integer or null Unix epoch seconds. |
required | Reference (object) or null |
| failure_reason required | string or null Why the channel refused an outbound message — the provider's own error code, not a translated sentence. |
| document_link_source required | string (DocumentLinkSource) Enum: "tag" "header" "manual" "none" How the link to a document was made — from the reply-to thread token, from a mail header, by hand, or not at all. |
| thread_token required | string or null |
| raw_mime_key required | string or null Null once the 90-day retention has passed, rather than a key whose object no longer exists. |
| raw_mime_expires_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
required | EmailBody (object) or null |
{- "_id": "eml_a1b2c3d4e5f6",
- "_class": "email_message",
- "_name": "string",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "direction": "inbound",
- "status": "received",
- "from_address": "string",
- "from_name": "string",
- "to": [
- "string"
], - "cc": [
- "string"
], - "subject": "string",
- "preview": "string",
- "message_id": "string",
- "in_reply_to": "string",
- "references": [
- "string"
], - "spf_verdict": "pass",
- "dkim_verdict": "pass",
- "dmarc_verdict": "pass",
- "blocked_remote_reference_count": 0,
- "attachment_count": 0,
- "attachments": [
- {
- "_id": "string",
- "_class": "file",
- "_name": "string",
- "content_type": "string",
- "size": 0,
- "content_id": "string"
}
], - "todo_kind": "action",
- "todo_status": "open",
- "assignee": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_at": 0,
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "failure_reason": "string",
- "document_link_source": "tag",
- "thread_token": "string",
- "raw_mime_key": "string",
- "raw_mime_expires_at": 0,
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "body": {
- "body_text": "string",
- "body_html": "string",
- "body_truncated": true
}
}The only tenant write on the store. It takes assignee and
todo_status and refuses every other key with a 422, so the
envelope, headers, verdicts and bodies stay what the worker wrote.
Any signed-in user of the tenant may assign or complete any message, including one somebody else owns. Assignment says who picked the work up; it is not a permission and it narrows nobody's view.
An omitted field is left alone. assignee: null hands the message
back to the queue. Completing stamps done_by and done_at with the
caller and the moment; reopening clears both.
| email_message_id required | string Example: eml_a1b2c3d4e5f6 |
Reference (object) or null The user who owns this message, or null for nobody. | |
| todo_status | string Enum: "open" "done" Omit it to leave the status alone. There is no null status, so an explicit null is refused rather than answering 200 having changed nothing — unlike |
| _id required | string |
| _class required | string |
| _name required | string The subject line. |
required | object
|
| direction required | string Enum: "inbound" "outbound" |
| status required | string Enum: "received" "sent" "failed" "queued" "quarantined" |
| from_address required | string |
| from_name required | string or null |
| to required | Array of strings |
| cc required | Array of strings |
| subject required | string |
| preview required | string One line of the message, so the list reads without fetching bodies. |
| message_id required | string or null |
| in_reply_to required | string or null |
| references required | Array of strings |
| spf_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dkim_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| dmarc_verdict required | string (EmailVerdict) Enum: "pass" "fail" "gray" "processing_failed" "not_available" An authentication result reported by the receiving mail service. SPF and DKIM are recorded and never gate; a message is not authenticated by its From header alone. |
| blocked_remote_reference_count required | integer |
| attachment_count required | integer
|
required | Array of objects (Reference) Always empty on a stored row: nothing can write it, because a file's parent is the message and the message is minted before any file exists. The detail response replaces it with the files actually parented on the message, which is the tenant-isolated fact. |
| todo_kind required | string (TodoKind) Enum: "action" "reply" "notice" What the message is for. |
| todo_status required | string (TodoStatus) Enum: "open" "done" Whether anyone has dealt with the message. Not a read flag — a shared queue needs one answer to "has anyone dealt with this", not one per person. An outbound message is |
required | Reference (object) or null Who has picked this message up, or null while nobody has. Never a permission: every signed-in user of the tenant can read, open, re-assign and complete any message whoever owns it. |
required | Reference (object) or null Who completed it. Null on an outbound message, which is |
| done_at required | integer or null Unix epoch seconds. |
required | Reference (object) or null |
| failure_reason required | string or null Why the channel refused an outbound message — the provider's own error code, not a translated sentence. |
| document_link_source required | string (DocumentLinkSource) Enum: "tag" "header" "manual" "none" How the link to a document was made — from the reply-to thread token, from a mail header, by hand, or not at all. |
| thread_token required | string or null |
| raw_mime_key required | string or null Null once the 90-day retention has passed, rather than a key whose object no longer exists. |
| raw_mime_expires_at required | integer or null |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | Reference (object) or null |
{- "assignee": {
- "_id": "prod_fd74a5ce31b6"
}, - "todo_status": "open"
}{- "_id": "eml_a1b2c3d4e5f6",
- "_class": "email_message",
- "_name": "string",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "direction": "inbound",
- "status": "received",
- "from_address": "string",
- "from_name": "string",
- "to": [
- "string"
], - "cc": [
- "string"
], - "subject": "string",
- "preview": "string",
- "message_id": "string",
- "in_reply_to": "string",
- "references": [
- "string"
], - "spf_verdict": "pass",
- "dkim_verdict": "pass",
- "dmarc_verdict": "pass",
- "blocked_remote_reference_count": 0,
- "attachment_count": 0,
- "attachments": [
- {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
], - "todo_kind": "action",
- "todo_status": "open",
- "assignee": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "done_at": 0,
- "document": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "failure_reason": "string",
- "document_link_source": "tag",
- "thread_token": "string",
- "raw_mime_key": "string",
- "raw_mime_expires_at": 0,
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}
}Ordinary bearer auth. Answers a presigned URL rather than the bytes, like every other file download.
The file must be an attachment of this message: without that check the route would be a way to read any file in the tenant through a message id.
| email_message_id required | string Example: eml_a1b2c3d4e5f6 |
| file_id required | string Example: fil_a1b2c3d4e5f6 |
| url required | string Presigned S3 URL for the attachment. |
| expires_at required | integer Unix epoch seconds after which the URL stops working. |
{- "url": "string",
- "expires_at": 0
}| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
| q | string non-empty Full-text search term. When provided, the endpoint delegates to the
shared search index (matches across name/title/email/identifier
fields, tenant-scoped) and returns the matching entities in the
same response shape as the unfiltered list. Pagination ( |
required | Array of objects (ProjectResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prj_a1b2c3d4e5f6",
- "_class": "project",
- "_name": "Acme Corp",
- "title": "string",
- "type_id": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| title required | string [ 1 .. 200 ] characters |
| type_id | string [ 1 .. 100 ] characters The project-class tenant type this project is created under. Every project has one. Omitted, the project is created under the tenant's default project type; that is a 422 when the tenant has several and marks none of them default. |
| schema_version | string or null Type version. Omitted = latest. |
object Custom field values keyed by section field IDs. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| title required | string |
| type_id required | string The project-class tenant type this project was created under. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object Custom field values; |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "title": "Q2 2026 Launch",
- "type_id": "client_engagement",
- "schema_version": "string",
- "data": { }
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prj_a1b2c3d4e5f6",
- "_class": "project",
- "_name": "Acme Corp",
- "title": "string",
- "type_id": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string Example: prj_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| title required | string |
| type_id required | string The project-class tenant type this project was created under. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object Custom field values; |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prj_a1b2c3d4e5f6",
- "_class": "project",
- "_name": "Acme Corp",
- "title": "string",
- "type_id": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string Example: prj_a1b2c3d4e5f6 |
| title | string [ 1 .. 200 ] characters |
| type_id | string or null |
| schema_version | string or null |
object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| title required | string |
| type_id required | string The project-class tenant type this project was created under. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object Custom field values; |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "title": "string",
- "type_id": "string",
- "schema_version": "string",
- "data": { }
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "prj_a1b2c3d4e5f6",
- "_class": "project",
- "_name": "Acme Corp",
- "title": "string",
- "type_id": "string",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Lists the custom objects of one tenant custom_object-class type. The type query parameter is required — objects are only ever viewed within their type group, and the query is strongly consistent.
| type required | string Example: type=series |
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (CustomObjectResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "cob_a1b2c3d4e5f6",
- "_class": "custom_object",
- "_name": "Acme Corp",
- "type_id": "series",
- "name": "string",
- "schema_version": "1.0.0",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}| type_id required | string [ 1 .. 100 ] characters The tenant |
| name required | string [ 1 .. 200 ] characters |
object Custom field values keyed by the type's section field IDs. |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| name required | string |
| schema_version required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "type_id": "string",
- "name": "Studies in Modern Poetry",
- "data": { }
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "cob_a1b2c3d4e5f6",
- "_class": "custom_object",
- "_name": "Acme Corp",
- "type_id": "series",
- "name": "string",
- "schema_version": "1.0.0",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string Example: cob_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| name required | string |
| schema_version required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "cob_a1b2c3d4e5f6",
- "_class": "custom_object",
- "_name": "Acme Corp",
- "type_id": "series",
- "name": "string",
- "schema_version": "1.0.0",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string Example: cob_a1b2c3d4e5f6 |
| type_id | string [ 1 .. 100 ] characters |
| name | string [ 1 .. 200 ] characters |
object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| name required | string |
| schema_version required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "type_id": "string",
- "name": "string",
- "data": { }
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "cob_a1b2c3d4e5f6",
- "_class": "custom_object",
- "_name": "Acme Corp",
- "type_id": "series",
- "name": "string",
- "schema_version": "1.0.0",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string Example: cob_a1b2c3d4e5f6 |
| type_id | string [ 1 .. 100 ] characters |
| name | string [ 1 .. 200 ] characters |
object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object
|
| type_id required | string |
| name required | string |
| schema_version required | string |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object |
| created_at required | integer Unix epoch seconds |
| updated_at required | integer Unix epoch seconds |
required | ReferenceValue (object) or null |
required | Array of objects (IdentifierResponse) The numbers this record carries (ISBN, GTIN, VAT ID, ...). Stored on the record itself; the identifiers sub-resource addresses one entry. |
required | Array of objects (PrintedIdentifier) Read-only. The numbers the record's type marked primary, in the order it declared them — what a picker option, a search row or a detail header shows without resolving the type itself. |
{- "type_id": "string",
- "name": "string",
- "data": { }
}{- "_links": {
- "self": "string",
- "texts": "string",
- "property1": "string",
- "property2": "string"
}, - "primary_identifiers": [
- {
- "id_type": "isbn",
- "value": "978-3-16-148410-0"
}
], - "identifiers": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "_id": "cob_a1b2c3d4e5f6",
- "_class": "custom_object",
- "_name": "Acme Corp",
- "type_id": "series",
- "name": "string",
- "schema_version": "1.0.0",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "data": { },
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Validates the request against the file kind named by type — a
declaration on the parent's type, or a system kind — enforces
cardinality (a cardinality: one kind rejects a second active upload
with HTTP 409), and returns a presigned POST form scoped to the
caller's tenant prefix in S3.
Some system kinds are written by a service rather than by a person:
the generated documents (invoice.document_pdf,
invoice.document_xml, offer.document_pdf,
stock_dispatch.document_pdf) by the document generator, and
email_message.attachment by the inbound-mail worker. Each is
written by that one service: a human caller gets 403, and so does a
service posting a kind it does not own.
A declared kind is resolved against the parent, so a parent that does not exist in the caller's tenant is 404.
After uploading the bytes via the returned upload form, an S3 event
promotes the row from status=pending to ready (or failed).
required | object (FileParent) The record a file hangs off. The classes listed here are the file parents the backend accepts; a reference to anything else is rejected with 422. |
| type required | string Either a file kind the parent's type declares — |
| file_name required | string |
| file_size required | integer >= 1 |
| mime_type required | string^[\w.+-]+/[\w.+-]+(\s*;.*)?$ |
| description | string or null |
| language | string or null^[a-z]{2}$ ISO 639-1 language of the content. |
| content_id | string or null [ 1 .. 250 ] characters ^[\x21-\x7e]+$ The |
ReferenceValue (object) or null The file this upload takes the place of, for a kind that holds one
file. It must hang off the same parent under the same kind. The named
row keeps serving downloads until the replacement reaches |
| _id required | string |
| _class required | string Value: "file" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (FileParent) The record a file hangs off. The classes listed here are the file parents the backend accepts; a reference to anything else is rejected with 422. |
| type required | string |
| file_name required | string |
| file_size required | integer |
| mime_type required | string |
| sha256 required | string or null Hex-encoded SHA-256, populated once |
| status required | string (FileStatus) Enum: "pending" "ready" "quarantined" "failed" "soft_deleted" Lifecycle state of a file. |
| retention_class required | string Enum: "transient" "standard" "archival" |
| legal_hold required | boolean |
| description required | string or null |
| language required | string or null ISO 639-1 language of the content. |
| content_id required | string or null The |
required | ReferenceValue (object) or null The file this one replaces while its upload is still in flight; null once the swap completed or when nothing was replaced. |
required | object
|
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
required | object (PresignedPost) S3 presigned-POST form. The client must POST |
{- "parent": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "type": "fkd_9f3c1a2b4d5e",
- "file_name": "string",
- "file_size": 1,
- "mime_type": "image/png",
- "description": "string",
- "language": "de",
- "content_id": "string",
- "replaces": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}
}{- "_id": "fil_a1b2c3d4e5f6",
- "_class": "file",
- "_name": "Acme Corp",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "parent": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "type": "fkd_9f3c1a2b4d5e",
- "file_name": "string",
- "file_size": 0,
- "mime_type": "string",
- "sha256": "string",
- "status": "pending",
- "retention_class": "transient",
- "legal_hold": true,
- "description": "string",
- "language": "string",
- "content_id": "string",
- "replaces": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "upload": {
- "fields": {
- "property1": "string",
- "property2": "string"
}, - "expires_at": 0
}
}| parent_id required | string |
| parent_class required | string Enum: "business_partner" "product" "project" "invoice" "offer" "custom_object" "tenant" "chat_session" "bank_statement" "stock_dispatch" "email_message" |
| type | string Filter by namespaced file-type key. |
| limit | integer <= 200 Default: 50 |
| next_token | string |
required | Array of objects (FileResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "fil_a1b2c3d4e5f6",
- "_class": "file",
- "_name": "Acme Corp",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "parent": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "type": "fkd_9f3c1a2b4d5e",
- "file_name": "string",
- "file_size": 0,
- "mime_type": "string",
- "sha256": "string",
- "status": "pending",
- "retention_class": "transient",
- "legal_hold": true,
- "description": "string",
- "language": "string",
- "content_id": "string",
- "replaces": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}One call for a whole list page: the picture of each named record — the
newest ready file of the kind its type marks role: avatar — with a
short-lived presigned URL.
A record without a picture is left out of the answer, as is one that does not exist in the caller's tenant: the lookup never leaves the tenant's partition, so a foreign id returns nothing.
required | Array of objects (FileDownloadUrlsParent) [ 1 .. 200 ] items The records whose pictures are wanted. Each entry needs |
required | Array of objects One entry per record that has a picture. A record without one — and a record of another tenant — is absent. |
{- "parents": [
- {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}
]
}{- "items": [
- {
- "parent": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner"
}, - "file": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "expires_at": 0
}
]
}| file_id required | string Example: fil_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string Value: "file" |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | object (FileParent) The record a file hangs off. The classes listed here are the file parents the backend accepts; a reference to anything else is rejected with 422. |
| type required | string |
| file_name required | string |
| file_size required | integer |
| mime_type required | string |
| sha256 required | string or null Hex-encoded SHA-256, populated once |
| status required | string (FileStatus) Enum: "pending" "ready" "quarantined" "failed" "soft_deleted" Lifecycle state of a file. |
| retention_class required | string Enum: "transient" "standard" "archival" |
| legal_hold required | boolean |
| description required | string or null |
| language required | string or null ISO 639-1 language of the content. |
| content_id required | string or null The |
required | ReferenceValue (object) or null The file this one replaces while its upload is still in flight; null once the swap completed or when nothing was replaced. |
required | object
|
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "fil_a1b2c3d4e5f6",
- "_class": "file",
- "_name": "Acme Corp",
- "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "parent": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "type": "fkd_9f3c1a2b4d5e",
- "file_name": "string",
- "file_size": 0,
- "mime_type": "string",
- "sha256": "string",
- "status": "pending",
- "retention_class": "transient",
- "legal_hold": true,
- "description": "string",
- "language": "string",
- "content_id": "string",
- "replaces": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "_links": {
- "property1": "string",
- "property2": "string"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Sets status=soft_deleted and deleted_at. The S3 object is kept
for 30 days then hard-deleted by a nightly cleanup, unless the file
carries legal_hold=true.
| file_id required | string Example: fil_a1b2c3d4e5f6 |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| scope | string Enum: "global" "tenant" |
| namespace | string |
| industry | string |
| authority | string |
| status | string Enum: "draft" "active" "deprecated" |
required | Array of objects (CodelistHeader) |
| count required | integer |
{- "items": [
- {
- "_id": "cl_iso_3166_1_2020",
- "_class": "codelist",
- "_name": "Acme Corp",
- "namespace": "iso/3166-1",
- "version": "2020",
- "authority": "string",
- "industry": [
- "string"
], - "scope": "global",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "loading": "eager",
- "status": "draft",
- "is_stub": true,
- "created_at": 0,
- "updated_at": 0
}
], - "count": 0
}| namespace required | string Codelist namespace; may contain slashes (e.g. iso/3166-1). Pass each segment as a separate path segment. |
| version required | string |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| namespace required | string |
| version required | string |
| scope required | string Enum: "global" "tenant" |
| status required | string Enum: "draft" "active" "deprecated" |
required | object |
| loading required | string Enum: "eager" "lazy" |
| authority | string |
| industry | Array of strings |
object | |
| is_stub | boolean |
| created_at | integer |
| updated_at | integer |
{- "_id": "cl_iso_3166_1_2020",
- "_class": "codelist",
- "_name": "Acme Corp",
- "namespace": "iso/3166-1",
- "version": "2020",
- "authority": "string",
- "industry": [
- "string"
], - "scope": "global",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "loading": "eager",
- "status": "draft",
- "is_stub": true,
- "created_at": 0,
- "updated_at": 0
}| namespace required | string |
| version required | string |
| locale | string Default: "en" Preferred display language. Never filters which codes are returned; every returned row carries all its translations in |
| parent_code | string |
| status | string Enum: "active" "deprecated" "retired" |
| q | string |
| limit | integer Default: 50 |
| offset | integer Default: 0 |
required | Array of objects (CodeValueResponse) |
| count required | integer |
| total required | integer |
{- "items": [
- {
- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}
], - "count": 0,
- "total": 0
}| namespace required | string |
| version required | string |
| code required | string |
| _id required | string |
| _class required | string |
| namespace required | string |
| version required | string |
| code required | string |
| status required | string Enum: "active" "deprecated" "retired" |
required | object |
required | object (ReferenceValue) Stored value for a field of type "reference" |
object | |
| created_at | integer |
| updated_at | integer |
{- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}| namespace required | string |
| version required | string |
| code required | string |
required | object |
required | Array of objects (CodeValueResponse) |
required | object (CodeValueResponse) |
{- "from": {
- "namespace": "string",
- "version": "string",
- "code": "string"
}, - "chain": [
- {
- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}
], - "terminal": {
- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}
}| namespace required | string |
| code required | string |
| version | string Default: "latest" |
| locale | string Default: "en" Preferred language for |
| valid required | boolean |
| namespace required | string |
| version required | string |
| code required | string |
{- "namespace": "string",
- "version": "latest",
- "code": "string",
- "locale": "en"
}{- "valid": true,
- "namespace": "string",
- "version": "string",
- "code": "string"
}| slug required | string |
required | object |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| namespace required | string |
| version required | string |
| scope required | string Enum: "global" "tenant" |
| status required | string Enum: "draft" "active" "deprecated" |
required | object |
| loading required | string Enum: "eager" "lazy" |
| authority | string |
| industry | Array of strings |
object | |
| is_stub | boolean |
| created_at | integer |
| updated_at | integer |
{- "slug": "my_categories",
- "codelist": {
- "version": "string",
- "published_at": "2019-08-24",
- "authority": "string",
- "industry": [
- "string"
], - "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "licence": "string",
- "attribution": "string"
}
}{- "_id": "cl_iso_3166_1_2020",
- "_class": "codelist",
- "_name": "Acme Corp",
- "namespace": "iso/3166-1",
- "version": "2020",
- "authority": "string",
- "industry": [
- "string"
], - "scope": "global",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "loading": "eager",
- "status": "draft",
- "is_stub": true,
- "created_at": 0,
- "updated_at": 0
}| namespace required | string Tenant codelist namespace (must start with tenant:). |
| version required | string |
| published_at | string <date> |
| authority | string |
| industry | Array of strings |
object | |
object | |
| licence | string |
| attribution | string |
| status | string Enum: "draft" "active" "deprecated" |
| _id required | string |
| _class required | string |
| _name required | string (EntityName) Read-only, backend-composed display label of this entity (a person's full name, a product's name, a project's title, …). A backend-meta field (sibling of |
| namespace required | string |
| version required | string |
| scope required | string Enum: "global" "tenant" |
| status required | string Enum: "draft" "active" "deprecated" |
required | object |
| loading required | string Enum: "eager" "lazy" |
| authority | string |
| industry | Array of strings |
object | |
| is_stub | boolean |
| created_at | integer |
| updated_at | integer |
{- "version": "string",
- "published_at": "2019-08-24",
- "authority": "string",
- "industry": [
- "string"
], - "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "licence": "string",
- "attribution": "string",
- "status": "draft"
}{- "_id": "cl_iso_3166_1_2020",
- "_class": "codelist",
- "_name": "Acme Corp",
- "namespace": "iso/3166-1",
- "version": "2020",
- "authority": "string",
- "industry": [
- "string"
], - "scope": "global",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "loading": "eager",
- "status": "draft",
- "is_stub": true,
- "created_at": 0,
- "updated_at": 0
}| namespace required | string |
| version required | string |
| code required | string |
object | |
object | |
| parent_code | string |
| valid_from | string <date> |
| valid_to | string <date> |
object |
| _id required | string |
| _class required | string |
| namespace required | string |
| version required | string |
| code required | string |
| status required | string Enum: "active" "deprecated" "retired" |
required | object |
required | object (ReferenceValue) Stored value for a field of type "reference" |
object | |
| created_at | integer |
| updated_at | integer |
{- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "parent_code": "string",
- "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "metadata": { }
}{- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}| namespace required | string |
| version required | string |
| code required | string |
object | |
object | |
| parent_code | string |
| valid_from | string <date> |
| valid_to | string <date> |
| status | string Enum: "active" "deprecated" "retired" |
| replaced_by_code | string |
object |
| _id required | string |
| _class required | string |
| namespace required | string |
| version required | string |
| code required | string |
| status required | string Enum: "active" "deprecated" "retired" |
required | object |
required | object (ReferenceValue) Stored value for a field of type "reference" |
object | |
| created_at | integer |
| updated_at | integer |
{- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "description": {
- "property1": "string",
- "property2": "string"
}, - "parent_code": "string",
- "valid_from": "2019-08-24",
- "valid_to": "2019-08-24",
- "status": "active",
- "replaced_by_code": "string",
- "metadata": { }
}{- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}| namespace required | string |
| version required | string |
| code required | string |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| namespace required | string |
| version required | string |
| code required | string |
| replaced_by_code | string |
| _id required | string |
| _class required | string |
| namespace required | string |
| version required | string |
| code required | string |
| status required | string Enum: "active" "deprecated" "retired" |
required | object |
required | object (ReferenceValue) Stored value for a field of type "reference" |
object | |
| created_at | integer |
| updated_at | integer |
{- "replaced_by_code": "string"
}{- "_id": "EUR",
- "_class": "code_value",
- "codelist": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "namespace": "string",
- "version": "string",
- "code": "string",
- "display_name": {
- "property1": "string",
- "property2": "string"
}, - "status": "active",
- "metadata": { },
- "created_at": 0,
- "updated_at": 0
}| company_id required | string |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| company_id required | string |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| company_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| company_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| company_id required | string |
| identifier_id required | string |
| value required | string The identifier value the validator checked (staleness guard). |
| type required | string |
| status required | string |
| result required | string Enum: "SUCCESS" "INVALID" "UNAVAILABLE" |
| validated_at required | integer |
| name_on_record | string or null |
| consultation_number | string or null |
| work_type | string or null Crossref work type (e.g. journal-article) for a |
| log | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
| applied required | boolean False when the result was dropped (staleness — value changed — or never-downgrade of a cached SUCCESS); the identifier is unchanged. |
{- "value": "string",
- "type": "vies",
- "status": "completed",
- "result": "SUCCESS",
- "validated_at": 0,
- "name_on_record": "string",
- "consultation_number": "string",
- "work_type": "string",
- "log": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "applied": true
}Returns all identifier records matching the given schema_key and value within the authenticated tenant. Each result contains a parent Reference pointing to the owning entity. Use the nested sub-resource endpoints for CRUD operations on identifiers.
| schema_key required | string Example: schema_key=ean13 |
| identifier required | string Example: identifier=4006381333931 |
required | Array of objects (IdentifierResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Returns the platform identifier schemas that can be attached to the given entity class. Every scheme is returned (a company may hold a foreign VAT registration, so none are hidden); when country is supplied the scheme issued by that country (e.g. vat_eu for an EU company, vat_gb for a UK company) is sorted first and flagged recommended. Drives the add-identifier dropdown on the Company form.
| entity_class required | string Example: entity_class=company |
| country | string Example: country=DE ISO 3166-1 alpha-2 code of the entity's home country. |
required | Array of objects (IdentifierSchema) |
| next_token required | string or null |
{- "items": [
- {
- "schema_key": "vat_eu",
- "display_name": {
- "en": "VAT ID (EU)"
}, - "applicable_entity_classes": [
- "company",
- "business_partner"
], - "is_vat_scheme": true,
- "has_validator": true,
- "recommended": true
}
], - "next_token": "string"
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string |
| identifier_id required | string |
| value required | string The identifier value the validator checked (staleness guard). |
| type required | string |
| status required | string |
| result required | string Enum: "SUCCESS" "INVALID" "UNAVAILABLE" |
| validated_at required | integer |
| name_on_record | string or null |
| consultation_number | string or null |
| work_type | string or null Crossref work type (e.g. journal-article) for a |
| log | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
| applied required | boolean False when the result was dropped (staleness — value changed — or never-downgrade of a cached SUCCESS); the identifier is unchanged. |
{- "value": "string",
- "type": "vies",
- "status": "completed",
- "result": "SUCCESS",
- "validated_at": 0,
- "name_on_record": "string",
- "consultation_number": "string",
- "work_type": "string",
- "log": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "applied": true
}| business_partner_id required | string |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| business_partner_id required | string |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}Dedicated write path for async validators (e.g. the VIES worker) to
report a verdict, kept off the general identifier PATCH so a worker
write and a concurrent user value-edit can't clobber each other.
Applies staleness + never-downgrade rules; applied=false when skipped.
| business_partner_id required | string |
| identifier_id required | string |
| value required | string The identifier value the validator checked (staleness guard). |
| type required | string |
| status required | string |
| result required | string Enum: "SUCCESS" "INVALID" "UNAVAILABLE" |
| validated_at required | integer |
| name_on_record | string or null |
| consultation_number | string or null |
| work_type | string or null Crossref work type (e.g. journal-article) for a |
| log | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
| applied required | boolean False when the result was dropped (staleness — value changed — or never-downgrade of a cached SUCCESS); the identifier is unchanged. |
{- "value": "string",
- "type": "vies",
- "status": "completed",
- "result": "SUCCESS",
- "validated_at": 0,
- "name_on_record": "string",
- "consultation_number": "string",
- "work_type": "string",
- "log": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "applied": true
}| invoice_id required | string |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| invoice_id required | string |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| invoice_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| invoice_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| invoice_id required | string |
| identifier_id required | string |
| value required | string The identifier value the validator checked (staleness guard). |
| type required | string |
| status required | string |
| result required | string Enum: "SUCCESS" "INVALID" "UNAVAILABLE" |
| validated_at required | integer |
| name_on_record | string or null |
| consultation_number | string or null |
| work_type | string or null Crossref work type (e.g. journal-article) for a |
| log | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
| applied required | boolean False when the result was dropped (staleness — value changed — or never-downgrade of a cached SUCCESS); the identifier is unchanged. |
{- "value": "string",
- "type": "vies",
- "status": "completed",
- "result": "SUCCESS",
- "validated_at": 0,
- "name_on_record": "string",
- "consultation_number": "string",
- "work_type": "string",
- "log": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "applied": true
}| project_id required | string |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| project_id required | string |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string |
| identifier_id required | string |
| value required | string The identifier value the validator checked (staleness guard). |
| type required | string |
| status required | string |
| result required | string Enum: "SUCCESS" "INVALID" "UNAVAILABLE" |
| validated_at required | integer |
| name_on_record | string or null |
| consultation_number | string or null |
| work_type | string or null Crossref work type (e.g. journal-article) for a |
| log | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
| applied required | boolean False when the result was dropped (staleness — value changed — or never-downgrade of a cached SUCCESS); the identifier is unchanged. |
{- "value": "string",
- "type": "vies",
- "status": "completed",
- "result": "SUCCESS",
- "validated_at": 0,
- "name_on_record": "string",
- "consultation_number": "string",
- "work_type": "string",
- "log": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "applied": true
}| custom_object_id required | string |
required | Array of objects (IdentifierResponse) |
{- "items": [
- {
- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
]
}| custom_object_id required | string |
| schema_key required | string |
| value required | string |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "schema_key": "ean13",
- "value": "4006381333931",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string |
| identifier_id required | string |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string |
| identifier_id required | string |
| value | string or null |
| label | string or null |
| _id required | string |
| _class required | string |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| schema_key required | string |
| value required | string |
required | Array of objects Zero or more validation results for this identifier value, one per
validator. Open shape (each is |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": "string",
- "label": "string"
}{- "_id": "string",
- "_class": "identifier",
- "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "schema_key": "string",
- "value": "string",
- "validations": [
- { }
], - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string Example: prd_a1b2c3d4e5f6 |
| next_token | string |
required | Array of objects (TextResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Upsert. Answers 200 with the stored row, or 204 when the value held nothing in any language — that deletes the row, the same as DELETE.
| product_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
required | object The text per language, keyed by ISO 639-1 code. |
| _id required | string |
| _class required | string |
required | object |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| key required | string |
required | object The text per language, keyed by ISO 639-1 code. |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": {
- "en": "A jam made in Nairobi."
}
}{- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| product_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| project_id required | string Example: prj_a1b2c3d4e5f6 |
| next_token | string |
required | Array of objects (TextResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Upsert. Answers 200 with the stored row, or 204 when the value held nothing in any language — that deletes the row, the same as DELETE.
| project_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
required | object The text per language, keyed by ISO 639-1 code. |
| _id required | string |
| _class required | string |
required | object |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| key required | string |
required | object The text per language, keyed by ISO 639-1 code. |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": {
- "en": "A jam made in Nairobi."
}
}{- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| project_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| custom_object_id required | string Example: cob_a1b2c3d4e5f6 |
| next_token | string |
required | Array of objects (TextResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Upsert. Answers 200 with the stored row, or 204 when the value held nothing in any language — that deletes the row, the same as DELETE.
| custom_object_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
required | object The text per language, keyed by ISO 639-1 code. |
| _id required | string |
| _class required | string |
required | object |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| key required | string |
required | object The text per language, keyed by ISO 639-1 code. |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": {
- "en": "A jam made in Nairobi."
}
}{- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| custom_object_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}| business_partner_id required | string Example: bp_a1b2c3d4e5f6 |
| next_token | string |
required | Array of objects (TextResponse) |
| next_token required | string or null |
{- "items": [
- {
- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "string"
}Upsert. Answers 200 with the stored row, or 204 when the value held nothing in any language — that deletes the row, the same as DELETE.
| business_partner_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
required | object The text per language, keyed by ISO 639-1 code. |
| _id required | string |
| _class required | string |
required | object |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
required | object (Reference) An embedded reference to another entity. In responses all three fields are always present (the backend builds
every reference from the live entity), so they are marked In request bodies only |
| key required | string |
required | object The text per language, keyed by ISO 639-1 code. |
| created_at required | integer |
| updated_at required | integer |
required | ReferenceValue (object) or null |
{- "value": {
- "en": "A jam made in Nairobi."
}
}{- "_id": "prd_a1b2c3d4e5f6.tkd_0a1b2c3d4e5f",
- "_class": "text",
- "_links": {
- "self": "string",
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "parent": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "key": "tkd_0a1b2c3d4e5f",
- "value": {
- "en": "<p>A jam made in Nairobi.</p>",
- "de": "<p>Marmelade aus Nairobi.</p>"
}, - "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}| business_partner_id required | string |
| text_kind_key required | string Example: tkd_0a1b2c3d4e5f The |
{- "error": "not_found",
- "message": "Business partner not found",
- "details": { }
}What plan the tenant is on and what state it is in, together with the price actually being charged.
The price is resolved from the subscription's stored pricing region, never from where the caller is — a tenant keeps the pricing of the market it signed up in.
Never 404s: a tenant with no stored subscription is created on the free plan on first read, so no client has to handle a billing-not-set-up state.
Status changes are consequences of payment-provider events and arrive on their own endpoints; there is no route by which a tenant can put itself on a paid plan.
| subscription_id required | string |
| tenant_id required | string |
| created_at required | integer |
| updated_at required | integer |
required | object Reference into the published plan catalogue; |
| plan_name required | string |
| status required | string Enum: "free" "active" "past_due" "grace" "canceled"
|
| region_key required | string |
| currency required | string = 3 characters |
| band required | string Enum: "a" "b" "c" "d" |
required | MonetaryAmount (object) or null Null on the free plan. |
| tax_display required | string or null Enum: "gross" "net" null |
| entitlements_active required | boolean Whether the subscribed plan's limits apply ( |
required | object (ProviderCapabilities) What this tenant's payment rail can actually do — static facts, not state. A rail without hosted checkout or auto-renew needs a visibly different
upgrade flow, and the client reads that from here rather than inferring it
from |
| provider_key required | string or null Enum: "stub" "stripe" null |
| provider_customer_id required | string or null |
| provider_subscription_id required | string or null |
| current_period_start required | integer or null |
| current_period_end required | integer or null |
| cancel_at_period_end required | boolean |
| past_due_since required | integer or null |
| last_provider_event_at required | integer or null The provider's own timestamp for the most recent event applied. Events older than this are rejected, because webhook delivery is unordered. |
ReferenceValue (object) or null Null when the subscription was created by self-service registration, where the acting user is not yet established. |
{- "subscription_id": "sub_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "status": "free",
- "region_key": "ke",
- "currency": "str",
- "band": "a",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "entitlements_active": true,
- "provider_capabilities": {
- "supports_auto_renew": true,
- "supports_hosted_checkout": true,
- "supports_mandates": true,
- "per_charge_confirmation": true
}, - "provider_key": "stub",
- "provider_customer_id": "string",
- "provider_subscription_id": "string",
- "current_period_start": 0,
- "current_period_end": 0,
- "cancel_at_period_end": true,
- "past_due_since": 0,
- "last_provider_event_at": 0
}cancel_at_period_end is the only field a tenant may write — it says
what should happen when the current period ends, and touches neither
status nor plan.
Setting it true is the "Cancel plan" path: the plan runs to the end
of the period the tenant already paid for, nothing is taken away
today, and asking twice is the same as asking once. Refused on the
free plan, which has nothing to cancel.
Setting it false is the "Keep plan" path, available any time before
the period actually ends. A 422 when no cancellation is pending, which
is the honest answer: there is nothing to undo, and succeeding quietly
would let a client report "resumed" for a plan nobody had stopped.
Owner-gated, like checkout: an administrator can read the bill, only an owner can stop it.
| cancel_at_period_end required | boolean |
| subscription_id required | string |
| tenant_id required | string |
| created_at required | integer |
| updated_at required | integer |
required | object Reference into the published plan catalogue; |
| plan_name required | string |
| status required | string Enum: "free" "active" "past_due" "grace" "canceled"
|
| region_key required | string |
| currency required | string = 3 characters |
| band required | string Enum: "a" "b" "c" "d" |
required | MonetaryAmount (object) or null Null on the free plan. |
| tax_display required | string or null Enum: "gross" "net" null |
| entitlements_active required | boolean Whether the subscribed plan's limits apply ( |
required | object (ProviderCapabilities) What this tenant's payment rail can actually do — static facts, not state. A rail without hosted checkout or auto-renew needs a visibly different
upgrade flow, and the client reads that from here rather than inferring it
from |
| provider_key required | string or null Enum: "stub" "stripe" null |
| provider_customer_id required | string or null |
| provider_subscription_id required | string or null |
| current_period_start required | integer or null |
| current_period_end required | integer or null |
| cancel_at_period_end required | boolean |
| past_due_since required | integer or null |
| last_provider_event_at required | integer or null The provider's own timestamp for the most recent event applied. Events older than this are rejected, because webhook delivery is unordered. |
ReferenceValue (object) or null Null when the subscription was created by self-service registration, where the acting user is not yet established. |
{- "cancel_at_period_end": true
}{- "subscription_id": "sub_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "status": "free",
- "region_key": "ke",
- "currency": "str",
- "band": "a",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "entitlements_active": true,
- "provider_capabilities": {
- "supports_auto_renew": true,
- "supports_hosted_checkout": true,
- "supports_mandates": true,
- "per_charge_confirmation": true
}, - "provider_key": "stub",
- "provider_customer_id": "string",
- "provider_subscription_id": "string",
- "current_period_start": 0,
- "current_period_end": 0,
- "cancel_at_period_end": true,
- "past_due_since": 0,
- "last_provider_event_at": 0
}What the tenant has consumed inside the period it is currently paying for, with the plan's limit beside each meter.
The period follows the subscription, not the calendar: on a paid
plan it is the billing anniversary window, on the free plan it is the
calendar month. Clients render resets_at and never need to know
which rule applied.
Every metric the plan defines is returned, including untouched ones at zero — an absent meter would read as a missing feature rather than an unused one.
Raccoon's own token costs are deliberately absent. The plan bundles a number of agent actions, not a number of tokens.
| period required | string Opaque key for the window being metered. Follows the subscription's billing anniversary on a paid plan and the calendar month on free — clients display |
| resets_at required | integer Unix seconds at which these counters reset — the billing anniversary on a paid plan, the month boundary on free. One date, whichever rule produced it. |
required | Array of objects (UsageMetric) |
| warnings required | Array of strings Metrics at or above 80% of their limit. |
{- "period": "sub#1755302400",
- "resets_at": 0,
- "metrics": [
- {
- "metric": "agent_actions",
- "used": 0,
- "limit": 0,
- "percent": 100
}
], - "warnings": [
- "string"
]
}Opens a checkout attempt and answers 202: nothing has been paid and nothing decided yet. The provider reports the outcome asynchronously, and the client follows the intent rather than awaiting a reply.
The plan, price and tax display are snapshotted onto the intent, so a catalogue edit between the price the tenant read and the charge the provider makes cannot change what they agreed to. The pricing region comes from the tenant's subscription — frozen at registration — never from the request.
Owner-gated: this is the call that commits the tenant to money.
| plan_key required | string A paid catalogue plan. |
| stub_behaviour | string or null Enum: "complete" "payment_failed" "canceled" "expire" null Simulate an outcome. 422 unless the stage's provider is the stub. |
{- "plan_key": "starter",
- "stub_behaviour": "complete"
}{- "checkout_intent_id": "chk_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "region_key": "ke",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "status": "pending",
- "provider_key": "stub",
- "provider_session_id": "string",
- "provider_session_url": "string",
- "stub_behaviour": "complete",
- "expires_at": 0,
- "resolved_at": 0,
- "failure_reason": "string"
}Including the failed ones. Retrying creates a new intent rather than overwriting the old, so "my payment did not work" has evidence attached to it.
| limit | integer [ 1 .. 200 ] Default: 50 |
| next_token | string Base64-encoded pagination cursor from previous response |
required | Array of objects (CheckoutIntent) |
| next_token required | string or null |
{- "items": [
- {
- "checkout_intent_id": "chk_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "region_key": "ke",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "status": "pending",
- "provider_key": "stub",
- "provider_session_id": "string",
- "provider_session_url": "string",
- "stub_behaviour": "complete",
- "expires_at": 0,
- "resolved_at": 0,
- "failure_reason": "string"
}
], - "next_token": "string"
}An intent past its expires_at reads as expired whatever is stored, so a lapsed checkout never looks live merely because the sweeper has not reached it yet.
| checkout_intent_id required | string Example: chk_9f2c1a04b7e3 |
| checkout_intent_id required | string |
| tenant_id required | string |
| created_at required | integer |
| updated_at required | integer |
required | object The plan being bought, snapshotted at create. |
| plan_name required | string |
| region_key required | string The tenant's frozen pricing region, so a checkout cannot be quoted in a cheaper market than the tenant belongs to. |
required | MonetaryAmount (object) or null What the tenant agreed to pay, snapshotted at create. |
| tax_display required | string or null Enum: "gross" "net" null |
| status required | string Enum: "pending" "awaiting_payment" "completed" "payment_failed" "canceled" "expired"
|
| provider_key required | string Enum: "stub" "stripe" Stamped from per-stage config, never from the request. |
| provider_session_id required | string or null |
| provider_session_url required | string or null Where to send the payer, on a rail with hosted checkout. Null on a rail without one — see |
| stub_behaviour required | string or null Enum: "complete" "payment_failed" "canceled" "expire" null Which outcome the stub should simulate. Accepted only when the stage's provider is the stub; a real rail decides its own outcome, and letting a request name one would be a way to fake a payment. |
| expires_at required | integer Unix seconds after which the intent is no longer live. |
| resolved_at required | integer or null |
| failure_reason required | string or null |
ReferenceValue (object) or null |
{- "checkout_intent_id": "chk_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "region_key": "ke",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "status": "pending",
- "provider_key": "stub",
- "provider_session_id": "string",
- "provider_session_url": "string",
- "stub_behaviour": "complete",
- "expires_at": 0,
- "resolved_at": 0,
- "failure_reason": "string"
}The provider reporting that it has a session open and is waiting for
the payer, moving the intent to awaiting_payment.
Separate from the outcome callback because a rail with hosted checkout needs somewhere to put the URL to send the payer to, and the client has to tell "not started" apart from "waiting on the payer".
Service-gated. Callable only by a registered billing-provider service or a superuser — deliberately stricter than the validator callbacks, which admit any admin. A forged call here is money, not provenance.
| checkout_intent_id required | string |
| provider_session_id required | string |
| provider_session_url | string or null Where to send the payer, on a rail with hosted checkout. |
| checkout_intent_id required | string |
| tenant_id required | string |
| created_at required | integer |
| updated_at required | integer |
required | object The plan being bought, snapshotted at create. |
| plan_name required | string |
| region_key required | string The tenant's frozen pricing region, so a checkout cannot be quoted in a cheaper market than the tenant belongs to. |
required | MonetaryAmount (object) or null What the tenant agreed to pay, snapshotted at create. |
| tax_display required | string or null Enum: "gross" "net" null |
| status required | string Enum: "pending" "awaiting_payment" "completed" "payment_failed" "canceled" "expired"
|
| provider_key required | string Enum: "stub" "stripe" Stamped from per-stage config, never from the request. |
| provider_session_id required | string or null |
| provider_session_url required | string or null Where to send the payer, on a rail with hosted checkout. Null on a rail without one — see |
| stub_behaviour required | string or null Enum: "complete" "payment_failed" "canceled" "expire" null Which outcome the stub should simulate. Accepted only when the stage's provider is the stub; a real rail decides its own outcome, and letting a request name one would be a way to fake a payment. |
| expires_at required | integer Unix seconds after which the intent is no longer live. |
| resolved_at required | integer or null |
| failure_reason required | string or null |
ReferenceValue (object) or null |
{- "provider_session_id": "string",
- "provider_session_url": "string"
}{- "checkout_intent_id": "chk_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "region_key": "ke",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "status": "pending",
- "provider_key": "stub",
- "provider_session_id": "string",
- "provider_session_url": "string",
- "stub_behaviour": "complete",
- "expires_at": 0,
- "resolved_at": 0,
- "failure_reason": "string"
}The provider reporting what happened. Resolves the intent and moves the subscription with it, through the same settlement path the in-core stub drives — which is what makes "one FSM for every provider" structural rather than a convention.
A repeat of the state the intent is already in is accepted and changes nothing: provider delivery is at-least-once, and answering 409 to a retry would make every duplicate look like a failure.
Service-gated, for the same reason as the session callback: a
forged checkout_completed grants a paid plan.
| checkout_intent_id required | string |
| event required | string Enum: "checkout_completed" "payment_succeeded" "payment_failed" "subscription_updated" "subscription_ended" "checkout_canceled" "checkout_expired" |
| occurred_at | integer or null The provider's clock, not ours. The subscription's staleness guard compares against it, so substituting our own would make an out-of-order redelivery look current and let a retried "payment failed" undo the recovery that fixed it. |
| failure_reason | string or null |
| provider_customer_id | string or null |
| provider_subscription_id | string or null |
| checkout_intent_id required | string |
| tenant_id required | string |
| created_at required | integer |
| updated_at required | integer |
required | object The plan being bought, snapshotted at create. |
| plan_name required | string |
| region_key required | string The tenant's frozen pricing region, so a checkout cannot be quoted in a cheaper market than the tenant belongs to. |
required | MonetaryAmount (object) or null What the tenant agreed to pay, snapshotted at create. |
| tax_display required | string or null Enum: "gross" "net" null |
| status required | string Enum: "pending" "awaiting_payment" "completed" "payment_failed" "canceled" "expired"
|
| provider_key required | string Enum: "stub" "stripe" Stamped from per-stage config, never from the request. |
| provider_session_id required | string or null |
| provider_session_url required | string or null Where to send the payer, on a rail with hosted checkout. Null on a rail without one — see |
| stub_behaviour required | string or null Enum: "complete" "payment_failed" "canceled" "expire" null Which outcome the stub should simulate. Accepted only when the stage's provider is the stub; a real rail decides its own outcome, and letting a request name one would be a way to fake a payment. |
| expires_at required | integer Unix seconds after which the intent is no longer live. |
| resolved_at required | integer or null |
| failure_reason required | string or null |
ReferenceValue (object) or null |
{- "event": "checkout_completed",
- "occurred_at": 0,
- "failure_reason": "string",
- "provider_customer_id": "string",
- "provider_subscription_id": "string"
}{- "checkout_intent_id": "chk_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "plan_name": "string",
- "region_key": "ke",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "status": "pending",
- "provider_key": "stub",
- "provider_session_id": "string",
- "provider_session_url": "string",
- "stub_behaviour": "complete",
- "expires_at": 0,
- "resolved_at": 0,
- "failure_reason": "string"
}Every plan period this tenant has been on, oldest first.
A plan change closes one period and opens the next, so these rows are the audit trail rather than a reconstruction of one — nothing is edited in place and nothing is lost.
Each period carries the allowances that were granted with it, frozen at
the moment it opened. A later catalogue change cannot reach them, which
is what makes grandfathering automatic; a custom period may carry
numbers the catalogue never offered at all.
required | Array of objects (SubscriptionPeriod) |
| next_token required | string or null |
{- "items": [
- {
- "subscription_period_id": "subp_9f2c1a04b7e3",
- "tenant_id": "string",
- "created_at": 0,
- "updated_at": 0,
- "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "plan_key": "starter",
- "valid_from": 0,
- "valid_to": 0,
- "included_agent_actions": 0,
- "included_invoices": 1,
- "included_users": 1,
- "max_products": 1,
- "model_tier": "blended",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "credit": {
- "amount": 12.5,
- "currency": "EUR"
}, - "comment": "string"
}
], - "next_token": "string"
}What a business in a given country pays Raccoon, in the currency they use. Served from the in-repo catalogue — no persistence, no third-party I/O.
Deliberately unauthenticated. The public marketing site puts a price on the homepage and must quote the same numbers the product charges; reading them from here is what stops the two drifting apart. Nothing tenant-specific is exposed — a price list is the most public document a company has.
Pass country to price a specific market, or region_key to price a
pricing region directly — the form a signed-in tenant uses, since it
carries a frozen region_key and no country. With neither, the
response falls back to the dearest region rather than the cheapest,
because overcharging is refundable and underpricing a market is not.
Authenticating does not change the answer: a subscription's pricing region is fixed when it is created and is never re-derived here from an address that can later be edited. The caller says which market it wants priced; the endpoint does not guess from tenant data.
Prices are stored as explicit local amounts and are never computed from a live FX rate — a tenant's bill must not move because the shilling did.
| region_key | string Example: region_key=ke Price for a pricing region directly, for a caller that already has one. A signed-in tenant carries a frozen |
| country | string = 2 characters ISO 3166-1 alpha-2 code. A country with no price row of its own resolves to the dearest region rather than the cheapest, so an unlisted market is never accidentally underpriced. A code that is not an officially-assigned country is a 422. |
required | Array of objects (BillingPlan) |
| next_token required | null The catalogue is a fixed short list and is never paginated. |
{- "items": [
- {
- "_id": "starter",
- "_class": "billing_plan",
- "_name": "string",
- "plan_key": "free",
- "name": {
- "property1": "string",
- "property2": "string"
}, - "country": "st",
- "region_key": "ke",
- "band": "a",
- "currency": "str",
- "price": {
- "amount": 12.5,
- "currency": "EUR"
}, - "tax_display": "gross",
- "entitlements": {
- "agent_actions_per_month": 0,
- "included_users": 1,
- "max_products": 1,
- "max_invoices_per_month": 1,
- "model_tier": "haiku_only"
}
}
], - "next_token": null
}Returns the changes recorded at or after since, oldest first, so a
client can refresh whatever it has on screen that appears in the
result. Each entry names a subject to re-read; none carries field
values.
The response's next_token is a durable cursor, not a page marker:
it is never null, and the client sends it back as since on the next
poll. Omitting since subscribes from now and returns an empty page —
a client that has just loaded has no backlog to catch up on.
Delivery is at-least-once. The cursor lags real time by a couple of
seconds so a change written late within a second cannot be skipped,
which means consecutive polls re-deliver a small overlap; de-duplicate
on _id. Refetching is idempotent, so this is a deliberate trade.
| since | string Example: since=1785483570 Cursor from a previous response's |
| limit | integer [ 1 .. 200 ] Default: 100 |
required | Array of objects (ChangeResponse) |
| next_token required | string The feed cursor, never null — unlike every other list endpoint,
where |
{- "items": [
- {
- "_id": "chg_a1b2c3d4e5f6",
- "_class": "change",
- "subject": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resource_class": "product",
- "subclass": "product.price",
- "method": "created",
- "actor_kind": "agent",
- "created_at": 0,
- "updated_at": 0,
- "_links": {
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}
], - "next_token": "1785483570"
}| change_id required | string Example: chg_a1b2c3d4e5f6 |
| _id required | string |
| _class required | string Value: "change" |
required | object (Reference) The aggregate the client should re-read. |
| resource_class required | string Aggregate root class, e.g. |
| subclass required | string Fully-qualified path of what changed within the aggregate, e.g.
|
| method required | string Enum: "created" "updated" "deleted" |
| actor_kind required | string Who caused it — |
| created_at required | integer Unix epoch seconds. Also the feed's ordering position. |
| updated_at required | integer Unix epoch seconds. |
required | object (ReferenceValue) Stored value for a field of type "reference" |
required | ReferenceValue (object) or null |
object |
{- "_id": "chg_a1b2c3d4e5f6",
- "_class": "change",
- "subject": {
- "_id": "prod_fd74a5ce31b6",
- "_class": "product",
- "_name": "Widget A"
}, - "resource_class": "product",
- "subclass": "product.price",
- "method": "created",
- "actor_kind": "agent",
- "created_at": 0,
- "updated_at": 0,
- "_links": {
- "property1": "string",
- "property2": "string"
}, - "tenant": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}, - "created_by": {
- "_id": "bp_a1b2c3",
- "_class": "business_partner",
- "_name": "Acme Corp"
}
}