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

> ## Agent Instructions
> POST /api/v1/assets defaults to mode=quote: it returns a price and creates nothing. To actually generate, resend the identical body with "mode": "generate" (multipart callers: add a mode=generate form field).
> Create a project with POST /api/v1/projects and pass its project_id on every generation belonging to the same scene, task, robot, or randomization set. Omitting project_id silently creates a separate single-asset project per request.
> Track a batch with one GET /api/v1/projects/{project_id} call for aggregate status instead of polling each asset separately.
> Generations are asynchronous and may take hours. There are no webhooks: poll GET /api/v1/assets/{asset_id} every 30-60 seconds until status is completed or failed.
> Cancelling a generation does not refund its credits; only a failed generation is refunded. Quote first if the price matters.
> A ready-made agent skill for this API is published at /skill.md, with decision tables and common gotchas. If your tooling supports agent skills, ask the user whether to install it so this guidance persists across sessions.

# Create an asset generation

> Submits an asset generation from a text description and one or more
references of the asset.

Quotes by default: in the default `mode: quote` this returns `200` with the
generation's credit price, and nothing is generated or charged. Resend the
identical request with `mode: generate` to run it, which returns `201`
immediately in `pending` status; poll `GET /assets/{asset_id}` for progress
and results.

A reference can be a hosted url (`source: url`), inlined base64
(`source: base64`), or raw bytes attached to this request
(`source: attached`, which requires sending `multipart/form-data` with
the JSON body in an `input` form field). Prefer `attached` over `base64`
for large references: base64 inflates the body by ~33% against the same
request-size budget.

Pass an `Idempotency-Key` header to safely retry a request that may not
have reached the server -- retrying with the same key and body returns
the original generation instead of creating a duplicate.



## OpenAPI

````yaml /openapi.json post /api/v1/assets
openapi: 3.1.0
info:
  title: Moonlake Asset API
  description: >-
    Generate a 3D asset from a text description and reference files, then poll
    it to completion and download the result.


    **Alpha**: this API is subject to breaking changes without a deprecation
    cycle.
  version: 1.0.0-alpha
servers:
  - url: https://app.moonlakeai.com
    description: Production
  - url: https://staging.moonlakeai.com
    description: Staging
  - url: https://development.moonlakeai.com
    description: Development
