StabisoDocs

API reference

Parties

Customers and vendors: master data, activation, bank details.

Operation Summary Scope Idempotency-Key
GET /v1/entities/{entity}/credit-exposure Get the credit exposure of customers with a credit limit read
GET /v1/entities/{entity}/parties List customers and vendors read
POST /v1/entities/{entity}/parties Create a customer or vendor draft required
GET /v1/entities/{entity}/parties/{party} Get a customer or vendor card read
PATCH /v1/entities/{entity}/parties/{party} Change a customer or vendor draft
POST /v1/entities/{entity}/parties/{party}/activate Activate a draft customer or vendor draft
POST /v1/entities/{entity}/parties/{party}/merge Merge a duplicate customer draft
POST /v1/entities/{entity}/parties/{party}/status Block a customer or vendor, set it inactive, or make it active again draft
POST /v1/entities/{entity}/parties/{party}/vat-check Check a customer's or vendor's VAT number in its public register draft
POST /v1/vat-registers/check Check a VAT number against its public register draft

GET /v1/entities/{entity}/credit-exposure

Get the credit exposure of customers with a credit limit

Every customer of the company with a credit limit, those over it first: its limit, what it owes (receivables: open invoices less open credit notes and payments on account), its invoices waiting for approval, what is left to invoice on its open sales orders (VAT included), the total (exposure), the credit still available and whether it is over the limit. All in the customer's currency: an amount in another currency is converted at today's ECB rate (today where the company is). An invoice that would take a customer above its limit waits for a second person when it is submitted; a sales order is not confirmed. Read-only; 404 for an unknown entity.

Required scope read (admin implies every scope)
Operation id get_credit_exposure_v1_entities__entity__credit_exposure_get

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
query format "csv" | "json" json (default) or csv: one row per customer with the columns customer, name, currency, credit_limit, receivables, pending_invoices, open_orders, exposure, available, over_limit and note, meaning what the JSON fields of the same names mean. (default "json")
query download boolean csv: true sends the file as an attachment; false inline. (default false)

Example request

curl "$ERP_URL/v1/entities/CH01/credit-exposure" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 JSON (the report) or CSV (one row per customer). CreditExposure, text/csv
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "entity": "string",
  "as_of": "2026-09-21",
  "customers": [
    {
      "party": "string",
      "name": "string",
      "currency": "string",
      "credit_limit": "string",
      "receivables": "string",
      "pending_invoices": "string",
      "open_orders": "string",
      "exposure": "string",
      "available": "string",
      "over_limit": true,
      "note": "string"
    }
  ]
}

GET /v1/entities/{entity}/parties

List customers and vendors

Customers and vendors of an entity, ordered by code, with their open balances (open and overdue amounts of posted documents per currency; credit notes count negative) and the requests waiting for a second person (pending_actions). All filters combine with AND. Someone who sees only their own or their team's records gets the customers those people own or have deals with (and every vendor).

Required scope read (admin implies every scope)
Operation id list_parties_v1_entities__entity__parties_get

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
query kind "customer" | "vendor" or null customer or vendor; default: both.
query q string or null Text in the name, VAT number (any part), code (starts with) or town (starts with); case-insensitive.
query status "active" | "blocked" | "draft" | "inactive" or null active, draft (not yet activated by a second person), blocked or inactive; default: all.
query country string or null ISO 3166-1 alpha-2 country, e.g. DE. (pattern ^[A-Za-z]{2}$)
query vat_number string or null Part of the VAT number or UID; spaces, dots and case are ignored, so 811569 finds DE 811 569 869.
query parent string (uuid) or null Only the subsidiaries of this party (its id): those naming it parent.
query owner_user_id string (uuid) or null Only the customers this person owns (GET /v1/people).
query as_of string (date) or null Day the overdue amounts are counted to (ISO 8601, e.g. 2026-09-30); default today where the entity is.
query limit integer Most parties returned, 1 to 1000. (min 1; max 1000; default 1000)

Example request

curl "$ERP_URL/v1/entities/CH01/parties" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of PartyRow
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "kind": "string",
    "code": "string",
    "name": "string",
    "country": "string",
    "subdivision": "string",
    "vat_number": "string",
    "business": true,
    "split_payment": false,
    "withholding_code": "string",
    "withholding_rate": "string",
    "vat_unverified": false,
    "currency": "string",
    "payment_terms_days": 1,
    "email": "string",
    "iban": "string",
    "street": "string",
    "building_number": "string",
    "postal_code": "string",
    "town": "string",
    "status": "active",
    "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "leitweg_id": "string",
    "electronic_address": "string",
    "electronic_address_scheme": "string",
    "cash_discount_percent": "string",
    "cash_discount_days": 1,
    "credit_limit": "string",
    "bank_accounts": [
      {
        "iban": "string",
        "bic": null,
        "label": null
      }
    ],
    "contacts": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "name": "string",
        "role": null,
        "email": null,
        "phone": null
      }
    ],
    "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "custom": {},
    "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "language": "string",
    "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "created_at": "2026-09-21T09:30:00Z",
    "balances": [
      {
        "currency": "string",
        "open": "string",
        "overdue": "string",
        "on_account": "0.00",
        "open_documents": 1,
        "overdue_documents": 1
      }
    ],
    "pending_actions": [
      "string"
    ]
  }
]

POST /v1/entities/{entity}/parties

Create a customer or vendor

Create a customer or vendor in an entity, identified by kind and code. Without a code it gets the company's next number (C-00001, V-00001, counted per company and kind without gaps); a code given is kept as written. A draft party is neither booked nor paid until a second person activates it. By default a customer is active; a person's new vendor is a draft with an activation request, an agent's vendor (or any party with bank details an agent creates) a plain draft (see the activate operation). The IBAN is checked and stored without spaces. Refuses with 409 when a code given exists for that kind, 422 for an invalid IBAN, Leitweg-ID or cash discount terms, a currency without exchange rates or an IBAN of your own company, 404 for an unknown entity or account, and 403 when the approval policy denies activation. The answer lists existing customers or vendors it may duplicate (same VAT number, an IBAN in common or the same name); the party is created anyway.

Required scope draft (admin implies every scope)
Idempotency-Key required
Operation id create_party_v1_entities__entity__parties_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).

Request body

application/json (required): PartyInput

