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

# List clients

> Returns every active client of your studio with their contact details,
credit and entry-pass balances, make-up sessions, and booking history.
Archived and blocked clients are excluded.

<Warning>
  This endpoint returns personal data. It requires your **secret API
  key** and is not callable from a browser. See
  [Authentication](/api/authentication).
</Warning>

Prefer the per-group `passBalances` array over the aggregated
`bundles.entries` object, which is deprecated. See the
[Client](/api/objects/client) object for the full field reference.




## OpenAPI

````yaml /api/v1/openapi.yaml get /v1/clients
openapi: 3.0.3
info:
  title: Zenamu API v1
  version: '1.0'
  description: The Zenamu public REST API.
servers:
  - url: https://api.zenamu.com
    description: Production
security:
  - zenamuPublicKey: []
tags:
  - name: Classes
  - name: Workshops
  - name: Lecturers
  - name: Places
  - name: Clients
  - name: Credits and passes
  - name: Pass groups
paths:
  /v1/clients:
    get:
      tags:
        - Clients
      summary: List clients
      description: |
        Returns every active client of your studio with their contact details,
        credit and entry-pass balances, make-up sessions, and booking history.
        Archived and blocked clients are excluded.

        <Warning>
          This endpoint returns personal data. It requires your **secret API
          key** and is not callable from a browser. See
          [Authentication](/api/authentication).
        </Warning>

        Prefer the per-group `passBalances` array over the aggregated
        `bundles.entries` object, which is deprecated. See the
        [Client](/api/objects/client) object for the full field reference.
      operationId: getClients
      responses:
        '200':
          description: The studio's active clients.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current one-minute window.
              schema:
                type: integer
                example: 100
            X-RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: integer
                minimum: 0
                example: 99
            X-RateLimit-Reset:
              description: Unix timestamp in seconds when the current window resets.
              schema:
                type: integer
                example: 1788336000
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientList'
              example:
                statusCode: 200
                message: Success
                data:
                  - id: 2
                    _id: ff3200995bcaa071c00481f32a1fd876
                    firstname: Lila
                    lastname: Kensington
                    email: lila.kensington@example.com
                    phone: null
                    clientBirthNumber: null
                    clientBirthday: '1987-01-01'
                    registrationDate: '2026-01-30'
                    marketingConsent: 1
                    bundles:
                      credits:
                        numberOfCredits: 0
                        validToDate: null
                      entries:
                        numberOfEntries: 8
                        validToDate: '2027-01-05'
                    passBalances:
                      - passGroupId: 1
                        passGroupName: 10-entry pass
                        numberOfEntries: 8
                        numberOfBlockedEntries: 0
                        validTo: '2027-01-05'
                    makeupSessions:
                      - validTo: '2026-10-09'
                    bookings:
                      totalBookingsCompleted: 15
                      lastBookingCompletedDate: '2026-10-01'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ForbiddenUltimate'
        '404':
          $ref: '#/components/responses/KeyNotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - zenamuSecretKey: []