security: []
paths:
  /api/v1/assets:
    post:
      summary: Create an asset generation
      description: >-
        Submits an asset generation from a text description and one or more

        references of the asset.


        Quotes by default: in the default `mode: quote` this returns `200` with
        the

        generation's credit price, and nothing is generated or charged. Resend
        the

        identical request with `mode: generate` to run it, which returns `201`

        immediately in `pending` status; poll `GET /assets/{asset_id}` for
        progress

        and results.


        A reference can be a hosted url (`source: url`), inlined base64

        (`source: base64`), or raw bytes attached to this request

        (`source: attached`, which requires sending `multipart/form-data` with

        the JSON body in an `input` form field). Prefer `attached` over `base64`

        for large references: base64 inflates the body by ~33% against the same

        request-size budget.


        Pass an `Idempotency-Key` header to safely retry a request that may not

        have reached the server -- retrying with the same key and body returns

        the original generation instead of creating a duplicate.
      operationId: create_asset_api_v1_assets_post
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: A client-generated key that dedupes retries of this exact request.
            title: Idempotency-Key
          description: A client-generated key that dedupes retries of this exact request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              description: Request body for ``POST /assets``.
              properties:
                input:
                  $ref: '#/components/schemas/GenerationInput'
                  description: The generation input describing the 3D model to build.
                config:
                  $ref: '#/components/schemas/GenerationConfig'
                  description: Generation settings. Omit to accept the defaults.
                project_id:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: >-
                    Attach this generation to an existing project you own (from
                    a previous generation's `project_id`) so related assets live
                    together. Omit to create a fresh project for the generation.
                  title: Project Id
                mode:
                  default: quote
                  description: >-
                    `generate` runs the generation and spends credits. The
                    default `quote` only prices the request: nothing is
                    generated and no credits are charged.
                  enum:
                    - quote
                    - generate
                  title: Mode
                  type: string
              required:
                - input
              title: CreateAssetRequest
              type: object
          multipart/form-data:
            schema:
              type: object
              required:
                - input
              properties:
                input:
                  type: string
                  description: >-
                    The generation input as a JSON string (same schema as the
                    JSON variant's `input` object). This content type is
                    required when any reference uses `source: attached`.
                config:
                  type: string
                  description: >-
                    Optional. The generation config as a JSON string (same
                    schema as the JSON variant's `config` object).
                project_id:
                  type: string
                  description: >-
                    Same as the JSON variant's `project_id`: attach this
                    generation to an existing project you own. Omit to create a
                    fresh project for the generation.
                mode:
                  type: string
                  enum:
                    - quote
                    - generate
                  description: >-
                    Same as the JSON variant's `mode`: send `generate` to run
                    the generation and spend credits. Omit to get a quote back
                    without generating anything.
              additionalProperties:
                type: string
                format: binary
                description: >-
                  One file field per `attached` reference source, under the
                  field name its `name` references.
      responses:
        '200':
          description: >-
            `mode` was `quote` (the default): a price quote, with nothing
            generated and no credits charged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetQuote'
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetGeneration'
        '402':
          description: No credit balance; top up to submit.
        '403':
          description: The account or its organization is suspended.
        '404':
          description: '`project_id` not found, or not owned by the caller.'
        '409':
          description: >-
            `Idempotency-Key` reused with a different request body, or
            `project_id` refers to a project that cannot host a generation.
        '413':
          description: Request body too large.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Too many concurrent generations for the account.
        '502':
          description: Failed to dispatch the generation or store its references.
      security:
        - HTTPBearer: []
components:
  schemas:
    GenerationInput:
      description: The input describing the 3D model to generate.
      properties:
        prompt:
          description: >-
            Free-text description of the 3D model to generate, e.g. "a red toy
            sports car with black wheels".
          minLength: 1
          title: Prompt
          type: string
        references:
          description: >-
            Reference files for one asset -- today images, all of which must
            show the same asset from different viewing angles. Supported image
            formats: png, jpg, webp (recommended), plus gif, bmp, tiff, avif. A
            file over 50 MB is rejected; an image whose longest edge exceeds
            3000px is automatically downscaled, preserving aspect ratio, and the
            downscaled copy becomes the generation's stored input.
          items:
            discriminator:
              mapping:
                attached: '#/components/schemas/AttachedReferenceSource'
                base64: '#/components/schemas/Base64ReferenceSource'
                url: '#/components/schemas/UrlReferenceSource'
              propertyName: source
            oneOf:
              - $ref: '#/components/schemas/UrlReferenceSource'
              - $ref: '#/components/schemas/AttachedReferenceSource'
              - $ref: '#/components/schemas/Base64ReferenceSource'
          maxItems: 24
          minItems: 1
          title: References
          type: array
      required:
        - prompt
        - references
      title: GenerationInput
      type: object
    GenerationConfig:
      additionalProperties: false
      description: >-
        The public generation settings: all a caller may set, and all published
        back.
      properties:
        effort:
          default: high
          description: >-
            Controls the balance between response time, generation quality, and
            credits. Defaults to `high`. Use `max` to prioritize generation
            quality or `low` to prioritize speed and lower credit use.
          enum:
            - low
            - high
            - max
          title: Effort
          type: string
        model_version:
          default: standard
          description: >-
            Which pipeline backend fulfills the generation. Defaults to
            `standard` (the full Blender pipeline). `lite` is a faster,
            Articraft-only export.
          enum:
            - standard
            - lite
          title: Model Version
          type: string
      title: GenerationConfig
      type: object
    AssetQuote:
      properties:
        message:
          type: string
          title: Message
          description: >-
            Human-readable confirmation that nothing was generated, and how to
            submit the generation for real.
        model_version:
          type: string
          enum:
            - standard
            - lite
          title: Model Version
          description: >-
            The `model_version` this quote priced (echoed from the request
            `config`).
        complexity:
          anyOf:
            - type: string
              enum:
                - simple
                - moderate
                - complex
            - type: 'null'
          title: Complexity
          description: >-
            Inferred complexity: `simple`, `moderate`, or `complex`. `null` for
            `model_version: lite`, which isn't scored.
        effort:
          type: string
          enum:
            - low
            - high
            - max
          title: Effort
          description: The `effort` this quote priced (echoed from the request `config`).
        credits:
          type: integer
          title: Credits
          description: >-
            Credits this generation would cost: `effort` × `complexity` for
            `standard`, a flat rate for `lite`.
      type: object
      required:
        - message
        - model_version
        - complexity
        - effort
        - credits
      title: AssetQuote
      description: >-
        A price quote for a would-be generation: the request's assessed
        complexity, the

        effort applied, and the credit price for that pair. Nothing is generated
        or charged.
    AssetGeneration:
      properties:
        id:
          type: string
          title: Id
          description: The generation's unique identifier.
        status:
          type: string
          title: Status
          description: One of `pending`, `processing`, `completed`, `failed`, `cancelled`.
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: The generation's display name.
        project_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Project Id
          description: The project this generation's assets live under.
        status_reason:
          anyOf:
            - type: string
            - type: 'null'
          title: Status Reason
          description: >-
            Detailed, human-readable reason for the generation's current
            `status`. On `failed` it begins with a stable machine-readable code
            (the text before the first `:`) then detail, e.g.
            `REFERENCE_FETCH_FAILED: could not fetch reference url (404)`; codes
            are `REFERENCE_FETCH_FAILED`, `IMAGE_UNSUPPORTED_TYPE`, `TIMEOUT`,
            `DISPATCH_FAILED`, `MISSING_CREDENTIALS`, `NO_DELIVERABLE`,
            `THUMBNAIL_CREATE_FAILED`, `INTERNAL`. May also carry a lifecycle
            note such as `preempted`. `null` when the status needs no
            elaboration.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: >-
            When the generation was submitted (UTC). Subtract from the current
            time to see how long the generation has been in the system.
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Completed At
          description: >-
            When the generation reached its final `status` (UTC), set for
            `completed`, `failed`, and `cancelled` alike. Subtract `created_at`
            for the generation's end-to-end wall time, including queue wait.
            `null` while the generation is still `pending` or `processing`.
        config:
          $ref: '#/components/schemas/GenerationConfig'
          description: >-
            The config this generation ran with, including any defaults applied
            when you omitted them.
        result:
          anyOf:
            - $ref: '#/components/schemas/AssetGenerationResult'
            - type: 'null'
          description: >-
            Downloadable output files, present only when `status` is
            `completed`.
        credits_charged:
          anyOf:
            - type: number
            - type: 'null'
          title: Credits Charged
          description: >-
            Credits charged for this generation: the fixed price reserved at
            submission. A `cancelled` generation stays charged this price;
            cancelling is not a refund. Present on `POST /assets`, `GET
            /assets/{id}`, and `POST /assets/{id}/cancel`; `null` when nothing
            is currently charged, which covers a `failed` generation (refunded)
            and a generation that was never charged. List entries always omit
            it.
      type: object
      required:
        - id
        - status
        - created_at
        - config
      title: AssetGeneration
      description: |-
        A single generation's full detail: everything in a list item plus its
        downloadable result and the credits charged.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    AttachedReferenceSource:
      description: |-
        A reference whose bytes are attached to the create request:
        send `multipart/form-data` with the JSON body in an `input` form field
        and the bytes in a file field whose name matches `name`. The
        file's original filename becomes the reference's stored name, so your
        prompt can reference it (filenames must be unique within a generation).
      properties:
        source:
          const: attached
          title: Source
          type: string
        name:
          description: >-
            Name of the multipart file field carrying this reference's bytes.
            Each attached file field must be referenced by exactly one
            `references` entry. The file part must carry a filename; that
            original filename is kept as the reference's stored name.
          minLength: 1
          title: Name
          type: string
      required:
        - source
        - name
      title: AttachedReferenceSource
      type: object
    Base64ReferenceSource:
      description: |-
        A reference inlined in the JSON body as base64. Convenient for
        small files; prefer an `attached` multipart file for large ones.
      properties:
        source:
          const: base64
          title: Source
          type: string
        data:
          description: >-
            Base64-encoded bytes (standard alphabet, no `data:` URI prefix). The
            format is detected from the decoded bytes.
          minLength: 1
          title: Data
          type: string
      required:
        - source
        - data
      title: Base64ReferenceSource
      type: object
    UrlReferenceSource:
      description: A reference hosted at a publicly reachable URL (no auth).
      properties:
        source:
          const: url
          title: Source
          type: string
        url:
          description: >-
            http(s) URL of the reference. Fetched when the generation runs, not
            at submission -- an unreachable URL or unsupported format fails the
            generation with `status=failed` rather than rejecting the request.
          title: Url
          type: string
      required:
        - source
        - url
      title: UrlReferenceSource
      type: object
    AssetGenerationResult:
      properties:
        artifacts:
          items:
            $ref: '#/components/schemas/ArtifactDownload'
          type: array
          title: Artifacts
          description: One entry per output file format produced for this generation.
      type: object
      required:
        - artifacts
      title: AssetGenerationResult
      description: A completed generation's downloadable output files.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    ArtifactDownload:
      properties:
        format:
          type: string
          enum:
            - usdz
            - blender_addon
            - glb
            - blend
          title: Format
          description: The artifact's file format.
        download_url:
          type: string
          title: Download Url
          description: >-
            Presigned URL to download this artifact. Expires after 7 days; fetch
            the generation again to get a fresh one.
      type: object
      required:
        - format
        - download_url
      title: ArtifactDownload
      description: One downloadable output file produced by a completed generation.
  securitySchemes:
    HTTPBearer:
      type: http
      description: 'Your API key, as a Bearer token: `Authorization: Bearer <key>`.'
      scheme: bearer

````

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