API Reference
Customers
Customers are the people and businesses you invoice. A customer carries its contact details, billing and shipping addresses, contacts, and tax settings.
Last updated 2026-09-22
Overview
The Customers API lets your integration create, read, update, and remove the customers in a workspace. A customer is the party you bill — it holds the display name, optional contact details, billing and shipping addresses, a list of contact people, and tax configuration used when invoicing.
Every customer is identified by a UUID. In API responses that UUID is returned as the `id` field, and the same value is what you pass in the path to retrieve, update, or delete a customer. Internal numeric identifiers and workspace foreign keys (such as `teamId`) are never exposed.
Key concepts
Identification
A customer is referenced by its UUID, returned as `id`. Pass that value in the path to retrieve, update, or delete. Bulk update rows use the same value under `uuid`. Optional `salesRepId` on create is a numeric workspace person id, not a UUID.
Required fields
Only `customer` (the name) is required to create a customer. Everything else — including email — is optional, and email does not have to be unique.
Contacts
Contacts can be managed inline through the `contacts` array on create and update, or one at a time through the `/contacts` sub-resource. The first contact populates the derived `contactName`.
Addresses
Billing and shipping addresses are embedded objects on the customer. A customer can also carry any number of additional locations through the `/addresses` sub-resource, each with its own label and primary flag.
Notes
The `notes` field on the customer is a single free-text blob. The `/notes` sub-resource is a separate running log: each entry is its own record, attributed to its author and capped at 1200 characters.
Merging duplicates
Duplicate customers are consolidated with `/merge`, which repoints every record at a target customer and soft-deletes the sources. Call `/merge/preview` first to count what would move.
Tax handling
Set `taxAutoCalculate` to true to derive tax from the address, or pass a `taxes` array of tax ids for manual rates. `taxExcluded` controls tax-exclusive treatment.
Status & lifecycle
Customers are active by default. Deleting a customer is a soft delete: its status becomes inactive and it stops appearing in active lists.
The customer object
Fields returned on a customer. Related objects (billing/shipping address, contacts, taxes, sales rep) are embedded when present.
Attributes
iduuidUnique identifier (UUID). Use this value in the path for retrieve, update, and delete.
customerstringCustomer or business name. This is the only field required when creating a customer.
emailstringPrimary contact email. Optional and not required to be unique.
mainPhonestringPrimary phone number.
websitestringWebsite URL. If you omit the protocol, the API stores it with an https:// prefix.
statusenumCustomer status. Defaults to active. Deleting a customer sets this to inactive.
One of: active, inactive
notesstringFree-text notes. HTML is sanitized on save.
paymentTermstringDefault payment term applied to invoices for this customer (for example net30).
taxNumberstringTax registration number.
taxAutoCalculatebooleanWhen true, tax is auto-calculated from the address instead of from the manual taxes list.
taxExcludedbooleanWhether amounts for this customer are treated as tax-exclusive.
contactNamestringDerived from the first contact; maintained automatically.
billingAddressobjectBilling address, or null.
streetstringStreet address.
citystringCity or locality.
statestringState, province, or region.
zipCodestringPostal or ZIP code.
countrystringCountry name or ISO code.
shippingAddressobjectShipping address, same shape as billingAddress, or null.
contactsarrayContact people for this customer.
iduuidContact identifier (UUID).
firstNamestringContact's first name.
lastNamestringContact's last name.
emailstringContact's email address.
phonestringContact's phone number.
isPrimarybooleanMarks the primary contact.
taxesarrayTax rates linked to the customer (used when taxAutoCalculate is false).
salesRepobjectThe assigned sales representative (a workspace person), or null.
createdAtdatetimeISO 8601 timestamp when the customer was created.
updatedAtdatetimeISO 8601 timestamp of the last update.
{
"id": "dfa3219e-6af8-4c53-997a-037534f63a35",
"customer": "Acme Corporation",
"email": "contact@acme.com",
"mainPhone": "+1234567890",
"website": "https://acme.com",
"status": "active",
"notes": "Preferred customer. Net-30 terms.",
"paymentTerm": "net30",
"taxNumber": null,
"taxAutoCalculate": false,
"taxExcluded": false,
"contactName": "John Doe",
"billingAddress": {
"id": "0b2c1f5e-7a9d-4f2b-9c1e-2a4b6d8e0f12",
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94102",
"country": "USA"
},
"shippingAddress": null,
"contacts": [
{
"id": "a5da3577-bf85-4e3a-aa73-df85ca69bc67",
"firstName": "John",
"lastName": "Doe",
"email": "john@acme.com",
"phone": "+1234567890",
"isPrimary": true
}
],
"taxes": [],
"salesRep": null,
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-28T14:22:30.000Z"
}Identifiers are UUIDs returned as id
Partner responses replace internal numeric ids with the record UUID under the `id` key and remove internal foreign keys such as teamId. Use the `id` value from a response wherever the path expects a customer identifier.How search works
The `search` query parameter on list matches the customer name, the derived contact name, and contact phone numbers (case-insensitive, partial). It does not search by email.A merge cannot be undone
Merging repoints invoices, transactions, projects, documents, contacts, addresses, and notes onto the target customer and soft-deletes the sources, in one transaction. There is no API call that reverses it — run `POST /partners/customers/merge/preview` and show the user the affected counts before committing.Deletion is restricted
A customer that has been assigned to an invoice, project, or transaction cannot be deleted and the request returns 400. Firm-managed (system-created) customers also cannot be deleted.Related
Recent changes
Customer sub-resources, merge, GST settings, and the last bulk routes
Closed every remaining gap between the reference and the backend partner routes — 20 endpoints that existed in count-dev but had no documentation. Customers gained its sub-resources: contacts, addresses, and notes each get full list/create/update/delete coverage, plus GET /partners/customers/{uuid}/revenue-overview and the two-step merge flow (POST /partners/customers/merge/preview, then POST /partners/customers/merge), which repoints every record onto a target customer and cannot be undone through the API. Workspace gained GET and PATCH /partners/workspace/gst-settings, including the manage_settings permission the PATCH requires and the 409 that locks the accounting basis after a return is filed. Also documented GET /partners/invoices/generate/number, POST /partners/projects/bulk, and POST /partners/transactions/review-bulk. npm run check:parity now reports 173 documented routes against 173 backend routes.
Budgets API and documentation parity
Added the Budgets API reference (14 endpoints), invoice send-history, and account sub-types list. Introduced an automated parity check (`npm run check:parity`) that compares documented routes against count-dev. Normalized customer path parameters to `{uuid}` and fixed the documents chunk-upload progress path.
Endpoints
/partners/customersReturns a paginated list of customers in the workspace.
/partners/customers/{uuid}Retrieves a single customer by its id (UUID).
/partners/customersCreates a new customer in the workspace.
/partners/customers/{uuid}Updates an existing customer. Only the fields you send are changed.
/partners/customers/bulkCreates up to 100 customers in one request with partial-success semantics.
/partners/customers/bulkUpdates up to 100 customers in one request with partial-success semantics.
/partners/customers/{uuid}Soft-deletes a customer (sets its status to inactive).
/partners/customers/{uuid}/contactsReturns every contact person attached to a customer.
/partners/customers/{uuid}/contactsAdds a contact person to a customer.
/partners/customers/{uuid}/contacts/{contactUuid}Updates one contact on a customer.
/partners/customers/{uuid}/contacts/{contactUuid}Removes a contact from a customer.
/partners/customers/{uuid}/addressesReturns every address attached to a customer.
/partners/customers/{uuid}/addressesAdds an address to a customer.
/partners/customers/{uuid}/addresses/{customerAddressUuid}Updates one address on a customer.
/partners/customers/{uuid}/addresses/{customerAddressUuid}Removes an address from a customer.
/partners/customers/{uuid}/notesReturns the notes logged against a customer, newest first.
/partners/customers/{uuid}/notesLogs a note against a customer.
/partners/customers/{uuid}/notes/{noteUuid}Rewrites the text of one customer note.
/partners/customers/{uuid}/notes/{noteUuid}Removes a note from a customer.
/partners/customers/{uuid}/revenue-overviewReturns billing totals and payment behaviour for one customer.
/partners/customers/merge/previewReports what a merge would move, without changing anything.
/partners/customers/mergeFolds one or more duplicate customers into a target customer.
