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

# Update Definition

Use this API to update an existing workflow definition. Atomically increments the version, snapshots the prior content, and rejects if the stored version mismatches `ifVersion`. In-flight executions keep running on the version they started with.

# Endpoint

`POST https://api.velt.dev/v2/workflow/definitions/update`

# Headers

**x-velt-api-key** `string` *required*

Your API key.

**x-velt-auth-token** `string` *required*

Your [Auth Token](https://velt.dev/docs/security/auth-tokens.md).

# Body

#### Params

Accepts every field from [Create Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/create-definition.md) plus:

> [!WARNING]
>
> Update replaces the definition; it is not a partial patch. Send the complete `name`, `nodes`, and `edges` on every call. Any field you omit is not preserved from the stored definition.
>
> Read the current definition with [Get Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/get-definition.md), change what you need, then send the whole object back with `ifVersion`. A read response is not accepted verbatim: strip the server-owned `version`, `createdAt`, `updatedAt`, `status`, and `compiled` fields first. Strip the explicit nulls too. Every optional field you never set comes back as `null`: `description`, `groups`, `triggers`, `tags`, `custom`, and `organizationId` / `documentId` inside `scope`. Update takes those fields as absent or as real values, never as `null`, so a leftover `null` or a leftover server-owned field fails the request with `INVALID_ARGUMENT`.

**data** `object` *required*

**properties**

**definitionId** `string` *required*

The definition to update.

**ifVersion** `integer` *required*

Optimistic-locking version. Must equal the stored definition's current `version`. If someone else updated the definition since you read it, the request is rejected with `FAILED_PRECONDITION` and a message like `Version conflict: expected 4, current 5`, so a concurrent edit is never silently overwritten.

**name** `string` *required*

1–200 chars.

**description** `string`

0–2000 chars.

**scope** `object`

Defaults to `{ level: "apiKey" }`. Options:

* `{ level: "apiKey" }`: workspace-wide.
* `{ level: "organization", organizationId: "<id>" }`: bound to one organization. `organizationId` is required (returns `INVALID_ARGUMENT` if omitted).
* `{ level: "document", organizationId: "<id>", documentId: "<id>" }`: bound to one document under an organization. Both fields required.

Update replaces `scope` like every other field. Omit it and `level` resets to `apiKey`, silently demoting an organization-scoped or document-scoped definition to workspace scope. Resend the `scope` you read from [Get Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/get-definition.md) on every update.

**nodes** `array` *required*

1–100 nodes of type `agent`, `human`, `notification`, or `webhook`. Each node accepts an optional `slaMs` (up to 7 days) and optional cosmetic `name` (1–200 chars) and `description` (≤ 2000 chars) labels. See [Node configuration](https://velt.dev/docs/ai/approval-engine/customize-behavior.md#node-configuration) and the [Create Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/create-definition.md) type table.

**edges** `array` *required*

0–500 edges, unified `EdgeSchema`: `{ from, to, on?, when?, loop? }`. `from` / `to` are `EdgeEndpoint`s (bare node-id string, `{ kind: "node", nodeId }`, or `{ kind: "group", groupId }`); `on` ∈ `approve` / `reject` / `always` (default) / `exhausted` / `custom`; `when` is valid only on `on:"custom"`; `loop { maxIterations: 1–20 }` only on an `on:"reject"` back-edge. A `human` node must have an outgoing `on:"reject"` edge. See [the edge model](https://velt.dev/docs/ai/approval-engine/customize-behavior.md#edge-model) for full semantics and the [Create Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/create-definition.md) field table.

**groups** `array`

0–100 parallel-group definitions. A `waitAll` or `cancelOnQuorum` group can be an edge source (`from: { kind: "group", groupId }`); group-to-node fan-out (`to: { kind: "group", groupId }`) is accepted for all policies. A forward `on:"reject"` from a `joinOnQuorum` / `cancelOnQuorum` group is rejected as a dead edge. See [parallel groups and quorum policies](https://velt.dev/docs/ai/approval-engine/customize-behavior.md#parallel-groups-and-quorum-policies).

**triggers** `array`

0–50 trigger declarations: `{ triggerId, eventName?, filters?, inboundWebhook?, schedule?, appTrigger? }`. A trigger starts executions for you, with no dispatch call. The three mechanisms are mutually exclusive on a single entry. See the [Create Definition](https://velt.dev/docs/api-reference/rest-apis/v2/approval-engine/definitions/create-definition.md) field table and [Triggers](https://velt.dev/docs/ai/approval-engine/customize-behavior.md#triggers).

Updating `triggers` replaces the stored array. Removing a `schedule` entry, or setting its `enabled` to `false`, stops that schedule from firing.

**webhookConfig** `object`

Default webhook receiver for every execution of this definition: `{ url, secret, eventTypes? }`. See [Webhook delivery](https://velt.dev/docs/ai/approval-engine/customize-behavior.md#webhook-delivery).

**tags** `string[]`

0–20 tags, each ≤ 64 chars.

**custom** `object`

Free-form metadata.

**organizationId** `string`

Required when scoped to an organization or document.

**documentId** `string`

Required when scoped to a document.

> [!NOTE]
>
> Every successful update increments `version` and snapshots the prior content. In-flight executions are immune to updates: they keep running on the pinned `definitionVersion` from their dispatch.
>
> Snapshots are kept for audit and recovery only. There is no endpoint to read an old version and no rollback, so keep your own copy of anything you may want to restore. See [Versioning](https://velt.dev/docs/ai/approval-engine/patterns.md#versioning-and-what-it-does-not-do).

## **Example Requests**

#### Update a definition

Only `name` changes here, so the request resends the unchanged `nodes` and `edges` verbatim.

```JSON theme={null}
{
  "data": {
    "definitionId": "marketing-copy-approval",
    "ifVersion": 1,
    "name": "Marketing copy approval (Q2 revision)",
    "scope": { "level": "apiKey" },
    "nodes": [
      { "nodeId": "agent-draft",   "type": "agent", "config": { "agentId": "copy-agent-v1",    "urlPath": "documentUrl" } },
      { "nodeId": "human-review",  "type": "human", "config": { "reviewers": [{ "userId": "u_reviewer_01", "mandatory": true }] } },
      { "nodeId": "agent-publish", "type": "agent", "config": { "agentId": "publish-agent-v1", "urlPath": "documentUrl" } },
      { "nodeId": "agent-rework",  "type": "agent", "config": { "agentId": "rework-agent-v1",  "urlPath": "documentUrl" } }
    ],
    "edges": [
      { "from": "agent-draft", "to": "human-review" },
      { "from": "human-review", "to": "agent-publish", "on": "approve" },
      { "from": "human-review", "to": "agent-rework", "on": "reject" }
    ]
  }
}
```

# Response

#### Success Response

```JSON theme={null}
{
  "result": {
    "definitionId": "marketing-copy-approval",
    "name": "Marketing copy approval (Q2 revision)",
    "description": null,
    "version": 2,
    "scope": { "level": "apiKey", "organizationId": null, "documentId": null },
    "nodes": [
      { "nodeId": "agent-draft", "type": "agent", "config": { "agentId": "copy-agent-v1", "urlPath": "documentUrl" } },
      { "nodeId": "human-review", "type": "human", "config": { "reviewers": [{ "userId": "u_reviewer_01", "mandatory": true }] } },
      { "nodeId": "agent-publish", "type": "agent", "config": { "agentId": "publish-agent-v1", "urlPath": "documentUrl" } },
      { "nodeId": "agent-rework", "type": "agent", "config": { "agentId": "rework-agent-v1", "urlPath": "documentUrl" } }
    ],
    "edges": [
      { "from": "agent-draft", "to": "human-review" },
      { "from": "human-review", "to": "agent-publish", "on": "approve" },
      { "from": "human-review", "to": "agent-rework", "on": "reject" }
    ],
    "groups": null,
    "compiled": {
      "forwardEdges": [
        { "from": "agent-draft", "to": "human-review", "role": "always", "when": null },
        { "from": "human-review", "to": "agent-publish", "role": "approve", "when": { "op": "eq", "args": [{ "var": "output.decision" }, "approve"] } },
        { "from": "human-review", "to": "agent-rework", "role": "reject", "when": { "op": "eq", "args": [{ "var": "output.decision" }, "reject"] } }
      ],
      "loops": []
    },
    "triggers": null,
    "tags": null,
    "custom": null,
    "createdAt": 1731432000000,
    "updatedAt": 1731518400000,
    "status": "active"
  }
}
```

#### Failure Response

```JSON theme={null}
{
  "error": {
    "message": "ERROR_MESSAGE",
    "status": "FAILED_PRECONDITION"
  }
}
```

**Errors:** `NOT_FOUND` (definition does not exist) / `FAILED_PRECONDITION` (`ifVersion` mismatch) / `INVALID_ARGUMENT` (schema, `compileGraph`, or linter failure).

```js theme={null}
{
  "result": {
    "definitionId": "marketing-copy-approval",
    "name": "Marketing copy approval (Q2 revision)",
    "description": null,
    "version": 2,
    "scope": { "level": "apiKey", "organizationId": null, "documentId": null },
    "nodes": [
      { "nodeId": "agent-draft", "type": "agent", "config": { "agentId": "copy-agent-v1", "urlPath": "documentUrl" } },
      { "nodeId": "human-review", "type": "human", "config": { "reviewers": [{ "userId": "u_reviewer_01", "mandatory": true }] } },
      { "nodeId": "agent-publish", "type": "agent", "config": { "agentId": "publish-agent-v1", "urlPath": "documentUrl" } },
      { "nodeId": "agent-rework", "type": "agent", "config": { "agentId": "rework-agent-v1", "urlPath": "documentUrl" } }
    ],
    "edges": [
      { "from": "agent-draft", "to": "human-review" },
      { "from": "human-review", "to": "agent-publish", "on": "approve" },
      { "from": "human-review", "to": "agent-rework", "on": "reject" }
    ],
    "groups": null,
    "compiled": {
      "forwardEdges": [
        { "from": "agent-draft", "to": "human-review", "role": "always", "when": null },
        { "from": "human-review", "to": "agent-publish", "role": "approve", "when": { "op": "eq", "args": [{ "var": "output.decision" }, "approve"] } },
        { "from": "human-review", "to": "agent-rework", "role": "reject", "when": { "op": "eq", "args": [{ "var": "output.decision" }, "reject"] } }
      ],
      "loops": []
    },
    "triggers": null,
    "tags": null,
    "custom": null,
    "createdAt": 1731432000000,
    "updatedAt": 1731518400000,
    "status": "active"
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.