# Create workflow

```{raw} html
<div class="mo-api-page-show-toc" aria-hidden="true"></div>
```

Create a workflow definition in the current workspace. Creating a workflow does not start a job automatically.

```text
POST https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments
```

## Preparation before calling

Prepare a personal access token with permission to create workflows, a target workspace ID, and workflow DSL.

## Request body

Replace `$AI_STUDIO_API_KEY`, `$WORKSPACE_ID`, and the workflow name and DSL in the examples with actual values.

:::::::{div} mo-api-tabs
::::::{tab-set}
:::::{tab-item} Input examples

::::{tab-set}
:::{tab-item} One-time run

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "daily-import",
    "dsl_yaml": "workflow:\\n  name: daily-import\\n  root: main\\nroot:\\n  chain: []\\n",
    "execution_mode": "one_shot"
  }'
```

:::
:::{tab-item} Dynamic service

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "order-query-service",
    "dsl_yaml": "workflow:\\n  name: order-query-service\\n  root: main\\nroot:\\n  chain: []\\n",
    "execution_mode": "dynamic_service",
    "dynamic_service": {
      "service_name": "order-query-service"
    }
  }'
```

:::
:::{tab-item} Scheduled run

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "daily-import",
    "dsl_yaml": "workflow:\\n  name: daily-import\\n  root: main\\nroot:\\n  chain: []\\n",
    "execution_mode": "cron",
    "cron_expression": "0 2 * * *"
  }'
```

:::
:::{tab-item} Volume trigger

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/workflow-deployments" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "volume-import",
    "dsl_yaml": "workflow:\\n  name: volume-import\\n  root: main\\nroot:\\n  chain: []\\n",
    "execution_mode": "volume_trigger",
    "volume_trigger": {
      "volume_id": 1001,
      "enabled": true
    }
  }'
```

:::
::::

:::::

:::::{tab-item} Parameter reference