Field Type Required Description
kind "customer" | "vendor" yes customer or vendor; a code is unique per kind in an entity.
code string or null Leave it out and the party gets the company's next number: C-00001 for a customer, V-00001 for a vendor, counted per company without gaps. Give one (up to 40 characters, e.g. the number of the system before) only to keep it; it is how documents and URLs name the party, and never changes. (min length 1; max length 40)
name string yes Legal name of the customer or vendor.
country string or null ISO 3166-1 alpha-2 country code, e.g. DE; drives the place of supply of the tax determination. Omitted: the country its VAT number names by its prefix, else the company's. (pattern ^[A-Z]{2}$)
subdivision string or null ISO 3166-2 subdivision where it matters for tax, e.g. DE-BY, or a US customer's state (US-CA), which decides its sales tax. A Spanish postal code gives it when left empty: 35 and 38 the Canary Islands (ES-CN), 51 Ceuta (ES-CE), 52 Melilla (ES-ML); one of another country, or that the postal code contradicts, is refused (422 party_subdivision_mismatch). (pattern ^[A-Z]{2}-[A-Z0-9]{1,3}$)
vat_number string or null VAT or UID number, e.g. DE811569869 or CHE-116.281.710 MWST; for a party of an EU country, the UK, Norway, Switzerland or Liechtenstein its format is checked, and its check digit for CH, DE, FR, IT, ES and BE (422 vat_number_invalid).
business boolean true for a business (B2B), false for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person. (default true)
split_payment boolean Customers of an Italian company: true for one under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter: public bodies and the companies the law lists). Its invoices show the VAT but it owes only the net amount and pays the VAT to the State; the VAT returns leave that VAT out. Default false. (default false)
currency string or null ISO 4217 currency of the party's documents and payments, e.g. EUR: functional or with exchange rates (422 party_currency_without_rates). Omitted: its country's currency when the company has exchange rates for it, else the company's. (pattern ^[A-Z]{3}$)
withholding_code string or null Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (GET /v1/entities/{entity}/withholding-tax/codes lists the codes of the company's country, e.g. IT-RA-20), or custom with withholding_rate; null for none. Changing it once a bill of the vendor is posted waits for a second person. (max length 20)
withholding_rate decimal string or null With withholding_code custom: the rate in percent of a bill's net amount before VAT, e.g. 18.5; a code of the table takes its own rate. (greater than 0)
payment_terms_days integer Days from the document date to the due date, 0 to 365; default 30. (min 0; max 365; default 30)
default_account string or null Revenue/expense account code.
email string or null Contact email address.
iban string or null IBAN payments to the party go to, stored without spaces; one of your own companies' accounts is refused (422 party_own_bank_account).
bank_accounts array of PartyBankAccount Further accounts payments may go to (a QR-IBAN).
language "de" | "en" | "fr" | "it" | "rm" | "sv" or null Correspondence language. Omitted: its country's, where the country has one of ours (DE and AT de, FR fr, IT it, SE sv, GB and US en); none for a country of several (CH, BE, CA): set it there.
contacts array of NewContact People at the party; later ones are added with POST /v1/contacts.
parent string or null Code (or id) of the company it belongs to, of the same kind.
custom map of string | number | integer | boolean or null Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people. Omitted: you.
street string or null Street of the postal address (up to 70 characters); used on QR-bills and XRechnung. (max length 70)
building_number string or null Building number of the postal address (up to 16 characters). (max length 16)
postal_code string or null Postal code of the address (up to 16 characters). (max length 16)
town string or null Town of the address (up to 35 characters). (max length 35)
leitweg_id string or null Customers: Leitweg-ID of a German public buyer (XRechnung buyer reference).
electronic_address string or null E-invoicing address (BT-34/BT-49), e.g. an email or Peppol id.
electronic_address_scheme string or null EAS code of the electronic address, e.g. EM (email), 0204, 9930.
status "active" | "draft" draft until a second person activates it. A vendor (or a party with bank details) created by an agent, and a vendor created from an e-invoice, start as draft; otherwise 'active' needs the approval policy to allow activate_party. (default "active")
cash_discount_percent decimal string or null Cash discount (Skonto) percent if paid within cash_discount_days, e.g. 2. (greater than 0)
cash_discount_days integer or null Days within which the cash discount applies, 0 to 365. (min 0; max 365)
credit_limit decimal string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed. (min 0)
source_sha256 string or null SHA-256 of the bill this vendor was read from (the bill wizard sends the sha256 of POST /v1/agents/bill-capture/read). The audit entry and the activation request then say that its bank details come from that invoice, and what the public VAT register said about its number: the approver sees what nobody has confirmed. (pattern ^[0-9a-f]{64}$)

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/parties" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "building_number": "1268",
  "contacts": [
    {
      "first_name": "Anna",
      "last_name": "Muster",
      "role": "Buchhaltung"
    }
  ],
  "country": "CH",
  "currency": "CHF",
  "iban": "CH44 3199 9123 0008 8901 2",
  "kind": "vendor",
  "language": "de",
  "name": "Neu Handel AG",
  "payment_terms_days": 20,
  "postal_code": "2501",
  "street": "Rue du Lac",
  "town": "Biel"
}'

Responses

Status Meaning Body
201 Created PartyCreated
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ]
}

GET /v1/entities/{entity}/parties/{party}

Get a customer or vendor card

A customer or vendor by code or id: master data (structured address, language, IBAN and further bank accounts, contacts, electronic address, Leitweg-ID), who created and activated it, open balances per currency, pending requests with who asked and, for bank details, the current and proposed values, payment_blockers, the reasons no payment to it can be released now, and for a customer with a credit limit its credit: what it owes and has on order against the limit, and the credit still available. 404 when not found; 409 when the code names both a customer and a vendor and kind is missing.

Required scope read (admin implies every scope)
Operation id get_party_v1_entities__entity__parties__party__get

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.
query kind "customer" | "vendor" or null customer or vendor; needed when one code names both a customer and a vendor (otherwise 409).
query as_of string (date) or null Day the overdue amounts are counted to (ISO 8601, e.g. 2026-09-30); default today where the entity is.

Example request

curl "$ERP_URL/v1/entities/CH01/parties/C-DE" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK PartyCard
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "balances": [
    {
      "currency": "string",
      "open": "string",
      "overdue": "string",
      "on_account": "0.00",
      "open_documents": 1,
      "overdue_documents": 1
    }
  ],
  "pending_actions": [
    "string"
  ],
  "created_by": {},
  "activated_by": {},
  "activated_at": "2026-09-21T09:30:00Z",
  "pending": [
    {
      "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "action": "string",
      "requested_by": {},
      "requested_at": "2026-09-21T09:30:00Z",
      "reason": "string",
      "current": {},
      "proposed": {}
    }
  ],
  "payment_blockers": [
    {
      "code": "string",
      "message": "string",
      "details": {}
    }
  ],
  "vat_check": {
    "registry": "ch_uid",
    "status": "invalid",
    "vat_number": "string",
    "name": "string",
    "name_matches": true,
    "reference": "string",
    "checked_at": "2026-09-21T09:30:00Z",
    "checked_by": {}
  },
  "credit": {
    "party": "string",
    "name": "string",
    "currency": "string",
    "credit_limit": "string",
    "receivables": "string",
    "pending_invoices": "string",
    "open_orders": "string",
    "exposure": "string",
    "available": "string",
    "over_limit": true,
    "note": "string"
  },
  "parent": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "name": "string"
  },
  "merged_into": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "subsidiaries": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string"
    }
  ],
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ],
  "open_support_cases": 0,
  "breached_support_cases": 0,
  "active_subscriptions": 0,
  "open_opportunities": 0
}

PATCH /v1/entities/{entity}/parties/{party}

Change a customer or vendor

Change a customer or vendor, e.g. its address, contacts or Leitweg-ID. Omitted or null fields stay as they are; "" clears a text field; contacts and bank_accounts replace the whole list.

