Approve an approval request
PUT/approvals/:identifier/approve
Records the caller's approval (sign-off) for the request. When this sign-off reaches the required quorum, the underlying action is executed synchronously and the request resolves to APPROVED; otherwise it stays PENDING with an incremented sign-off count. Idempotent-safe: a second sign-off by the same approver is rejected.
The caller cannot approve their own request. An approval request in a
different entity is reported as 404.
MFA step-up (approve only). The caller must first complete a TOTP
challenge of type APPROVAL_REVIEW bound to this approval, via
POST /mfa/challenge/start/APPROVAL_REVIEW then
POST /mfa/challenge/verify/APPROVAL_REVIEW (both take the approval's
UUID as resourceIdentifier). Approving without a completed challenge
fails with MFA_REQUIRED. The challenge is per-approver — in a
multi-approver quorum each approver completes their own. Rejecting does
not require a challenge.
Requires the approvals.request.approve permission in the selected
entity.
Request
Responses
- 202
- 401
- 403
- 404
- 409
- 410
- 500
Sign-off recorded (request may now be resolved or still pending)
Missing/invalid JWT or entity selection
RBAC_PERMISSION_DENIED — caller lacks the route-level approvals.request.approve permission; APPROVAL_CANNOT_APPROVE_OWN_REQUEST — caller is the requester (self-approval blocked); APPROVAL_INSUFFICIENT_PERMISSION — caller lacks the action's own permission for the request's target scope.
APPROVAL_REQUEST_NOT_FOUND — not found in this entity
APPROVAL_REQUEST_ALREADY_RESOLVED — request is no longer PENDING; APPROVAL_ALREADY_SIGNED_OFF — caller has already signed off on it.
APPROVAL_REQUEST_EXPIRED — the request's TTL has passed; it can no longer be actioned.
MFA_REQUIRED — no completed APPROVAL_REVIEW challenge exists for this approver and approval. Complete the start+verify challenge flow, then retry. (Surfaces as 500 by the shared error mapping; the UI drives the challenge before calling approve, so callers normally never see it.)