Approval Workflows

Replace an approval workflow

PUT/approval-workflows/{id}

Replaces the organisation's steps for this type with the tree in steps (exactly one root) and returns it. Voters without the permissions the type needs are dropped and listed in meta.removed_user_ids. Requests already in progress are not changed. Sending the same tree again changes nothing. dry_run shows the result without saving it. Emits approval_workflow.updated when the steps changed; no email. Undo it by sending the earlier tree or with POST /approval-workflows/{id}/actions/reset.

Path parameters

  • idstringRequired#

    The workflow type, such as internal_publish. Workflows are keyed by their type, not a UUID. The types are client_invite, incoming_connect, internal_provider_publish, internal_publish and provider_approval; any other value is 404.

    One of: client_invite, incoming_connect, internal_provider_publish, internal_publish, provider_approval

Query parameters

  • dry_runboolean#

    Validate and run the call without committing it, returning what the real call would return with meta.dry_run set.

Headers

  • Idempotency-Keystring#

    Makes a retry safe. Send a new UUID for each new request and reuse it only to retry that request; the first response is replayed for 24 hours.

Request body

application/json, required · ApprovalWorkflowReplace

  • The workflow as a tree. Send exactly one root step, with the later steps under next_steps. At most 50 steps in all and 10 levels deep.

{
  "steps": [
    {
      "name": "Compliance review",
      "description": "Check the deal documents before publishing.",
      "approval_label": "Approve for publishing",
      "vote_type": "majority",
      "voter_ids": [
        "3f1c1a52-6a0e-4b7d-9c53-1d2e8f7a6b40",
        "9b2f6d1e-0c4a-4f58-8e37-5a1c2d3e4f60"
      ],
      "next_steps": [
        {
          "name": "Final sign-off",
          "description": "A director confirms the deal can go live.",
          "approval_label": "Publish",
          "vote_type": "single",
          "voter_ids": [
            "7d4e2b90-1a3c-4e6f-8b5d-0c9a8e7f6d51"
          ],
          "next_steps": []
        }
      ]
    }
  ]
}

Responses

200

The workflow after the change, with meta.removed_user_ids listing the voters that were dropped.

ApprovalWorkflow
{
  "data": {
    "id": "string",
    "request_kind": "opportunity",
    "custom": true,
    "steps": [
      {}
    ],
    "created_at": "2026-06-12T10:00:00+00:00",
    "updated_at": "2026-06-12T10:00:00+00:00"
  },
  "meta": {
    "removed_user_ids": [
      "9a9d1c5e-4f2b-4c8e-9a7d-2f1e6b3c4d5a"
    ],
    "dry_run": true
  }
}
401

Authentication failed. error.code is one of invalid_token, expired, revoked.

Error
403

Authorization failed. error.code is one of org_disabled, ip_blocked, missing_scope, scope_disabled, user_disabled.

Error
404

Resource not found (error.code = not_found).

Error
422

The body breaks a rule, with one entry per problem. A step left with no voter who holds a permission the type needs is rule eligible_voters on steps.<path>.voter_ids, such as steps.0.next_steps.1.voter_ids, and nothing is saved.

Error
429

Rate limit exceeded (error.code = rate_limited).

Error

Examples

curl -X PUT https://your-org-domain/kong/core/api/v2/approval-workflows/{id}\
  -H "Authorization: Bearer $HELM_API_KEY"\
  -H "Content-Type: application/json"\
  -d '{
  "steps": [
    {
      "name": "Compliance review",
      "description": "Check the deal documents before publishing.",
      "approval_label": "Approve for publishing",
      "vote_type": "majority",
      "voter_ids": [
        "3f1c1a52-6a0e-4b7d-9c53-1d2e8f7a6b40",
        "9b2f6d1e-0c4a-4f58-8e37-5a1c2d3e4f60"
      ],
      "next_steps": [
        {
          "name": "Final sign-off",
          "description": "A director confirms the deal can go live.",
          "approval_label": "Publish",
          "vote_type": "single",
          "voter_ids": [
            "7d4e2b90-1a3c-4e6f-8b5d-0c9a8e7f6d51"
          ],
          "next_steps": []
        }
      ]
    }
  ]
}'