New bank details (iban, bank_accounts) are not applied: they become a request that a second person approves (pending on the card), and payments to the party are blocked meanwhile. Once a document of the party is posted or pending approval, a new name, vat_number, country, subdivision, currency or credit_limit is such a request too. Only humans change bank or key details (403 for agents); a second open request of the same kind answers 409. A credit limit is for customers only (422, credit_limit_customers_only). status: active does what the activate operation does.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id update_party_v1_entities__entity__parties__party__patch

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.
query kind "customer" | "vendor" yes customer or vendor; required.

Request body

application/json (required): PartyUpdate

Field Type Required Description
name string or null New legal name; once the party is past draft, or a document of it is posted or pending approval, this waits for a second person.
country string or null New ISO 3166-1 alpha-2 country; waits for a second person like name. (pattern ^[A-Z]{2}$)
subdivision string or null ISO 3166-2 subdivision where it matters for tax, e.g. DE-BY, or a US customer's state (US-CA); empty clears it. A Spanish postal code gives it as on create (422 party_subdivision_mismatch on a contradiction); a change waits for a second person like name. (pattern ^([A-Z]{2}-[A-Z0-9]{1,3})?$)
vat_number string or null New VAT or UID number (format checked as on create, 422); waits for a second person like name.
business boolean or null true for a business (B2B), false for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person.
split_payment boolean or null Customers of an Italian company: true for one under split payment (DPR 633/1972 art. 17-ter); applies to invoices drafted from then on.
currency string or null New ISO 4217 currency: the functional currency or one with exchange rates (422 party_currency_without_rates); waits for a second person like name. (pattern ^[A-Z]{3}$)
email string or null Contact email address.
iban string or null New IBAN, stored without spaces. It is not applied at once: a second person must approve it and payments to the party are blocked meanwhile. "" clears it.
bank_accounts array of PartyBankAccount or null New list of further bank accounts; replaces the list. Waits for a second person's approval like iban.
language "de" | "en" | "fr" | "it" | "rm" | "sv" | "" or null Correspondence language (de, fr, it, en, sv, rm); "" clears.
parent string or null Code (or id) of the company it belongs to; "" clears it.
custom map of string | number | integer | boolean or null or null Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null New owner. Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people.
withholding_code string or null Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (GET /v1/entities/{entity}/withholding-tax/codes lists the codes of the company's country, e.g. IT-RA-20), or custom with withholding_rate; "" removes it. Waits for a second person like name. (max length 20)
withholding_rate decimal string or null With withholding_code custom: the rate in percent of a bill's net amount before VAT. (greater than 0)
payment_terms_days integer or null Days from the document date to the due date, 0 to 365; waits for a second person like name. (min 0; max 365)
default_account string or null Code of the revenue (customer) or expense (vendor) account used on document lines that name no account, e.g. 6570.
street string or null Street of the postal address (up to 70 characters); used on QR-bills and XRechnung. (max length 70)
building_number string or null Building number of the postal address (up to 16 characters). (max length 16)
postal_code string or null Postal code of the address (up to 16 characters). (max length 16)
town string or null Town of the address (up to 35 characters). (max length 35)
leitweg_id string or null Customers: the Leitweg-ID of a German public buyer (validated, including its check digits); becomes the XRechnung buyer reference.
electronic_address string or null E-invoicing address (EN 16931 BT-34 / BT-49), e.g. an email address or a Peppol id.
electronic_address_scheme string or null Scheme of the electronic address (EAS code), e.g. EM (email), 0204 or 9930; needs an electronic_address.
status "active" | "draft" or null 'active' activates a draft party (as POST …/activate); 'draft' blocks its documents and payments again.
cash_discount_percent decimal string or null 0 removes the terms; waits like name. (min 0)
cash_discount_days integer or null Days within which the cash discount applies, 0 to 365; waits for a second person like name. (min 0; max 365)
credit_limit decimal string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed. "" removes the limit. Waits for a second person like name. (min 0)

Example request

curl -X PATCH "$ERP_URL/v1/entities/CH01/parties/C-DE?kind=value" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "language": "de",
  "parent": "C-GROUP",
  "payment_terms_days": 20
}'

Responses

Status Meaning Body
200 OK PartyCard
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "balances": [
    {
      "currency": "string",
      "open": "string",
      "overdue": "string",
      "on_account": "0.00",
      "open_documents": 1,
      "overdue_documents": 1
    }
  ],
  "pending_actions": [
    "string"
  ],
  "created_by": {},
  "activated_by": {},
  "activated_at": "2026-09-21T09:30:00Z",
  "pending": [
    {
      "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "action": "string",
      "requested_by": {},
      "requested_at": "2026-09-21T09:30:00Z",
      "reason": "string",
      "current": {},
      "proposed": {}
    }
  ],
  "payment_blockers": [
    {
      "code": "string",
      "message": "string",
      "details": {}
    }
  ],
  "vat_check": {
    "registry": "ch_uid",
    "status": "invalid",
    "vat_number": "string",
    "name": "string",
    "name_matches": true,
    "reference": "string",
    "checked_at": "2026-09-21T09:30:00Z",
    "checked_by": {}
  },
  "credit": {
    "party": "string",
    "name": "string",
    "currency": "string",
    "credit_limit": "string",
    "receivables": "string",
    "pending_invoices": "string",
    "open_orders": "string",
    "exposure": "string",
    "available": "string",
    "over_limit": true,
    "note": "string"
  },
  "parent": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "name": "string"
  },
  "merged_into": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "subsidiaries": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string"
    }
  ],
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ],
  "open_support_cases": 0,
  "breached_support_cases": 0,
  "active_subscriptions": 0,
  "open_opportunities": 0
}

POST /v1/entities/{entity}/parties/{party}/activate

Activate a draft customer or vendor

Activate a draft customer or vendor (four eyes).

A person with the approve scope who did not create the party activates it at once; anyone else's call (every call, when the approval policy says so) becomes an approval request (pending) for a second person. Agents are refused. Safe to repeat: a second call answers 409 (already active, or already requested).

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id activate_party_v1_entities__entity__parties__party__activate_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.
query kind "customer" | "vendor" or null customer or vendor; needed when one code names both a customer and a vendor (otherwise 409).

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/parties/C-DE/activate" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK PartyCard
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "balances": [
    {
      "currency": "string",
      "open": "string",
      "overdue": "string",
      "on_account": "0.00",
      "open_documents": 1,
      "overdue_documents": 1
    }
  ],
  "pending_actions": [
    "string"
  ],
  "created_by": {},
  "activated_by": {},
  "activated_at": "2026-09-21T09:30:00Z",
  "pending": [
    {
      "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "action": "string",
      "requested_by": {},
      "requested_at": "2026-09-21T09:30:00Z",
      "reason": "string",
      "current": {},
      "proposed": {}
    }
  ],
  "payment_blockers": [
    {
      "code": "string",
      "message": "string",
      "details": {}
    }
  ],
  "vat_check": {
    "registry": "ch_uid",
    "status": "invalid",
    "vat_number": "string",
    "name": "string",
    "name_matches": true,
    "reference": "string",
    "checked_at": "2026-09-21T09:30:00Z",
    "checked_by": {}
  },
  "credit": {
    "party": "string",
    "name": "string",
    "currency": "string",
    "credit_limit": "string",
    "receivables": "string",
    "pending_invoices": "string",
    "open_orders": "string",
    "exposure": "string",
    "available": "string",
    "over_limit": true,
    "note": "string"
  },
  "parent": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "name": "string"
  },
  "merged_into": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "subsidiaries": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string"
    }
  ],
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ],
  "open_support_cases": 0,
  "breached_support_cases": 0,
  "active_subscriptions": 0,
  "open_opportunities": 0
}

