Skip to main content

Conventions

Format​

  • Request and response bodies are JSON (Content-Type: application/json), with three exceptions: endpoints that attach a file use multipart/form-data (see Uploading files); the report export endpoints return a PDF or Excel file; and getPaymentView returns HTML.
  • Property names are camelCase.
  • Dates and timestamps are ISO 8601 strings, for example 2026-09-25 or 2026-09-25T00:00:00.000Z.
  • Amounts are plain JSON numbers in the business's currency, rounded to 2 decimals.

IDs are chosen by the caller​

Records such as contacts, items, accounts, taxes, transactions and payments are identified by a string ID (contactId, itemId, accountId, taxId, txnId, paymentId) that you generate when creating the record. Use a UUID or another globally unique string.

Create, update and upsert​

Write endpoints are named upsert…. If a record with that ID already exists in your business it is updated; otherwise it is created. There is no separate create/update call. To update, send the full record again with the same ID — fields you omit are treated as unset, so read the record first, modify it, and send it back.

Because the ID is yours, retrying a timed-out create with the same ID does not produce a duplicate.

Lists and "no content"​

List endpoints return a JSON array. When there is nothing to return they respond 204 No Content with an empty body rather than 200 [] — make sure your client handles an empty body.

Incremental sync (gtimeStamp)​

Many list endpoints take an optional trailing path segment, /{gtimeStamp}. Pass an ISO 8601 timestamp (URL-encoded) to receive only records changed at or after that time — use this to sync efficiently instead of downloading everything each run.

GET /masterdata/getItems/2026-09-01T00%3A00%3A00.000Z

An invalid timestamp returns 400.

JSON in query strings​

Filters on read endpoints are passed as JSON encoded into a query parameter (URL-encode it):

curl -G "$BASE_URL/txndata/getTxns/Invoice" \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode 'dateFilter={"predefinedDateFilter":"Custom","fromDate":"2026-04-01","toDate":"2026-09-25"}'

dateFilter​

FieldTypeNotes
predefinedDateFilterstringOne of Today, Yesterday, ThisWeek, LastWeek, ThisMonth, LastMonth, Last30Days, Last90Days, ThisQuarter, LastQuarter, ThisYear, LastYear, Custom, AllTime.
fromDate, toDateISO 8601 stringUsed with Custom.
fyStartMonth, fyStartDayintegerOptional financial-year start (month 1–12, day 1–31) for ThisYear/LastYear.

Unknown properties in dateFilter are rejected with 400.

Uploading files​

upsertTxn, upsertPayment, upsertItemwFile and upsertContactwFile accept an optional attachment, so they take multipart/form-data instead of a JSON body. The record itself is sent as a JSON string in a form field:

EndpointJSON fieldFile field
POST /txndata/upsertTxntxnDtofile
POST /txndata/upsertPaymentpaymentDtofile
POST /masterdata/upsertItemwFileitemDtofiles (one or more)
POST /masterdata/upsertContactwFilecontactfile (one or more)
curl -X POST "$BASE_URL/txndata/upsertTxn" \
-H "x-api-key: YOUR_API_KEY" \
-F 'txnDto={"txnHeader":{...},"lineItems":[...]}'

Note that upsertTxn and upsertPayment always use multipart, even with no attachment. upsertItem and upsertContact (without a file) take a plain JSON body.