---
title: "[Beta] Create a workflow"
method: POST
path: "/workflows"
tags: ["Workflows (Beta)"]
---

# [Beta] Create a workflow

`POST /workflows`

Create a new workflow. The workflow is created as an inactive draft (version 1). Use the activate endpoint to make it live. Use GET /workflows/definitions to discover available action and trigger types. Rejects definitions that fail deep validation (missing required action inputs or trigger configuration) with a 400 carrying structured issues.

## Request body

- CreateWorkflowPublicInput
  - `name` string, required — Workflow name
  - `description` string — Workflow description
  - `trigger_type` 'manual-trigger' | 'ai-trigger' | 'cron-trigger' | 'form-trigger' | 'webhook' | 'contact-created' | 'contact-updated' | 'phone-call-started' | 'phone-call-finished' | 'ticket-created' | 'ticket-reassigned' | 'ticket-resolved' | 'ticket-handoff' | 'pre-ticket-handoff' | 'ticket-tag-added' | 'ticket-inactive' | 'agent-inactive' | 'sequence-completed' | 'csat-score-submit' | 'prohibited-topic-detected' | 'sla-first-reply-breached' | 'sla-next-reply-breached' | 'sla-resolution-breached' | 'voice-call-transferred' | 'pre-voice-call-transfer' | 'pre-phone-call-finished' | 'manual-ticket-trigger' | 'contact-message-received' | 'first-contact-message-received' | 'macro-called' | 'ai-response-completed' | 'agent-availability-changed' | 'agent-avail-in-team-changed' | 'ai-response-requested' | 'ticket-reopened', required — What starts the workflow. Use "manual-trigger" for on-demand execution, "ai-trigger" for AI-initiated, "webhook" for external HTTP triggers, "cron-trigger" for scheduled runs, or event-based triggers like "ticket-created", "contact-created", etc.
  - `trigger_configuration` unknown
  - `workflow_blocks` unknown[], required — Array of workflow steps and control-flow blocks. Each step is an object with { "$kind": "Action", "id": "<unique-step-id>", "type": "<action-type>", "name": "<display-name>", "input": { ... } }. Control-flow blocks use { "$kind": "Block", "type": "if-else", "id": "<unique-id>", "inputs": { "condition": { "operatorName": "equals", "left": "{{step_id.field}}", "right": "value" } }, "branches": { "then": [...steps], "else": [...steps] } }. Use {{step_id.field}} to reference outputs from previous steps (no `.output.` segment — the field sits directly under the step id).
    - unknown
  - `workflow_editor_state` unknown

## Response `201`

Default Response

- WorkflowDetailPublicResponseDto
  - `id` number, required — Version serial ID
  - `workflow_id` string, required — Workflow UUID (groups all versions of the same workflow)
  - `name` string, required — Workflow name
  - `description` string, nullable, required — Workflow description
  - `is_active` boolean, nullable, required — Whether this version is currently active
  - `trigger_type` string, required — Trigger type: "manual-trigger", "ai-trigger", "cron-trigger", "webhook", "form-trigger", or event-based triggers
  - `version_number` number, required — Version number (increments with each edit)
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `workflow_blocks` unknown[], nullable, required — Workflow step/block definitions
    - unknown
  - `trigger_configuration` unknown, required
  - `webhook_url` string, nullable, required — Trigger URL for webhook-type workflows. Call this URL (POST) to trigger the workflow. Null for non-webhook workflows.

## Other responses

- `400` — Default Response
- `500` — Internal Server Error

---

[API](https://skmtc.net/open/apis/opencx-api.md) · [All operations](https://skmtc.net/open/apis/opencx-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/open/opencx-api/revisions/57b06b52302d/schema)