POST /v1/entities/{entity}/parties/{party}/merge

Merge a duplicate customer

Merge this customer, entered twice, into into, a customer of the same company (ADR-0089). Only a customer without business records of its own is merged: no document, payment, order, subscription, price list, mandate, won deal or request waiting for approval names it (409 party_merge_has_records lists what does). Its contacts, deals, activities and subsidiaries move to the customer that stays, its own field values fill the ones that one has none of, and it becomes inactive for good (merged_into on its card). Returns the card of the customer that stays. Vendors are not merged. A person's decision: 403 merge_agent for an agent. 422 merge_same for itself; 409 party_merged if either was merged already, party_merge_loop if the one that stays belongs to its group below it.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id merge_party_v1_entities__entity__parties__party__merge_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.

Request body

application/json (required): CustomerMerge

Field Type Required Description
into string yes Code or id of the customer that stays (same company). (min length 1)

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/parties/C-DE/merge" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "into": "C-CH"
}'

Responses

Status Meaning Body
200 OK PartyCard
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "balances": [
    {
      "currency": "string",
      "open": "string",
      "overdue": "string",
      "on_account": "0.00",
      "open_documents": 1,
      "overdue_documents": 1
    }
  ],
  "pending_actions": [
    "string"
  ],
  "created_by": {},
  "activated_by": {},
  "activated_at": "2026-09-21T09:30:00Z",
  "pending": [
    {
      "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "action": "string",
      "requested_by": {},
      "requested_at": "2026-09-21T09:30:00Z",
      "reason": "string",
      "current": {},
      "proposed": {}
    }
  ],
  "payment_blockers": [
    {
      "code": "string",
      "message": "string",
      "details": {}
    }
  ],
  "vat_check": {
    "registry": "ch_uid",
    "status": "invalid",
    "vat_number": "string",
    "name": "string",
    "name_matches": true,
    "reference": "string",
    "checked_at": "2026-09-21T09:30:00Z",
    "checked_by": {}
  },
  "credit": {
    "party": "string",
    "name": "string",
    "currency": "string",
    "credit_limit": "string",
    "receivables": "string",
    "pending_invoices": "string",
    "open_orders": "string",
    "exposure": "string",
    "available": "string",
    "over_limit": true,
    "note": "string"
  },
  "parent": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "name": "string"
  },
  "merged_into": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "subsidiaries": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string"
    }
  ],
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ],
  "open_support_cases": 0,
  "breached_support_cases": 0,
  "active_subscriptions": 0,
  "open_opportunities": 0
}

POST /v1/entities/{entity}/parties/{party}/status

Block a customer or vendor, set it inactive, or make it active again

Ask a second person to change the status (four eyes, as a change of key details): the answer lists the request in pending (action change_party_status), decided with POST /v1/approvals/{id}/approve or reject by someone other than the requester.

blocked: no new documents, orders or subscriptions for the party and nothing paid to it (payment proposals leave its bills out, payments and payment files refuse it); what it pays still settles its open items. Payments to it are blocked already while the block waits. inactive: no longer used, nothing paid to it or received from it; only a party without open items, documents or payments waiting for approval, open purchase orders or active subscriptions and recurring invoices (409 party_has_open_items). active makes a blocked or inactive party usable again; a draft has no status change (409 party_status_move), it is activated instead. People only (403 for agents and when the policy denies change_party_details); 409 for a move the rules do not allow or a request already waiting.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id change_party_status_v1_entities__entity__parties__party__status_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.
query kind "customer" | "vendor" or null customer or vendor; needed when one code names both a customer and a vendor (otherwise 409).

Request body

application/json (required): PartyStatusInput

Field Type Required Description
status "active" | "blocked" | "inactive" yes blocked: no new documents or orders, nothing paid to it. inactive: no longer used (only without open items). active: in use again.
reason string yes Why; the approver sees it and it is audited. (min length 1; max length 500)

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/parties/C-DE/status" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Disputed deliveries, legal review",
  "status": "blocked"
}'

Responses

Status Meaning Body
200 OK PartyCard
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "code": "string",
  "name": "string",
  "country": "string",
  "subdivision": "string",
  "vat_number": "string",
  "business": true,
  "split_payment": false,
  "withholding_code": "string",
  "withholding_rate": "string",
  "vat_unverified": false,
  "currency": "string",
  "payment_terms_days": 1,
  "email": "string",
  "iban": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "status": "active",
  "group_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "leitweg_id": "string",
  "electronic_address": "string",
  "electronic_address_scheme": "string",
  "cash_discount_percent": "string",
  "cash_discount_days": 1,
  "credit_limit": "string",
  "bank_accounts": [
    {
      "iban": "string",
      "bic": "string",
      "label": "string"
    }
  ],
  "contacts": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "role": "string",
      "email": "string",
      "phone": "string"
    }
  ],
  "parent_party_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "custom": {},
  "owner_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "language": "string",
  "default_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "created_at": "2026-09-21T09:30:00Z",
  "balances": [
    {
      "currency": "string",
      "open": "string",
      "overdue": "string",
      "on_account": "0.00",
      "open_documents": 1,
      "overdue_documents": 1
    }
  ],
  "pending_actions": [
    "string"
  ],
  "created_by": {},
  "activated_by": {},
  "activated_at": "2026-09-21T09:30:00Z",
  "pending": [
    {
      "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "action": "string",
      "requested_by": {},
      "requested_at": "2026-09-21T09:30:00Z",
      "reason": "string",
      "current": {},
      "proposed": {}
    }
  ],
  "payment_blockers": [
    {
      "code": "string",
      "message": "string",
      "details": {}
    }
  ],
  "vat_check": {
    "registry": "ch_uid",
    "status": "invalid",
    "vat_number": "string",
    "name": "string",
    "name_matches": true,
    "reference": "string",
    "checked_at": "2026-09-21T09:30:00Z",
    "checked_by": {}
  },
  "credit": {
    "party": "string",
    "name": "string",
    "currency": "string",
    "credit_limit": "string",
    "receivables": "string",
    "pending_invoices": "string",
    "open_orders": "string",
    "exposure": "string",
    "available": "string",
    "over_limit": true,
    "note": "string"
  },
  "parent": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "name": "string"
  },
  "merged_into": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "code": "string",
    "name": "string"
  },
  "subsidiaries": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string"
    }
  ],
  "possible_duplicates": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "code": "string",
      "name": "string",
      "status": "string",
      "same": [
        "iban"
      ],
      "message": "string"
    }
  ],
  "open_support_cases": 0,
  "breached_support_cases": 0,
  "active_subscriptions": 0,
  "open_opportunities": 0
}

