---
title: "Create workflow"
method: POST
path: "/agents/v2/workflows"
tags: ["Workflows"]
---

# Create workflow

`POST /agents/v2/workflows`

## Request

- Base URL: `https://odyssey.asteroid.ai`
- URL: `https://odyssey.asteroid.ai/agents/v2/workflows`
- Auth: API key in header `X-Api-Key`

Create a workflow and its first version. Without a version, the workflow starts blank with a single start node.

## Request body

- WorkflowsWorkflowCreateRequest: Request to create a workflow and its first version
  - `name` string, required: Name for the new workflow. Characters outside the workflow-name charset (letters, digits, spaces, hyphens) are sanitized server-side — create flows carry defaulted names (templates, prebuilt states) the user never typed, which must not fail validation.
  - `organizationId` string, uuid
  - `version` WorkflowsVersionCreateRequest: Request to create a new unpublished version of a workflow
    - `environmentTemplate` AgentsWorkflowExternalEnvironmentTemplate: Environment template on the external API. Omits admin-only OS fields.
      - `config` union, required
        - AgentsWorkflowBrowserTemplateConfig: Customer-facing browser environment template configuration
          - `provider` 'anchor', required: Browser provider type
        - AgentsWorkflowExternalOsTemplateConfig: Customer-facing OS environment template configuration. Admin-only fields live on OsTemplateConfig.
          - `osType` 'linux' | 'windows' | 'citrix': Operating system the environment sandbox runs
          - `provider` 'daytona' | 'local', required: OS provider type
          - `public` boolean, required: Ignored and always false. Kept so SDKs released before it was dropped still parse.
          - `snapshotName` string: Ignored, and never returned. A workflow boots the snapshot of the custom environment it is bound to, or the default image.
      - `type` 'browser' | 'os', required: Type of execution environment
    - `graph` AgentsGraphModelsAgentGraph, required
      - `nodes` AgentsGraphModelsNodesNode[], required
        - `description` string: Deprecated: field is no longer populated and will be removed.
        - `id` string, uuid, required
        - `name` string, required: Display name. New and renamed nodes accept letters, digits, spaces, and hyphens only (historical versions may carry other characters, so responses are not pattern-constrained).
        - `position` AgentsGraphModelsNodesPosition
          - `x` integer, required
          - `y` integer, required
        - `properties` union, required
          - object
            - `type` 'start', required
          - object
            - `capabilities` AgentsGraphModelsNodesPropertiesNodeCapabilities: Coarse environment-level capability toggles for an AI node.
              - …
            - `compression_strategies` string[]
            - `input_schema` object
            - `instructions` string, required
            - `model` string, required
            - `playwright_script_properties` AgentsGraphModelsNodesPropertiesIrisPlaywrightScriptProperties
              - …
            - `script_failure_action` 'fallback_to_ai' | 'cancel_execution': What happens when a script fails on a scripted node. `fallback_to_ai` (default): fall back to LLM-driven execution. `cancel_execution`: cancel the execution immediately.
            - `script_filepath` string: Relative path (within the node's own shared directory) of the Playwright script that the runtime should execute before the LLM. Setting this turns the node into a fast-path scripted node — combine with `script_failure_action: "cancel_execution"` to skip the LLM entirely on success and cancel on failure. The path is resolved at runtime against the node's shared directory — i.e. `shared/<node-key>/<script_filepath>` on disk in the sandbox. `<node-key>` is owned by the runtime (currently the node's slug, may move to its UUID), so authors do not have to encode it and renaming a node does not break the path. Examples (typical): - `./scripts/main.js` - `./scripts/login.js` A leading `./` is optional but canonical — both `scripts/main.js` and `./scripts/main.js` are accepted, and the platform normalizes to the `./`-prefixed form when it writes this value back out. Constraints: - Must be relative (no leading `/`). - Must NOT start with `shared/` — it is already relative to the node's shared directory; the runtime adds the `shared/<node-key>/` prefix. - Must end in `.js` (Playwright, browser), `.ps1` (PowerShell, Windows desktop) or `.sh` (bash, Linux desktop). - Must not contain `..` segments or duplicate slashes. - May contain a single `{{variant_key}}` placeholder, which the runtime substitutes with the execution's `variant_key` so a single workflow can target per-tenant script trees (e.g. `./variants/{{variant_key}}/scripts/main.js` → `shared/<node-key>/variants/<variant-key>/scripts/main.js`). Requires the agent to have `variant_mode` enabled, and the placeholder must be the segment directly under `variants/`.
            - `thinking_budget_tokens` integer
            - `thinking_effort` 'low' | 'medium' | 'high' | 'max'
            - `thinking_mode` 'adaptive' | 'enabled' | 'disabled'
            - `type` 'iris', required
          - object
            - `llm_vars` AgentsGraphModelsNodesPropertiesPlaywrightScriptLLMVar[], required
              - …
            - `script` string, required
            - `type` 'playwright_script', required
          - object
            - `body` object, required
            - `headers` object, required
            - `method` 'GET' | 'POST' | 'PUT' | 'DELETE', required
            - `type` 'api', required
            - `url` string, required
          - object
            - `type` 'url', required
            - `url` string, required
          - object
            - `instructions` string
            - `instructionsEnabled` boolean
            - `model` string
            - `outcomes` AgentsGraphModelsNodesPropertiesOutcomeString[], required
            - `schema` object
            - `type` 'output', required
        - `type` 'start' | 'iris' | 'playwright_script' | 'api' | 'url' | 'output', required
      - `sticky_notes` AgentsGraphModelsStickyNote[], required
        - `color` string
        - `content` string, required
        - `id` string, uuid, required
        - `position` AgentsGraphModelsNodesPosition
          - `x` integer, required
          - `y` integer, required
        - `size` AgentsGraphModelsNodesSize
          - `height` integer, required
          - `width` integer, required
      - `transitions` AgentsGraphModelsTransitionsTransition[], required
        - `description` string
        - `from` string, uuid, required
        - `id` string, uuid, required
        - `properties` union, required
          - object
            - `type` 'iris', required
          - object
            - `name` string, required
            - `selectors` string[], required
            - `type` 'selector', required
          - object
            - `type` 'outcome_success', required
        - `require_confirmation` boolean, required
        - `schema` object
        - `to` string, uuid, required
        - `type` 'iris' | 'selector' | 'outcome_success', required
    - `inputs` AgentsWorkflowInput[]: Typed input definitions for this workflow. Names referenced in prompts but omitted here default to optional strings.
      - `defaultValue` unknown
      - `description` string
      - `name` string, required: The variable name. Matches [a-zA-Z_][a-zA-Z0-9_]* and is unique within the workflow.
      - `required` boolean, required: Whether a value must be supplied at execution time. Defaults to false.
      - `schema` object, required: A single-field JSON Schema fragment describing the input's type, e.g. {type: "string"}, {type: "number"}, {type: "object", properties: {...}}. Validated adaptively at execution time.
    - `parentId` string, uuid
    - `rules` string, required
    - `settings` AgentsGraphModelsExternalSettings, required: Configuration settings for workflow execution
      - `custom_environment_id` string, uuid, nullable: Custom environment executions of this workflow boot on: its environment type and snapshot replace the workflow's own environment, its profile rows restrict which profile an execution may use, and a kept-warm environment hands out a pre-warmed copy. On a new version, omit it to keep the environment of the workflow's latest version (its editable head, which can be newer than the published one), or send null to boot the workflow's own environment. On a new workflow, there is nothing to keep: omit it or send null for no custom environment.
      - `max_timeout_mins` integer, required: Maximum timeout in minutes
      - `viewport_height` integer, required: Browser viewport height in pixels
      - `viewport_width` integer, required: Browser viewport width in pixels

## Response `201`

The request has succeeded and a new resource has been created as a result.

- WorkflowsWorkflowCreateResponse: Response after creating a workflow
  - `id` string, uuid, required

## Other responses

- `400`: The server could not understand the request due to invalid syntax.
- `401`: Access is unauthorized.
- `403`: Access is forbidden.
- `404`: The server cannot find the requested resource.
- `409`: The request conflicts with the current state of the server.
- `500`: Server error

---

[API](https://skmtc.dev/asteroid/apis/agent-service.md) - [All operations](https://skmtc.dev/asteroid/apis/agent-service/llms.txt) - [OpenAPI document](https://skmtc.dev/asteroid/apis/agent-service/revisions/ccc134d1d510?raw)
