Skip to main content
The audit trail is a forensic, append-only log of every mutating request against an Organization’s data. Each row stores the actor, credential type, declared actor, request id, route, method, and a diff of what changed. GET requests do not produce audit records. The trail belongs to the Organization. You read it in two ways: Both routes need books read in the Organization. Both return the same page shape.
Open in the app. This resource has a page in the Sintropix web app at https://app.sintropix.com/organizations/{organizationId}/settings/log, where each id in braces is the same UUID as in the API route or response. The Log lives in the Organization's settings, with an Entidad filter. A record's own history is in the Actividad tab of its panel. When you mention a record to a user, include that link. See Link to the App for the full URL grammar.
The Log moved from the Entity to the Organization. GET /api/entities/:entityId/audit-trail now requires tableName and rowId. To list every write of an Entity, call the Organization route with entityIds.

List the Organization Log

GET /api/organizations/:organizationId/audit-trail Returns a paginated page of the Organization’s audit envelopes, plus the named resources needed to render them without extra lookups. Writes that belong to no Organization never appear. With no filter, the page lists every envelope of the Organization. That includes the envelopes of Organization routes that name no Entity, such as a Partner merge or a Dimension change. Those have entityId set to null, and the app labels them Empresa. Query params How the Entity filter matches Send entityIds, includeOrganizationEnvelopes, or both, to narrow the Log:
  • An envelope matches an Entity when it names that Entity, or when it changes a row of that Entity. For example, a Partner merge names no Entity, but it shows under each Entity whose rows it changed.
  • Inside a matched envelope, the changes to rows of Entities you didn’t select are hidden. Changes to rows the whole Organization shares, such as a Partner, always show.
  • A row that moved between two Entities shows under both.
  • With includeOrganizationEnvelopes=true, the envelopes that name no Entity also match.
Selecting every Entity plus Empresa gives the same Log as no filter. An API key confined to one Entity reads its own Entity and the Empresa envelopes by default. Asking for another Entity in entityIds answers 404 with ENTITY_NOT_FOUND_ERROR.

List the history of one record

GET /api/entities/:entityId/audit-trail Returns the audit envelopes that changed one row of the Entity, the same history the Actividad tab of a record shows in the app. An envelope never shows a change to another Entity’s rows. Query params Accepted tableName values The trail records changes to the tables of the books and the records around them, for example ledger_entry, ledger_entry_line, invoice, invoice_attachment, attachment, partner, partner_alias, partner_bank_details, entity_partner, bank_movement, bank_movement_attachment, bank_account, reconciliation_allocation, fixed_asset, fixed_asset_class, fixed_asset_depreciation_entry, intercompany_entry, expense_claim, and task. Any string is accepted; one that names no audited row matches nothing. Some parents also pull in their child rows: tableName=ledger_entry returns changes to that entry and to its ledger_entry_line rows; tableName=invoice returns changes to that invoice and to its invoice_attachment links; tableName=bank_movement returns changes to that movement and to its bank_movement_attachment links; tableName=partner returns changes to that Partner, its partner_alias rows, its entity_partner links, and the Partners merged into it. The invoice and bank movement histories also carry the attachment rows of the files linked in the same request. For tableName=partner_bank_details, pass the Partner’s id as rowId. For an Expense Rendition, tableName=invoice also returns the history of the Expense Claim it came from: who submitted it and who approved it.

Response

Both routes answer 200 with this page: Each envelope: Each change: Keys inside before, after, and rowPrimaryKey are the stored column names in snake_case (for example entry_date, partner_id), not the camelCase names used elsewhere in the API. namedResources carries the display facts of exactly the resources the page’s envelopes point at, so a feed can render names without further lookups: A resource that no longer exists is absent from these lists; treat an id you cannot resolve as unknown.

What the trail captures

The audit trail is row-level and automatic: every write is recorded by the database itself, so no endpoint can skip it. Every mutating request produces one Audit Envelope grouping its Audit Changes:
  • Actor: actorUserId plus the name and role the authenticated user had at the write. A deleted user keeps that name and role in the trail, and the Log shows (eliminado) after their name.
  • Credential type: session for browser sessions, api_key for API key requests, system for changes made by Sintropix itself
  • Declared actor: the value of the x-audit-actor header on API-key mutations (stored as a claim, not a verified identity). Changes Erwin makes while a person chats with him in the app carry erwin, with that person as the actor. A Source Feed sync that writes the Standing or Tax Period of a landed DTE carries source-feed, credited to the system.
  • Declared reason: the value of the x-audit-reason header (trimmed, up to 500 characters) explaining why the change was made; required on API-key mutations, optional on browser sessions
  • Declared trigger: the value of the optional x-audit-trigger header (stored as a claim), naming what started the agent turn behind the write. Every write Erwin makes carries the trigger of his turn: schedule when a schedule started it, or slack, app, chat, or terminal when a person’s message there started it. An envelope whose declaredActor starts with erwin and whose declaredTrigger is schedule is a change Erwin made on his own
  • Request id: a server-generated unique id grouping all changes in one request
  • Route and HTTP method: the endpoint that produced the mutation, or the scheduled job that made it
  • Entity id: the entity scope the change occurred within
  • Diff: for inserts and deletes, the full row image; for updates, only the columns that moved with before and after values
GET requests are not audited. Unbooking (soft delete) is no longer traceless: the removed entry’s full image survives as Audit Changes.

Scheduled jobs

Some changes are made by Sintropix on a schedule, with no request behind them. Their envelopes carry credentialType: "system", and route and method name the job instead of an endpoint: A sync you start on demand keeps the route and method of that request.

Status codes