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 }