components:
  schemas:
    ClientList:
      type: object
      properties:
        statusCode:
          type: integer
          example: 200
        message:
          type: string
          example: Success
        data:
          type: array
          items:
            $ref: '#/components/schemas/Client'
    Client:
      type: object
      properties:
        id:
          type: integer
          description: >-
            Numeric client ID. This is the value you pass as `clientId` when
            granting credits or passes.
        _id:
          type: string
          description: Opaque client ID, used by other Zenamu surfaces.
        firstname:
          type: string
          nullable: true
        lastname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        phone:
          type: string
          nullable: true
        clientBirthNumber:
          type: string
          nullable: true
          description: National identification number, where the studio collects it.
        clientBirthday:
          type: string
          format: date
          nullable: true
        registrationDate:
          type: string
          format: date
          nullable: true
          description: >-
            When the account was created, or when the first order was placed for
            a client who never set a password.
        marketingConsent:
          type: integer
          description: >-
            Whether the client agreed to receive the studio's newsletters. `1`
            for granted, `0` otherwise.
        bundles:
          type: object
          properties:
            credits:
              type: object
              properties:
                numberOfCredits:
                  type: integer
                  description: Current credit balance.
                validToDate:
                  type: string
                  format: date
                  nullable: true
                  description: Expiry of the credits, `null` when there are none.
            entries:
              type: object
              deprecated: true
              description: >-
                **Deprecated.** The entry balance summed across every pass
                group, with the latest expiry across groups. It hides the
                per-group breakdown as soon as a studio has more than one group.
                Read `passBalances` instead.
              properties:
                numberOfEntries:
                  type: integer
                validToDate:
                  type: string
                  format: date
                  nullable: true
        passBalances:
          type: array
          description: >-
            Active entry-pass balances broken down per group. Empty when the
            client holds none. Summing `numberOfEntries` across the array gives
            the deprecated `bundles.entries.numberOfEntries`.
          items:
            $ref: '#/components/schemas/PassBalance'
        makeupSessions:
          type: array
          description: Compensations the client can still redeem.
          items:
            $ref: '#/components/schemas/MakeupSession'
        bookings:
          type: object
          properties:
            totalBookingsCompleted:
              type: integer
              description: >-
                The client's completed classes and past workshops, summed
                together. A class counts once its reservation is completed; a
                workshop once its date has passed and its order is paid or
                awaiting payment.
            lastBookingCompletedDate:
              type: string
              format: date
              nullable: true
              description: The most recent of those, `null` when there is none.
    ErrorResponse:
      type: object
      required:
        - statusCode
        - message
      properties:
        statusCode:
          type: integer
          description: Repeats the HTTP status code.
        error:
          type: string
          description: >-
            Short label — `Internal Server Error` for `500`, `Too Many Requests`
            for `429`, `Error` otherwise.
        message:
          type: string
          description: >-
            Human-readable explanation. For `500` this is a fixed generic
            message; the detail is logged server-side.
    PassBalance:
      type: object
      description: A client's active entry balance in one pass group.
      properties:
        passGroupId:
          type: integer
          description: The group's ID, matching `id` from `GET /v1/pass-groups`.
        passGroupName:
          type: string
          nullable: true
          description: Group name. `null` for a studio's original default group.
        numberOfEntries:
          type: integer
          description: The entry balance recorded on this group.
        numberOfBlockedEntries:
          type: integer
          description: >-
            Entries tied up by a pending waitlist reservation, released when
            that reservation resolves. To show a single "entries left" number,
            use `max(0, numberOfEntries - numberOfBlockedEntries)`, which is
            what Zenamu's own reporting uses.
        validTo:
          type: string
          format: date
          nullable: true
          description: Last day the entries can be used, `YYYY-MM-DD`.
    MakeupSession:
      type: object
      description: One compensation entry the client can still redeem.
      properties:
        validTo:
          type: string
          format: date
          description: Last day the make-up session can be used.
  responses:
    Unauthorized:
      description: No API key was sent.
      headers:
        X-RateLimit-Limit:
          description: Maximum requests allowed in the current one-minute window.
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            minimum: 0
            example: 99
        X-RateLimit-Reset:
          description: Unix timestamp in seconds when the current window resets.
          schema:
            type: integer
            example: 1788336000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 401
            error: Error
            message: >-
              Missing access token. You must send your access token in the
              request header ('Authorization: Bearer YOUR_ACCESS_TOKEN' )
    ForbiddenUltimate:
      description: >-
        Your studio's plan does not allow the private API — it requires the
        Ultimate plan. See [Plans and access](/api#plans-and-access).
      headers:
        X-RateLimit-Limit:
          description: Maximum requests allowed in the current one-minute window.
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            minimum: 0
            example: 99
        X-RateLimit-Reset:
          description: Unix timestamp in seconds when the current window resets.
          schema:
            type: integer
            example: 1788336000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 403
            error: Error
            message: The Zenamu API is only available on the Ultimate tariff.
    KeyNotFound:
      description: >-
        The API key was not recognized. Zenamu answers an unknown key with
        `404`, not `401` — see
        [Authentication](/api/authentication#authentication-errors).
      headers:
        X-RateLimit-Limit:
          description: Maximum requests allowed in the current one-minute window.
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            minimum: 0
            example: 99
        X-RateLimit-Reset:
          description: Unix timestamp in seconds when the current window resets.
          schema:
            type: integer
            example: 1788336000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 404
            error: Error
            message: API key not found
    TooManyRequests:
      description: >-
        You exceeded 100 calls per minute on this endpoint. See [Rate
        limits](/api/rate-limits).
      headers:
        X-RateLimit-Limit:
          description: Maximum requests allowed in the current one-minute window.
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            minimum: 0
            example: 99
        X-RateLimit-Reset:
          description: Unix timestamp in seconds when the current window resets.
          schema:
            type: integer
            example: 1788336000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 429
            error: Too Many Requests
            message: 'Rate limit exceeded: up to 100 requests per minute per endpoint.'
    InternalServerError:
      description: >-
        Unexpected server error. Retry with backoff if the call is safe to
        repeat.
      headers:
        X-RateLimit-Limit:
          description: Maximum requests allowed in the current one-minute window.
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            minimum: 0
            example: 99
        X-RateLimit-Reset:
          description: Unix timestamp in seconds when the current window resets.
          schema:
            type: integer
            example: 1788336000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 500
            error: Internal Server Error
            message: >-
              We apologize, but there was an error on our end. If problems
              persist, please contact us at support@zenamu.com
  securitySchemes:
    zenamuPublicKey:
      type: http
      scheme: bearer
      description: >-
        Your **public API key** (`zen_pub_…`), sent as `Authorization: Bearer
        <key>`. Browser-safe. See [Authentication](/api/authentication).
    zenamuSecretKey:
      type: http
      scheme: bearer
      description: >-
        Your **secret API key** (`zen_live_…`), sent as `Authorization: Bearer
        <key>`. Backend-to-backend only — never expose it in a browser. See
        [Authentication](/api/authentication).

````