openapi: 3.0.3
info:
  title: Snowpixel
  description: 'Snowpixel public REST API for server-side scripts and services. Authenticate
    with an account-owned API key. POST /v1/generations requires Idempotency-Key:
    reuse the same key and normalized request to recover the original acceptance response;
    use a new key for an intentional new generation. Keys are account-scoped and never
    expire.'
  version: 2.0.0
servers:
- url: https://api.snowpixel.app
paths:
  /v1/models:
    get:
      summary: Discover enabled generation presets
      operationId: listModels
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Sanitized contracts and current prices. REST presets accept
            prompts and empty params; app reference capabilities are channel-specific.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelCatalog'
        '401':
          description: Invalid or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
      parameters:
      - name: contractVersion
        in: query
        schema:
          type: integer
          enum:
          - 1
          - 2
          default: 1
  /v1/generations:
    post:
      summary: Create generation
      operationId: createGeneration
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerationCreateRequest'
            examples:
              promptOnly:
                summary: Prompt-only image generation
                value:
                  model: snowpixel-image-v1
                  prompt: A snowy pixel cabin
              promptOnlyAudio:
                summary: Prompt-only audio generation
                value:
                  model: snowpixel-audio-v1
                  prompt: Rain on a neon city street
              promptOnlyVideo:
                summary: Prompt-only video generation
                value:
                  model: snowpixel-video-v1
                  prompt: A neon robot walking through rain
              promptOnlyWithParams:
                summary: Prompt-only image generation with empty v1 params
                value:
                  model: snowpixel-image-v1
                  prompt: A snowy pixel cabin
                  params: {}
      responses:
        '409':
          description: Idempotency key conflicts with a different normalized request,
            or a new submission fails model/price admission. No additional credits
            are reserved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                quoteChanged:
                  value:
                    error:
                      code: quote_changed
                      message: Review the current generation price.
                      field: quote
                      quote:
                        pricingVersion: presets-1
                        amount: 1
                modelUnavailable:
                  value:
                    error:
                      code: model_unavailable
                      message: This model is unavailable.
                      field: model
                idempotency_conflict:
                  value:
                    error:
                      code: idempotency_conflict
                      message: This Idempotency-Key was already used with a different
                        request.
        '202':
          description: Original durable acceptance response, returned for both first
            submissions and matching retries. Poll the job for current status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerationCreateResponse'
              examples:
                accepted:
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    status: pending
                    pollUrl: /v1/generations/AbCdEfGhIjKlMnOpQr01
                acceptedAudio:
                  value:
                    id: AbCdEfGhIjKlMnOpQr02
                    model: snowpixel-audio-v1
                    status: pending
                    pollUrl: /v1/generations/AbCdEfGhIjKlMnOpQr02
                accepted3d:
                  value:
                    id: AbCdEfGhIjKlMnOpQr04
                    model: snowpixel-3d-v1
                    status: pending
                    pollUrl: /v1/generations/AbCdEfGhIjKlMnOpQr04
                acceptedVideo:
                  value:
                    id: AbCdEfGhIjKlMnOpQr05
                    model: snowpixel-video-v1
                    status: pending
                    pollUrl: /v1/generations/AbCdEfGhIjKlMnOpQr05
        '400':
          description: Invalid request, unsupported model, invalid prompt, or unsupported
            v1 params.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidRequest:
                  summary: Malformed body, extra fields, or unsupported params
                  value:
                    error:
                      code: invalid_request
                      message: Invalid request.
                unsupportedModel:
                  summary: Unsupported model
                  value:
                    error:
                      code: unsupported_model
                      message: Unsupported model.
                      field: model
                invalidPrompt:
                  summary: Invalid prompt
                  value:
                    error:
                      code: invalid_prompt
                      message: Invalid prompt.
                unsupportedRevision:
                  value:
                    error:
                      code: unsupported_revision
                      message: Unsupported model revision.
                      field: revision
                idempotency_key_required:
                  value:
                    error:
                      code: idempotency_key_required
                      message: Provide an Idempotency-Key header.
                invalid_idempotency_key:
                  value:
                    error:
                      code: invalid_idempotency_key
                      message: Idempotency-Key must contain 1 to 255 visible ASCII
                        characters without whitespace.
        '401':
          description: Missing, invalid, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidApiKey:
                  value:
                    error:
                      code: invalid_api_key
                      message: Invalid API key.
                revokedApiKey:
                  value:
                    error:
                      code: revoked_api_key
                      message: API key has been revoked.
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '402':
          description: Insufficient credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficientCredits:
                  value:
                    error:
                      code: insufficient_credits
                      message: Insufficient credits.
        '500':
          description: Credit reservation or dispatch compensation could not be confirmed.
            Check the account balance before deliberately submitting another job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                internalError:
                  value:
                    error:
                      code: internal_error
                      message: Generation submission could not be confirmed.
        '503':
          description: Transaction contention or durable submission temporarily unavailable.
            Retry with the same key and request. Existing receipts remain replayable
            when dispatch is disabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                generationBusy:
                  value:
                    error:
                      code: generation_busy
                      message: Generation is busy. Please retry.
                generationPaused:
                  value:
                    error:
                      code: generation_paused
                      message: Generation is temporarily paused while we prepare for
                        launch.
                submission_unavailable:
                  value:
                    error:
                      code: submission_unavailable
                      message: Generation submission is temporarily unavailable. Retry
                        with the same key and request.
                account_initialization_required:
                  value:
                    error:
                      code: account_initialization_required
                      message: Account lifecycle initialization is pending.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
                spending_limit_exceeded:
                  value:
                    error:
                      code: spending_limit_exceeded
                      message: The API key monthly credit limit has been reached.
        '429':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                concurrency_limit_exceeded:
                  value:
                    error:
                      code: concurrency_limit_exceeded
                      message: Account concurrency limit reached. Retry later.
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        description: Case-sensitive, account-scoped key. Reuse with the same normalized
          request after a timeout or uncertain error. Never expires. Another active
          API credential on the same account can replay it. Use a new key for a new
          generation.
        schema:
          type: string
          minLength: 1
          maxLength: 255
          pattern: ^[!-~]{1,255}$
      description: The receipt, credit reservation, job, and durable dispatch intent
        commit atomically. Matching retries return the original 202 body even after
        settlement; poll for current status. Normalization uses the first accepted
        schema and defaults, Unicode prompt rules, and numeric equivalence; object
        order is ignored and array order preserved. Explicit revision and quote preconditions
        (including presence) are part of request identity. Pre-reservation failures
        do not consume keys. Playground is unchanged.
    get:
      summary: List account API and Playground jobs
      security:
      - bearerAuth: []
      parameters:
      - name: cursor
        in: query
        schema: &id001
          type: string
      - name: model
        in: query
        schema: *id001
      - name: status
        in: query
        schema: *id001
      - name: lifecycle
        in: query
        schema: *id001
      - name: origin
        in: query
        schema: *id001
      - name: keyId
        in: query
        schema: *id001
      - name: createdAfter
        in: query
        schema:
          type: string
          format: date-time
      - name: createdBefore
        in: query
        schema:
          type: string
          format: date-time
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      responses:
        '200':
          description: List account API and Playground jobs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerationPage'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
        '400':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_cursor:
                  value:
                    error:
                      code: invalid_cursor
                      message: Invalid cursor for this account and filters.
                invalid_request:
                  value:
                    error:
                      code: invalid_request
                      message: Invalid request.
      description: Newest first, ordered by creation time and ID. Cursors bind account,
        filters, and initial creation cutoff. Status filters are live, not a historical
        snapshot. Use keyId=unattributed for historical or Playground jobs without
        a key. createdAfter is inclusive; createdBefore is exclusive.
  /v1/generations/{id}:
    get:
      summary: Get generation status
      operationId: getGeneration
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: 20-character alphanumeric generation job ID returned by Snowpixel.
        schema:
          type: string
          minLength: 20
          maxLength: 20
          pattern: ^[A-Za-z0-9]{20}$
      responses:
        '200':
          description: Generation status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Generation'
              examples:
                pending:
                  summary: Pending generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: pending
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: null
                    outputs: []
                pendingAudio:
                  summary: Pending audio generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr02
                    model: snowpixel-audio-v1
                    prompt: Rain on a neon city street
                    status: pending
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: null
                    outputs: []
                recovering:
                  summary: Provider outcome is unknown; recovery is running
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: pending
                    recoveryStatus: outcome_unknown
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: null
                    outputs: []
                pending3d:
                  summary: Pending 3D generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr04
                    model: snowpixel-3d-v1
                    prompt: A stylized crystal castle
                    status: pending
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: null
                    outputs: []
                pendingVideo:
                  summary: Pending video generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr05
                    model: snowpixel-video-v1
                    prompt: A neon robot walking through rain
                    status: pending
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: null
                    outputs: []
                completed:
                  summary: Completed generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: completed
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: '2026-06-25T12:03:00+00:00'
                    outputs:
                    - url: https://cdn.example/generated.png
                      originalUrl: https://cdn.example/original.png
                      metadata:
                        width: 1024
                        height: 1024
                partial_failed:
                  summary: All children settled with some successful outputs
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-audio-v1
                    prompt: A snowy pixel cabin
                    status: partial_failed
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: '2026-06-25T12:03:00+00:00'
                    outputs:
                    - url: https://cdn.example/generated.wav
                      originalUrl: null
                      metadata: {}
                    error:
                      code: partial_generation_failed
                downstreamFailure:
                  summary: Downstream generation failed; billing is unchanged
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: failed
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: '2026-06-25T12:02:00+00:00'
                    outputs: []
                    error:
                      code: generation_failed
                unresolved:
                  summary: No usable outputs after the recovery deadline; credit refunded
                    once
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: failed
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: '2026-06-26T12:00:00+00:00'
                    outputs: []
                    error:
                      code: generation_unresolved
                failed:
                  summary: Failed generation
                  value:
                    id: AbCdEfGhIjKlMnOpQr01
                    model: snowpixel-image-v1
                    prompt: A snowy pixel cabin
                    status: failed
                    createdAt: '2026-06-25T12:00:00+00:00'
                    completedAt: '2026-06-25T12:00:01+00:00'
                    outputs: []
                    error:
                      code: dispatch_failed
        '400':
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidRequest:
                  value:
                    error:
                      code: invalid_request
                      message: Invalid request.
        '401':
          description: Missing, invalid, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidApiKey:
                  value:
                    error:
                      code: invalid_api_key
                      message: Invalid API key.
                revokedApiKey:
                  value:
                    error:
                      code: revoked_api_key
                      message: API key has been revoked.
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '404':
          description: Generation was not found in the authenticated account. Other
            accounts' jobs also return 404.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                notFound:
                  value:
                    error:
                      code: not_found
                      message: Resource not found.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
  /v1/assets:
    post:
      operationId: initiateAsset
      summary: Initiate an immutable private upload
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  asset: &id002
                    $ref: '#/components/schemas/ModuleAsset'
                  upload:
                    type: object
                    properties:
                      url:
                        type: string
                      method:
                        type: string
                      headers:
                        type: object
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetInitiation'
    get:
      operationId: listAssets
      summary: List reusable uploads
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items: *id002
                  cursor:
                    type: string
                    nullable: true
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      parameters:
      - name: cursor
        in: query
        schema:
          type: string
  /v1/assets/{id}:
    get:
      operationId: getAsset
      summary: Inspect an upload
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema: &id003
                type: object
                properties:
                  asset: *id002
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          pattern: ^[a-f0-9]{32}$
    delete:
      operationId: deleteAsset
      summary: Prevent future use; retain bytes while accepted jobs need them
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  state:
                    type: string
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          pattern: ^[a-f0-9]{32}$
  /v1/assets/{id}/complete:
    post:
      operationId: completeAsset
      summary: Verify uploaded media before use
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema: *id003
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          pattern: ^[a-f0-9]{32}$
  /v1/generations/quote:
    post:
      operationId: quoteGeneration
      summary: Validate inputs and calculate upfront credits without creating a job
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  quote:
                    $ref: '#/components/schemas/GenerationQuote'
                  model:
                    type: string
                  revision:
                    type: string
                  prompt:
                    type: string
                  params:
                    type: object
                  inputs:
                    type: object
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - snowpixel-image-v1
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties: {}
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      reference:
                        type: object
                        required:
                        - assetId
                        additionalProperties: false
                        properties:
                          assetId:
                            type: string
                            pattern: ^[a-f0-9]{32}$
                        x-file-constraints:
                          contentTypes:
                          - image/png
                          - image/jpeg
                          - image/webp
                          maxBytes: 20971520
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - snowpixel-audio-v1
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties: {}
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      reference:
                        type: object
                        required:
                        - assetId
                        additionalProperties: false
                        properties:
                          assetId:
                            type: string
                            pattern: ^[a-f0-9]{32}$
                        x-file-constraints:
                          contentTypes:
                          - image/png
                          - image/jpeg
                          - image/webp
                          maxBytes: 20971520
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - snowpixel-3d-v1
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties: {}
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      reference:
                        type: object
                        required:
                        - assetId
                        additionalProperties: false
                        properties:
                          assetId:
                            type: string
                            pattern: ^[a-f0-9]{32}$
                        x-file-constraints:
                          contentTypes:
                          - image/png
                          - image/jpeg
                          - image/webp
                          maxBytes: 20971520
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - snowpixel-video-v1
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties: {}
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      reference:
                        type: object
                        required:
                        - assetId
                        additionalProperties: false
                        properties:
                          assetId:
                            type: string
                            pattern: ^[a-f0-9]{32}$
                        x-file-constraints:
                          contentTypes:
                          - image/png
                          - image/jpeg
                          - image/webp
                          maxBytes: 20971520
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - dev-flux-image
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      width:
                        type: integer
                        enum:
                        - 512
                        - 1024
                        default: 1024
                  inputs:
                    type: object
                    additionalProperties: false
                    properties: {}
                  revision:
                    type: string
                    enum:
                    - flux-direct-1
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - test-hosted-image
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      width:
                        type: integer
                        enum:
                        - 512
                        - 1024
                        default: 1024
                  inputs:
                    type: object
                    additionalProperties: false
                    properties: {}
                  revision:
                    type: string
                    enum:
                    - hosted-fixture-1
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - dev-stable-audio
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      duration:
                        type: integer
                        enum:
                        - 10
                        - 30
                        default: 30
                  inputs:
                    type: object
                    additionalProperties: false
                    properties: {}
                  revision:
                    type: string
                    enum:
                    - stable-audio-direct-1
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - test-compatible-image
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      width:
                        type: integer
                        enum:
                        - 512
                        - 1024
                        default: 1024
                  inputs:
                    type: object
                    additionalProperties: false
                    properties: {}
                  revision:
                    type: string
                    enum:
                    - compatible-image-1
                required:
                - model
                - prompt
                - revision
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - test-compatible-image
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 2
                    x-normalized-maxLength: 300
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      width:
                        type: integer
                        enum:
                        - 512
                        - 1024
                        default: 512
                  inputs:
                    type: object
                    additionalProperties: false
                    properties: {}
                  revision:
                    type: string
                    enum:
                    - compatible-image-2
                required:
                - model
                - prompt
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - test-schema-image
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    default: ''
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 0
                    x-normalized-maxLength: 4000
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      style:
                        type: string
                        enum:
                        - natural
                        - custom
                        default: natural
                        x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim;
                          Unicode code points
                      quality:
                        type: integer
                        minimum: 1
                        maximum: 4
                        default: 2
                      strength:
                        type: number
                        minimum: 0
                        maximum: 1
                        multipleOf: 0.1
                        default: 0.5
                      preserve:
                        type: boolean
                        default: true
                      instructions:
                        type: string
                        default: ''
                        x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim;
                          Unicode code points
                        x-normalized-maxLength: 1000
                    allOf:
                    - anyOf:
                      - required:
                        - style
                        properties:
                          style:
                            enum:
                            - custom
                      - allOf:
                        - not:
                            required:
                            - style
                            properties:
                              style:
                                enum:
                                - custom
                        - not:
                            required:
                            - instructions
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      references:
                        type: array
                        minItems: 1
                        maxItems: 4
                        items:
                          type: object
                          required:
                          - assetId
                          additionalProperties: false
                          properties:
                            assetId:
                              type: string
                              pattern: ^[a-f0-9]{32}$
                          x-file-constraints:
                            contentTypes:
                            - image/png
                            - image/jpeg
                            - image/webp
                            maxBytes: 20971520
                    required:
                    - references
                  revision:
                    type: string
                    enum:
                    - test-schema-image-1
                required:
                - model
                - inputs
              - type: object
                additionalProperties: false
                properties:
                  model:
                    type: string
                    enum:
                    - test-schema-media
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                  prompt:
                    type: string
                    default: ''
                    x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                      code points
                    x-normalized-minLength: 0
                    x-normalized-maxLength: 4000
                  params:
                    type: object
                    additionalProperties: false
                    properties:
                      duration:
                        type: integer
                        minimum: 1
                        maximum: 60
                        default: 10
                      instrumental:
                        type: boolean
                        default: false
                  inputs:
                    type: object
                    additionalProperties: false
                    properties:
                      source:
                        type: object
                        required:
                        - assetId
                        additionalProperties: false
                        properties:
                          assetId:
                            type: string
                            pattern: ^[a-f0-9]{32}$
                        x-file-constraints:
                          contentTypes:
                          - audio/wav
                          - audio/mpeg
                          - audio/flac
                          - video/mp4
                          - video/webm
                          maxBytes: 104857600
                          maxDuration: 600
                    required:
                    - source
                  revision:
                    type: string
                    enum:
                    - test-schema-media-1
                required:
                - model
                - inputs
  /v1/balance:
    get:
      summary: Read account credit balance and API concurrency
      security:
      - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Read account credit balance and API concurrency
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Balance'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
  /v1/usage:
    get:
      summary: Read daily API usage, grouped by job admission date
      security:
      - bearerAuth: []
      parameters:
      - name: fromDate
        in: query
        schema:
          type: string
          format: date
      - name: toDate
        in: query
        schema:
          type: string
          format: date
      - name: keyId
        in: query
        schema: *id001
      - name: model
        in: query
        schema: *id001
      responses:
        '200':
          description: Read daily API usage, grouped by job admission date
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Usage'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
      description: Dates are inclusive UTC calendar dates, defaulting to the last
        30 days including today, maximum 90. No creative-app jobs are included. Reserved
        is outstanding credit, charged is net settled charge, refunded is confirmed
        returned credit. Unknown historical costs are counted without repricing. keyId=unattributed
        selects jobs without recorded attribution.
  /v1/generations/{id}/cancel:
    post:
      summary: Request best-effort cancellation
      security:
      - bearerAuth: []
      parameters:
      - &id004
        name: id
        in: path
        required: true
        schema: *id001
      responses:
        '200':
          description: Request best-effort cancellation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Generation'
        '202':
          description: Cancellation is pending.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Generation'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
        '409':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                cancellation_unavailable:
                  value:
                    error:
                      code: cancellation_unavailable
                      message: This historical job does not support cancellation.
        '404':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                not_found:
                  value:
                    error:
                      code: not_found
                      message: Resource not found.
      description: Idempotent. Stops unsent work and attempts to stop running work.
        Fully refunds only proven non-execution; once any stage starts the full accepted
        price is charged. Unconfirmed execution is billed at the 24-hour deadline.
        Retains already committed outputs. completedAt remains null while cancellation
        is pending.
  /v1/webhook-deliveries:
    get:
      summary: List webhook delivery history retained for 90 days
      security:
      - bearerAuth: []
      parameters:
      - name: cursor
        in: query
        schema: *id001
      - name: jobId
        in: query
        schema: *id001
      - name: endpointId
        in: query
        schema: *id001
      responses:
        '200':
          description: List webhook delivery history retained for 90 days
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryPage'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
        '400':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_cursor:
                  value:
                    error:
                      code: invalid_cursor
                      message: Invalid cursor for this account and filters.
                invalid_request:
                  value:
                    error:
                      code: invalid_request
                      message: Invalid request.
  /v1/webhook-deliveries/{id}:
    get:
      summary: Read a delivery and its 25 most recent attempts
      security:
      - bearerAuth: []
      parameters:
      - *id004
      responses:
        '200':
          description: Read a delivery and its 25 most recent attempts
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryDetail'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
  /v1/webhook-deliveries/{id}/retry:
    post:
      summary: Queue an idempotent manual delivery retry
      security:
      - bearerAuth: []
      parameters:
      - *id004
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          minLength: 1
          maxLength: 255
      responses:
        '200':
          description: Queue an idempotent manual delivery retry
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookRetry'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                expired_api_key:
                  value:
                    error:
                      code: expired_api_key
                      message: API key has expired.
        '403':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficient_scope:
                  value:
                    error:
                      code: insufficient_scope
                      message: API key does not grant this operation.
        '409':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                delivery_busy:
                  value:
                    error:
                      code: delivery_busy
                      message: This delivery is in progress.
        '400':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                idempotency_key_required:
                  value:
                    error:
                      code: idempotency_key_required
                      message: Provide an Idempotency-Key header.
                invalid_idempotency_key:
                  value:
                    error:
                      code: invalid_idempotency_key
                      message: Idempotency-Key must contain 1 to 255 visible ASCII
                        characters without whitespace.
        '404':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                not_found:
                  value:
                    error:
                      code: not_found
                      message: Resource not found.
  /v1/assets/{id}/download:
    get:
      operationId: downloadAsset
      summary: Issue an owner-authorized download link valid for 15 minutes
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                  expiresAt:
                    type: string
                    nullable: true
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          pattern: ^[a-f0-9]{32}$
      - name: role
        in: query
        schema:
          type: string
          default: original
      - name: recipe
        in: query
        schema:
          type: string
        description: Required when several derivatives have the same role.
  /v1/assets/adopt:
    post:
      operationId: adoptAsset
      summary: Register media from an owned historical job
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema: *id003
        '400':
          description: Invalid request
        '401':
          description: Invalid credentials
        '404':
          description: Asset not found for this account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - jobId
              - index
              additionalProperties: false
              properties:
                jobId:
                  type: string
                index:
                  type: integer
                  minimum: 0
                collection:
                  type: string
                  enum:
                  - images
                  - apiMedia
                  default: images
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Snowpixel API key
  schemas:
    ModelCatalog:
      type: object
      required:
      - contractVersion
      - models
      properties:
        contractVersion:
          type: integer
          enum:
          - 1
          - 2
        unavailableModels:
          type: array
          description: Sanitized disabled/retired entries for identifying historical
            work; never selectable for new generation.
          items:
            $ref: '#/components/schemas/ModelCatalogEntry'
        models:
          type: array
          items:
            $ref: '#/components/schemas/ModelCatalogEntry'
    ModelCatalogEntry:
      type: object
      required:
      - id
      - label
      - kind
      - mediaKind
      - revision
      - contractVersion
      - inputs
      - params
      - output
      - price
      - availability
      properties:
        id:
          type: string
        label:
          type: string
        kind:
          type: string
          enum:
          - preset
          - direct
        mediaKind:
          type: string
        revision:
          type: string
        contractVersion:
          type: integer
          enum:
          - 1
          - 2
        inputs:
          type: object
        params:
          type: object
        output:
          type: object
        availability:
          type: object
        price:
          $ref: '#/components/schemas/GenerationQuote'
        schema:
          type: object
        pricing:
          type: object
    GenerationQuote:
      type: object
      additionalProperties: false
      required:
      - pricingVersion
      - amount
      properties:
        pricingVersion:
          type: string
          minLength: 1
          pattern: \S
        amount:
          type: integer
          minimum: 1
          maximum: 9007199254740991
      description: Optional admission precondition, never a client-selected charge.
        Malformed quotes fail with 400; valid mismatches fail with 409 and a refreshed
        error.quote. Omission accepts the current published price.
    GenerationCreateRequest:
      type: object
      allOf:
      - $ref: '#/components/schemas/GenerationModelSelection'
      required:
      - model
      additionalProperties: false
      properties:
        quote:
          $ref: '#/components/schemas/GenerationQuote'
        revision:
          type: string
          description: Optional immutable direct model revision. Presets reject explicit
            revisions with unsupported_revision.
        model:
          type: string
          description: Select an enabled ID from GET /v1/models. Development fixtures
            are gated and have no commercial release price.
        prompt:
          type: string
          description: NFC text with LF line endings and trimmed edge whitespace.
            Requiredness and code-point limits belong to the selected model revision.
          example: A snowy pixel cabin
        params:
          type: object
          description: Settings declared by the selected model revision; defaults
            and conditions are applied by the server.
          example: {}
        inputs:
          type: object
          description: Named files and ordered reference arrays using ready asset
            IDs.
    GenerationModelSelection:
      oneOf:
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - snowpixel-image-v1
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties: {}
          inputs:
            type: object
            additionalProperties: false
            properties:
              reference:
                type: object
                required:
                - assetId
                additionalProperties: false
                properties:
                  assetId:
                    type: string
                    pattern: ^[a-f0-9]{32}$
                x-file-constraints:
                  contentTypes:
                  - image/png
                  - image/jpeg
                  - image/webp
                  maxBytes: 20971520
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - snowpixel-audio-v1
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties: {}
          inputs:
            type: object
            additionalProperties: false
            properties:
              reference:
                type: object
                required:
                - assetId
                additionalProperties: false
                properties:
                  assetId:
                    type: string
                    pattern: ^[a-f0-9]{32}$
                x-file-constraints:
                  contentTypes:
                  - image/png
                  - image/jpeg
                  - image/webp
                  maxBytes: 20971520
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - snowpixel-3d-v1
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties: {}
          inputs:
            type: object
            additionalProperties: false
            properties:
              reference:
                type: object
                required:
                - assetId
                additionalProperties: false
                properties:
                  assetId:
                    type: string
                    pattern: ^[a-f0-9]{32}$
                x-file-constraints:
                  contentTypes:
                  - image/png
                  - image/jpeg
                  - image/webp
                  maxBytes: 20971520
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - snowpixel-video-v1
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties: {}
          inputs:
            type: object
            additionalProperties: false
            properties:
              reference:
                type: object
                required:
                - assetId
                additionalProperties: false
                properties:
                  assetId:
                    type: string
                    pattern: ^[a-f0-9]{32}$
                x-file-constraints:
                  contentTypes:
                  - image/png
                  - image/jpeg
                  - image/webp
                  maxBytes: 20971520
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - dev-flux-image
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              width:
                type: integer
                enum:
                - 512
                - 1024
                default: 1024
          inputs:
            type: object
            additionalProperties: false
            properties: {}
          revision:
            type: string
            enum:
            - flux-direct-1
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - test-hosted-image
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              width:
                type: integer
                enum:
                - 512
                - 1024
                default: 1024
          inputs:
            type: object
            additionalProperties: false
            properties: {}
          revision:
            type: string
            enum:
            - hosted-fixture-1
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - dev-stable-audio
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              duration:
                type: integer
                enum:
                - 10
                - 30
                default: 30
          inputs:
            type: object
            additionalProperties: false
            properties: {}
          revision:
            type: string
            enum:
            - stable-audio-direct-1
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - test-compatible-image
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              width:
                type: integer
                enum:
                - 512
                - 1024
                default: 1024
          inputs:
            type: object
            additionalProperties: false
            properties: {}
          revision:
            type: string
            enum:
            - compatible-image-1
        required:
        - model
        - prompt
        - revision
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - test-compatible-image
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 2
            x-normalized-maxLength: 300
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              width:
                type: integer
                enum:
                - 512
                - 1024
                default: 512
          inputs:
            type: object
            additionalProperties: false
            properties: {}
          revision:
            type: string
            enum:
            - compatible-image-2
        required:
        - model
        - prompt
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - test-schema-image
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            default: ''
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 0
            x-normalized-maxLength: 4000
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              style:
                type: string
                enum:
                - natural
                - custom
                default: natural
                x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                  code points
              quality:
                type: integer
                minimum: 1
                maximum: 4
                default: 2
              strength:
                type: number
                minimum: 0
                maximum: 1
                multipleOf: 0.1
                default: 0.5
              preserve:
                type: boolean
                default: true
              instructions:
                type: string
                default: ''
                x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode
                  code points
                x-normalized-maxLength: 1000
            allOf:
            - anyOf:
              - required:
                - style
                properties:
                  style:
                    enum:
                    - custom
              - allOf:
                - not:
                    required:
                    - style
                    properties:
                      style:
                        enum:
                        - custom
                - not:
                    required:
                    - instructions
          inputs:
            type: object
            additionalProperties: false
            properties:
              references:
                type: array
                minItems: 1
                maxItems: 4
                items:
                  type: object
                  required:
                  - assetId
                  additionalProperties: false
                  properties:
                    assetId:
                      type: string
                      pattern: ^[a-f0-9]{32}$
                  x-file-constraints:
                    contentTypes:
                    - image/png
                    - image/jpeg
                    - image/webp
                    maxBytes: 20971520
            required:
            - references
          revision:
            type: string
            enum:
            - test-schema-image-1
        required:
        - model
        - inputs
      - type: object
        additionalProperties: false
        properties:
          model:
            type: string
            enum:
            - test-schema-media
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
          prompt:
            type: string
            default: ''
            x-normalization: NFC, CR/CRLF to LF, ECMAScript edge trim; Unicode code
              points
            x-normalized-minLength: 0
            x-normalized-maxLength: 4000
          quote:
            $ref: '#/components/schemas/GenerationQuote'
          params:
            type: object
            additionalProperties: false
            properties:
              duration:
                type: integer
                minimum: 1
                maximum: 60
                default: 10
              instrumental:
                type: boolean
                default: false
          inputs:
            type: object
            additionalProperties: false
            properties:
              source:
                type: object
                required:
                - assetId
                additionalProperties: false
                properties:
                  assetId:
                    type: string
                    pattern: ^[a-f0-9]{32}$
                x-file-constraints:
                  contentTypes:
                  - audio/wav
                  - audio/mpeg
                  - audio/flac
                  - video/mp4
                  - video/webm
                  maxBytes: 104857600
                  maxDuration: 600
            required:
            - source
          revision:
            type: string
            enum:
            - test-schema-media-1
        required:
        - model
        - inputs
    GenerationCreateResponse:
      type: object
      required:
      - id
      - model
      - status
      - pollUrl
      properties:
        id:
          type: string
          minLength: 20
          maxLength: 20
          pattern: ^[A-Za-z0-9]{20}$
          description: Unique 20-character ASCII alphanumeric API Generation Job ID.
          example: AbCdEfGhIjKlMnOpQr01
        model:
          type: string
        status:
          type: string
          enum:
          - pending
        pollUrl:
          type: string
          description: Append this path to the API base URL, preserving any configured
            path prefix. Poll with the same Bearer authentication.
          example: /v1/generations/AbCdEfGhIjKlMnOpQr01
    Generation:
      type: object
      required:
      - id
      - model
      - prompt
      - status
      - createdAt
      - completedAt
      - outputs
      properties:
        modelLabel:
          type: string
          nullable: true
          description: Label recorded at admission; retained after retirement. Unknown
            historical labels remain null.
        revision:
          type: string
          nullable: true
        contractVersion:
          type: integer
          nullable: true
        credits:
          type: object
          description: Persisted accounting facts. reserved is the original debit;
            charged is null while unsettled and never causes a second debit. refunded
            is confirmed returned credits. Missing historical amounts remain null;
            failed status alone does not imply a refund.
          properties:
            reserved:
              type: integer
              nullable: true
            charged:
              type: integer
              nullable: true
            refunded:
              type: integer
              nullable: true
            pricingVersion:
              type: string
              nullable: true
            settlementPolicy:
              type: string
              nullable: true
        id:
          type: string
          minLength: 20
          maxLength: 20
          pattern: ^[A-Za-z0-9]{20}$
          description: Unique 20-character ASCII alphanumeric API Generation Job ID.
          example: AbCdEfGhIjKlMnOpQr01
        model:
          type: string
        prompt:
          type: string
          description: The trimmed prompt stored for this job.
          example: A snowy pixel cabin
        status:
          type: string
          enum:
          - pending
          - completed
          - partial_failed
          - failed
          - cancelled
        recoveryStatus:
          type: string
          enum:
          - outcome_unknown
          description: Optional detail on pending jobs while provider acceptance or
            execution is being reconciled. Keep polling this job; do not submit a
            replacement.
        createdAt:
          type: string
          format: date-time
          nullable: true
          description: ISO 8601 creation time, or null when unavailable.
        completedAt:
          type: string
          format: date-time
          nullable: true
          description: ISO 8601 completion or failure time, or null. Pending jobs
            always return null.
        outputs:
          type: array
          description: Committed outputs, including outputs retained by cancellation.
            Outputs uploaded after cancellation are fenced and cleaned up.
          items:
            $ref: '#/components/schemas/GenerationOutput'
        error:
          type: object
          description: Present on failed and partial_failed jobs. generation_unresolved
            means the 24-hour recovery deadline elapsed with no usable outputs and
            the reserved credit was refunded once. generation_failed and partial_generation_failed
            do not imply a refund. partial_failed preserves usable outputs. Legacy
            failed jobs can retain partial assets internally without returning them
            here.
          nullable: true
          required:
          - code
          properties:
            code:
              type: string
              enum:
              - dispatch_failed
              - generation_failed
              - generation_unresolved
              - partial_generation_failed
        apiKeyId:
          type: string
          nullable: true
        origin:
          type: string
          enum:
          - api
          - playground
        lifecycle:
          type: string
          enum:
          - unknown
          - queued
          - running
          - publishing
          - completed
          - partial_failed
          - failed
          - cancelled
        cancellation:
          type: object
          properties:
            refunded:
              type: boolean
            reason:
              type: string
              enum:
              - not_started
              - execution_started
              - execution_unconfirmed
          required:
          - refunded
          - reason
        queuedAt:
          type: string
          format: date-time
          nullable: true
        startedAt:
          type: string
          format: date-time
          nullable: true
        publishingAt:
          type: string
          format: date-time
          nullable: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
        cancelRequestedAt:
          type: string
          format: date-time
          nullable: true
    GenerationOutput:
      type: object
      required:
      - url
      - originalUrl
      - metadata
      properties:
        id:
          type: string
          description: Stable within the job, including historical reads.
        kind:
          type: string
          enum:
          - image
          - audio
          - video
          - 3d
          - unknown
        contentType:
          type: string
        width:
          type: number
        height:
          type: number
        duration:
          type: number
        model:
          type: string
          nullable: true
        revision:
          type: string
          nullable: true
        previews:
          type: array
          items:
            type: object
        url:
          type: string
          format: uri
          nullable: true
          description: Output asset URL, or null when unavailable.
        originalUrl:
          type: string
          format: uri
          nullable: true
          description: Original asset URL, or null when unavailable.
        metadata:
          type: object
          additionalProperties: true
          description: Model-dependent output details. Fields may vary or be absent.
    ErrorResponse:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
              enum:
              - delivery_busy
              - expired_api_key
              - insufficient_scope
              - spending_limit_exceeded
              - concurrency_limit_exceeded
              - account_initialization_required
              - invalid_cursor
              - cancellation_unavailable
              - idempotency_key_required
              - invalid_idempotency_key
              - idempotency_conflict
              - submission_unavailable
              - quote_changed
              - model_unavailable
              - unsupported_revision
              - generation_busy
              - generation_paused
              - invalid_api_key
              - revoked_api_key
              - not_found
              - invalid_request
              - unsupported_model
              - invalid_prompt
              - insufficient_credits
              - dispatch_failed
              - internal_error
            message:
              type: string
            field:
              type: string
            quote:
              $ref: '#/components/schemas/GenerationQuote'
    ModuleAsset:
      type: object
      required:
      - id
      - name
      - state
      - contentType
      - bytes
      properties:
        id:
          type: string
        name:
          type: string
        state:
          type: string
          enum:
          - uploading
          - ready
          - deleted
        contentType:
          type: string
        bytes:
          type: integer
        width:
          type: integer
        height:
          type: integer
        duration:
          type: number
        sha256:
          type: string
        createdAt:
          type: string
          format: date-time
        provenance:
          type: object
        derivatives:
          type: array
          items:
            type: object
            properties:
              role:
                type: string
              recipe:
                type: string
              contentType:
                type: string
              bytes:
                type: integer
              width:
                type: integer
              height:
                type: integer
              duration:
                type: number
    AssetInitiation:
      type: object
      additionalProperties: false
      required:
      - name
      - contentType
      - bytes
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        contentType:
          type: string
          enum:
          - image/png
          - image/jpeg
          - image/webp
          - audio/wav
          - audio/mpeg
          - audio/flac
          - video/mp4
          - video/webm
        bytes:
          type: integer
          minimum: 1
          maximum: 104857600
    GenerationSummary:
      type: object
      required:
      - id
      - model
      - status
      - createdAt
      - completedAt
      - outputs
      properties:
        modelLabel:
          type: string
          nullable: true
          description: Label recorded at admission; retained after retirement. Unknown
            historical labels remain null.
        revision:
          type: string
          nullable: true
        contractVersion:
          type: integer
          nullable: true
        credits:
          type: object
          description: Persisted accounting facts. reserved is the original debit;
            charged is null while unsettled and never causes a second debit. refunded
            is confirmed returned credits. Missing historical amounts remain null;
            failed status alone does not imply a refund.
          properties:
            reserved:
              type: integer
              nullable: true
            charged:
              type: integer
              nullable: true
            refunded:
              type: integer
              nullable: true
            pricingVersion:
              type: string
              nullable: true
            settlementPolicy:
              type: string
              nullable: true
        id:
          type: string
          minLength: 20
          maxLength: 20
          pattern: ^[A-Za-z0-9]{20}$
          description: Unique 20-character ASCII alphanumeric API Generation Job ID.
          example: AbCdEfGhIjKlMnOpQr01
        model:
          type: string
        status:
          type: string
          enum:
          - pending
          - completed
          - partial_failed
          - failed
          - cancelled
        recoveryStatus:
          type: string
          enum:
          - outcome_unknown
          description: Optional detail on pending jobs while provider acceptance or
            execution is being reconciled. Keep polling this job; do not submit a
            replacement.
        createdAt:
          type: string
          format: date-time
          nullable: true
          description: ISO 8601 creation time, or null when unavailable.
        completedAt:
          type: string
          format: date-time
          nullable: true
          description: ISO 8601 completion or failure time, or null. Pending jobs
            always return null.
        outputs:
          type: array
          description: Committed outputs, including outputs retained by cancellation.
            Outputs uploaded after cancellation are fenced and cleaned up.
          items:
            $ref: '#/components/schemas/GenerationOutput'
        error:
          type: object
          description: Present on failed and partial_failed jobs. generation_unresolved
            means the 24-hour recovery deadline elapsed with no usable outputs and
            the reserved credit was refunded once. generation_failed and partial_generation_failed
            do not imply a refund. partial_failed preserves usable outputs. Legacy
            failed jobs can retain partial assets internally without returning them
            here.
          nullable: true
          required:
          - code
          properties:
            code:
              type: string
              enum:
              - dispatch_failed
              - generation_failed
              - generation_unresolved
              - partial_generation_failed
        apiKeyId:
          type: string
          nullable: true
        origin:
          type: string
          enum:
          - api
          - playground
        lifecycle:
          type: string
          enum:
          - unknown
          - queued
          - running
          - publishing
          - completed
          - partial_failed
          - failed
          - cancelled
        cancellation:
          type: object
          properties:
            refunded:
              type: boolean
            reason:
              type: string
              enum:
              - not_started
              - execution_started
              - execution_unconfirmed
          required:
          - refunded
          - reason
        queuedAt:
          type: string
          format: date-time
          nullable: true
        startedAt:
          type: string
          format: date-time
          nullable: true
        publishingAt:
          type: string
          format: date-time
          nullable: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
        cancelRequestedAt:
          type: string
          format: date-time
          nullable: true
    GenerationPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/GenerationSummary'
        cursor:
          type: string
          nullable: true
      required:
      - items
      - cursor
    Balance:
      type: object
      properties:
        available:
          type: integer
          minimum: 0
        reserved:
          type: integer
          minimum: 0
        activeJobs:
          type: integer
          minimum: 0
        concurrencyLimit:
          type: integer
          minimum: 0
        unit:
          type: string
          enum:
          - credits
      required:
      - available
      - reserved
      - activeJobs
      - concurrencyLimit
      - unit
    UsageTotals:
      type: object
      properties:
        requests: &id005
          type: integer
          minimum: 0
        charged: &id006
          type: integer
          minimum: 0
        refunded: &id007
          type: integer
          minimum: 0
        reserved: &id008
          type: integer
          minimum: 0
        unknownCosts: &id009
          type: integer
          minimum: 0
      required:
      - requests
      - charged
      - refunded
      - reserved
      - unknownCosts
    Usage:
      type: object
      properties:
        fromDate:
          type: string
          format: date
        toDate:
          type: string
          format: date
        requests: *id005
        charged: *id006
        refunded: *id007
        reserved: *id008
        unknownCosts: *id009
        daily:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              requests: *id005
              charged: *id006
              refunded: *id007
              reserved: *id008
              unknownCosts: *id009
            required:
            - date
            - requests
            - charged
            - refunded
            - reserved
            - unknownCosts
      required:
      - fromDate
      - toDate
      - requests
      - charged
      - refunded
      - reserved
      - unknownCosts
      - daily
    WebhookDelivery:
      type: object
      properties:
        id: *id001
        eventId: *id001
        jobId: *id001
        endpointId: *id001
        state:
          type: string
          enum:
          - pending
          - delivering
          - succeeded
          - failed
        attemptCount:
          type: integer
          minimum: 0
        nextAttemptAt: &id010
          type: string
          format: date-time
          nullable: true
        createdAt: *id010
      required:
      - id
      - eventId
      - jobId
      - endpointId
      - state
      - attemptCount
      - nextAttemptAt
      - createdAt
    WebhookDeliveryPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/WebhookDelivery'
        cursor:
          type: string
          nullable: true
      required:
      - items
      - cursor
    WebhookDeliveryDetail:
      allOf:
      - $ref: '#/components/schemas/WebhookDelivery'
      - type: object
        properties:
          attempts:
            type: array
            maxItems: 25
            items:
              type: object
        required:
        - attempts
    WebhookRetry:
      type: object
      properties:
        id: *id001
        eventId: *id001
        state:
          type: string
          enum:
          - pending
      required:
      - id
      - eventId
      - state
