> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finsync.ar/llms.txt
> Use this file to discover all available pages before exploring further.

# List company audit logs

> Read-only audit trail for the API-key company. Tenant scope is always audit_logs.company_id (the changed row, never the actor). Employee / personal keys need audit.view; scoped employees only see Operation and Transaction rows visible under their client scope.

**Email on actor**: included because changed_by is stored as the employee email. It is not an AuthUser secret.

**Known gaps**: channel is null unless a WhatsAppOperationDraft exists for the operation (whatsapp or twin). Company x-api-key writes usually have actor=null. Historical rows pre-FS-03 may have a null company_id and are hidden.



## OpenAPI

````yaml /docs/openapi.json get /api/audit-logs
openapi: 3.0.0
info:
  title: FinSync API Documentation
  version: 1.0.0
  description: API documentation for FinSync application
  contact:
    name: FinSync Support
    email: support@finsync.com
servers:
  - url: https://api.finsync.ar
    description: Direct Fly API (preferred for API keys and webhooks)
  - url: https://finsync.ar
    description: Same-origin via finsync.ar (Vercel rewrite)
security:
  - apiKey: []
tags:
  - name: Clients
    description: Operations related to clients and their accounts
  - name: Tags
    description: >-
      Company-scoped client labels (Configuración > Etiquetas). Distinct from
      the special Centro de resultados / Centro de costos tag used for budget
      clients.
  - name: Accounts
    description: Operations related to account balances
  - name: Cost Centers
    description: Company centros de resultados (cost_center_id) and their budgets
  - name: Audit
    description: >-
      Read-only company audit trail. Requires audit.view for employee / personal
      API keys. Company x-api-key sees the full company. Tenant scope is
      audit_logs.company_id (FS-03: never attributed by actor).
  - name: Operations
    description: Operations for creating and managing financial operations
  - name: Operation Types
    description: Company operation types management
  - name: Transaction Types
    description: Company transaction types management
  - name: WhatsApp Tools
    description: >-
      Company-scoped WhatsApp bot operation tools (Configuración > WhatsApp >
      Tools). Same WhatsAppOperationTool rows as the dashboard. Authenticate
      with x-api-key.
  - name: External client
    description: >-
      Exports for external (portal-linked) clients. Authenticate with
      `x-api-key` (company-owned client ID) or `Authorization: Bearer` (Auth.js
      session for an ExternalAccessGrant).
  - name: Mesas
    description: >-
      Company FX trading desks (mesas). Same records and paths as the dashboard
      Mesas module. Integrators authenticate with x-api-key; the dashboard uses
      an employee session. Superadmin must set mesas_enabled first; there is no
      public PATCH for that flag. created_by / opened_by / closed_by are null
      for API-key callers.
  - name: Home metrics
    description: >-
      Named dashboard home metrics (list + values). API keys receive the
      Métricas-group cards (day P&L, commissions, cost centers) without the
      metrics-password cookie. Employee sessions need the matching view
      permission; they still skip the UI password gate on this surface.
paths:
  /api/audit-logs:
    get:
      tags:
        - Audit
      summary: List company audit logs
      description: >-
        Read-only audit trail for the API-key company. Tenant scope is always
        audit_logs.company_id (the changed row, never the actor). Employee /
        personal keys need audit.view; scoped employees only see Operation and
        Transaction rows visible under their client scope.


        **Email on actor**: included because changed_by is stored as the
        employee email. It is not an AuthUser secret.


        **Known gaps**: channel is null unless a WhatsAppOperationDraft exists
        for the operation (whatsapp or twin). Company x-api-key writes usually
        have actor=null. Historical rows pre-FS-03 may have a null company_id
        and are hidden.
      parameters:
        - in: query
          name: entity
          schema:
            type: string
          description: >-
            Table name or alias (operation, transaction, account, client, mesa,
            cheque, invoice, …). Defaults to every tenant-visible table except
            internal_impersonation.
        - in: query
          name: entityId
          schema:
            type: integer
        - in: query
          name: dateFrom
          schema:
            type: string
          description: >-
            Inclusive lower bound. Date-only (YYYY-MM-DD) is that calendar day
            00:00 ART.
        - in: query
          name: dateTo
          schema:
            type: string
          description: >-
            Inclusive upper bound. Date-only is that calendar day 23:59:59.999
            ART.
        - in: query
          name: userId
          schema:
            type: integer
          description: >-
            Employee id in this company. Resolved to Employee.email and matched
            against changed_by. Unknown ids return an empty page.
        - in: query
          name: action
          schema:
            type: string
            enum:
              - create
              - update
              - cancel
              - revert
              - delete
        - in: query
          name: page
          schema:
            type: integer
            default: 1
        - in: query
          name: pageSize
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        '200':
          description: Paginated audit logs for this company
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/PublicAuditLogItem'
                  pagination:
                    type: object
                    properties:
                      page:
                        type: integer
                      pageSize:
                        type: integer
                      total:
                        type: integer
                      totalPages:
                        type: integer
        '400':
          description: Invalid filter
        '401':
          description: Unauthorized
        '403':
          description: Employee key lacks audit.view
        '500':
          description: Server error
      security:
        - apiKey: []
