Skip to content

Submitting Work ​

There are two ways to submit a workflow:

  1. Generic — POST /v2/consumer/workflows with a steps array and polymorphic $type on each step. Use it to chain steps, mix step types, attach callbacks, tags, metadata or upgradeMode, or when your SDK handles the discriminator itself.
  2. Per-recipe — POST /v2/consumer/recipes/{recipe} with a single typed body (no $type). Each recipe wraps a single-step workflow. Use it when you only run one step type and want the simplest typed body — e.g. InvokeChatCompletionStepTemplate, InvokeComfyStepTemplate, etc.

The generic path returns a Workflow; a recipe returns only its step's output. You can mix them freely.

The generic path ​

http
POST https://orchestration.civitai.com/v2/consumer/workflows?whatif=false&wait=60
Authorization: Bearer <your-token>
Content-Type: application/json

{
  "steps": [
    {
      "$type": "imageGen",
      "input": {
        "engine": "flux",
        "prompt": "A cat astronaut floating through neon space",
        "width": 1024,
        "height": 1024
      }
    }
  ]
}

Workflow-level body fields ​

Everything in the table lives alongside steps. See the full WorkflowTemplate schema for types.

FieldPurpose
stepsRequired. One or more step objects, each with its own $type and input.
callbacksWebhooks for lifecycle events — see Results & webhooks.
tagsIndexed string tags for later lookup via QueryWorkflows. Great for tenant / campaign / user IDs.
metadataArbitrary JSON attached to the workflow. Not indexed — use for notes, correlation IDs, UI hints.
argumentsValues steps can read via { "$ref": "$arguments" } — see Workflow arguments.
allowMatureContentControls mature-content gating and which Buzz currency pays — see Payments (Buzz) below.
experimentalMarks the workflow as experimental; may relax some guardrails.
upgradeModeHow to handle a workflow paid with blue/green Buzz that turns out to produce mature content — see Payments (Buzz).
currenciesRestrict which Buzz currencies may settle this workflow (see Payments (Buzz)).
tipsOptional tip amount attached to the workflow.

Query parameters ​

ParamDefaultPurpose
wait0Seconds to block waiting for the workflow to finish; keep it below your HTTP client's timeout. If it is still running then, you get a 202.
whatiffalseIf true, validates and resolves the workflow (provider, estimated cost, required resources) without actually running it. Great for CI smoke tests and cost previews.
hideMatureContentfalseIf true, mature blobs on the response won't include a url. Useful for rendering in user-facing UIs without re-checking policy per-blob.

Status codes ​

CodeMeaning
200 OKThe workflow reached a terminal state within your wait budget.
202 AcceptedThe workflow is still running. The body is the current workflow; continue via webhooks or GetWorkflow.
400 Bad RequestBody failed validation — see Errors & retries for the response shape.
401 UnauthorizedMissing or invalid bearer token.
403 ForbiddenToken is valid but not allowed to use this recipe / resource / mature content flag.
429 Too Many RequestsRate limited. Wait for the Retry-After seconds, then retry — see Rate limits & quotas.

Payments (Buzz) ​

Workflows are paid for with Buzz, Civitai's on-platform currency, from the balances on your civitai.com account; you never pass dollar amounts in the API. There are three currencies:

CurrencyEarned / boughtValid for
Blue (blue)Earned by interacting on civitai.comSFW workflows only
Green (green)PurchasedSFW workflows only
Yellow (yellow)PurchasedSFW and NSFW workflows

Default charging ​

If you don't set currencies, the orchestrator charges your account in order blue → green → yellow, splitting across currencies if needed (all your blue first, the remainder from green, then yellow).

Restricting to specific currencies ​

Set currencies to limit which accounts can settle the workflow:

json
{
  "steps": [ /* ... */ ],
  "currencies": ["green", "yellow"]
}

Only currencies you list will be drawn on. If none of them cover the cost, the submission is rejected with a payment error.

Mature content and currency interaction ​

  • Setting allowMatureContent: true forces payment in yellow Buzz (the only NSFW-capable currency).
  • Setting allowMatureContent: false restricts to SFW and allows blue/green (plus yellow) to pay.
  • Leaving allowMatureContent unset means the orchestrator decides after seeing which currency was charged: if the workflow settled with blue or green, it's treated as SFW; if it settled with yellow, mature content is allowed.

upgradeMode — when the output turns out mature ​

If the workflow was paid with blue or green Buzz (SFW) but the generated content is classified as mature, upgradeMode controls what happens:

  • "manual" — the mature output is withheld and the workflow waits on you. To release it, call UpdateWorkflow (PUT) or PatchWorkflow (PATCH) with allowMatureContent: true. The orchestrator refunds the blue/green Buzz and charges yellow. If your yellow balance is insufficient, the update returns 400.
  • "automatic" — the orchestrator does that swap for you inline, charging the difference in yellow Buzz and delivering the mature output (or failing the workflow if yellow is insufficient).

Previewing cost ​

whatif=true returns a cost estimate, broken down per currency, without running the workflow.

The per-recipe path ​

http
POST https://orchestration.civitai.com/v2/consumer/recipes/chatCompletion?whatif=false
Authorization: Bearer <your-token>
Content-Type: application/json

{
  "model": "openai/gpt-oss-120b",
  "messages": [
    { "role": "user", "content": "Summarize this release note: ..." }
  ]
}

Each /v2/consumer/recipes/{recipe} endpoint builds a single-step workflow for you, so:

  • The request body is the step's input schema directly — no $type, no steps array.
  • The query parameters are whatif, allowMatureContent, experimental, ephemeral and tier. There is no wait or hideMatureContent, and no callbacks, tags, metadata or upgradeMode — use the generic path for those.
  • The call blocks until the workflow finishes (there is no 202), and the workflow is canceled if the connection drops first. Use the generic path for anything that may outlast your HTTP client's timeout.
  • The response is the step's output (e.g. ChatCompletionOutput), not a Workflow.

Updating and querying ​

After submitting, you can:

UpdateWorkflow (PUT) returns 200 with the full workflow body, and accepts ?whatif=true to price a change without applying it.

Resource availability.status includes queued: a resource waiting in a download queue (it carries a queuePosition) reports queued, while unavailable means "eligible, but nothing is fetching it". Clients that exhaustively match on status must handle both.

UpdateWorkflowStep / PatchWorkflowStep update a step's metadata (the only field they accept) in any state; a step's input can't be changed.

Civitai Developer Documentation