---
title: "Replace a workflow document"
description: "Whole-document replace. `If-Match` and the body's `updated_at` must both equal the workflow's current `updated_at`; the slug cannot change."
url: https://docs.spinrun.ai/api/workflows/replace-workflow
markdown_url: https://docs.spinrun.ai/api/workflows/replace-workflow.md
---

# Replace a workflow document

Whole-document replace. `If-Match` and the body's `updated_at` must both equal the workflow's current `updated_at`; the slug cannot change.

## PUT /api/build/workflows/{ref}

Replace a workflow document

Whole-document replace. `If-Match` and the body's `updated_at` must both equal the workflow's current `updated_at`; the slug cannot change.

Operation id: `replaceWorkflow`

### Parameters

| Name | In | Required | Type | Description |
|---|---|---|---|---|
| ref | path | yes | string | Agent or workflow id or slug. |
| If-Match | header | yes | string | The document's current `updated_at` as an entity tag, e.g. `"2026-09-01T10:00:00.000Z"`, or `*`. |

### Request body

`application/json`

```json
{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "const": "spinrun.workflow/v1",
      "description": "Document discriminator."
    },
    "slug": {
      "type": "string",
      "maxLength": 80,
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
      "description": "URL slug. Cannot change after creation."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80,
      "description": "Display name."
    },
    "description": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 500
        },
        {
          "type": "null"
        }
      ],
      "description": "What the workflow does."
    },
    "enabled": {
      "type": "boolean",
      "description": "Whether the workflow runs."
    },
    "updated_at": {
      "description": "Version stamp. Required on replace.",
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
    },
    "space": {
      "type": "object",
      "properties": {
        "team": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 160
            },
            {
              "type": "null"
            }
          ],
          "description": "Team slug, or null."
        }
      },
      "required": [
        "team"
      ],
      "description": "Where the workflow lives."
    },
    "send_as": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        {
          "type": "null"
        }
      ],
      "description": "Identity runs send as."
    },
    "inputs": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "maxLength": 40,
        "pattern": "^[a-z0-9_]+$",
        "description": "Input name."
      },
      "additionalProperties": {
        "type": "object",
        "properties": {
          "description": {
            "description": "What the input is for.",
            "type": "string",
            "maxLength": 200
          },
          "default": {
            "description": "Default value."
          }
        },
        "description": "One workflow input."
      },
      "description": "Inputs with optional defaults."
    },
    "schedule": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "cron": {
              "type": "string",
              "minLength": 9,
              "maxLength": 120,
              "description": "Cron expression."
            },
            "timezone": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "IANA timezone."
            }
          },
          "required": [
            "cron",
            "timezone"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Optional schedule."
    },
    "steps": {
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "maxLength": 40,
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                "description": "Step handle a later step references."
              },
              "kind": {
                "type": "string",
                "const": "tool",
                "description": "Step kind."
              },
              "tool": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "description": "Tool slug to call."
              },
              "args": {
                "default": {},
                "description": "Arguments for the tool.",
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              },
              "after": {
                "default": [],
                "description": "Steps this one waits for.",
                "maxItems": 10,
                "type": "array",
                "items": {
                  "type": "string",
                  "maxLength": 40,
                  "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                  "description": "Step handle a later step references."
                }
              },
              "note": {
                "description": "Author note, not executed.",
                "type": "string",
                "maxLength": 300
              }
            },
            "required": [
              "id",
              "kind",
              "tool"
            ],
            "description": "One tool call in a workflow."
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "maxLength": 40,
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                "description": "Step handle a later step references."
              },
              "kind": {
// … 83 more lines elided
```

### Responses

| Status | Description |
|---|---|
| 200 | Replaced. `ETag` carries the new `updated_at`. |
| 400 | Malformed JSON, a document that fails validation, or a field that contradicts the URL. |
| 401 | No or invalid token. The `WWW-Authenticate` header names the authorization server. |
| 403 | The grant has no Build authorization. |
| 404 | No such agent, workflow or run visible to this token. |
| 409 | The document changed since it was read (`current` and `applied` say where to rebase), or the write half-landed, or the document's state refuses the change. |
| 413 | Body over the document limit (64 KiB). |
| 428 | `If-Match` is required when replacing. |

#### 200 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "data": {
      "type": "object",
      "properties": {
        "document": {},
        "applied": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "changes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "version": {
          "type": "number"
        },
        "webhook_urls": {
          "description": "Present on agent writes that created a webhook trigger: the one-time URL, shown once.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "trigger_id": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "trigger_id",
              "url"
            ],
            "additionalProperties": false
          }
        }
      },
      "required": [
        "document",
        "applied",
        "changes",
        "version"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "data"
  ],
  "additionalProperties": false
}
```

#### 400 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```

#### 401 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```

#### 403 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```

#### 404 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```

#### 409 · `application/json`

```json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "error": {
          "type": "string"
        },
        "current": {
          "description": "The current document, or null when nothing was read."
        },
        "applied": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Stages that had already landed before the refusal."
        }
      },
      "required": [
        "error",
        "current",
        "applied"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "error": {
          "type": "string"
        }
      },
      "required": [
        "error"
      ],
      "additionalProperties": false
    }
  ]
}
```

#### 413 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```

#### 428 · `application/json`

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
```
