List transactions

Returns recognized (mapped) expense transactions by default.

amount is an object: value/currency are the original transaction amount; convertedValue is that amount in the organization display currency. Values are in minor currency units (e.g., cents).

Cursor-paginated: pass size for the page size and the returned nextCursor as cursor for the next page.

Sort with sort=<field>:asc|desc; sorting by amount uses the display-currency converted value. See transactionSortSchema for the sortable fields.

Bound a period with filters on transactionDate, using the dayOnOrAfter / dayOnOrBefore operators — they match whole days, so a time component in the value is ignored rather than cutting that day short.

Use aggs for spend totals and breakdowns instead of paging through transactions and summing them client-side. Pair it with a transactionDate filter to bound the period and size=1 to keep the response compact — the numbers come back in aggregations.

Example — spend per app for 2026 year-to-date (aggs and filters are JSON and must be URL-encoded; shown decoded here for readability):

GET /transactions?size=1&filters=[{"key":"transactionDate","op":"dayOnOrAfter","value":"2026-01-01"},{"key":"transactionDate","op":"dayOnOrBefore","value":"2026-08-31"}]&aggs={"field":"appName","aggregationType":"groupBy","options":{"size":100,"sort":{"order":"desc","aggFunc":"sum","field":"amount"}},"aggs":[{"field":"amount","aggregationType":"metric","options":{"metricFunction":"sum"}}]}

Reading the result — in a groupBy bucket, value is the transaction count, not the amount. The metric you asked for is in the bucket's own aggregations: [{"key":"slack","value":37,"aggregations":{"amount":106414875}}] means 37 transactions totalling 1064148.75 in display currency. Reading value as money is the most common way to get this wrong.

A trailing {"key":"Other"} bucket rolls up everything past options.size (max 100) and carries no aggregations — skip it or widen the window.

Aggregated amounts are in the organization display currency, in minor units (cents). appName group keys are lower-cased (the field is indexed with a lowercase normalizer); group by idApp instead when you need the exact name casing.

  • Rate limit: 100 requests per minute

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Query Params
integer
1 to 2147483647

Filter transactions by app id

string

Filter transactions by source

string
length ≤ 800

Free-text search on transaction description

string
Defaults to mapped

Filter by mapping status (comma-separated). Defaults to mapped. Unmatched statuses (unknown, recommend_map) are unavailable when the org hides unmatched expenses.

string

Sort order, e.g. transactionDate:desc. Sortable fields: id, transactionDate, amount, description, source, appName, appAccountName, reportedByFullName, mappingStatus, mappingLogic, idExternalTransaction, externalAccountId, externalAccountName. Sorting by amount uses the display-currency converted value.

integer
1 to 1000

The max amount of results to return

string

A base64 string indicating the offset from which to start.
Pass the value of nextCursor returned from the previous call to get the next set of results

string
Defaults to id,idApp,transactionDate,amount,source,description,mappingStatus

List of fields to return for each transaction.
Allowed fields: id, idApp, appName, idAppAccount, appAccountName, idUpload, fileName, transactionDate, origTransactionDate, amount, source, description, extraInfo, department, domain, externalAccountId, externalAccountName, mappingStatus, mappingLogic, reportedBy, reportedByFullName, idExternalTransaction

string

Filters expression — accepts either shape: (1) Flat array of filter objects, AND-combined. Each item is {key, op, value}. (2) Array of filter groups, OR-combined. Each item is {id, filters} where filters is a flat array. See *_fields_metadata for valid keys and per-filterType operators. Omit value for isSet/isNotSet/relativeDateToday/exists/notExists. Use an array value for anyOf/allOf/noneOf/isExactly. Sent on the wire as a JSON-encoded string.

string

JSON string representing aggregation configuration. Structure: '{"field":"string","aggregationType":"metric|groupBy|date_range|date_histogram","options":{"size":"integer","sort":{"field":"string","order":"desc|asc","aggFunc":"total|sum|avg|max|min"},"metricFunction":"total|sum|avg|max|min","dateHistogramOptions":{"datePeriod":"hourly|daily|weekly|monthly|quarterly|yearly","hardBounds":{"min":"string","max":"string"},"extendedBounds":{"min":"string","max":"string"},"filterEmptyBuckets":"boolean"}},"aggs":{"field":"string","aggregationType":"metric|groupBy|date_range|date_histogram","options":{"metricFunction":"total|sum|avg|max|min"}}}'. metricFunction is REQUIRED when aggregationType is "metric". For aggregationType "date_histogram", options.dateHistogramOptions is REQUIRED and datePeriod, hardBounds, extendedBounds and filterEmptyBuckets all live INSIDE it — putting them directly on options is rejected with 400 "options.dateHistogramOptions" is required. The nested "aggs" is OPTIONAL and, when present, must be a JSON OBJECT with this same structure — never a JSON-encoded string.

Response

Language
Credentials
Header
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
*/*