POST /v1/entities/{entity}/parties/{party}/vat-check

Check a customer's or vendor's VAT number in its public register

Ask the public register of the party's VAT number (VIES, the Swiss UID register or HMRC) whether it is registered for VAT, as POST /v1/vat-registers/check does, and keep a definite answer (valid or invalid) on the card (vat_check) and in the audit trail.

For a UK number, when the entity has a UK VAT number of its own, HMRC also gives a consultation number (reference): the proof that the number was checked that day. Advice only: nothing is refused on the answer. unavailable (the register did not answer) and not_configured (this server has no access to the register yet, e.g. HMRC credentials not set up) keep the last answer. 422 no_vat_number when the party has none; 429 past 30 register checks a minute per organization.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id check_party_vat_number_v1_entities__entity__parties__party__vat_check_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
path party string yes Customer or vendor code, e.g. C-DE or V-BM.
query kind "customer" | "vendor" or null customer or vendor; needed when one code names both a customer and a vendor (otherwise 409).

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/parties/C-DE/vat-check" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK RegisterCheck
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "country": "string",
  "vat_number": "string",
  "registry": "ch_uid",
  "status": "invalid",
  "name": "string",
  "address": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "name_matches": true,
  "message": "string",
  "reference": "string",
  "checked_at": "2026-09-21T09:30:00Z",
  "cached": false
}

POST /v1/vat-registers/check

Check a VAT number against its public register

Ask the public register whether a VAT number is valid, and for the registered name.

EU numbers (and XI) are checked in VIES, Swiss UIDs in the UID register, UK numbers with HMRC (when the server is configured for it). The answer is advisory: invalid says the register does not know the number as registered for VAT, unavailable that it did not answer in time and the check can be repeated. Definite answers are kept for a day (cached). Nothing is stored or changed. The number and name go in the body, never the URL. An organization may make 30 checks a minute that reach a register (cached answers do not count); beyond that the answer is 429 with retry_after_seconds.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id check_vat_number_v1_vat_registers_check_post

Request body

application/json (required): RegisterCheckInput

Field Type Required Description
country string or null ISO 3166-1 alpha-2 country of the party, e.g. DE. A number shaped like another country's (e.g. an IE registration of a US company, ATU… at a German address) is checked in that country's register. Omitted: the country the number's prefix names (no_register for a number without one); the answer says which. (pattern ^[A-Za-z]{2}$)
vat_number string yes The VAT number as written, e.g. DE811569869 or CHE-123.456.788 MWST. (min length 4; max length 40)
name string or null The party's name as you have it: name_matches says whether the register's name is the same company's. (max length 200)

Example request

curl -X POST "$ERP_URL/v1/vat-registers/check" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "country": "DE",
  "name": "Muster Lieferant GmbH",
  "vat_number": "DE811569869"
}'

Responses

Status Meaning Body
200 OK RegisterCheck
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "country": "string",
  "vat_number": "string",
  "registry": "ch_uid",
  "status": "invalid",
  "name": "string",
  "address": "string",
  "street": "string",
  "building_number": "string",
  "postal_code": "string",
  "town": "string",
  "name_matches": true,
  "message": "string",
  "reference": "string",
  "checked_at": "2026-09-21T09:30:00Z",
  "cached": false
}

Schemas

Balance

Open posted documents of a party in one currency (credit notes count negative).

Field Type Required Description
currency string yes ISO 4217 currency of the amounts.
open string yes Open amount of posted documents (credit notes negative), less what is on account (on_account): what the party owes, or is owed, in this currency.
overdue string yes The part of it due before the as_of day.
on_account string What is left on account of the party's posted payments, not yet applied to an invoice or bill (ADR-0045): received from a customer, or paid to a vendor, ahead. Positive; open is already less it. (default "0.00")
open_documents integer yes Number of documents with an open amount.
overdue_documents integer yes Number of those that are overdue.

CreditExposure

The customers of a company with a credit limit, and their exposure today.

Field Type Required Description
entity string yes The company's code.
as_of string (date) yes Today where the company is: amounts in another currency are converted at this day's ECB reference rate.
customers array of CreditPosition yes Every customer with a credit limit, those over it first, then by code.

CreditPosition

One customer's credit exposure against its credit limit, in the customer's currency.

Field Type Required Description
party string yes The customer's code, e.g. C-SE.
name string yes The customer's name.
currency string yes The customer's currency: every amount here is in it.
credit_limit string or null yes The most the customer may owe; null for no limit.
receivables string or null yes What the customer owes on posted documents: open invoices less open credit notes and payments received on account.
pending_invoices string or null yes The totals of its invoices waiting for a second person's approval.
open_orders string or null yes What is left to invoice on its open sales orders, VAT included.
exposure string or null yes receivables + pending_invoices + open_orders; null when an amount in another currency has no exchange rate today (note).
available string or null yes credit_limit - exposure: what may still be invoiced or ordered; negative when over the limit; null without a limit.
over_limit boolean yes true when the exposure is above the credit limit.
note string or null Why the exposure could not be worked out (an exchange rate missing today).

CustomerMerge

Field Type Required Description
into string yes Code or id of the customer that stays (same company). (min length 1)

NewContact

A person at a new customer or vendor.

Field Type Required Description
first_name string or null First name. (min length 1; max length 100)
role string or null Role or department, e.g. Head of purchasing. A role that says billing, accounting or Buchhaltung makes the contact one an invoice goes to by default. (max length 100)
email string or null E-mail address. (max length 200)
phone string or null Phone number. (max length 50)
mobile string or null Mobile number. (max length 50)
last_name string yes Last name. A name sent instead is split: its last word is the last name, the words before it the first name. (min length 1; max length 100)

PartyBankAccount

A further account of a customer or vendor next to its IBAN, e.g. a QR-IBAN.

Field Type Required Description
iban string yes IBAN of the account, 5 to 42 characters; stored without spaces. (min length 5; max length 42)
bic string or null BIC/SWIFT code of the bank (8 or 11 characters). (pattern ^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$)
label string or null Short label for the account, e.g. QR-IBAN. (max length 70)

PartyCard

One customer or vendor with everything its card shows.

