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

# List characters

> GET /v1/characters returns the account's saved characters, newest first, with the handle each one is mentioned by.

Your own characters, newest first, with `limit` and `cursor` for paging: send the `next_cursor` of one page as `cursor` to get the next, until it is null. Each entry's `handle` is what a prompt mentions as `@handle`; `id` is what [`DELETE /v1/characters/{character_id}`](/api/endpoints/delete-character) takes.

Other users' public characters are not listed. They can still be mentioned by handle in a prompt. See [Characters and references](/api/inputs#characters-and-references).


## OpenAPI

````yaml api/openapi.json GET /v1/characters
openapi: 3.1.0
info:
  title: Mage API
  version: v1
  description: >-
    Run Mage models from your own code: submit a generation, poll its status,
    download the result. Every request is paid in gems.
  contact:
    name: Mage
    url: https://www.mage.space
    email: mage@mage.space
servers:
  - url: https://api.mage.space
    description: Production
security:
  - apiKey: []
tags:
  - name: Requests
    description: Submit, poll, and cancel generations.
  - name: Catalog
    description: What the API can generate with.
  - name: Account
    description: The gems balance.
  - name: Uploads
    description: Large input files.
  - name: Characters
    description: Saved characters a prompt mentions by `@handle`.
  - name: References
    description: Saved image and audio references a prompt mentions by `@handle`.
  - name: Image models
    description: One endpoint per image architecture.
  - name: Video models
    description: One endpoint per video architecture.
paths:
  /v1/characters:
    get:
      tags:
        - Characters
      summary: List characters
      description: >-
        The account's own characters, newest first. Other users' public
        characters are not listed; they are reached by `@handle` in a prompt.
      operationId: list_characters
      parameters:
        - name: limit
          in: query
          required: false
          description: Entities per page, 1 to 200; 50 when omitted.
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: cursor
          in: query
          required: false
          description: The `next_cursor` of the previous page.
          schema:
            type: string
      responses:
        '200':
          description: One page of characters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CharacterList'
              example:
                data:
                  - id: 3f9c2a1e-7b44-4d2e-9a0f-6c1d8e2b5a71
                    handle: ana
                    name: Ana
                    description: A red-haired courier in a green jacket.
                    image_url: https://cdn3.mage.space/characters/user/image/9b1e.jpg
                    voice_url: https://cdn3.mage.space/references/user/audio/7d2c.mp3
                    visibility: private
                    created_at: '2026-09-18T10:00:00.000Z'
                next_cursor: null
        '400':
          $ref: '#/components/responses/InvalidListRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CharacterList:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
                description: >-
                  The character id, as `DELETE /v1/characters/{character_id}`
                  takes it.
              handle:
                type: string
                description: Mention the character in a prompt as `@handle`.
              name:
                type: string
                description: The display name.
              description:
                anyOf:
                  - type: string
                  - type: 'null'
                description: Your notes, or null.
              image_url:
                type: string
                format: uri
                description: The portrait.
              voice_url:
                anyOf:
                  - type: string
                    format: uri
                  - type: 'null'
                description: The processed voice clip, or null for a character without one.
              visibility:
                type: string
                enum:
                  - public
                  - private
                description: >-
                  Characters created through the API are private; publishing
                  happens in the app.
              created_at:
                type: string
                format: date-time
                description: When it was created.
            required:
              - id
              - handle
              - name
              - description
              - image_url
              - voice_url
              - visibility
              - created_at
            additionalProperties: false
          description: The page, newest first.
        next_cursor:
          anyOf:
            - type: string
            - type: 'null'
          description: Send as `cursor` for the next page; null on the last page.
      required:
        - data
        - next_cursor
      additionalProperties: false
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - invalid_request
                - invalid_config
                - architecture_not_found
                - architecture_retired
                - request_not_found
                - character_not_found
                - reference_not_found
                - not_found
                - insufficient_gems
                - forbidden
                - content_blocked
                - request_finished
                - handle_taken
                - too_many_requests
                - generation_failed
                - internal_error
              description: A stable error code; treat an unknown code by its HTTP status.
            message:
              type: string
              description: What went wrong, for a person.
            request_id:
              description: >-
                The request the refusal belongs to, when one was recorded before
                the refusal.
              type: string
              format: uuid
            gems_required:
              description: The price of the refused generation, on `insufficient_gems`.
              type: number
            docs_url:
              description: Where to read the API reference, on `not_found`.
              type: string
              format: uri
            handle:
              description: The handle that is taken, on `handle_taken`.
              type: string
          required:
            - code
            - message
          additionalProperties: true
          description: Further fields depend on the code.
      required:
        - error
      additionalProperties: false
  responses:
    InvalidListRequest:
      description: >-
        `limit` is not a whole number in range, or `cursor` is not a
        `next_cursor` from an earlier page.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_request
              message: '`limit` must be a whole number from 1 to 200.'
    Unauthorized:
      description: The key is missing, malformed, unknown, or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: The API key is invalid or has been revoked.
    InternalError:
      description: >-
        Something failed on Mage's side. Retry, and contact support if it
        persists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: internal_error
              message: >-
                Something went wrong on our side. Retry, and contact support if
                it persists.
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        An API key from Settings → API, sent as `Authorization: Bearer
        mage_sk_…`. Keys are for server-side code only.

````