Civitai Orchestration API

Submit AI generation workflows — image, video, audio, language, and LoRA training — through a single contract at `https://orchestration.civitai.com`. Races multiple providers and engines (Flux 1/2, SDXL, SD1, Z-Image, Qwen, Seedream, Grok, WAN 2.1-2.7, Kling, LTX2, Vidu, Veo 3, HunyuanVideo) behind one workflow API. Includes blob upload with NSFW moderation, presigned URLs, in-order serialized webhooks (`workflow:succeeded`, `workflow:failed`, etc.), and Buzz-metered billing. Bearer-token authenticated.

Documentation

Specifications

Examples

Schemas & Data

Other Resources

OpenAPI Specification

civitai-orchestration-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Civitai Orchestration API
  version: 'v2'
  description: |
    Submit AI generation workflows — image, video, audio, language, and LoRA training — through a single
    contract. The Orchestration API races multiple providers and engines behind one workflow surface and
    delivers results via webhooks or polling. Authenticate with a Bearer token issued at civitai.com.
  contact:
    name: Civitai Developer Support
    url: https://developer.civitai.com/orchestration/
  termsOfService: https://civitai.com/content/tos
  license:
    name: Civitai Terms of Service
    url: https://civitai.com/content/tos
servers:
- url: https://orchestration.civitai.com
  description: Civitai Orchestration API
security:
- BearerAuth: []
tags:
- name: Workflows
  description: Submit and manage generation workflows.
- name: Blobs
  description: Upload and reference blobs for inputs and outputs.
