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

# Create reference

> POST /v1/references saves a private image or audio reference and returns the handle a prompt mentions it by.

Save a reference: a `name`, a `kind`, and the media for that kind. An `object`, `location`, `pose`, or `outfit` takes an `image` (an https URL, an [upload](/api/endpoints/create-upload) URL, or a data URL of a JPEG or PNG), stored with the reference for as long as it exists. An `audio` reference takes an `audio` clip (MP3 or WAV) instead, which goes through the same processing as a clip uploaded in the app: trimmed to 15 seconds and normalized.

The `handle` follows the same rules as a character's: 1 to 15 lowercase letters, digits, underscores, or dashes, starting with a letter, unique among live characters and references, and fixed once created. Leave it out to have one derived from the name. A handle already in use is a `409 handle_taken`.

References created through the API are private.


## OpenAPI

````yaml api/openapi.json POST /v1/references
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/references:
    post:
      tags:
        - References
      summary: Create reference
      description: >-
        Save a private reference: an object, location, pose, or outfit from an
        image, or an audio reference from a clip. Its `handle` is what a prompt
        mentions.
      operationId: create_reference
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateReferenceRequest'
            example:
              name: Red coat
              handle: red-coat
              kind: outfit
              image: https://example.com/red-coat.jpg
      responses:
        '201':
          description: The reference.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Reference'
              example:
                id: a81f0c5d-2e6b-4f93-b7c4-0d9e5a3c2f18
                handle: red-coat
                name: Red coat
                kind: outfit
                description: null
                image_url: https://cdn3.mage.space/references/user/image/4c2d.jpg
                audio_url: null
                created_at: '2026-09-18T10:05:00.000Z'
        '400':
          $ref: '#/components/responses/InvalidCreateRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/CreateForbidden'
        '409':
          $ref: '#/components/responses/HandleTaken'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CreateReferenceRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 50
          description: The display name.
        handle:
          description: >-
            The `@handle` prompts mention it by: 1 to 15 lowercase letters,
            digits, underscores, or dashes, starting with a letter. Derived from
            the name when omitted. Cannot be changed later.
          type: string
        kind:
          type: string
          enum:
            - object
            - location
            - pose
            - outfit
            - audio
          description: >-
            What the reference is. The four image kinds take `image`; `audio`
            takes `audio`.
        image:
          description: >-
            The image, for the four image kinds: an https URL, an upload URL, or
            a data URL of a JPEG or PNG. Stored permanently with the reference.
          anyOf:
            - type: string
              format: uri
            - type: string
              pattern: ^data:[^;,]+(?:;[^;,]+)*;base64,
        audio:
          description: >-
            The clip, for `kind: "audio"`: an https URL, an upload URL, or a
            data URL of an MP3 or WAV. Trimmed to 15 seconds and normalized,
            like a clip uploaded in the app.
          anyOf:
            - type: string
              format: uri
            - type: string
              pattern: ^data:[^;,]+(?:;[^;,]+)*;base64,
        description:
          description: Optional notes, for your own reference.
          type: string
          maxLength: 500
      required:
        - name
        - kind
      additionalProperties: false
    Reference:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: >-
            The reference id, as `DELETE /v1/references/{reference_id}` takes
            it.
        handle:
          type: string
          description: Mention the reference in a prompt as `@handle`.
        name:
          type: string
          description: The display name.
        kind:
          type: string
          enum:
            - object
            - location
            - pose
            - outfit
            - audio
          description: What the reference is.
        description:
          anyOf:
            - type: string
            - type: 'null'
          description: Your notes, or null.
        image_url:
          anyOf:
            - type: string
              format: uri
            - type: 'null'
          description: The image, for the four image kinds; null for an audio reference.
        audio_url:
          anyOf:
            - type: string
              format: uri
            - type: 'null'
          description: 'The processed clip, for `kind: "audio"`; null otherwise.'
        created_at:
          type: string
          format: date-time
          description: When it was created.
      required:
        - id
        - handle
        - name
        - kind
        - description
        - image_url
        - audio_url
        - created_at
      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:
    InvalidCreateRequest:
      description: >-
        The body is not a JSON object, a required field is missing, a value is
        out of range, `handle` breaks the handle rules, or a media source could
        not be fetched or is not an accepted format. The message names the
        field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_request
              message: '`name` is required.'
    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.
    CreateForbidden:
      description: The account cannot create characters or references.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: forbidden
              message: This account cannot create characters or references.
    HandleTaken:
      description: >-
        A live character or reference already uses the handle. Choose another,
        or omit `handle` to derive one from the name.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: handle_taken
              message: >-
                The handle `@ana` is taken. Choose another, or omit `handle` to
                derive one from the name.
              handle: ana
    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.

````