Acessing Audit Data

Audit entries provide a detailed record of changes made to entities within the Salsa platform. As a partner, you can query audit entries for your employers to track modifications, monitor activity, and maintain compliance records.

What is the Audit Log?

The Audit Log provides a detailed record of changes made to your payroll data. Every time an entity is created, updated, or deleted, an audit entry captures who made the change, what changed, and when it happened.

Use the Audit Log to:

  • Compliance — maintain a tamper-proof history of payroll changes for regulatory and internal audits.
  • Change tracking — see exactly what was modified on a worker, bank account, payroll run, etc.
  • Debugging — trace unexpected data back to the action that caused it.

Querying Audit Entries

Audit entries are accessed via the auditEntries GraphQL query. Results are paginated and sorted by timestamp (ascending) by default.

query {
  auditEntries(
    page: 0
    size: 100
    filterBy: { ... }
    orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }
  ) {
    totalPages
    nodes {
      id
      auditTimestamp
      entityId
      entityType
      action
      event
      entity
      actor {
        ... on AuditUser {
          displayName
          userEmail
        }
        ... on AuditApiClient {
          displayName
          apiClient
        }
        ... on AuditSystem {
          displayName
        }
      }
      employer {
        id
        legalName
      }
      worker {
        id
      }
      httpRequest {
        traceId
        requestId
        ipAddress
      }
    }
  }
}

You can also query audit entries scoped to a specific entity by using the auditEntries field on any auditable entity (e.g., a Worker or Employer).


Pagination

The auditEntries query uses page-based pagination. Pass page and size to control which page of results you receive.

ParameterTypeDefaultDescription
pageInt0Zero-based page index.
sizeInt500Number of entries per page (max 500).

The response includes totalPages so you know how many pages are available.

Paginating through all results

# First page
query {
  auditEntries(page: 0, size: 100) {
    totalPages
    nodes { id auditTimestamp entityType action event }
  }
}

# Next page
query {
  auditEntries(page: 1, size: 100) {
    totalPages
    nodes { id auditTimestamp entityType action event }
  }
}

Keep incrementing page until you reach totalPages - 1.


Filters

Use the filterBy argument to narrow results. The following filters are available:

FilterTypeDescription
entityTypeStringFilter by entity type (e.g., "WorkerContract").
workerIdStringFilter entries related to a specific worker.
auditTimestampBoundedDateTimeIntervalInputFilter by date range using start and end.

Date Range Filter

The auditTimestamp filter accepts a bounded date-time interval:

filterBy: {
  auditTimestamp: {
    start: "2025-01-01T00:00:00Z"
    end: "2025-01-31T23:59:59Z"
  }
}

Both start and end are inclusive.


Sorting

Results are sorted by AUDIT_TIMESTAMP in ascending order by default. You can change the direction:

orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }

Available Fields

Each audit entry contains:

FieldTypeDescription
idIDUnique identifier for the audit entry.
auditTimestampDateTimeUTC timestamp of when the change occurred.
entityIdIDIdentifier of the entity that was changed.
entityTypeStringType of the entity (e.g., "WorkerContract", "EmployerBankAccount").
actionStringHigh-level action category (e.g., CREATE, UPDATE, DELETE).
eventStringHuman-readable description of the change.
entityStringJSON representation of the entity's state after the change.
actorAuditActorWho performed the action (see Actor Types).
employerEmployerThe employer associated with this entry.
workerWorkerThe worker associated with this entry (if applicable).


Audit Coverage

The following entities and actions are tracked in the Audit Log.

Money Movement

EntityActions
Employer bank accountCreate, Update, Delete
Worker bank accountCreate, Update, Delete
Employer money movement policyCreate, Update
Pay distributionCreate, Update

Profile

EntityActions
Employer taxes setupCreate, Update, Delete
Worker taxes setupCreate, Update, Delete, Override
Worker addressCreate, Update, Terminate
Worker contractCreate, Update, Delete
Worker work locationAdd, Update, Remove
Employer addressCreate, Update, Delete
Worker nameUpdate

Payroll

EntityActions
Payroll runRun, Confirm, Cancel, Delete, Update
Worker payroll runCreate
Payroll run workers listInclude, Exclude
Worker payroll elementUpdate
Worker pay distributionUpdate
Partner payroll settingsCreate, Update, Delete

Accounting

EntityActions
Partner accounting settingsCreate, Update, Delete

Examples

Query changes in a date range

query {
  auditEntries(
    filterBy: {
      auditTimestamp: {
        start: "2025-01-01T00:00:00Z"
        end: "2025-01-31T23:59:59Z"
      }
    }
    orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }
  ) {
    totalPages
    nodes {
      id
      auditTimestamp
      entityType
      action
      event
      actor {
        ... on AuditUser { displayName userEmail }
        ... on AuditApiClient { displayName apiClient }
        ... on AuditSystem { displayName }
      }
    }
  }
}

Query changes for a specific worker

query {
  auditEntries(
    filterBy: {
      workerId: "worker-uuid-here"
    }
    orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }
  ) {
    totalPages
    nodes {
      id
      auditTimestamp
      entityType
      action
      event
      entity
    }
  }
}

Query changes by entity type

query {
  auditEntries(
    filterBy: {
      entityType: "WorkerContract"
      auditTimestamp: {
        start: "2025-06-01T00:00:00Z"
        end: "2025-06-30T23:59:59Z"
      }
    }
    orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }
  ) {
    totalPages
    nodes {
      id
      auditTimestamp
      action
      event
      entity
      worker { id }
      employer { id legalName }
    }
  }
}

Query with actor details and pagination

query {
  auditEntries(
    page: 0
    size: 50
    filterBy: {
      auditTimestamp: {
        start: "2025-03-01T00:00:00Z"
        end: "2025-03-31T23:59:59Z"
      }
    }
    orderBy: { field: AUDIT_TIMESTAMP, sort: DESCENDING }
  ) {
    totalPages
    nodes {
      id
      auditTimestamp
      entityType
      action
      event
      actor {
        ... on AuditUser {
          displayName
          userEmail
        }
        ... on AuditApiClient {
          displayName
          apiClient
        }
        ... on AuditSystem {
          displayName
        }
      }
      httpRequest {
        traceId
        requestId
        ipAddress
      }
    }
  }
}

Understanding Changes

The entity field contains a JSON snapshot of the entity after the change was applied. The Audit Log captures the current state at the time of the action — it does not store a diff or the previous state.

To understand what changed, compare the entity snapshots of consecutive audit entries for the same entityId.

The event field provides a human-readable summary of the change, which is useful for displaying in a UI without parsing the JSON.