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
Case-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
Filter 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)
Filter by tag name (repeatable, containment semantics)
promoFilter by promotion UUID (repeatable): customers holding a redemption
Filter 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
Comma-separated countable fields (status, customer_type, mode, vat_validation_status, preferred_currency) to include per-value counts for
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
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.
Values for the organization's configured custom-field definitions.
customer_typeBuyer classification: BUSINESS, CONSUMER, or UNKNOWN; defaults to UNKNOWN when omitted.
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.
disabled_providersPayment provider ids that must not be used to charge this customer; each must be a known provider and unique.
einvoice_emailOverride email address for e-invoice delivery; null = fall back to email.
emailPrimary contact email; the default recipient for invoices and portal links. Required.
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.
nameCustomer's display / legal name as it appears on invoices. Required.
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 setting.
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
Customer 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
Customer 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
Customer 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.
disabled_providersReplacement list of disabled payment provider ids; omit to leave unchanged, empty array to clear.
einvoice_emailNew e-invoice delivery email; empty string clears it and falls back to email.
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
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
Customer 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
Update customer payment-provider settings
Updates only preferred_provider and/or disabled_providers.
path Parameters
idCustomer UUID
Customer 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
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
Customer 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
Customer 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
Customer 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
expires_atOptional expiry for the override; must be in the future when set.
reasonExplanation recorded for the manual override. Required.
statusManual override outcome: "valid" or "invalid"; defaults to "valid" when omitted.
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
Customer 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
Customer 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