Customers API

Customer records hold billing details and belong to one studio. Their UUIDs link invoices to off-chain billing information. They are not payer wallet addresses. See the customer guide for the dashboard workflow.

Endpoints and responses#

All endpoints accept HMAC or Privy JWT. Read routes enforce customer:read for HMAC; writes enforce customer:write.

Method and pathInputSuccess response
GET /v1/customersFilters below200 { data: Customer[], meta: { total, limit, offset, hasMore } }
GET /v1/customers/:idCustomer UUID200 { data: Customer }
POST /v1/customersComplete create object201 { data: Customer }
PATCH /v1/customers/:idPartial update object200 { data: Customer }
DELETE /v1/customers/:idCustomer UUID204, no response body

List filters: type=entity|person, search (name or email), walletAddress (EVM address), limit (integer 1 through 100, default 25), and cursor. Despite its name, this customer cursor is a decimal offset, not a customer ID or the invoice-list cursor. Start without a cursor, then send cursor=25 for the next page of 25. Use meta.offset + data.length while meta.hasMore is true. Do not parse an empty 204 response as JSON.

Create and update fields#

FieldRequirement
typeRequired on create: entity or person. Immutable after creation.
legalNameRequired nonempty string
emailRequired valid email
addressRequired for both types: nonempty street, city, postal, and valid ISO country code in country
registrationNumberRequired nonempty string for an entity
tradeNameOptional entity field
taxIdOptional person field
vatNumber, notesOptional strings
walletAddressOptional EVM address

PATCH accepts the editable fields above except type and rejects unknown fields. Omitted fields are retained. If changing address, provide the entire address object. Do not use null to clear string fields: it is not accepted by this schema.

Returned customers include id, studioId, type, billing fields, createdAt, updatedAt, and stored metadata when present. Creation does not accept arbitrary metadata. Database timestamps are date-time strings, not invoice Unix-second timestamps.

Example mutation: create a person customer#

This request creates a customer record. Replace the example billing data, sign the exact JSON bytes using the HMAC scheme, and send them to POST /v1/customers with Content-Type: application/json.

json
{
  "type": "person",
  "legalName": "Example Customer",
  "email": "[email protected]",
  "address": {
    "street": "10 Example Street",
    "city": "London",
    "postal": "SW1A 1AA",
    "country": "GB"
  }
}

For an entity, set type to entity and include its real registrationNumber. Store the returned UUID for invoice issuance. Creating a customer does not create an invoice or send an invoice email.

Invalid data returns 400; missing/inaccessible customer records return 404; a duplicate name (on create or rename) returns 409 with code: "CUSTOMER_EXISTS" and the existingCustomerId to update instead (null when the name belongs to a deleted customer and cannot be reused). Do not assume customer creation supports invoice idempotency headers. After an ambiguous create response, search existing records before submitting again.

Deleting a customer does not cancel its on-chain invoices or erase already-issued encrypted invoice metadata. Review existing invoices before deleting billing records. The MCP customer tool also supports creation and billing-field updates, using snake-case names such as registration_number.