components:
  schemas:
    PublicAuditLogItem:
      type: object
      properties:
        id:
          type: integer
        entity:
          type: string
          description: >-
            audit_logs.table_name (Operation, Transaction, Account, Client,
            Mesa, …). Hidden: internal_impersonation.
        entity_id:
          type: integer
        action:
          type: string
          enum:
            - create
            - update
            - cancel
            - revert
            - delete
          description: >-
            Normalized from INSERT/UPDATE/DELETE. cancel = status became
            adjusted from a non-completed status. revert = status completed →
            adjusted. Soft-delete (deleted_at set) is delete. Revert of an
            operation by creating a counterpart is not a separate stored action;
            it appears as create on the counterpart plus optional cancel/revert
            on adjusted transactions.
        raw_action:
          type: string
          enum:
            - INSERT
            - UPDATE
            - DELETE
        actor:
          $ref: '#/components/schemas/PublicAuditActor'
        channel:
          type: string
          nullable: true
          enum:
            - dashboard
            - whatsapp
            - api
            - twin
            - system
          description: >-
            Only whatsapp and twin are derived today (via
            WhatsAppOperationDraft.conversation_id). dashboard, api, and system
            are not stored on historical rows and are returned as null rather
            than guessed.
        channel_detail:
          $ref: '#/components/schemas/PublicAuditChannelDetail'
        timestamp:
          type: string
          format: date-time
        before:
          type: object
          nullable: true
          description: >-
            Redacted old_data snapshot. Secrets, tokens, hashes, and auth fields
            are stripped.
        after:
          type: object
          nullable: true
          description: Redacted new_data snapshot.
        changes:
          type: array
          nullable: true
          items:
            type: object
            properties:
              field:
                type: string
              before: {}
              after: {}
    PublicAuditActor:
      type: object
      description: >-
        Resolved actor for an audit event or operation. Email is included
        because audit_logs.changed_by stores only the employee email; without it
        integrators cannot tell two people with the same display name apart. It
        is Employee.email, never an AuthUser secret, password hash, or session
        token. id is null when the email does not match a current employee of
        this company (deleted employee, missing GUC, company API key write).
      properties:
        id:
          type: integer
          nullable: true
        name:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
    PublicAuditChannelDetail:
      type: object
      description: >-
        Present only when channel is whatsapp or twin and a
        WhatsAppOperationDraft exists for the operation. Not stored on
        audit_logs.
      properties:
        requested_by:
          type: object
          properties:
            contact_id:
              type: integer
            phone:
              type: string
              nullable: true
            employee:
              $ref: '#/components/schemas/PublicEmployeeActor'
            client:
              type: object
              nullable: true
              properties:
                id:
                  type: integer
                name:
                  type: string
                  nullable: true
    PublicEmployeeActor:
      type: object
      description: >-
        Resolved company employee. Used next to existing integer actor ids
        (opened_by, closed_by, created_by). Name only; email is omitted here
        because those fields are already employee ids.
      properties:
        id:
          type: integer
        name:
          type: string
          nullable: true
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: API Key for authentication

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.