---
title: "Create a workflow"
method: POST
path: "/api/v1/workflows"
tags: ["Workflow Control Plane"]
---

# Create a workflow

`POST /api/v1/workflows`

## Request

- Base URL: `https://orchestrator.getaxonflow.com`
- URL: `https://orchestrator.getaxonflow.com/api/v1/workflows`
- Auth: none declared
- TypeScript: <https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/docs/api/v1/workflows/post.ts> (a function with typed inputs; its response is checked against the schema)

Register a new workflow from an external orchestrator (LangChain, LangGraph, CrewAI).
Returns a workflow_id to use for subsequent step gate checks.

## Request body

- CreateWorkflowRequest
  - `workflow_name` string, required: Human-readable name for the workflow
  - `source` 'langgraph' | 'langchain' | 'crewai' | 'external': Source orchestrator
  - `trace_id` string: External trace ID for correlation with Langsmith, Datadog, or OpenTelemetry
  - `metadata` object: Additional workflow metadata

## Response `201`

Workflow created

- CreateWorkflowResponse
  - `workflow_id` string: Unique workflow identifier
  - `workflow_name` string
  - `status` 'in_progress' | 'completed' | 'aborted' | 'failed'
  - `trace_id` string: External trace ID for correlation with Langsmith, Datadog, or OpenTelemetry
  - `started_at` string, date-time
  - `created_at` string, date-time: When the workflow row was inserted. Distinct from `started_at` because workflows can be created in a staged-but-not-running state.
  - `source` 'langgraph' | 'langchain' | 'crewai' | 'external': Echoes the request's `source` so callers don't need a separate read after creation to learn which orchestrator owns the workflow.

## Other responses

- `400`: Invalid request (triplet envelope)

---

[API](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api.md) - [All operations](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/revisions/f408ef3ec9dd?raw)
