A customer represents a person or company that purchases your products and services. Customers are the foundation of your billing relationship - every subscription, invoice, and payment is tied to a customer record.
Each customer has a billing profile including address, preferred currency, tax identifiers, and custom fields. Customers can be tagged for segmentation, merged when duplicates are discovered, and validated through identity verification providers.
Key concepts:
- External ID - your internal identifier for this customer, used for idempotent upserts
- Billing model - controls how charges are calculated (prepaid, postpaid, or hybrid)
- Customer type -
individualorcompany, affects tax treatment and invoice formatting - Metadata - arbitrary key-value pairs for your own bookkeeping
List customers
Returns a paginated list of customers with optional status and tag filters.
query Parameters
created_atFilter on created_at (date-time). Operators: eq, gt, gte, lt, lte — dot grammar, e.g. created_at.gt=value; a bare created_at=value means eq.
customer_typeFilter on customer_type (enum). Operators: eq, in — dot grammar, e.g. customer_type.in=value; a bare customer_type=value means eq. A bare comma-separated value is in-sugar: customer_type=a,b means customer_type.in=a,b. Legal values: BUSINESS, CONSUMER, UNKNOWN.
emailFilter on email (string). Operators: eq, in, contains — dot grammar, e.g. email.in=value; a bare email=value means eq. A bare comma-separated value is in-sugar: email=a,b means email.in=a,b.
external_idFilter on external_id (string). Operators: eq, in — dot grammar, e.g. external_id.in=value; a bare external_id=value means eq. A bare comma-separated value is in-sugar: external_id=a,b means external_id.in=a,b.
nameFilter on name (string). Operators: eq, in, contains — dot grammar, e.g. name.in=value; a bare name=value means eq. A bare comma-separated value is in-sugar: name=a,b means name.in=a,b.
preferred_currencyFilter on preferred_currency (string). Operators: eq, in — dot grammar, e.g. preferred_currency.in=value; a bare preferred_currency=value means eq. A bare comma-separated value is in-sugar: preferred_currency=a,b means preferred_currency.in=a,b.
updated_atFilter on updated_at (date-time). Operators: eq, gt, gte, lt, lte — dot grammar, e.g. updated_at.gt=value; a bare updated_at=value means eq.
vat_validation_statusFilter on vat_validation_status (enum). Operators: eq, in — dot grammar, e.g. vat_validation_status.in=value; a bare vat_validation_status=value means eq. A bare comma-separated value is in-sugar: vat_validation_status=a,b means vat_validation_status.in=a,b. Legal values: UNVALIDATED, PENDING, VALID, INVALID, ERROR, MANUAL, MAINTENANCE.
limitPage size. Values above the server-side cap are clamped (standard default 50, cap 200; a few document-heavy lists use larger windows). Invalid values fall back to the default.
cursorOpaque continuation token from the previous response's pagination.cursor. Omit for the first page. Cursors are stateless and do not expire, but are only valid for the list and filters that produced them.
searchCase-insensitive substring match over name, email and external_id; relevance-ranked (exact > prefix > substring) unless an explicit sort is given
statusFilter by status. Filterable fields (status, external_id, name, email, preferred_currency, vat_validation_status, customer_type, created_at, updated_at) accept apifilter operator suffixes in the dot grammar, e.g. status.in=A,B
tagFilter by tag name (repeatable, containment semantics)
promoFilter by promotion UUID (repeatable): customers holding a redemption
countsComma-separated countable fields (status, customer_type, mode, vat_validation_status, preferred_currency) to include per-value counts for
sortOrdering: created_at, name, email, status, customer_type, preferred_currency or vat_validation_status, each with an optional :asc/:desc suffix (default created_at:desc). An unknown value is rejected. Cursors are bound to the ordering that issued them, so changing sort mid-walk needs a fresh first page. Sorting suppresses relevance ranking when search is also given.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List customers › Responses
OK
Create a customer
Creates a new customer with an auto-provisioned wallet.
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Create a customer › Request Body
customer_typeBuyer classification driving tax treatment and invoicing: BUSINESS, CONSUMER, or UNKNOWN. Required.
emailPrimary contact email; the default recipient for invoices and portal links. Required.
nameCustomer's display / legal name as it appears on invoices. Required.
auto_validate_vatPer-request hint: null = auto-validate VAT after creation when eligible, false = skip the auto-trigger. Still gated by the workspace and per-customer VAT disable flags.
Postal billing address; when provided, line1, city, postal_code and country are required and it is used for tax determination.
contact_nameDisplay name for the primary billing contact - the natural person behind a company account. Defaults to the customer's own name when omitted.
Values for the organization's configured custom-field definitions.
Default auto-topup amount as {value, currency}, MAJOR units. Currency should match preferred_currency.
default_auto_topup_enabledWhether the auto-provisioned wallet enables automatic top-up.
Default wallet credit limit as {value, currency}, MAJOR units. Currency should match the customer's preferred_currency; it is echoed from preferred_currency on read.
Default low-balance threshold as {value, currency}, MAJOR units. Currency should match preferred_currency.
Default wallet max balance as {value, currency}, MAJOR units. Currency should match preferred_currency.
Default wallet max single-credit as {value, currency}, MAJOR units. Currency should match preferred_currency.
EN 16931 BG-15 DELIVER TO ADDRESS, when supplies are delivered somewhere other than the billing address; when provided, line1, city, postal_code and country are required.
delivery_location_idEN 16931 BT-71, the deliver-to location identifier (GLN or agreed site code).
delivery_party_nameEN 16931 BT-70, the deliver-to party name.
disabled_providersPayment provider ids that must not be used to charge this customer; each must be a known provider and unique.
einvoice_profileStanding per-customer e-invoice format (e.g. XRECHNUNG_3_0_UBL); omit to inherit. Must name a profile this deployment still offers - see GET /v1/e-invoicing/profiles.
external_idCaller-assigned external identifier for cross-referencing in your own systems; must be unique per organization when set.
localeBCP-47-style locale (one of en, de, fr, es, it, pt, nl, ja) for invoice and communication language.
Free-form key/value metadata for caller use; not interpreted by billing.
modeWallet settlement mode for the auto-provisioned wallet: PREPAID or POSTPAID.
payment_terms_daysNet payment terms in days for invoice due dates (0-365); null = inherit the customer-type default, then the organization setting.
peppol_idPeppol participant identifier in scheme:value form used as the buyer endpoint for e-invoice delivery.
prefer_einvoicePer-customer master switch for structured e-invoicing; null = inherit the workspace's rollout audience, true/false decide outright.
preferred_currencyISO 4217 currency the customer is billed in; seeds the auto-provisioned wallet.
preferred_providerPreferred payment provider id tried first when charging; must be a known provider and must not also appear in disabled_providers.
Tax identifiers keyed by scheme (e.g. "vat"); required for BUSINESS customers in EU countries.
vat_validation_disabledWhen true, automatic VAT-ID validation is skipped for this customer; requires vat_validation_disabled_reason.
vat_validation_disabled_reasonReason recorded when vat_validation_disabled is true; required in that case.
Create a customer › Responses
Created
Merge customers
Merges two customers into one.
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Merge customers › Request Body
source_customer_idCustomer whose records are moved and which is then retired; must differ from target_customer_id.
strategyPREVIEW to compute the merge result without applying it, or MOVE_ALL to perform the merge.
target_customer_idSurviving customer that absorbs the source's records.
Merge customers › Responses
OK
Get a customer
Returns a single customer by UUID.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get a customer › Responses
OK
Delete a customer
Soft-deletes a customer by UUID.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Delete a customer › Responses
No Content
Update a customer
Updates an existing customer by UUID.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Update a customer › Request Body
auto_validate_vatPer-request hint: null = auto-validate VAT after update when eligible, false = skip the auto-trigger. Still gated by the workspace and per-customer VAT disable flags.
Replacement billing address; omit to leave unchanged.
Replacement custom-field values; omit to leave unchanged.
customer_typeNew buyer classification: BUSINESS, CONSUMER, or UNKNOWN; omit to leave unchanged.
Default auto-topup amount as {value, currency}, MAJOR units. Currency should match preferred_currency.
default_auto_topup_enabledNew auto-top-up default for wallets seeded from this customer; omit to leave unchanged.
Default wallet credit limit as {value, currency}, MAJOR units. Currency should match preferred_currency.
Default low-balance threshold as {value, currency}, MAJOR units. Currency should match preferred_currency.
Default wallet max balance as {value, currency}, MAJOR units. Currency should match preferred_currency.
Default wallet max single-credit as {value, currency}, MAJOR units. Currency should match preferred_currency.
Replacement EN 16931 BG-15 deliver-to address; when provided, line1, city, postal_code and country are required. Omit to leave unchanged.
delivery_location_idNew EN 16931 BT-71 deliver-to location identifier; empty string clears it.
delivery_party_nameNew EN 16931 BT-70 deliver-to party name; empty string clears it.
disabled_providersReplacement list of disabled payment provider ids; omit to leave unchanged, empty array to clear.
einvoice_profileNew standing per-customer e-invoice format (e.g. XRECHNUNG_3_0_UBL); empty string clears it back to inherit. Must name a profile this deployment still offers - see GET /v1/e-invoicing/profiles.
emailNew primary contact email; omit to leave unchanged, cannot be set empty.
external_idNew caller-assigned external identifier; omit to leave unchanged.
localeNew locale (one of en, de, fr, es, it, pt, nl, ja); omit to leave unchanged.
Replacement free-form key/value metadata; omit to leave unchanged.
nameNew display / legal name; omit to leave unchanged, cannot be set empty.
payment_terms_daysNew net payment terms in days (0-365); omit to leave unchanged.
peppol_idNew Peppol participant identifier (scheme:value); empty string clears it.
prefer_einvoiceNew per-customer e-invoicing switch; omit to leave unchanged.
preferred_currencyNew ISO 4217 billing currency; must be allowed by the workspace billing-currency policy.
preferred_providerNew preferred payment provider id; empty string clears it. Must be a known provider and must not appear in disabled_providers.
statusNew lifecycle status: active, suspended, or churned; omit to leave unchanged.
Replacement tax identifiers keyed by scheme; omit to leave unchanged.
vat_validation_disabledWhen true, disables automatic VAT-ID validation; requires vat_validation_disabled_reason.
vat_validation_disabled_reasonReason recorded when vat_validation_disabled is true; required in that case.
Update a customer › Responses
OK
List a customer's contacts
Every contact on file for the customer, ordered billing, technical, admin, e-invoicing, primary first. A contact's role decides which emails it receives; the primary contact of a role is the address those emails are sent to. The list is small and bounded by design, so it is returned whole and is not paginated.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List a customer's contacts › Responses
OK
Add a contact to a customer
Adds an address in one of four roles: billing (invoices, credit notes, payment reminders and receipts), technical (subscription changes and balance alerts), admin (account-level and contractual notices) or einvoice (structured e-invoice delivery). Omit is_primary to let the first contact in a role become the address that role's mail is sent to; pass true to take the role over from whichever contact holds it. Returns 409 when the address already holds that role for this customer.
path Parameters
idCustomer UUID
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Add a contact to a customer › Request Body
categoryWhat this contact receives. Required.
emailThe mailbox to add. Required.
is_primaryWhether mail for this category is addressed here. Omit to let the first contact in a category become its primary and later ones not. true takes the category over from whichever contact currently holds it.
nameOptional display name.
Add a contact to a customer › Responses
Created
Remove a customer contact
Removes the contact. Idempotent - removing one that is already gone succeeds. If it was the primary for its role, mail for that role falls back to the billing contact.
path Parameters
idCustomer UUID
contactIdContact UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Remove a customer contact › Responses
No Content
Update a customer contact
Changes a contact's address, name, role or primary flag. Setting is_primary demotes whichever contact currently holds the role, in one transaction. Clearing it leaves the role with no address at all, and mail for that role falls back to the billing contact.
path Parameters
idCustomer UUID
contactIdContact UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Update a customer contact › Request Body
categoryMove this contact to a different category. It keeps is_primary, so moving a primary into an occupied category takes that category over.
emailMove this contact to a different mailbox.
is_primarytrue addresses this category here, demoting whichever contact held it. false leaves the category with no primary at all, so it falls back to the billing contact.
nameSet the display name; an empty string clears it.
Update a customer contact › Responses
OK
List the documents on a customer
Returns the customer's documents. Uploads that were never confirmed are not listed; pass status=quarantined to see the uploads that were refused.
path Parameters
idThe owning record's UUID
query Parameters
statusWhich documents to list. Defaults to the accepted ones; quarantined lists the uploads that were refused.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List the documents on a customer › Responses
OK
Change customer billing mode (PREPAID / POSTPAID)
Flips a customer between PREPAID and POSTPAID. Mode lives on the customer; all of the customer's wallets share it. The mode is forward-looking only: the flip performs no balance recompute or movement, and any current cash / held / promo state on each wallet carries over unchanged. PREPAID's "available ≥ amount" guard applies to subsequent debits; POSTPAID's credit_limit guard does the same.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Change customer billing mode (PREPAID / POSTPAID) › Request Body
modeTarget wallet settlement mode: PREPAID or POSTPAID.
reasonOptional audit-trail reason for the mode change.
Change customer billing mode (PREPAID / POSTPAID) › Responses
OK
List a customer's live negotiated rates
Every rate this customer is currently promised on a live subscription that an offer effective from at would supersede, with its window and the offer that promised it. A negotiated rate is scoped to one subscription item, so a second engagement is quoted on its own terms — this read is how the operator sees the number to repeat or replace instead of remembering it. Nothing is superseded by calling it: rates change only when a quote is accepted. Unpaginated; a customer with none is an empty list, not a 404.
path Parameters
idCustomer UUID
query Parameters
atThe instant to answer for, RFC3339 — normally the proposed offer's effective date. Defaults to now.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List a customer's live negotiated rates › Responses
OK
Update customer payment-provider settings
Updates only preferred_provider and/or disabled_providers.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Update customer payment-provider settings › Request Body
disabled_providersReplacement list of payment provider ids that must not be used to charge this customer; omit to leave unchanged, empty array to clear.
preferred_providerNew preferred payment provider id tried first when charging; empty string clears it, omit to leave unchanged. Must be a known provider and must not appear in disabled_providers.
Update customer payment-provider settings › Responses
OK
Where each kind of customer mail is sent
One row per list - billing, quotes & contracts, payment reminders, legal notices, technical - showing the address that receives it, the addresses copied on it, and where that answer came from: the list itself, the billing fallback, the customer's main address, or nobody. It is the same lookup the sending path performs, so what it shows is what happens.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Where each kind of customer mail is sent › Responses
OK
Change customer type (BUSINESS / CONSUMER / UNKNOWN)
Flips the customer's tax-relevant classification. Type drives reverse-charge eligibility, default payment terms, price-display mode, and consumer-protection law applicability - every flip is an accounting decision and must carry a reason. Forward-looking: prior invoices are NOT re-issued. UNKNOWN→BUSINESS in an EU jurisdiction surfaces a "corrective invoice candidate" hint via the customer.type_changed event so operators can review affected invoices through the credit-note service.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Change customer type (BUSINESS / CONSUMER / UNKNOWN) › Request Body
customer_typeTarget buyer classification: BUSINESS, CONSUMER, or UNKNOWN.
reasonAudit-trail reason for the type change. Required.
Change customer type (BUSINESS / CONSUMER / UNKNOWN) › Responses
OK
Trigger a VAT verification (VIES live check)
Runs a synchronous VIES validation against the customer's vat_number and returns the updated customer. Idempotent - safe to call repeatedly. Honours the workspace kill switch (tax.vat_validation_enabled), the per-customer opt-out, and the configured maintenance window.
path Parameters
idCustomer UUID
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Trigger a VAT verification (VIES live check) › Responses
OK
Set a manual VAT-validation override
Operator override for cases where VIES disagrees with out-of-band evidence. Writes a MANUAL verification row with reason + actor + TTL provenance and promotes customers.vat_validation_status to MANUAL. The recheck job demotes back to PENDING when the TTL elapses.
path Parameters
idCustomer UUID
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Set a manual VAT-validation override › Request Body
reasonExplanation recorded for the manual override. Required.
statusManual override outcome: "valid" or "invalid"; defaults to "valid" when omitted.
expires_atOptional expiry for the override; must be in the future when set.
Set a manual VAT-validation override › Responses
OK
Clear a manual VAT-validation override
Removes the operator MANUAL row by transitioning to PENDING. The customer's vat_validation_status returns to UNVALIDATED until the next auto- or manual-trigger lands a fresh VIES result. Idempotent.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Clear a manual VAT-validation override › Responses
OK
Get customer wallet
Returns the primary wallet for a customer.
path Parameters
idCustomer UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get customer wallet › Responses
OK