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

# Tenants in the key's scope

> A key for all tenants lists every tenant except internal ones, in
id order. A key scoped to one tenant lists that tenant only.




## OpenAPI

````yaml /reference/openapi/metrics-v1.yaml get /tenants
openapi: 3.1.0
info:
  title: Veristar machine metrics API
  version: 1.0.0
  summary: Read-only aggregate web and API metrics for downstream machine consumers.
  description: |
    The contract of `/api/metrics/v1/` (plan phase 12,
    docs/reference/control-plane-api.md section 9). Every request carries an
    operator API key as `Authorization: Bearer sa_op_<40 base62 characters>`.
    Console session cookies are never accepted here, and keys are accepted
    nowhere else.

    Conventions shared by every route:

    * Only `GET` is defined. Every answer carries `Cache-Control: no-store`
      and `X-Request-Id`.
    * A query parameter that the route does not list, or one given twice, is
      400 `invalid_query`.
    * Days are UTC days `yyyy-mm-dd`; hours are RFC 3339 UTC hour starts such
      as `2026-11-12T09:00:00Z`. Ranges include both ends.
    * A key scoped to one tenant reads only that tenant. Naming another
      tenant is 403 `scope_forbidden`. A key for all tenants never sees
      internal tenants (the monitoring probe); naming one is 404.
    * List routes return at most `limit` items (1 to 500, default 500) and an
      opaque `next_cursor`, `null` on the last page. A cursor is bound to the
      route and every other query parameter; with any other combination it
      is 400 `invalid_cursor`. The range a cursor carries is checked again on
      every page with the limits of a first page; a cursor that breaks them
      is 400 `invalid_cursor`.
    * Each key may make 10 requests per second per control plane instance
      (token bucket, burst 20). Above that the answer is 429 `rate_limited`
      with `Retry-After` in seconds.
    * Percentiles come from summed histogram buckets and are never averaged.
      A percentile in the open bucket above 10 s has `*_seconds: null` and
      `*_over_10s: true`.
  license:
    name: Apache-2.0
    identifier: Apache-2.0
servers:
  - url: /api/metrics/v1
security:
  - operatorKey: []
paths:
  /tenants:
    get:
      summary: Tenants in the key's scope
      description: |
        A key for all tenants lists every tenant except internal ones, in
        id order. A key scoped to one tenant lists that tenant only.
      operationId: listTenants
      parameters:
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/cursor'
      responses:
        '200':
          description: One page of tenants.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantList'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/Internal'
components:
  parameters:
    limit:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 500
        default: 500
    cursor:
      name: cursor
      in: query
      required: false
      description: The `next_cursor` of the previous page.
      schema:
        type: string
        minLength: 1
  headers:
    X-Request-Id:
      description: The id of the request, also in the error envelope and the server log.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before the next request.
      required: true
      schema:
        type: string
        pattern: ^[1-9][0-9]*$
  schemas:
    TenantList:
      type: object
      additionalProperties: false
      required:
        - items
        - next_cursor
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Tenant'
        next_cursor:
          $ref: '#/components/schemas/Cursor'
    Tenant:
      type: object
      additionalProperties: false
      required:
        - id
        - slug
        - name
        - status
        - created_at
        - sites
        - sites_verified
        - sites_with_stellar_toml
        - verified
        - stellar_toml
      properties:
        id:
          $ref: '#/components/schemas/ID'
        slug:
          type: string
        name:
          type: string
        status:
          $ref: '#/components/schemas/TenantStatus'
        created_at:
          $ref: '#/components/schemas/Time'
        sites:
          description: Sites that are not removed.
          allOf:
            - $ref: '#/components/schemas/Count'
        sites_verified:
          description: Sites with a successful domain verification (control-plane-api 5.8).
          allOf:
            - $ref: '#/components/schemas/Count'
        sites_with_stellar_toml:
          description: Sites whose stellar.toml check found one (control-plane-api 5.12).
          allOf:
            - $ref: '#/components/schemas/Count'
        verified:
          type: boolean
          description: At least one verified site.
        stellar_toml:
          type: boolean
          description: At least one site with a stellar.toml.
    Cursor:
      type:
        - string
        - 'null'
      description: Opaque position of the next page, `null` on the last page.
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - invalid_query
                - invalid_cursor
                - unauthenticated
                - scope_forbidden
                - not_found
                - method_not_allowed
                - rate_limited
                - internal
                - unavailable
            message:
              type: string
            request_id:
              type: string
    ID:
      type: string
      pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
    TenantStatus:
      type: string
      enum:
        - pending
        - active
        - rejected
        - suspended
        - removed
    Time:
      type: string
      description: RFC 3339 in UTC with at most millisecond digits.
      pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,3})?Z$
    Count:
      type: integer
      minimum: 0
  responses:
    BadRequest:
      description: >-
        A malformed or unknown query parameter (`invalid_query`) or cursor
        (`invalid_cursor`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthenticated:
      description: >-
        No key, a malformed or unknown key, or an expired or revoked key
        (`unauthenticated`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        WWW-Authenticate:
          required: true
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: The key's token bucket is empty (`rate_limited`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Internal:
      description: Anything unexpected (`internal`); details only in the server log.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    operatorKey:
      type: http
      scheme: bearer
      description: An operator API key, `sa_op_` followed by 40 base62 characters.

````

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