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

# Grava um evento (ou um lote de até 100) da trilha de auditoria do seu app

> Mande o evento na hora do fato. Com o cabeçalho Idempotency-Key (até 255), repetir a chamada devolve os mesmos ids; a mesma chave com outro corpo é 409. Sem a chave, o evento idêntico é gravado uma vez. A trilha é só de acréscimo: nada se edita nem se apaga antes da retenção. Exige uma chave secreta criada COM o escopo audit_logs:write (chaves sem restrição não o têm).



## OpenAPI

````yaml /api-reference/openapi.json post /audit-logs/events
openapi: 3.1.0
info:
  title: UNIFOKAL API
  version: v1
  summary: >-
    Verificação de identidade: sessão criada no servidor, jornada no widget,
    resultado no webhook.
  description: >-
    A versão vive no caminho (/v1); não existe header de versão. Adição
    compatível (campo, módulo ou chave nova) NÃO sobe a versão: ignore o que não
    conhecer. Todo erro tem a forma { error, message }: o código é estável, a
    mensagem não. Ids são prefixo + ULID. Webhooks são assinados (HMAC SHA-256
    no header X-IDSAAS-Signature, janela de 300s; o segredo é SEU, mínimo 32
    caracteres) e o header x-idsaas-event carrega o tipo do evento.
  termsOfService: https://unifokal.com/termos
  contact:
    name: UNIFOKAL
    url: https://docs.unifokal.com/
servers:
  - url: https://api.unifokal.com/v1
security: []
externalDocs:
  description: >-
    Documentação completa em https://docs.unifokal.com/. Briefing para agentes
    de IA em https://unifokal.com/llms.txt.
  url: https://docs.unifokal.com/
paths:
  /audit-logs/events:
    post:
      summary: >-
        Grava um evento (ou um lote de até 100) da trilha de auditoria do seu
        app
      description: >-
        Mande o evento na hora do fato. Com o cabeçalho Idempotency-Key (até
        255), repetir a chamada devolve os mesmos ids; a mesma chave com outro
        corpo é 409. Sem a chave, o evento idêntico é gravado uma vez. A trilha
        é só de acréscimo: nada se edita nem se apaga antes da retenção. Exige
        uma chave secreta criada COM o escopo audit_logs:write (chaves sem
        restrição não o têm).
      operationId: ingestAuditLogEvents
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            maxLength: 255
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AuditLogEventRequest'
                - $ref: '#/components/schemas/AuditLogBatchRequest'
      responses:
        '201':
          description: Os ids, na ordem do lote.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditLogIngestResponse'
        '400':
          description: >-
            Códigos estáveis: invalid_json, validation_error. Ramifique pelo
            campo error, nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - invalid_json
                          - validation_error
        '401':
          description: >-
            Códigos estáveis: invalid_api_key. Ramifique pelo campo error, nunca
            pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - invalid_api_key
        '402':
          description: >-
            Códigos estáveis: insufficient_balance. Ramifique pelo campo error,
            nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - insufficient_balance
        '403':
          description: >-
            Códigos estáveis: credential_type_not_allowed,
            organization_suspended, test_key_used_in_production,
            insufficient_scope, ip_not_allowed. Ramifique pelo campo error,
            nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - credential_type_not_allowed
                          - organization_suspended
                          - test_key_used_in_production
                          - insufficient_scope
                          - ip_not_allowed
        '404':
          description: >-
            Códigos estáveis: organization_not_found. Ramifique pelo campo
            error, nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - organization_not_found
        '409':
          description: >-
            Códigos estáveis: idempotency_key_reused. Ramifique pelo campo
            error, nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - idempotency_key_reused
        '413':
          description: >-
            Códigos estáveis: payload_too_large. Ramifique pelo campo error,
            nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - payload_too_large
        '422':
          description: >-
            Códigos estáveis: audit_batch_size, audit_occurred_at_future,
            audit_occurred_at_too_old, audit_metadata_invalid,
            audit_schema_mismatch. Ramifique pelo campo error, nunca pela
            mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - audit_batch_size
                          - audit_occurred_at_future
                          - audit_occurred_at_too_old
                          - audit_metadata_invalid
                          - audit_schema_mismatch
        '429':
          description: >-
            Códigos estáveis: rate_limited. Ramifique pelo campo error, nunca
            pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - rate_limited
      security:
        - secretKey: []
components:
  schemas:
    AuditLogEventRequest:
      type: object
      properties:
        organization_id:
          type: string
          pattern: ^aorg_[0-9A-HJKMNP-TV-Z]{26}$
        action:
          type: string
          maxLength: 100
          pattern: ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$
        occurred_at:
          type: string
        actor:
          type: object
          properties:
            type:
              type: string
              minLength: 1
              maxLength: 100
              description: Espaços nas pontas são removidos antes da validação.
            id:
              type: string
              minLength: 1
              maxLength: 255
            name:
              type: string
              minLength: 1
              maxLength: 255
            metadata:
              type: object
              properties: {}
          required:
            - type
            - id
        targets:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                minLength: 1
                maxLength: 100
                description: Espaços nas pontas são removidos antes da validação.
              id:
                type: string
                minLength: 1
                maxLength: 255
              name:
                type: string
                minLength: 1
                maxLength: 255
              metadata:
                type: object
                properties: {}
            required:
              - type
              - id
          minItems: 1
          maxItems: 50
        context:
          type: object
          properties:
            location:
              type: string
            user_agent:
              type: string
              maxLength: 512
        metadata:
          type: object
          properties: {}
        version:
          type: integer
          minimum: 1
          maximum: 1000
      required:
        - action
        - occurred_at
        - actor
        - targets
      description: >-
        Um evento do seu app. organization_id é a empresa (aorg_) do seu
        cliente, ou null para um evento da sua conta. occurred_at até 5 minutos
        no futuro e dentro da retenção. metadata só com valores simples (texto,
        número, booleano), até 50 chaves e 4 KiB.
    AuditLogBatchRequest:
      type: object
      required:
        - events
      properties:
        events:
          type: array
          minItems: 1
          maxItems: 100
          items:
            $ref: '#/components/schemas/AuditLogEventRequest'
    AuditLogIngestResponse:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            type: object
            required:
              - id
              - replayed
            properties:
              id:
                type: string
                pattern: ^alog_[0-9A-HJKMNP-TV-Z]{26}$
              replayed:
                type: boolean
                description: >-
                  true quando a mesma chave e o mesmo corpo já tinham sido
                  gravados.
    ErrorEnvelope:
      type: object
      description: >-
        Todo erro da API tem exatamente esta forma. O campo error é um código
        estável (contrato); message é texto livre e pode mudar sem aviso.
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Código estável do erro. Ramifique por ele.
        message:
          type: string
          description: Texto explicativo. NÃO é contrato.
      additionalProperties: false
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: >-
        Chave secreta (unifokal_live_ em produção, unifokal_test_ no sandbox: 64
        hex mais CRC-32) no Authorization: Bearer. Só no seu servidor: nunca no
        browser ou app (o widget monta apenas com o id vs_ da sessão). Não
        existe chave publishable.

````

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