Creating a workflow requires `name` and `dsl_yaml`. When `source_type` is omitted, the workflow uses manual DSL (`manual_dsl`). Do not send `workflow_id` or `runtime_context` when creating a workflow; use [Update workflow](update-workflow.md#request-body) to modify an existing workflow.

::::{tab-set}
:class: mo-api-parameter-table

:::{tab-item} One-time run

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Workflow name. |
| `description` | string | No | Workflow description. |
| `dsl_yaml` | string | Yes | YAML text of the workflow DSL. |
| `execution_mode` | string | No | Execution mode. Defaults to `one_shot`. |
| `source_type` | string | No | Workflow source type. Defaults to `manual_dsl`. DSL that uses a Memory Governance WorkItem must set this to `memory_governance`. |
| `runtime_fields` | object | No | Runtime input form configuration. |
| `runtime_layout` | object | No | Runtime input form layout configuration. |
| `default_values` | object | No | Default values for the runtime input form. |
| `design_graph` | object | No | Workflow design-graph configuration. |
| `compute_resource_id` | string | No | Associated compute resource ID. |

:::
:::{tab-item} Dynamic service

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Workflow name. |
| `dsl_yaml` | string | Yes | YAML text of the workflow DSL. |
| `execution_mode` | string | Yes | Set to `dynamic_service`. |
| `dynamic_service` | object | Yes | Dynamic-service configuration. |
| `dynamic_service.service_name` | string | No | Dynamic service name. |
| `dynamic_service.input_schema` | string | No | Schema for dynamic-service input. |
| `dynamic_service.output_schema` | string | No | Schema for dynamic-service output. |
| `dynamic_service.result_mode` | string | No | Result mode for the dynamic service. |
| `dynamic_service.runtime_spec_json` | string | No | JSON text of runtime configuration for the dynamic service. |

For other optional fields, see the One-time run tab.

:::
:::{tab-item} Scheduled run

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Workflow name. |
| `dsl_yaml` | string | Yes | YAML text of the workflow DSL. |
| `execution_mode` | string | Yes | Set to `cron`. |
| `cron_expression` | string | Yes | Cron expression. |

For other optional fields, see the One-time run tab.

:::
:::{tab-item} Volume trigger

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Workflow name. |
| `dsl_yaml` | string | Yes | YAML text of the workflow DSL. |
| `execution_mode` | string | Yes | Set to `volume_trigger`. |
| `volume_trigger` | object | No | Volume-trigger configuration. `volume_id` is required when the runtime input form does not provide a volume ID. |
| `volume_trigger.volume_id` | integer | Conditional | Required when the runtime input form does not provide a volume ID. |
| `volume_trigger.enabled` | boolean | No | Whether to enable the volume trigger. |
| `volume_trigger.auto_dispatch_enabled` | boolean | No | Whether to automatically dispatch volume-triggered runs. |
| `volume_trigger.vars_json` | string | No | JSON text of variables used by the volume trigger. |
| `volume_trigger.max_concurrency` | integer | No | Maximum concurrency for volume-triggered runs. |

For other optional fields, see the One-time run tab.

:::
::::

:::::
::::::
:::::::

## Successful response

Returns `200` on success. The service saves the workflow definition but does not start a job automatically. Save `data.workflow.id` for viewing, updating, or starting the workflow.

:::::::{div} mo-api-tabs
::::::{tab-set}
:::::{tab-item} Response example

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "workflow": {
      "id": "wf-001",
      "name": "daily-import",
      "source_type": "manual_dsl",
      "execution_mode": "one_shot",
      "draft_id": "draft-001",
      "status": "ready"
    },
    "deployment": {
      "workflow_app_id": "wf-001",
      "workflow_def_id": "def-001",
      "workflow_version_id": "ver-001",
      "workflow_name": "daily-import",
      "version": 1,
      "execution_mode": "one_shot"
    }
  }
}
```

:::::
:::::{tab-item} Field reference

::::{tab-set}
:::{tab-item} Common fields

| Field | Type | Description |
| --- | --- | --- |
| `code` | string | `OK` when successful. |
| `msg` | string | `OK` when successful. |
| `data` | object | Response data. |

:::
:::{tab-item} Workflow summary

`data.workflow` is the summary of the created workflow.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Workflow ID. |
| `name` | string | Workflow name. |
| `source_type` | string | Workflow source type. |
| `execution_mode` | string | Saved execution mode. |
| `draft_id` | string | Workflow draft ID. |
| `status` | string | Current workflow status. |

:::
:::{tab-item} Deployment details

`data.deployment` contains the published workflow version and execution-mode resource.

| Field | Type | Description |
| --- | --- | --- |
| `workflow_app_id` | string | Workflow application ID. |
| `workflow_def_id` | string | Workflow definition ID. |
| `workflow_version_id` | string | Workflow version ID. |
| `workflow_name` | string | Workflow name. |
| `version` | integer | Workflow version number. |
| `execution_mode` | string | Published execution mode. |

:::
:::{tab-item} Conditional fields

| Field | Type | Returned when |
| --- | --- | --- |
| `data.workflow.cron_expression` | string | The workflow is scheduled. |
| `data.workflow.candidate_id` | string | A candidate version exists. |
| `data.deployment.previous_workflow_version_id` | string | Updating an existing workflow version. |
| `data.deployment.disabled_cron_task_ids` | array of string | Replacing a scheduled task. |
| `data.deployment.volume_trigger` | object | The workflow uses a volume trigger. |
| `data.deployment.cron_task` | object | The workflow is scheduled. |
| `data.deployment.dynamic_service` | object | The workflow uses a dynamic service. |
| `data.warnings` | array of string | Deployment produces warnings. |

:::
::::

:::::
::::::
:::::::

## Error response

:::::::{div} mo-api-tabs
::::::{tab-set}
:::::{tab-item} Response example

```json
{
  "code": "ErrParamInvalid",
  "msg": "Request parameters are invalid",
  "data": null
}
```

:::::
:::::{tab-item} Field reference

| Field | Type | Description |
| --- | --- | --- |
| `code` | string | Error code. |
| `msg` | string | Error description. |
| `data` | null | Empty on error. |

:::::
::::::
:::::::

## Follow-up operations

Save `data.workflow.id`. To verify the created workflow, [View workflow details](get-workflow.md#request-example); to run it immediately, [Start workflow job](../workflow-jobs/start-workflow-job.md#request-example).
