List transactions
Returns recognized (mapped) expense transactions by default.<br/><br/>Request mappingReason in fields to see why a transaction has its matching status (e.g. The ignored word "trip" was found, Search term "atlassian" is the longest found).<br/><br/>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).<br/><br/>Cursor-paginated: pass size for the page size and the returned nextCursor as cursor for the next page.<br/><br/>Sort with sort=<field>:asc|desc; sorting by amount uses the display-currency converted value. See transactionSortSchema for the sortable fields.<br/><br/>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.<br/><br/>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.<br/><br/>Example — spend per app for 2026 year-to-date (aggs and filters are JSON and must be URL-encoded; shown decoded here for readability):<br/><br/>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"}}]}<br/><br/>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.<br/><br/>A trailing {"key":"Other"} bucket rolls up everything past options.size (max 100) and carries no aggregations — skip it or widen the window.<br/><br/>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.<br/><br/>
<p><ul><li>Rate limit: 100 requests per minute</li></ul></p>Request
- Base URLhttps://api.toriihq.com/v1.0
- AuthAPI key in header Authorization
Query parameters
Filter transactions by app id
Filter transactions by source
Free-text search on transaction description
Filter by mapping status (comma-separated). Defaults to mapped. Unmatched statuses (unknown, recommend_map) are unavailable when the org hides unmatched expenses.
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.
The max amount of results to return
A base64 string indicating the offset from which to start. <br>Pass the value of nextCursor returned from the previous call to get the next set of results
List of fields to return for each transaction.<br>Allowed fields: id, idApp, appName, idAppAccount, appAccountName, idUpload, fileName, transactionDate, origTransactionDate, amount, source, description, extraInfo, department, domain, externalAccountId, externalAccountName, mappingStatus, mappingLogic, mappingReason, reportedBy, reportedByFullName, idExternalTransaction
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.
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
Transactions
Example response
{
"transactions": [
{
"id": 1000,
"idApp": 1000,
"appName": "Salesforce",
"idAppAccount": 1000,
"appAccountName": "Production account",
"idUpload": 1000,
"fileName": "expenses-q1.csv",
"transactionDate": "2022-02-03",
"amount": {
"value": 130000,
"currency": "EUR",
"convertedValue": 150000
},
"source": "netsuite",
"description": "Salesforce subscription",
"extraInfo": "PO-4821",
"department": "Engineering",
"domain": "acme.com",
"externalAccountId": "60000",
"externalAccountName": "Software Subscriptions",
"mappingStatus": "mapped",
"mappingLogic": "manually",
"mappingReason": "Search term \"salesforce\" is the longest found",
"reportedBy": 1000,
"reportedByFullName": "Tony Stark",
"idExternalTransaction": "INV-1001"
}
],
"count": 100,
"total": 1000,
"nextCursor": "WzE0NjM1Mzg4NTcsIjY1NDMyMyJd"
}Changes
No recorded changes to this operation across all 1 revision of this API.