Skip to main content
This guide covers the document history for accounts payable documents. Tesouro also provides document history for accounts receivable documents.

Overview

The document history for payables provides visibility into key actions performed on these documents. Each event includes the timestamp, the type of action, and the user (or system) that performed it. This helps teams and auditors understand when documents were created, updated, or linked - and by whom. To access a document’s history, call GET /payables/{payable_id}/history. You can filter the history by event type (event_type__in), by the user a record is attributed to (entity_user_id__in), or by a date range (timestamp__gt, timestamp__gte, timestamp__lt, timestamp__lte). The two __in parameters take a list, so repeat one to pass several values. The history consists of a list of timestamped events that have occurred since the document was created. The event_data structure varies based on the event_type. For a description of available data fields and query parameters, see the endpoint description.
The successful 200 response returns the history of the payable:
The history of a deleted payable remains readable. This is deliberate: the last record of a deleted payable is its deleted event, and that record is exactly what someone asks for when they want to know what happened to the document.

Roles and permissions

To access a payable’s change history using an organization user token, this user must have a role with the payables.read permission. If the permission type is allowed_for_own (rather than allowed), the user can access the change history only for documents that they themselves created, but the returned history still includes the changes made to their documents by other users. If a partner-level token is used, no special permissions are needed.

Who made the change

Every history record identifies the actor behind the event. The entity_user_ prefix on these field names is historical; each one refers to an organization user. The name and role values are captured when the record is written and are never recalculated, so a record shows the name and role that the user held at the time of the event, not the ones they hold today. All four are null in system records, and also when the name or role could not be resolved as the record was written. Use recorded_by to tell those two cases apart. approval_requested, auto_approved, and payment_reverted records are always system.

Event types

Payable history includes the following event types:

approval_action

This event indicates that an approval decision was made on the payable. The action is approved or rejected. The approval_source tells you how the decision was made: acted_at is the moment the decision was made, as reported by the system that made it. It is null when that system did not report one. reject_reason is set only for a rejection, and only when a reason was given. The three approval_policy_* fields and approval_request_id are set only on a policy-driven decision.

approval_requested

This event indicates that an approval policy matched this payable and was applied to it. It is always a system record: applying a policy is something the platform did, not a person. The event_data object holds a snapshot of the policy as it read when it was applied. The snapshot is frozen into the record, so renaming or reconfiguring the policy later does not change what this record says was asked for. Only approval_policy_id is always present.
If no policy matched the payable, no record is written. An absent record is the correct history of “there was nothing to approve”.

approvals_bypassed

This event indicates that an admin force approved the payable while other people’s approvals were still pending. It names the approvers who were stepped over. The record is attributed to the admin who forced the approval, so recorded_by is user and the actor fields name them. It sits alongside the approval_action record for the forced decision itself, which carries approval_source force. The event_data object carries the same people twice:
  • bypassed_approver_ids - the IDs of the approvers who were still pending. Always present.
  • bypassed_approvers - the same people with the names they held at the moment of the force approval. Each entry has an id, a first_name, and a last_name. The names are frozen into the record, so renaming an approver later does not change it. Both names are null for an approver whose name could not be resolved as the record was written, and the entry is kept either way, in the same order as bypassed_approver_ids.
A force approval that stepped over nobody records no event at all. Approvers routed by role rather than named individually are not counted as pending, so an approval step that names a role records nobody.

auto_approved

This event indicates that an approval policy approved the payable with nobody in the loop. It is always a system record. It is recorded alongside the approval_action record for the same decision, not instead of it: approval_action stays the machine-readable record of the decision, and this one is the System-attributed line a reader sees in the timeline. It is never recorded for a rejection, and never when a person acted. acted_at is always present here. The two approval_policy_* fields and approval_policy_process_id are set when the message that drove the approval carried them.

credit_note_linked

This event indicates that a credit note was linked to the payable. The event_data object contains the ID of the credit note, and its document_id when the credit note has one.

credit_note_unlinked

This event indicates that a credit note was unlinked from the payable. The event_data object has the same shape as credit_note_linked.

deleted

This event indicates that the payable was deleted by calling DELETE /payables/{payable_id}. The event_data object contains the old_status that the payable held before it was deleted, and no new status. The history of a deleted payable stays readable, so this record can still be retrieved.

file_attached

This event indicates that a file was attached to the payable. The event_data object contains the name, size in bytes, and URL of the attached file.

file_detached

This event indicates that the payable’s file was detached and deleted by calling DELETE /payables/{payable_id}/file. The event_data object contains the ID of the detached file, and its name. The file_name is null when the file record could no longer be read at the moment of detaching.

line_item_added

This event indicates that a line item was added to the payable. The event_data object identifies the new line item, so a timeline can name it without a further call. Only line_item_id and name are always present, and name can be null.

line_item_removed

This event indicates that a line item was removed from the payable. The event_data object contains the ID of the removed line item and nothing else.

line_item_updated

