Developer

Customers and vendors

Two resources, one shape. List, read, create, and pull a statement of account.

Customers and vendors are separate resources rather than one /parties?type= switch, so each maps to exactly one scope. The party type is pinned by the URL and never read from your request — a customers-only key can never reach a vendor.

MethodEndpointPurpose
GET/customersList — page, page_size, search. Scope sales_customers:read
POST/customersCreate — name required. Scope sales_customers:create
GET/customers/{id}Detail
GET/customers/{id}/statementStatement of account — startDate, endDate

/vendors is the same four, on purchases_vendors.

Creating one

bash
curl -X POST https://api.trabalance.com/api/v1/customers \
-H "Authorization: Bearer tk_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8c1f2a7e-9d40-4a21-b0c5-6f2e1d7a4c33" \
-d '{ "name": "Acme Corp", "email": "[email protected]", "currency": "USD",
      "paymentTerm": 30, "creditLimit": 25000 }'
FieldRequiredNotes
nameYesLegal or trading name, up to 255 characters
emailNoMust be a valid address
phone, address, city, state, country, countryCodeNocountryCode is ISO 3166-1 alpha-2
currencyNoISO 4217; defaults to the business currency
taxId, website, noteNo
creditLimitNoNumber, 0 or more
paymentTermNoWhole days, 0 or more
categoryId, centerIds[]NoCategory, and the locations this party is visible in

Unknown fields are passed through to the same producer the dashboard's form posts to, so anything the form accepts, this accepts. Two fields are stripped whatever you send: id (which would turn the create into an update) and files.

The conflict you will meet

If the party already has a relationship with this business, nothing is created and you get a 409:

json
{ "error": "conflict",
"error_description": "A customer with this email already exists in your business." }

Search first (GET /customers?search=acme) when your side cannot guarantee uniqueness.

Statement of account

bash
curl "https://api.trabalance.com/api/v1/customers/<id>/statement?startDate=2026-01-01&endDate=2026-08-31" \
-H "Authorization: Bearer tk_live_…"

The statement is produced by the same ledger producer the app's party page reads, so the closing balance it returns is the balance the customer sees on their statement — not a second calculation that can drift.

ℹ️Balances are never recomputed

Every figure on a party comes from the ledger producer. Do not sum documents on your side and expect the total to match — invoices, credit notes, receipts, opening balances and write-offs all contribute, and the producer is the only thing that knows the whole set.