Field Type Required Description
id string (uuid) yes Id of the customer or vendor.
kind string yes customer or vendor.
code string yes The party's short code, e.g. C-DE; unique per kind in an entity.
name string yes Legal name.
country string yes ISO 3166-1 alpha-2 country code.
subdivision string or null yes ISO 3166-2 subdivision used for tax, if any.
vat_number string or null yes VAT or UID number.
business boolean yes true for a business (B2B), false for a private person (B2C).
split_payment boolean Italy: true for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount. (default false)
withholding_code string or null Vendors: the withholding tax code its bills keep back (IT-RA-20, custom); null for none.
withholding_rate string or null Vendors: the withholding rate in percent of a bill's net amount before VAT.
vat_unverified boolean true for a vendor created from a received document whose vat_number (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of vat_number that passes the check clears it. (default false)
currency string yes ISO 4217 currency of the party's documents and payments.
payment_terms_days integer yes Days from the document date to the due date.
email string or null yes Contact email address.
iban string or null yes IBAN payments to the party go to, without spaces.
street string or null Street of the postal address.
building_number string or null Building number of the postal address.
postal_code string or null Postal code of the address.
town string or null Town of the address.
status string active; draft until a second person activates it (a draft is neither booked nor paid); blocked (no new documents or orders, nothing paid to it; what it pays still settles its open items) or inactive (no longer used, no open items). (default "active")
group_entity_id string (uuid) or null Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (ic_ar_control, ic_ap_control) and are mirrored in that entity.
leitweg_id string or null Leitweg-ID of a German public buyer (XRechnung buyer reference).
electronic_address string or null E-invoicing address (EN 16931 BT-34 / BT-49).
electronic_address_scheme string or null EAS code of the electronic address, e.g. EM.
cash_discount_percent string or null Cash discount (Skonto) percent if paid within the days.
cash_discount_days integer or null Days within which the cash discount applies.
credit_limit string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed.
bank_accounts array of PartyBankAccount Further accounts payments may go to.
contacts array of PartyContact People at the party (GET /v1/contacts?party_id=).
parent_party_id string (uuid) or null Id of the company it belongs to (a party of the same kind).
custom object Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people.
language string or null Correspondence language (de, fr, it, en, sv, rm).
default_account_id string (uuid) or null Id of the revenue or expense account used on lines without an account.
created_at string (date-time) or null When the party was created (UTC).
balances array of Balance Open posted documents per currency: open and overdue amount and number of documents; credit notes count negative.
pending_actions array of string Requests waiting for a second person: activate_party, change_bank_details.
created_by object or null From the audit trail.
activated_by object or null Who activated it last, if it started as a draft.
activated_at string (date-time) or null When the party was last activated (UTC).
pending array of PendingRequest The requests waiting for a second person, with who asked and why.
payment_blockers array of BlockerOut Why no payment to the party can be released now.
vat_check PartyVatCheck or null The public register's last answer for the current VAT number, with its consultation reference as proof; null until it is checked from the card.
credit CreditPosition or null Customers with a credit limit: what the customer owes and has on order against its limit today, and the credit still available; null without a limit.
parent PartyRef or null The company it belongs to.
owner Person or null The owner (owner_user_id), by name.
merged_into PartyRef or null The customer this duplicate was merged into (it is inactive).
subsidiaries array of PartyRef The parties that name it as their parent company.
possible_duplicates array of PossibleDuplicate Other customers or vendors of the same company with the same VAT number, an IBAN in common or the same name.
open_support_cases integer Support cases of this customer that are open or waiting on the customer. (default 0)
breached_support_cases integer Support cases of this customer where a service level is breached. (default 0)
active_subscriptions integer Active recurring subscriptions of this customer. (default 0)
open_opportunities integer Open sales pipeline deals (opportunities) for this customer. (default 0)

PartyContact

A person at a customer or vendor, as its card lists them.

Field Type Required Description
id string (uuid) yes Id of the contact (GET /v1/contacts/{contact_id}).
name string yes First and last name.
role string or null Role or department, e.g. Buchhaltung.
email string or null E-mail address.
phone string or null Phone number.

PartyCreated

A new customer or vendor, with the existing ones it may duplicate.

Field Type Required Description
id string (uuid) yes Id of the customer or vendor.
kind string yes customer or vendor.
code string yes The party's short code, e.g. C-DE; unique per kind in an entity.
name string yes Legal name.
country string yes ISO 3166-1 alpha-2 country code.
subdivision string or null yes ISO 3166-2 subdivision used for tax, if any.
vat_number string or null yes VAT or UID number.
business boolean yes true for a business (B2B), false for a private person (B2C).
split_payment boolean Italy: true for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount. (default false)
withholding_code string or null Vendors: the withholding tax code its bills keep back (IT-RA-20, custom); null for none.
withholding_rate string or null Vendors: the withholding rate in percent of a bill's net amount before VAT.
vat_unverified boolean true for a vendor created from a received document whose vat_number (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of vat_number that passes the check clears it. (default false)
currency string yes ISO 4217 currency of the party's documents and payments.
payment_terms_days integer yes Days from the document date to the due date.
email string or null yes Contact email address.
iban string or null yes IBAN payments to the party go to, without spaces.
street string or null Street of the postal address.
building_number string or null Building number of the postal address.
postal_code string or null Postal code of the address.
town string or null Town of the address.
status string active; draft until a second person activates it (a draft is neither booked nor paid); blocked (no new documents or orders, nothing paid to it; what it pays still settles its open items) or inactive (no longer used, no open items). (default "active")
group_entity_id string (uuid) or null Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (ic_ar_control, ic_ap_control) and are mirrored in that entity.
leitweg_id string or null Leitweg-ID of a German public buyer (XRechnung buyer reference).
electronic_address string or null E-invoicing address (EN 16931 BT-34 / BT-49).
electronic_address_scheme string or null EAS code of the electronic address, e.g. EM.
cash_discount_percent string or null Cash discount (Skonto) percent if paid within the days.
cash_discount_days integer or null Days within which the cash discount applies.
credit_limit string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed.
bank_accounts array of PartyBankAccount Further accounts payments may go to.
contacts array of PartyContact People at the party (GET /v1/contacts?party_id=).
parent_party_id string (uuid) or null Id of the company it belongs to (a party of the same kind).
custom object Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people.
language string or null Correspondence language (de, fr, it, en, sv, rm).
default_account_id string (uuid) or null Id of the revenue or expense account used on lines without an account.
created_at string (date-time) or null When the party was created (UTC).
possible_duplicates array of PossibleDuplicate Customers or vendors of the same company with the same VAT number, an IBAN in common or the same name. The party is created anyway (a vendor as a draft); check them before it is activated.

PartyInput

Field Type Required Description
kind "customer" | "vendor" yes customer or vendor; a code is unique per kind in an entity.
code string or null Leave it out and the party gets the company's next number: C-00001 for a customer, V-00001 for a vendor, counted per company without gaps. Give one (up to 40 characters, e.g. the number of the system before) only to keep it; it is how documents and URLs name the party, and never changes. (min length 1; max length 40)
name string yes Legal name of the customer or vendor.
country string or null ISO 3166-1 alpha-2 country code, e.g. DE; drives the place of supply of the tax determination. Omitted: the country its VAT number names by its prefix, else the company's. (pattern ^[A-Z]{2}$)
subdivision string or null ISO 3166-2 subdivision where it matters for tax, e.g. DE-BY, or a US customer's state (US-CA), which decides its sales tax. A Spanish postal code gives it when left empty: 35 and 38 the Canary Islands (ES-CN), 51 Ceuta (ES-CE), 52 Melilla (ES-ML); one of another country, or that the postal code contradicts, is refused (422 party_subdivision_mismatch). (pattern ^[A-Z]{2}-[A-Z0-9]{1,3}$)
vat_number string or null VAT or UID number, e.g. DE811569869 or CHE-116.281.710 MWST; for a party of an EU country, the UK, Norway, Switzerland or Liechtenstein its format is checked, and its check digit for CH, DE, FR, IT, ES and BE (422 vat_number_invalid).
business boolean true for a business (B2B), false for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person. (default true)
split_payment boolean Customers of an Italian company: true for one under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter: public bodies and the companies the law lists). Its invoices show the VAT but it owes only the net amount and pays the VAT to the State; the VAT returns leave that VAT out. Default false. (default false)
currency string or null ISO 4217 currency of the party's documents and payments, e.g. EUR: functional or with exchange rates (422 party_currency_without_rates). Omitted: its country's currency when the company has exchange rates for it, else the company's. (pattern ^[A-Z]{3}$)
withholding_code string or null Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (GET /v1/entities/{entity}/withholding-tax/codes lists the codes of the company's country, e.g. IT-RA-20), or custom with withholding_rate; null for none. Changing it once a bill of the vendor is posted waits for a second person. (max length 20)
withholding_rate decimal string or null With withholding_code custom: the rate in percent of a bill's net amount before VAT, e.g. 18.5; a code of the table takes its own rate. (greater than 0)
payment_terms_days integer Days from the document date to the due date, 0 to 365; default 30. (min 0; max 365; default 30)
default_account string or null Revenue/expense account code.
email string or null Contact email address.
iban string or null IBAN payments to the party go to, stored without spaces; one of your own companies' accounts is refused (422 party_own_bank_account).
bank_accounts array of PartyBankAccount Further accounts payments may go to (a QR-IBAN).
language "de" | "en" | "fr" | "it" | "rm" | "sv" or null Correspondence language. Omitted: its country's, where the country has one of ours (DE and AT de, FR fr, IT it, SE sv, GB and US en); none for a country of several (CH, BE, CA): set it there.
contacts array of NewContact People at the party; later ones are added with POST /v1/contacts.
parent string or null Code (or id) of the company it belongs to, of the same kind.
custom map of string | number | integer | boolean or null Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people. Omitted: you.
street string or null Street of the postal address (up to 70 characters); used on QR-bills and XRechnung. (max length 70)
building_number string or null Building number of the postal address (up to 16 characters). (max length 16)
postal_code string or null Postal code of the address (up to 16 characters). (max length 16)
town string or null Town of the address (up to 35 characters). (max length 35)
leitweg_id string or null Customers: Leitweg-ID of a German public buyer (XRechnung buyer reference).
electronic_address string or null E-invoicing address (BT-34/BT-49), e.g. an email or Peppol id.
electronic_address_scheme string or null EAS code of the electronic address, e.g. EM (email), 0204, 9930.
status "active" | "draft" draft until a second person activates it. A vendor (or a party with bank details) created by an agent, and a vendor created from an e-invoice, start as draft; otherwise 'active' needs the approval policy to allow activate_party. (default "active")
cash_discount_percent decimal string or null Cash discount (Skonto) percent if paid within cash_discount_days, e.g. 2. (greater than 0)
cash_discount_days integer or null Days within which the cash discount applies, 0 to 365. (min 0; max 365)
credit_limit decimal string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed. (min 0)
source_sha256 string or null SHA-256 of the bill this vendor was read from (the bill wizard sends the sha256 of POST /v1/agents/bill-capture/read). The audit entry and the activation request then say that its bank details come from that invoice, and what the public VAT register said about its number: the approver sees what nobody has confirmed. (pattern ^[0-9a-f]{64}$)

PartyRef

Another customer or vendor named by this one (its parent company or a subsidiary).

Field Type Required Description
id string (uuid) yes Id of the party.
code string yes Its code.
name string yes Its name.

PartyRow

A customer or vendor in a list, with its open balance and pending requests.

Field Type Required Description
id string (uuid) yes Id of the customer or vendor.
kind string yes customer or vendor.
code string yes The party's short code, e.g. C-DE; unique per kind in an entity.
name string yes Legal name.
country string yes ISO 3166-1 alpha-2 country code.
subdivision string or null yes ISO 3166-2 subdivision used for tax, if any.
vat_number string or null yes VAT or UID number.
business boolean yes true for a business (B2B), false for a private person (B2C).
split_payment boolean Italy: true for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount. (default false)
withholding_code string or null Vendors: the withholding tax code its bills keep back (IT-RA-20, custom); null for none.
withholding_rate string or null Vendors: the withholding rate in percent of a bill's net amount before VAT.
vat_unverified boolean true for a vendor created from a received document whose vat_number (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of vat_number that passes the check clears it. (default false)
currency string yes ISO 4217 currency of the party's documents and payments.
payment_terms_days integer yes Days from the document date to the due date.
email string or null yes Contact email address.
iban string or null yes IBAN payments to the party go to, without spaces.
street string or null Street of the postal address.
building_number string or null Building number of the postal address.
postal_code string or null Postal code of the address.
town string or null Town of the address.
status string active; draft until a second person activates it (a draft is neither booked nor paid); blocked (no new documents or orders, nothing paid to it; what it pays still settles its open items) or inactive (no longer used, no open items). (default "active")
group_entity_id string (uuid) or null Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (ic_ar_control, ic_ap_control) and are mirrored in that entity.
leitweg_id string or null Leitweg-ID of a German public buyer (XRechnung buyer reference).
electronic_address string or null E-invoicing address (EN 16931 BT-34 / BT-49).
electronic_address_scheme string or null EAS code of the electronic address, e.g. EM.
cash_discount_percent string or null Cash discount (Skonto) percent if paid within the days.
cash_discount_days integer or null Days within which the cash discount applies.
credit_limit string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed.
bank_accounts array of PartyBankAccount Further accounts payments may go to.
contacts array of PartyContact People at the party (GET /v1/contacts?party_id=).
parent_party_id string (uuid) or null Id of the company it belongs to (a party of the same kind).
custom object Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people.
language string or null Correspondence language (de, fr, it, en, sv, rm).
default_account_id string (uuid) or null Id of the revenue or expense account used on lines without an account.
created_at string (date-time) or null When the party was created (UTC).
balances array of Balance Open posted documents per currency: open and overdue amount and number of documents; credit notes count negative.
pending_actions array of string Requests waiting for a second person: activate_party, change_bank_details.

PartyStatusInput

A request to block a customer or vendor, set it inactive, or make it active again.

Field Type Required Description
status "active" | "blocked" | "inactive" yes blocked: no new documents or orders, nothing paid to it. inactive: no longer used (only without open items). active: in use again.
reason string yes Why; the approver sees it and it is audited. (min length 1; max length 500)

PartyUpdate

Fields that can be changed (null leaves a field as is, "" clears it).

Bank details (iban, bank_accounts) are not changed at once: the change waits for a second person's approval and payments are blocked meanwhile, as are key details of a party past draft or with posted documents. status: active does what the activate operation does.

Field Type Required Description
name string or null New legal name; once the party is past draft, or a document of it is posted or pending approval, this waits for a second person.
country string or null New ISO 3166-1 alpha-2 country; waits for a second person like name. (pattern ^[A-Z]{2}$)
subdivision string or null ISO 3166-2 subdivision where it matters for tax, e.g. DE-BY, or a US customer's state (US-CA); empty clears it. A Spanish postal code gives it as on create (422 party_subdivision_mismatch on a contradiction); a change waits for a second person like name. (pattern ^([A-Z]{2}-[A-Z0-9]{1,3})?$)
vat_number string or null New VAT or UID number (format checked as on create, 422); waits for a second person like name.
business boolean or null true for a business (B2B), false for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person.
split_payment boolean or null Customers of an Italian company: true for one under split payment (DPR 633/1972 art. 17-ter); applies to invoices drafted from then on.
currency string or null New ISO 4217 currency: the functional currency or one with exchange rates (422 party_currency_without_rates); waits for a second person like name. (pattern ^[A-Z]{3}$)
email string or null Contact email address.
iban string or null New IBAN, stored without spaces. It is not applied at once: a second person must approve it and payments to the party are blocked meanwhile. "" clears it.
bank_accounts array of PartyBankAccount or null New list of further bank accounts; replaces the list. Waits for a second person's approval like iban.
language "de" | "en" | "fr" | "it" | "rm" | "sv" | "" or null Correspondence language (de, fr, it, en, sv, rm); "" clears.
parent string or null Code (or id) of the company it belongs to; "" clears it.
custom map of string | number | integer | boolean or null or null Values of the organization's own fields (GET /v1/custom-fields) by key, e.g. {"industry": "Retail"}: text, a number, a date (2026-10-23), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value.
owner_user_id string (uuid) or null New owner. Customers: the sales person who looks after it (GET /v1/people); a vendor has none. Who sees only their own or their team's records gives it to one of those people.
withholding_code string or null Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (GET /v1/entities/{entity}/withholding-tax/codes lists the codes of the company's country, e.g. IT-RA-20), or custom with withholding_rate; "" removes it. Waits for a second person like name. (max length 20)
withholding_rate decimal string or null With withholding_code custom: the rate in percent of a bill's net amount before VAT. (greater than 0)
payment_terms_days integer or null Days from the document date to the due date, 0 to 365; waits for a second person like name. (min 0; max 365)
default_account string or null Code of the revenue (customer) or expense (vendor) account used on document lines that name no account, e.g. 6570.
street string or null Street of the postal address (up to 70 characters); used on QR-bills and XRechnung. (max length 70)
building_number string or null Building number of the postal address (up to 16 characters). (max length 16)
postal_code string or null Postal code of the address (up to 16 characters). (max length 16)
town string or null Town of the address (up to 35 characters). (max length 35)
leitweg_id string or null Customers: the Leitweg-ID of a German public buyer (validated, including its check digits); becomes the XRechnung buyer reference.
electronic_address string or null E-invoicing address (EN 16931 BT-34 / BT-49), e.g. an email address or a Peppol id.
electronic_address_scheme string or null Scheme of the electronic address (EAS code), e.g. EM (email), 0204 or 9930; needs an electronic_address.
status "active" | "draft" or null 'active' activates a draft party (as POST …/activate); 'draft' blocks its documents and payments again.
cash_discount_percent decimal string or null 0 removes the terms; waits like name. (min 0)
cash_discount_days integer or null Days within which the cash discount applies, 0 to 365; waits for a second person like name. (min 0; max 365)
credit_limit decimal string or null Customers: the most the customer may owe, in its currency (currency), e.g. 100000; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed. "" removes the limit. Waits for a second person like name. (min 0)

PartyVatCheck

The register's last definite answer for a customer's or vendor's VAT number.

Field Type Required Description
registry "ch_uid" | "uk_hmrc" | "vies" yes The register that answered.
status "invalid" | "valid" yes valid: registered for VAT; invalid: the register does not know it.
vat_number string yes The number as it was asked, compacted.
name string or null The registered name, if given.
name_matches boolean or null Whether the registered name matches the party's name.
reference string or null The register's consultation reference, kept as proof (HMRC's consultation number when your entity has a UK VAT number).
checked_at string (date-time) yes When the register answered (UTC).
checked_by object or null Who asked.

PendingRequest

Field Type Required Description
approval_id string (uuid) yes Id of the approval request; decide it with POST /v1/approvals/{id}/approve or reject.
action string yes activate_party, change_bank_details, change_party_details or change_party_status.
requested_by object yes The actor (type, id) that asked.
requested_at string (date-time) yes When it was requested (UTC).
reason string yes Why a second person is needed.
current object or null The values now (changes).
proposed object or null The values once approved (changes).

PossibleDuplicate

Another customer or vendor of the same company this one may duplicate.

Field Type Required Description
id string (uuid) yes Id of the other customer or vendor.
code string yes Its code, e.g. V-ALP.
name string yes Its legal name.
status string yes Its status: draft, active, blocked or inactive.
same array of "iban" | "name" | "vat_number" yes What both have in common: the VAT number (compared as a registration), an IBAN, or the name (case, punctuation and legal forms such as AG or GmbH ignored).
message string yes The warning in words, e.g. Possible duplicate of V-ALP Alpen Werkzeug AG: same VAT number and IBAN.

RegisterCheck

What the public register says about a VAT number. Advisory: nothing is refused on it.

Field Type Required Description
country string yes ISO 3166-1 alpha-2 country the number was checked for.
vat_number string yes The number as it was sent to the register, compacted.
registry "ch_uid" | "uk_hmrc" | "vies" or null yes vies (EU VIES, also XI for Northern Ireland), ch_uid (Swiss UID register) or uk_hmrc (HMRC's VAT number check); null when the country has none here.
status "invalid" | "no_register" | "not_configured" | "unavailable" | "valid" yes valid (the register knows the number as registered for VAT), invalid (it does not), unavailable (the register did not answer: try again later), not_configured (this server has no access to the register yet, e.g. HMRC without its credentials: the number was not checked) or no_register (no register is checked for this country).
name string or null The registered name, when the register gives one.
address string or null The registered address on one line, when the register gives one.
street string or null Street, when the register splits it.
building_number string or null Building number, if given.
postal_code string or null Postal code, if given.
town string or null Town, if given.
name_matches boolean or null Whether the registered name matches name of the request (case, punctuation and legal-form suffixes ignored); null when either is missing.
message string or null Why the number is invalid or the register unavailable.
reference string or null The register's reference for this consultation, kept as proof that the number was checked: HMRC's consultation number, given when the check names your own UK VAT number as the one asking (a customer or vendor card's check does).
checked_at string (date-time) yes When the register answered (UTC).
cached boolean true when the answer came from the last day's cache. (default false)

RegisterCheckInput

A VAT number to check, in the body: a sole trader's number and name are personal data and stay out of URLs and access logs.

Field Type Required Description
country string or null ISO 3166-1 alpha-2 country of the party, e.g. DE. A number shaped like another country's (e.g. an IE registration of a US company, ATU… at a German address) is checked in that country's register. Omitted: the country the number's prefix names (no_register for a number without one); the answer says which. (pattern ^[A-Za-z]{2}$)
vat_number string yes The VAT number as written, e.g. DE811569869 or CHE-123.456.788 MWST. (min length 4; max length 40)
name string or null The party's name as you have it: name_matches says whether the register's name is the same company's. (max length 200)
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3