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

# Create Workflow

> Create and execute a new ComfyUI workflow

## Overview

Create and execute a new ComfyUI workflow. This endpoint accepts multipart form data to support file uploads for workflow parameters.

<Note>
  Workflows are automatically scheduled on available runners based on tag matching. Ensure you have active runners with matching tags.
</Note>

<Warning>
  The API playground does not support file uploads. Use cURL, Postman, or your application code to test this endpoint.
</Warning>

## Content Type

This endpoint requires `multipart/form-data` content type for file upload support.

**Maximum file size:** 50MB per request

## Request Parameters

<ParamField body="name" type="string" required>
  A descriptive name for your workflow (1-200 characters).
</ParamField>

<ParamField body="workflow_json" type="file" required>
  A JSON file containing the ComfyUI workflow definition. This should be exported from ComfyUI or constructed programmatically.
</ParamField>

<ParamField body="tags" type="string">
  Comma-separated list of tags for runner selection. The workflow will be scheduled on a runner with matching tags.

  Example: `production,gpu-a100,image-generation`
</ParamField>

### Dynamic Parameters

The workflow supports dynamic parameters using placeholders:

<ParamField body="$text_parameter_name" type="string">
  Text parameter - prefix the field name with `$` followed by the placeholder name from your workflow.

  Example: `$prompt` for a text prompt
</ParamField>

<ParamField body="$file_parameter_name" type="file">
  File parameter - prefix the field name with `$` followed by the placeholder name, and include the file.

  Example: `$input_image` for an image file
</ParamField>

<ParamField body="#choice_parameter_name" type="string">
  Choice parameter - prefix the field name with `#` followed by the placeholder name.

  Example: `#sampler` for sampler selection
</ParamField>

<Info>
  Learn more about placeholders and dynamic parameters in the [Workflows concept](/concepts/workflows) page.
</Info>

## Response

<ResponseField name="id" type="string" required>
  Unique identifier (UUID) for the workflow.
</ResponseField>

<ResponseField name="name" type="string" required>
  The workflow's name.
</ResponseField>

<ResponseField name="status" type="string" required>
  Initial status of the workflow (typically `accepted`).

  Possible values: `accepted`, `uploaded`, `queued`, `running`, `completed`, `cancelled`, `invalid`, `failed`
</ResponseField>

<ResponseField name="tags" type="string[]" required>
  Array of tags associated with the workflow.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  ISO 8601 timestamp when the workflow was created.
</ResponseField>

<ResponseField name="updated_at" type="string" required>
  ISO 8601 timestamp when the workflow was last updated.
</ResponseField>

<ResponseField name="started_at" type="string">
  ISO 8601 timestamp when execution started (null initially).
</ResponseField>

<ResponseField name="completed_at" type="string">
  ISO 8601 timestamp when execution completed (null initially).
</ResponseField>

## Example Response

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Text to Image Generation",
  "status": "accepted",
  "tags": ["production", "text2img"],
  "created_at": "2024-01-15T14:30:00Z",
  "updated_at": "2024-01-15T14:30:00Z",
  "started_at": null,
  "completed_at": null
}
```

## cURL Example

Since the API playground doesn't support file uploads, use this cURL command to test:

```bash theme={null}
curl -X POST https://api.comfycontrol.app/v1/workflow \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "name=My Workflow" \
  -F "tags=production,gpu" \
  -F "workflow_json=@/path/to/workflow.json" \
  -F '$prompt=A beautiful sunset over mountains' \
  -F '$input_image=@/path/to/image.png' \
  -F '#sampler=euler_ancestral'
```

Replace:

* `YOUR_API_TOKEN` with your actual API token
* `/path/to/workflow.json` with your ComfyUI workflow JSON file
* `/path/to/image.png` with any input images (if needed)
* Add dynamic parameters as needed with `$` prefix for text/files, `#` prefix for choices

The `-F` flag automatically handles `multipart/form-data` with proper boundaries.

## Workflow Lifecycle

After creation, the workflow goes through these states:

1. **accepted** - Workflow created and queued for processing
2. **uploaded** - Files uploaded to storage
3. **queued** - Waiting in runner's queue
4. **running** - Currently executing on a runner
5. **completed** - Execution finished successfully
6. **failed** - Execution failed with an error
7. **cancelled** - Manually cancelled
8. **invalid** - Invalid workflow definition

## Error Responses

<ResponseField name="400" type="error">
  Bad request - validation error in the request.

  Common causes:

  * Missing required fields (name, workflow\_json)
  * Invalid workflow JSON structure
  * File size exceeds 50MB limit
  * Invalid tags format
  * Workflow parameter validation failed
  * No runner available with matching tags
</ResponseField>

<ResponseField name="401" type="error">
  Unauthorized - invalid or missing authentication token.
</ResponseField>

<ResponseField name="403" type="error">
  Forbidden - workflow parameter limit exceeded for your tier, or insufficient permissions.
</ResponseField>

## Notes

* Workflows are automatically assigned to runners based on tag matching
* If no tags are specified, the workflow can run on any active runner
* File parameters are stored securely and deleted after workflow completion
* Use the subscribe endpoint to monitor workflow progress in real-time
* You can create multiple workflows simultaneously
* Workflow status updates can be monitored via the subscribe (SSE) endpoint or by polling the get endpoint
* **Use cURL, Postman, or application code** for testing - the API playground doesn't support file uploads
