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

# List people in a library

> Returns a paginated list of people (named identities that group one or more faces), ordered according to `sort` (newest first by default), optionally filtered by asset, album, name, or ID. Use this to enumerate who appears in the library, to resolve a user-typed name to a `person_id`, or to find who appears in a specific asset or album.

By default only **named** people are returned; pass `name_filter=all` or `name_filter=unnamed` to include clusters that haven't been named yet.

To list the underlying faces for a specific person, use `list_faces` with `person_id`.

**Pagination** is cursor-based: when `has_more` is true, pass the `id` of the last person in `data` as `starting_after_id` to fetch the next page.



## OpenAPI

````yaml https://api.gumnut.ai/openapi.json get /api/people
openapi: 3.1.0
info:
  title: Gumnut API
  description: API for using Gumnut to manage photos and videos
  version: 0.1.0
servers: []
security: []
paths:
  /api/people:
    get:
      tags:
        - people
      summary: List people in a library
      description: >-
        Returns a paginated list of people (named identities that group one or
        more faces), ordered according to `sort` (newest first by default),
        optionally filtered by asset, album, name, or ID. Use this to enumerate
        who appears in the library, to resolve a user-typed name to a
        `person_id`, or to find who appears in a specific asset or album.


        By default only **named** people are returned; pass `name_filter=all` or
        `name_filter=unnamed` to include clusters that haven't been named yet.


        To list the underlying faces for a specific person, use `list_faces`
        with `person_id`.


        **Pagination** is cursor-based: when `has_more` is true, pass the `id`
        of the last person in `data` as `starting_after_id` to fetch the next
        page.
      operationId: list_people
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            maximum: 200
            minimum: 1
            description: >-
              Maximum number of people to return per page (1–200). Defaults to
              20.
            default: 20
            title: Limit
          description: Maximum number of people to return per page (1–200). Defaults to 20.
        - name: starting_after_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Cursor for pagination. Pass the `id` of the last person in the
              previous response's `data` to fetch the next page. Omit for the
              first page.
            title: Starting After Id
          description: >-
            Cursor for pagination. Pass the `id` of the last person in the
            previous response's `data` to fetch the next page. Omit for the
            first page.
        - name: asset_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Return only people who have at least one face in this asset.
              Useful for 'who is in this photo?'.
            title: Asset Id
          description: >-
            Return only people who have at least one face in this asset. Useful
            for 'who is in this photo?'.
        - name: album_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Return only people who appear in at least one asset of this album.
              Useful for 'who is in this album?'.
            title: Album Id
          description: >-
            Return only people who appear in at least one asset of this album.
            Useful for 'who is in this album?'.
        - name: ids
          in: query
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: 'null'
            description: >-
              Look up specific people by ID (max 200; each ID has the `person_`
              prefix). Accepts multiple `ids=` query params or a single
              comma-delimited value (e.g., `ids=person_1,person_2`). When set,
              `name_filter` defaults to `all` so unnamed clusters are included
              in the lookup.
            title: Ids
          description: >-
            Look up specific people by ID (max 200; each ID has the `person_`
            prefix). Accepts multiple `ids=` query params or a single
            comma-delimited value (e.g., `ids=person_1,person_2`). When set,
            `name_filter` defaults to `all` so unnamed clusters are included in
            the lookup.
        - name: name
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                maxLength: 255
              - type: 'null'
            description: >-
              Filter by name using case-insensitive substring matching. Use this
              to resolve a user-supplied name like 'Alice' into a `person_id`,
              then pass that ID into `search_assets.person_ids` or
              `list_assets.person_ids`.
            title: Name
          description: >-
            Filter by name using case-insensitive substring matching. Use this
            to resolve a user-supplied name like 'Alice' into a `person_id`,
            then pass that ID into `search_assets.person_ids` or
            `list_assets.person_ids`.
        - name: name_filter
          in: query
          required: false
          schema:
            anyOf:
              - $ref: '#/components/schemas/NameFilter'
              - type: 'null'
            description: >-
              Filter by name status: `named` returns only people with a name;
              `unnamed` returns only nameless face clusters awaiting a name;
              `all` returns both. Defaults to `named` (or `all` when `ids` is
              provided).
            title: Name Filter
          description: >-
            Filter by name status: `named` returns only people with a name;
            `unnamed` returns only nameless face clusters awaiting a name; `all`
            returns both. Defaults to `named` (or `all` when `ids` is provided).
        - name: sort
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/PersonSort'
            description: >-
              Sort order for results: `created_at_desc` (newest people first;
              default) / `created_at_asc`, `name_asc` / `name_desc`
              (alphabetical by name, locale-aware; unnamed people always sort
              last), or `asset_count_desc` / `asset_count_asc` (by number of
              photos the person appears in). Name sorts cannot be combined with
              `name_filter=unnamed`.
            default: created_at_desc
          description: >-
            Sort order for results: `created_at_desc` (newest people first;
            default) / `created_at_asc`, `name_asc` / `name_desc` (alphabetical
            by name, locale-aware; unnamed people always sort last), or
            `asset_count_desc` / `asset_count_asc` (by number of photos the
            person appears in). Name sorts cannot be combined with
            `name_filter=unnamed`.
        - name: library_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Library to list from. Optional if the user has a single library;
              required when they have multiple.
            title: Library Id
          description: >-
            Library to list from. Optional if the user has a single library;
            required when they have multiple.
        - name: include
          in: query
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: 'null'
            description: >-
              Opt-in expansion fields. Supported values: `cluster_metrics` (adds
              the nested `cluster_metrics` object — `pairwise_p90`,
              `pairwise_mean`, `face_count` — for each Person with a populated
              centroid). Accepts multiple `include=` query params or a single
              comma-delimited value. Unknown values return 422.
            title: Include
          description: >-
            Opt-in expansion fields. Supported values: `cluster_metrics` (adds
            the nested `cluster_metrics` object — `pairwise_p90`,
            `pairwise_mean`, `face_count` — for each Person with a populated
            centroid). Accepts multiple `include=` query params or a single
            comma-delimited value. Unknown values return 422.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPeopleResponse'
        '404':
          description: Not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    NameFilter:
      type: string
      enum:
        - named
        - unnamed
        - all
      title: NameFilter
    PersonSort:
      type: string
      enum:
        - created_at_desc
        - created_at_asc
        - name_asc
        - name_desc
        - asset_count_desc
        - asset_count_asc
      title: PersonSort
      description: |-
        Sort orders for list_people. Each value encodes column + direction;
        decompose via the `column` and `direction` properties.
    PaginatedPeopleResponse:
      properties:
        data:
          items:
            $ref: '#/components/schemas/PersonResponse'
          type: array
          title: Data
          description: List of people
        has_more:
          type: boolean
          title: Has More
          description: >-
            True if there are more people after this page. Pass the last
            person's `id` as `starting_after_id` to fetch the next page.
      type: object
      required:
        - data
        - has_more
      title: PaginatedPeopleResponse
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    PersonResponse:
      properties:
        id:
          type: string
          title: Id
          description: Unique person identifier with 'person_' prefix
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: Optional name assigned to this person
        birth_date:
          anyOf:
            - type: string
              format: date
            - type: 'null'
          title: Birth Date
          description: Optional birth date of this person
        is_hidden:
          type: boolean
          title: Is Hidden
          description: Whether this person should be hidden from the UI
        is_favorite:
          type: boolean
          title: Is Favorite
          description: Whether this person is marked as a favorite
        asset_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Asset Count
          description: >-
            Number of unique photos this person appears in, or null if not
            computed
        thumbnail_face_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Thumbnail Face Id
          description: ID of the face resource used as this person's thumbnail
        asset_urls:
          anyOf:
            - additionalProperties:
                $ref: '#/components/schemas/AssetVariant'
              type: object
            - type: 'null'
          title: Asset Urls
          description: >-
            Asset variants from this person's thumbnail face. May be null when
            embedded in an AssetResponse; use /api/people endpoints for full
            person data.
        cluster_metrics:
          anyOf:
            - $ref: '#/components/schemas/ClusterMetricsResponse'
            - type: 'null'
          description: >-
            Cohesion metrics for this person's face cluster. Populated only when
            `include=cluster_metrics` is requested on the people endpoint, and
            only for persons with a populated centroid (newly-created empty
            Persons will have null). See `ClusterMetricsResponse` for the shape.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When this person record was created
        updated_at:
          type: string
          format: date-time
          title: Updated At
          description: When this person record was last updated
      type: object
      required:
        - id
        - is_hidden
        - is_favorite
        - created_at
        - updated_at
      title: PersonResponse
      description: Represents a person identified through face clustering and recognition.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    AssetVariant:
      properties:
        url:
          type: string
          title: Url
          description: URL to fetch this image variant
        mimetype:
          type: string
          title: Mimetype
          description: MIME type of the served image
        width:
          anyOf:
            - type: integer
            - type: 'null'
          title: Width
          description: Target width in pixels (null if unknown)
      type: object
      required:
        - url
        - mimetype
      title: AssetVariant
      description: A single image variant with its URL, MIME type, and target width.
    ClusterMetricsResponse:
      properties:
        pairwise_p90:
          type: number
          title: Pairwise P90
          description: >-
            90th-percentile pairwise cosine distance between faces in this
            person's cluster. Lower = more cohesive cluster; loose clusters
            (higher pairwise_p90) are gated out of the face-assignment path to
            prevent further drift.
        pairwise_mean:
          type: number
          title: Pairwise Mean
          description: >-
            Mean pairwise cosine distance between faces in this person's
            cluster.
        face_count:
          type: integer
          title: Face Count
          description: >-
            Number of faces that fed into the centroid and pairwise metrics.
            This is the cluster-membership count, **not** the same as
            `asset_count` — `face_count` counts every face row, while
            `asset_count` counts distinct assets (one asset can contribute
            multiple faces of the same person).
      type: object
      required:
        - pairwise_p90
        - pairwise_mean
        - face_count
      title: ClusterMetricsResponse
      description: |-
        Cohesion metrics for a Person's face cluster — surfaced via
        ``include=cluster_metrics`` on the people endpoints. These describe how
        tight the cluster is in embedding space (lower = more cohesive) and
        drive both the production face-assignment cohesion gate and the
        operator-facing face cleanup dashboard.

````