paths:
  /v2/consumer/workflows:
    post:
      operationId: submitWorkflow
      summary: Submit Workflow
      tags: [Workflows]
      description: Submit a new workflow composed of one or more steps. Each step references a recipe such as
        an image, video, audio, or training generator.
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/WorkflowRequest' }
      responses:
        '202':
          description: Workflow accepted for processing.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Workflow' }
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '402':
          description: Insufficient Buzz balance.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Error' }
        '429': { $ref: '#/components/responses/RateLimited' }
    get:
      operationId: queryWorkflows
      summary: Query Workflows
      tags: [Workflows]
      parameters:
      - { name: take, in: query, schema: { type: integer, default: 20, maximum: 100 } }
      - { name: cursor, in: query, schema: { type: string } }
      - { name: tags, in: query, schema: { type: array, items: { type: string } } }
      - { name: status, in: query, schema: { type: string, enum: [unassigned, preparing, processing, succeeded, failed, expired, canceled] } }
      responses:
        '200':
          description: Page of workflows.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items: { $ref: '#/components/schemas/Workflow' }
                  nextCursor: { type: string }
  /v2/consumer/workflows/{workflowId}:
    parameters:
    - { name: workflowId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getWorkflow
      summary: Get Workflow
      tags: [Workflows]
      responses:
        '200':
          description: Workflow status and outputs.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Workflow' }
        '404': { $ref: '#/components/responses/NotFound' }
    put:
      operationId: updateWorkflow
      summary: Update Workflow
      tags: [Workflows]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/WorkflowUpdate' }
      responses:
        '200':
          description: Updated workflow.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Workflow' }
    patch:
      operationId: patchWorkflow
      summary: Patch Workflow
      tags: [Workflows]
      requestBody:
        required: true
        content:
          application/json-patch+json:
            schema:
              type: array
              items: { type: object }
      responses:
        '200':
          description: Patched workflow.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Workflow' }
    delete:
      operationId: deleteWorkflow
      summary: Delete Workflow
      tags: [Workflows]
      responses:
        '204': { description: Deleted. }
  /v2/consumer/blobs:
    post:
      operationId: uploadBlob
      summary: Upload Blob
      tags: [Blobs]
      description: Upload a blob (image, video, audio) with built-in NSFW moderation.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [file]
              properties:
                file: { type: string, format: binary }
                moderate: { type: boolean, default: true }
      responses:
        '201':
          description: Uploaded blob.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Blob' }
  /v2/consumer/blobs/upload-url:
    get:
      operationId: getBlobUploadUrl
      summary: Get Blob Upload URL
      tags: [Blobs]
      parameters:
      - { name: mimeType, in: query, required: true, schema: { type: string } }
      - { name: sizeBytes, in: query, schema: { type: integer } }
      responses:
        '200':
          description: Presigned upload URL.
          content:
            application/json:
              schema:
                type: object
                properties:
                  blobId: { type: string }
                  uploadUrl: { type: string, format: uri }
                  expiresAt: { type: string, format: date-time }
                  headers:
                    type: object
                    additionalProperties: { type: string }
  /v2/consumer/blobs/{blobId}:
    parameters:
    - { name: blobId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getBlob
      summary: Get Blob
      tags: [Blobs]
      responses:
        '200':
          description: Blob metadata and download URL.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Blob' }
    head:
      operationId: headBlob
      summary: Head Blob
      tags: [Blobs]
      description: Check blob existence and moderation status without downloading metadata.
      responses:
        '200': { description: Blob exists. }
        '404': { description: Blob not found. }
  /v2/consumer/blobs/{blobId}/refresh:
    post:
      operationId: refreshBlob
      summary: Refresh Blob URL
      tags: [Blobs]
      parameters:
      - { name: blobId, in: path, required: true, schema: { type: string } }
      responses:
        '200':
          description: Refreshed blob with new signed URL.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Blob' }
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: token
      description: Personal API token issued at https://civitai.com/user/account.
  responses:
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    RateLimited:
      description: Too many requests.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
  schemas:
    Error:
      type: object
      properties:
        code: { type: string }
        message: { type: string }
        traceId: { type: string }
    WorkflowRequest:
      type: object
      required: [steps]
      properties:
        tags:
          type: array
          items: { type: string }
        callbackUrl:
          type: string
          format: uri
          description: HTTPS callback URL for webhook delivery.
        callbackEvents:
          type: array
          items:
            type: string
            enum: [workflow:*, workflow:succeeded, workflow:failed, workflow:processing, workflow:expired, workflow:canceled, step:*, job:*]
        detailed: { type: boolean, default: false }
        steps:
          type: array
          items: { $ref: '#/components/schemas/WorkflowStep' }
    WorkflowUpdate:
      type: object
      properties:
        tags:
          type: array
          items: { type: string }
        status:
          type: string
          enum: [canceled]
    WorkflowStep:
      type: object
      required: [$type, input]
      properties:
        $type:
          type: string
          description: Recipe type — e.g. imageGen, videoGen, audioGen, textGen, training, upscale.
          enum: [imageGen, videoGen, audioGen, textGen, transcribe, tts, music, upscale, interpolate, training, comfy, moderation]
        name: { type: string }
        input: { $ref: '#/components/schemas/StepInput' }
        priority:
          type: string
          enum: [low, normal, high]
    StepInput:
      type: object
      description: Recipe-specific input. The shape depends on `$type`. Common image-gen properties shown.
      properties:
        engine:
          type: string
          description: Engine identifier — e.g. flux2, flux1, sdxl, sd1, z-image, qwen, seedream, grok, wan2.5, kling, ltx2, vidu, veo3, hunyuan.
        model: { type: string, description: 'AIR or model identifier, e.g. urn:air:sdxl:checkpoint:civitai:12345@67890' }
        prompt: { type: string }
        negativePrompt: { type: string }
        width: { type: integer }
        height: { type: integer }
        aspectRatio: { type: string }
        steps: { type: integer }
        cfgScale: { type: number }
        sampler: { type: string }
        seed: { type: integer }
        clipSkip: { type: integer }
        quantity: { type: integer, default: 1, maximum: 10 }
        additionalNetworks:
          type: array
          items:
            type: object
            properties:
              air: { type: string }
              strength: { type: number }
        images:
          type: array
          description: Input image blob IDs for img2img / video / editing.
          items: { type: string }
        duration: { type: number, description: 'Seconds, for video.' }
        fps: { type: integer }
        upscaler: { type: string }
    Workflow:
      type: object
      properties:
        id: { type: string }
        status:
          type: string
          enum: [unassigned, preparing, processing, succeeded, failed, expired, canceled]
        tags:
          type: array
          items: { type: string }
        createdAt: { type: string, format: date-time }
        startedAt: { type: string, format: date-time }
        completedAt: { type: string, format: date-time }
        cost:
          type: object
          properties:
            base: { type: integer, description: Buzz cost. }
            total: { type: integer }
            currency: { type: string, enum: [BUZZ] }
        steps:
          type: array
          items: { $ref: '#/components/schemas/WorkflowStepResult' }
    WorkflowStepResult:
      type: object
      properties:
        name: { type: string }
        $type: { type: string }
        status: { type: string }
        startedAt: { type: string, format: date-time }
        completedAt: { type: string, format: date-time }
        jobs:
          type: array
          items: { $ref: '#/components/schemas/Job' }
    Job:
      type: object
      properties:
        id: { type: string }
        status: { type: string }
        startedAt: { type: string, format: date-time }
        completedAt: { type: string, format: date-time }
        result:
          type: object
          properties:
            blobs:
              type: array
              items:
                type: object
                properties:
                  blobId: { type: string }
                  url: { type: string, format: uri }
                  mimeType: { type: string }
                  width: { type: integer }
                  height: { type: integer }
                  durationMs: { type: integer }
                  nsfwLevel: { type: integer }
    Blob:
      type: object
      properties:
        id: { type: string }
        mimeType: { type: string }
        sizeBytes: { type: integer }
        url: { type: string, format: uri }
        urlExpiresAt: { type: string, format: date-time }
        sha256: { type: string }
        nsfwLevel: { type: integer }
        nsfwReason: { type: string }
        createdAt: { type: string, format: date-time }