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

# Workflows API: Create, Read, Update, Delete DSLs

> Persist, retrieve, update, and delete workflow DSL definitions so you can submit them to the engine or iterate on them between sessions.

The Workflows API gives you a durable store for your workflow definitions. You save a workflow here once and then reference it by ID when executing, sharing, or editing it. Every workflow is stored as its full DSL JSON document, and you can retrieve or replace it at any time. All endpoints are relative to `http://localhost:8082`.

***

## POST /workflows

Save a new workflow definition. Devset stores the DSL document and makes it retrievable by the `id` field you provide inside the body.

<ParamField body="id" type="string" required>
  A unique, human-readable identifier for this workflow, such as `order-flow` or `payment-retry`.
</ParamField>

<ParamField body="messageType" type="string" required>
  The broker type this workflow targets. Accepted values: `kafka`, `rabbit`.
</ParamField>

<ParamField body="producerName" type="string" required>
  The name of the connector to use. Must match a connector saved via the [Connectors API](/reference/api/connectors).
</ParamField>

<ParamField body="topic" type="string">
  The Kafka topic to publish to. Required when `messageType` is `kafka`.
</ParamField>

<ParamField body="exchange" type="string">
  The RabbitMQ exchange to publish to. Used when `messageType` is `rabbit`.
</ParamField>

<ParamField body="routingKey" type="string">
  The RabbitMQ routing key. Used when `messageType` is `rabbit`.
</ParamField>

<ParamField body="contentType" type="string">
  The payload content type. Defaults to `json`. Use `protobuf` for Protocol Buffer payloads.
</ParamField>

<ParamField body="schemaId" type="string">
  Optional identifier of a registered schema to use for payload validation and serialization.
</ParamField>

<ParamField body="executions" type="integer">
  Number of times to execute the pipeline per run. Defaults to `1`.
</ParamField>

<ParamField body="state" type="object">
  Initial workflow-level state map. Values set here are available to pipeline stages via `$ref` expressions.
</ParamField>

<ParamField body="pipeline" type="array" required>
  Ordered list of stage definitions. Each stage describes one message to produce.
</ParamField>

**Request example**

```json theme={null}
{
  "id": "order-flow",
  "messageType": "kafka",
  "topic": "orders.events",
  "producerName": "local-kafka",
  "executions": 1,
  "pipeline": [
    {
      "name": "order-created",
      "set": {
        "id": { "$fn": "uuid()" },
        "amount": 42,
        "status": "PENDING"
      }
    },
    {
      "name": "order-confirmed",
      "set": {
        "id": { "$ref": "order-created.id" },
        "status": "CONFIRMED"
      }
    }
  ]
}
```

**Response — 201 Created**

The full stored workflow document is returned.

```json theme={null}
{
  "id": "order-flow",
  "messageType": "kafka",
  "topic": "orders.events",
  "producerName": "local-kafka",
  "executions": 1,
  "pipeline": [
    {
      "name": "order-created",
      "set": {
        "id": { "$fn": "uuid()" },
        "amount": 42,
        "status": "PENDING"
      }
    },
    {
      "name": "order-confirmed",
      "set": {
        "id": { "$ref": "order-created.id" },
        "status": "CONFIRMED"
      }
    }
  ]
}
```

***

## GET /workflows

List all saved workflows. The response is an array of workflow documents. Use `GET /workflows/{workflowId}` to fetch a specific workflow by ID.

**Response — 200 OK**

```json theme={null}
[
  {
    "id": "order-flow",
    "messageType": "kafka",
    "topic": "orders.events",
    "producerName": "local-kafka",
    "executions": 1,
    "pipeline": []
  },
  {
    "id": "payment-retry",
    "messageType": "kafka",
    "topic": "payments.events",
    "producerName": "local-kafka",
    "executions": 3,
    "pipeline": []
  },
  {
    "id": "notification-flow",
    "messageType": "rabbit",
    "exchange": "notifications",
    "routingKey": "user.notified",
    "producerName": "local-rabbit",
    "executions": 1,
    "pipeline": []
  }
]
```

<ResponseField name="id" type="string">
  The unique identifier for this workflow.
</ResponseField>

<ResponseField name="messageType" type="string">
  The broker type: `kafka` or `rabbit`.
</ResponseField>

<ResponseField name="producerName" type="string">
  The connector used to dispatch messages.
</ResponseField>

<ResponseField name="topic" type="string | null">
  The target Kafka topic, or `null` for RabbitMQ workflows.
</ResponseField>

<ResponseField name="exchange" type="string | null">
  The target RabbitMQ exchange, or `null` for Kafka workflows.
</ResponseField>

<ResponseField name="routingKey" type="string | null">
  The RabbitMQ routing key, or `null` for Kafka workflows.
</ResponseField>

<ResponseField name="executions" type="integer">
  Number of executions configured for this workflow.
</ResponseField>

<ResponseField name="pipeline" type="array">
  Ordered list of stage definitions.
</ResponseField>

***

## GET /workflows/{workflowId}

Retrieve the complete DSL document for a single workflow, including all stage definitions.

**Path parameters**

<ParamField path="workflowId" type="string" required>
  The `id` of the workflow to retrieve.
</ParamField>

**Response — 200 OK**

```json theme={null}
{
  "id": "order-flow",
  "messageType": "kafka",
  "topic": "orders.events",
  "producerName": "local-kafka",
  "executions": 1,
  "pipeline": [
    {
      "name": "order-created",
      "set": {
        "id": { "$fn": "uuid()" },
        "amount": 42,
        "status": "PENDING"
      }
    }
  ]
}
```

***

## PUT /workflows/{workflowId}

Replace an existing workflow definition entirely. The body must be the full DSL document — partial updates are not supported. Devset overwrites the previously stored definition and returns the updated document.

**Path parameters**

<ParamField path="workflowId" type="string" required>
  The `id` of the workflow to replace.
</ParamField>

<ParamField body="(workflow DSL)" type="object" required>
  The complete, updated workflow DSL document. Must include all required top-level fields and a full `pipeline` array.
</ParamField>

**Request example**

```json theme={null}
{
  "id": "order-flow",
  "messageType": "kafka",
  "topic": "orders.events",
  "producerName": "local-kafka",
  "executions": 1,
  "pipeline": [
    {
      "name": "order-created",
      "set": {
        "id": { "$fn": "uuid()" },
        "amount": 99,
        "status": "PENDING",
        "currency": "USD"
      }
    }
  ]
}
```

**Response — 200 OK**

```json theme={null}
{
  "id": "order-flow",
  "messageType": "kafka",
  "topic": "orders.events",
  "producerName": "local-kafka",
  "executions": 1,
  "pipeline": [
    {
      "name": "order-created",
      "set": {
        "id": { "$fn": "uuid()" },
        "amount": 99,
        "status": "PENDING",
        "currency": "USD"
      }
    }
  ]
}
```

<Note>
  If you change the `id` field inside the body, Devset uses the path parameter `workflowId` as the authoritative identifier. Avoid changing `id` in a `PUT` request to prevent confusion.
</Note>

***

## DELETE /workflows/{workflowId}

Permanently delete a saved workflow definition. This operation cannot be undone.

**Path parameters**

<ParamField path="workflowId" type="string" required>
  The `id` of the workflow to delete.
</ParamField>

**Response — 204 No Content**

An empty `204 No Content` response confirms that the workflow was deleted successfully.

<Warning>
  Deleting a workflow does not cancel or affect any runs that were already submitted using that workflow. Active runs continue to completion regardless of whether the source definition is deleted.
</Warning>
