Choosing an endpoint

Open in the interactive reference

Many resources offer more than one way to do the same thing: a read by id, a collection and a search, and for some resources bulk writes or events.

The choice decides which filters you can use, whether you get list records or full records, and how many requests a job takes.

Common jobs

Each row names the endpoint to call and the section with the detail.

To Call See
List or scan records GET /x Pagination and querying
Find a record by its name or number POST /x/search Reading records
Download a file a record carries GET /public/files/{handle} Files
Send a file, such as an attachment POST /public/files/{namespace}/{operationId}, then the endpoint with the upload reference Files
Read a record another record points to, such as customerId GET /customers/{id} as a second request. No endpoint can include related records. Reading records
Sync the changes since your last run GET /x?filter[lastModifiedDate][gte]=…&sort=lastModifiedDate. People absences and absence types don't return lastModifiedDate. Deleted records don't appear; see Deleted records. Pagination and querying
Export every record A paging loop over GET /x. A walk ends after about 100,000 records, so narrow larger exports with a filter. Pagination and querying
Create or change a record, then check it POST or PATCH, then GET /x/{id} Writes
Create or delete many records at once POST /x/bulk or /bulk-delete, where the resource has one. Inventory and some project endpoints do. Bulk writes
React to changes as they happen Subscribe to events. Invoices, journal entries and people publish them. For other records, sync on a schedule. Webhooks
Retry a write safely after a timeout Send an Idempotency-Key header. Almost every write accepts it, and one that doesn't lists IDEMPOTENCY_NOT_SUPPORTED. Idempotency

Reading: by id, the collection or search

Check the resource's endpoint list first. Many resources offer both a collection, GET /x, and a search, POST /x/search. When a resource has both, choose in this order:

  1. You know the id: use GET /x/{id}.
  2. You match text, such as a name, email or number, or pass several values for one filter: use POST /x/search. Its filters travel in the request body.
  3. You list or sync records, filtering on ids, statuses or dates: use GET /x.
  4. Still unsure: use search. It returns full records, and its filters sit in the body rather than the query string.

Collections that page differently

Twelve collections don't follow Pagination and querying. They take pageSize and a cursor as plain query parameters, return the records in data.items, and ignore page[…], filter[…], sort and fields without an error. Each one's description says so.

Collection Cursor Changed since
GET crm/opportunities, crm/prospects, crm/quotes cursor modifiedFrom, modifiedTo
GET accounting/refunds, accounting/sales-order-shipments cursor modifiedFrom, modifiedTo
GET accounting/usages cursor lastModifiedFrom
GET accounting/performance-obligations/{id}/products cursor —
GET accounting/books/{bookId}/entity-assignments page —
GET base/custom-dimensions, base/custom-dimensions/{customDimensionUuid}/values cursor —
GET psa/expenses/budgets cursor —
GET psa/expenses/summary pageCursor —

Examples

Which read to use

GET  /accounting/customers/{id}     id known
POST /accounting/customers/search   a name, or several values
GET  /accounting/customers          ids, statuses or dates