This guide covers the history of expenses. Tesouro also provides document history for accounts
receivable and payable
history.
Overview
Tesouro keeps a history of every change made to an expense, from the moment the transaction is created to its final approval state. The history records what changed, who changed it, and when. To read the history of an expense, callGET /transactions/{transaction_id}/expense_history:
timestamp, an event_type, an event_data payload whose shape follows the event type, and the fields that identify the actor:
Filtering and paging
Roles and permissions
To read an expense’s history using an organization user token, the user must have a role with thetransaction.read permission.
If the permission type is allowed_for_own (rather than allowed), the user can read the history of their own expenses and of the expenses owned by the people who report to them. The returned history still includes the changes that other users made to those expenses.
If a partner-level token is used, no special permissions are needed.
Who made the change
Every entry identifies the actor behind the event:
The name and role values are captured when the entry is written and are never recalculated, so an entry shows the name and role that the user held at the time of the event, not the ones they hold today. All five are
null in system entries, and the name and role fields are also null on older entries where they were not captured. Use recorded_by to tell those two cases apart.
Event types
event_type is an open vocabulary and it grows over time. Treat it as a string, and let your
integration ignore a type it does not recognize rather than fail on it.
The expense status values are
new, approve_in_progress, approved, rejected, and canceled.
expense_created
expense_updated
event_data.fields maps each changed field name to the change made to it. An entry with no tracked field changed carries an empty map.
submitted
approval_requested
approval_action
An approver acted on the expense. See Record an approval action for how these entries are written.
auto_approved
approvals_bypassed
An administrator force approved the expense, which cancelled the approvals that were still pending.
bypassed_approver_ids is the audit fact and is always present. bypassed_approvers is a display convenience and is empty when the names could not be resolved.
status_changed
The fallback for a status transition that has no more specific event type.
reopened
A decided expense was reopened. The payload is a plain status transition and reads with the same fields as status_changed.
canceled
The expense was canceled. The payload is a plain status transition and reads with the same fields as status_changed.
deleted
The expense was deleted. Its history stays readable.
receipt_matched
receipt_unlinked
auto_categorized
payment_status_changed
The card payment behind the expense changed status. This is the payment_processing_status vocabulary, not the expense one: created, processing, succeeded, declined, refunded, and failed.
Record an approval action
Approval services record their decisions by callingPOST /transactions/{transaction_id}/expense_history. The call appends one approval_action entry.
The user must have a role with the transaction.approve permission.
action and acted_at are required. Everything else is optional, and a field you omit is left out of the stored payload rather than stored as null.
201 response confirms the entry was recorded:
timestamp is the acted_at you send, not the moment of the call, so a decision recorded late still lands in the right place in the timeline. And a repeated call for the same policy auto-approval is a no-op that still answers 201, so a retry does not create a second entry.