This event indicates that a line item of the payable was updated. The event_data object contains the ID of the line item and a fields map that describes what changed, in the same shape as payable_updated: each entry is keyed by the name of a changed field and gives the old and new values of that field. The following line item fields are tracked:
  • name
  • description
  • quantity
  • unit_price
  • unit
  • subtotal
  • tax
  • tax_amount
  • total
  • ledger_account_id
  • accounting_tax_rate_id
An update where none of these changed records an empty field map ({"fields": {}}), which still records that someone edited the line.

marked_as_paid

This event indicates that the payable was marked as fully paid by calling POST /payables/{payable_id}/mark-as-paid. The event_data object contains the total amount_paid in minor units, the optional comment that the call supplied, and the provenance of the payment. Each provenance field carries the value that the call supplied, and is null if that call did not supply it:
  • payment_record_id - ID of the payment record behind this payment.
  • payment_intent_id - ID of the payment intent that was paid.
  • payment_method - the payment method used, for example ach.
  • paid_at - the date and time when the payment was executed.
  • is_external - true if the payment was recorded manually rather than processed by Tesouro.
A payment that Tesouro processed carries all five. A payment that an organization user recorded by hand carries only the fields that their call included, so payment_record_id, payment_intent_id, and payment_method are usually null in that case. This event carries no amount_due, because a fully paid payable owes nothing by definition. marked_as_partially_paid is the event that carries one.

marked_as_partially_paid

This event indicates that the payable was marked as partially paid by calling POST /payables/{payable_id}/mark-as-partially-paid. The event_data object carries the same five provenance fields as marked_as_paid, the amount_paid in minor units, and the amount_due still owed after this payment. The amount_due is recalculated from the new amount_paid, so any discount or linked credit note is accounted for. This event carries no comment.

payable_created

This is the first event in each payable’s history. The event_data object describes how the payable came into being, rather than what it contained: an uploaded or emailed bill starts as a near-empty draft, and the values that OCR or a user fills in later are recorded by payable_updated.
  • payable_source - upload if the payable was created through the API or by uploading a file, email if it arrived in the organization’s mailbox.
  • source_of_payable_data - ocr if the payable’s data was read from the document, user_specified if it was supplied in the request.
  • sender - the email address the payable arrived from. Set only for an email arrival.
  • document_id - the document number of the payable. Almost always null here, because an uploaded or emailed bill gets its document number later. It is set when the payable was created with data.

payable_updated

This event is recorded when the payable is successfully updated via PATCH /payables/{payable_id}, and when a linked counterpart is synced onto the payable. The event_data object contains a fields map that describes what changed. Each entry is keyed by the name of a changed field, and gives the old and new values of that field. Both keys are always present, and either can be null when the value was unset or cleared. Fields that hold a nested object are expanded into dotted paths, so changing one part of the payment terms records a single payment_terms.discount.number_of_days entry rather than replacing the whole object. Where a field holds an ID that resolves to a display name, the entry also carries old_label and new_label - currently counterpart_id. Labels are frozen at event time and never resolved on read, so a counterpart renamed later still reads in this record as it read at the time. The following fields are tracked:
  • amount
  • amount_paid
  • subtotal
  • tax
  • tax_amount
  • discount_amount
  • currency
  • due_date
  • issued_at
  • description
  • document_id
  • sender
  • counterpart_id
  • counterpart_bank_account_id
  • counterpart_address_id
  • counterpart_vat_id_id
  • enforce_approval_policy_id
  • payment_terms
  • tag_ids
  • project_id
  • purchase_order_id
The order of tag_ids is not significant, so reordering the tags of a payable is not recorded as a change. An update where none of the tracked fields changed records an empty field map ({"fields": {}}), which still records that someone edited the payable. A counterpart sync that changed nothing records no event at all, because it is a step inside another operation rather than an edit of its own.
The following changes do not trigger the payable_updated event:

payment_reverted

This event indicates that a payment recorded against the payable was reverted, and the payable moved back to an unpaid or partially paid status. It is always a system record. The event_data object carries the same five provenance fields as marked_as_paid, the amount_paid that remains recorded on the payable after the reversal, and the new_status the payable moved to.

reopened

This event indicates that a payable was reopened for editing by calling POST /payables/{payable_id}/reopen, which returns it to the new status. Only a payable in the rejected or waiting_to_be_paid status can be reopened; any other status is rejected with a 409. The event_data object is an old and new status pair, identical in shape to status_changed. Reopening also records a status_changed event for the same transition.

status_changed

This event indicates that the payable’s status was changed. The event_data object contains the old and new statuses.
See payable statuses for the possible status values.

submitted_for_approval

This event indicates that the payable was submitted for approval by calling POST /payables/{payable_id}/submit-for-approval. The event_data object contains the status transition and skipped_approval_flow, which is true when the organization is configured to skip the approval flow. In that case the payable moves straight to waiting_to_be_paid instead of approve_in_progress. This event is recorded alongside the status_changed event for the same transition, not instead of it: it names the act and says whether approval was skipped, which the generic status record cannot.

See also

  • Webhooks - get notified about certain events in real time