> ## 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.

# List classifications

> Paginated in the envelope the Laravel v3 API returns, so a console that
walks `next_page_url` keeps working.

The page is taken after the policy filter rather than in SQL, because
visibility is a per-classification decision: paging in the query would
return short pages whenever a caller could not see some rows, and
`total` would describe rows the caller is not allowed to know about.




## OpenAPI

````yaml /openapi/stand-alone/v3.yaml get /api/v3/classifications
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/classifications:
    get:
      tags:
        - Classifications
        - STAND
      summary: List classifications
      description: |
        Paginated in the envelope the Laravel v3 API returns, so a console that
        walks `next_page_url` keeps working.

        The page is taken after the policy filter rather than in SQL, because
        visibility is a per-classification decision: paging in the query would
        return short pages whenever a caller could not see some rows, and
        `total` would describe rows the caller is not allowed to know about.
      operationId: listClassifications
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: A page of classifications.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Classification'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  parameters:
    Page:
      name: page
      in: query
      description: 1-based page number.
      schema:
        type: integer
        minimum: 1
        default: 1
    PerPage:
      name: per_page
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 15
  schemas:
    Page:
      type: object
      description: |
        The paginator envelope of the v3 API this service replaces, reproduced
        field for field so a console that walks `next_page_url` keeps working.
      required:
        - current_page
        - data
        - last_page
        - path
        - per_page
        - total
      properties:
        current_page:
          type: integer
        data:
          type: array
        first_page_url:
          type: string
          format: uri
        from:
          type:
            - integer
            - 'null'
          description: 1-based index of the first row on this page; null when empty.
        last_page:
          type: integer
          description: At least 1
          even for no results.: null
        last_page_url:
          type: string
          format: uri
        links:
          type: array
          description: Built for rendering a pager. Labels carry HTML entities.
          items:
            type: object
            properties:
              url:
                type:
                  - string
                  - 'null'
              label:
                type: string
                examples:
                  - '&laquo; Previous'
              page:
                type:
                  - integer
                  - 'null'
              active:
                type: boolean
        next_page_url:
          type:
            - string
            - 'null'
          format: uri
        path:
          type: string
          format: uri
        per_page:
          type: integer
        prev_page_url:
          type:
            - string
            - 'null'
          format: uri
        to:
          type:
            - integer
            - 'null'
        total:
          type: integer
    Classification:
      type: object
      required:
        - id
        - name
        - slug
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        description:
          type:
            - string
            - 'null'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        users:
          type: array
          description: Users holding this clearance directly.
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              email:
                type: string
                format: email
              name:
                type: string
        roles:
          type: array
          description: Roles whose members hold this clearance.
          items:
            type: object
            properties:
              name:
                type: string
    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
  responses:
    Forbidden:
      description: |
        Authenticated, but not permitted. Also returned for a revoked API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  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.

````