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

# Generate a Workflow

> Create a workflow from a natural-language prompt

Create a workflow from a plain-language prompt entirely through the API — no browser session required. Opus AI agents design and build the workflow for you, and this endpoint returns immediately with a `runId` you poll until the generation finishes.

<Note>
  Generation is asynchronous. This endpoint creates the workflow and starts the run, then returns right away. Track progress with [Get Run Status](/api-reference/workflow-generation/get-run-status) until the run reaches a terminal status.
</Note>

Requires the **Workflow: Full** permission in the target workspace.

## Body Parameters

<ParamField body="prompt" type="string" required>
  What to build, in plain language. Be specific: the goal, the steps you already know, decisions to be made, and the systems involved.
</ParamField>

<ParamField body="workspaceId" type="string" required>
  The UUID of the workspace to create the workflow in. You must be a member of this workspace.
</ParamField>

<ParamField body="name" type="string">
  Workflow name. Defaults to the first 60 characters of the prompt.
</ParamField>

<ParamField body="displayName" type="string">
  Short title for the run. Generated automatically when omitted.
</ParamField>

<ParamField body="fileIds" type="string[]">
  Uploaded file references to give the AI as context (process docs, examples, specs). Maximum of 10.
</ParamField>

<ParamField body="orgUnitIds" type="string[]">
  Org unit UUIDs to tag the new workflow to. Maximum of 100. Omitted or empty means no tagging.
</ParamField>

<Note>
  Your organization is always taken from the API key — it cannot be set in the body.
</Note>

## Response

<ResponseField name="entityId" type="string" required>
  The workflow's catalog entity ID.
</ResponseField>

<ResponseField name="workflowId" type="string" required>
  The workflow ID. Use this as `{workflowId}` in [Get Run Status](/api-reference/workflow-generation/get-run-status) and [Cancel a Run](/api-reference/workflow-generation/cancel-run).
</ResponseField>

<ResponseField name="workflowVersionId" type="string" required>
  The ID of the workflow version created for this generation.
</ResponseField>

<ResponseField name="runId" type="string" required>
  The generation run ID. Poll it with [Get Run Status](/api-reference/workflow-generation/get-run-status).
</ResponseField>

<ResponseField name="status" type="string" required>
  The initial run status (e.g., `processing`).
</ResponseField>

<ResponseField name="confirmed" type="boolean">
  Whether the run is registered and underway. `false` indicates the run was not confirmed in room state.
</ResponseField>

## Errors

<ResponseField name="400" type="Bad Request">
  Invalid body (bad UUIDs, more than 10 files or 100 org units), or the API key has no active organization.
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  Missing, invalid, or expired API key, or the key's user is no longer a member of the organization.
</ResponseField>

<ResponseField name="403" type="Forbidden">
  The key's user lacks the **Workflow: Full** permission in the target workspace.
</ResponseField>

<ResponseField name="404" type="Not Found">
  `No workspace found` — the workspace doesn't exist or you don't have access to it.
</ResponseField>

<ResponseField name="409" type="Conflict">
  This workflow already has a run in progress. Only one run is allowed at a time.
</ResponseField>

<ResponseField name="429" type="Too Many Requests">
  Too many active runs. Limits are 20 per workspace and 100 per organization. The response body carries `{scope, limit, active}`. Your API key's own rate limit can also return `429`.
</ResponseField>

<ResponseField name="503" type="Service Unavailable">
  Generation is temporarily unavailable — retry shortly.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://operator.opus.com/api/v1/workflow/generate \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {YOUR_API_KEY}' \
    --data '{
      "prompt": "Classify an incoming support email as billing or technical, then draft a reply for the chosen category.",
      "workspaceId": "{YOUR_WORKSPACE_ID}"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://operator.opus.com/api/v1/workflow/generate"
  headers = {
      "Content-Type": "application/json",
      "Authorization": "Bearer {YOUR_API_KEY}"
  }
  payload = {
      "prompt": "Classify an incoming support email as billing or technical, then draft a reply for the chosen category.",
      "workspaceId": "{YOUR_WORKSPACE_ID}"
  }

  response = requests.post(url, json=payload, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://operator.opus.com/api/v1/workflow/generate",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer {YOUR_API_KEY}",
      },
      body: JSON.stringify({
        prompt:
          "Classify an incoming support email as billing or technical, then draft a reply for the chosen category.",
        workspaceId: "{YOUR_WORKSPACE_ID}",
      }),
    }
  );

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Response theme={null}
  {
    "entityId": "{ENTITY_ID}",
    "workflowId": "{WORKFLOW_ID}",
    "workflowVersionId": "{WORKFLOW_VERSION_ID}",
    "runId": "{RUN_ID}",
    "status": "processing",
    "confirmed": true
  }
  ```
</ResponseExample>
