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

# Export/purge audit logs

> Streams matching records as JSONL or CSV, optionally gzipped. With
`purge` set, the exported records are deleted in the same transaction
that read them, so nothing can be purged that was not successfully
exported.

A purge is itself recorded, with the window it covered, so a later chain
verification can tell an authorised purge apart from tampering. Requires
`audit:export`, and `audit:purge` as well when purging.




## OpenAPI

````yaml /openapi/stand-alone/v3.yaml post /api/v3/audit-logs/export
openapi: 3.1.0
info:
  title: Qanapi Standalone API
  version: 3.0.0
  summary: Single-tenant encryption, key management, classification and audit service.
  description: >
    A standalone cryptographic service. Callers hand it data and it returns

    ciphertext, or hand it ciphertext and it returns data, with every operation

    authorised by policy and recorded on a tamper-evident audit trail.


    ## Authentication


    Two credentials reach the same principal:


    - **API key** in `X-Qanapi-Authorization`, for machine callers. A key
    reaches
      only the configurations it is linked to.
    - **User bearer token** in `Authorization`, from `POST /api/v3/auth/login`,
      for a person working through a console.

    An API key outranks a bearer token when a request carries both, because a

    key names a narrower credential than the user that owns it.


    ## Status codes


    The credential failures are worth stating plainly, because they are not what

    a reader would guess and clients branch on them:


    | Situation | Status |

    |---|---|

    | No credential presented at all | `400` |

    | A credential that does not verify | `401` |

    | A revoked API key | `403` |

    | Authenticated but not permitted | `403` |

    | Request body or parameter is invalid | `422` |


    All of these match the Laravel v3 API this service replaces. Every error
    body

    carries `message` and `error`; validation failures additionally carry a

    field-keyed `errors` object.


    ## Rate limiting


    Every response carries `X-RateLimit-Limit` and `X-RateLimit-Remaining`. The

    window is per node and keyed on the client address, so a cluster of n nodes

    admits n times the configured figure.
  license:
    name: Proprietary
    identifier: LicenseRef-Qanapi-Commercial
servers:
  - url: https://{host}
    description: A deployed instance, behind the reverse proxy that terminates TLS.
    variables:
      host:
        default: qanapi.example.com
  - url: http://localhost:8000
    description: The local Compose cluster, through its load balancer.
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: STAND
    description: |
      Every operation this service serves. Carried on all of them so the
      standalone surface can be selected as a whole, which matters where this
      description is rendered or merged alongside another Qanapi API.

      It is a marker rather than a grouping: each operation keeps the tag that
      says what it does, and that one is listed first.
  - name: Health
    description: |
      Liveness and readiness probes. Registered outside the authentication,
      audit and transport layers, so a load balancer polling them without
      credentials still gets an answer.
  - name: Authentication
    description: Logging in, and creating the first administrator.
  - name: Users
    description: User accounts and their roles.
  - name: API keys
    description: >
      Machine credentials. A key is scoped to a set of configurations and
      reaches

      nothing until it is linked to at least one.
  - name: Configurations
    description: >
      Encryption configurations, called configurations on the wire for
      compatibility

      with the v3 API this service replaces. A configuration owns a master key
      and is

      the unit of cryptographic isolation.
  - name: Classifications
    description: |
      Sensitivity labels and the clearance that reaches them.
  - name: Policies
    description: Allow and deny rules binding a principal to actions on resources.
  - name: Encryption
    description: >
      The data plane. Field-level or whole-body encryption under a
      configuration,

      optionally forwarded onward to a destination of the caller's choosing.
  - name: KMS
    description: Customer-managed key lifecycle, import and export.
  - name: Audit
    description: The tamper-evident record of everything the service did.
  - name: Transport
    description: The service's own key pair, for end-to-end encrypted request bodies.
paths:
  /api/v3/audit-logs/export:
    post:
      tags:
        - Audit
        - STAND
      summary: Export/purge audit logs
      description: |
        Streams matching records as JSONL or CSV, optionally gzipped. With
        `purge` set, the exported records are deleted in the same transaction
        that read them, so nothing can be purged that was not successfully
        exported.

        A purge is itself recorded, with the window it covered, so a later chain
        verification can tell an authorised purge apart from tampering. Requires
        `audit:export`, and `audit:purge` as well when purging.
      operationId: exportAuditLogs
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExportRequest'
      responses:
        '200':
          description: The export stream.
          content:
            application/x-ndjson:
              schema:
                type: string
            text/csv:
              schema:
                type: string
            application/gzip:
              schema:
                type: string
                format: binary
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationFailed'
components:
  schemas:
    ExportRequest:
      type: object
      description: Accepts every filter the query endpoint accepts, plus these.
      properties:
        from:
          type: string
          format: date-time
        to:
          type: string
          format: date-time
        action:
          type: string
        container_id:
          type: string
        principal_id:
          type: string
        principal_type:
          type: string
        status:
          type: string
        request_id:
          type: string
        instance_id:
          type: string
        format:
          type: string
          enum:
            - jsonl
            - csv
          default: jsonl
        gzip:
          type: boolean
          default: false
        purge:
          type: boolean
          default: false
          description: |
            Delete the exported records in the same transaction that read them,
            so nothing is purged that was not successfully exported. Requires
            `audit:purge`, and is itself recorded with the window it covered.
    Error:
      type: object
      required:
        - message
        - error
      properties:
        message:
          type: string
          description: >
            Human readable. A 5xx is described by its category and nothing more:

            operational detail such as a path or a setting name stays in the
            log.
          examples:
            - Unauthorized.
        error:
          type: string
          description: |
            A stable machine readable code. This service sends it and the v3 API
            it replaces does not, which is what lets the two share the same
            `message` strings without losing specificity: `Resource not found.`
            still arrives alongside `KmsKeyNotFoundException`.
          examples:
            - InvalidApiKeyException
    ValidationError:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          required:
            - errors
          properties:
            errors:
              type: object
              description: >
                Messages keyed by the field they concern. A failure with no
                single

                field to blame is filed under `request`.
              additionalProperties:
                type: array
                items:
                  type: string
              examples:
                - type:
                    - The type field is required.
                  configuration_ids:
                    - No configuration has the id `...`.
  responses:
    Forbidden:
      description: |
        Authenticated, but not permitted. Also returned for a revoked API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ValidationFailed:
      description: |
        The request body or a parameter is invalid. `message` is always
        `Validation failed`; the specifics are in `errors`, keyed by field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Qanapi-Authorization
      description: >
        A machine credential, `qk_` followed by its secret. The first twelve

        characters are an indexed prefix; the rest is compared in constant time

        against a stored SHA-256 hash. A key reaches only the configurations it
        is

        linked to.


        It may also be sent as `Authorization: Bearer qk_...`, which is

        recognised by the prefix.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        A user token from `POST /api/v3/auth/login`. The token asserts a role,
        but the database decides it, so a role changed or a user deleted after
        the token was issued takes effect immediately. A token minted before a
        password change is refused.

````