Docs

Action statuses

Every status a protected action, approval request and execution can have: meaning, transitions, receipts and dashboard labels.

Every tool call the Gateway decides becomes a protected action: a record of the call, its decision and what happened next. The action's status tells you where it is in its life, whether it can still change, and whether a signed receipt exists for it.

This page lists every status in the current implementation. The same values appear in the Cloud API (status on GET /api/v1/orgs/<org-id>/actions, also usable as a ?status= filter) and in the dashboard's Status column and filter. Webhook events report most of the transitions. Agents see a different vocabulary, described in What the agent sees.

Statuses at a glance

StatusDashboard labelMeaningCan still changeReceipt
deniedDeniedThe decision refused the call. Nothing ran.NoNo
pending_approvalPending approvalWaiting for an approver to decide the approval request.YesNot yet
approvedApprovedAllowed to run, but not run yet: either the policy allowed it, or an approver approved it.YesNot yet
executingExecutingThe Gateway consumed the approval and is calling the upstream, or has not recorded the outcome yet.YesNot yet
succeededSucceededThe upstream call completed and its result is recorded.NoYes
failedFailedThe execution started but did not succeed.NoYes, in almost every case
rejectedRejectedAn approver rejected the request. Nothing ran.NoYes
cancelledCancelledAn owner or admin cancelled it before it ran.NoYes
expiredExpiredClosed without running: it timed out or was superseded.NoNo
authorizedAuthorized (decision only)Decision only: K-Block authorized the exact call and handed the authorization to the caller, which is responsible for executing it. K-Block executed nothing, records no execution and cannot confirm whether the caller executed it.NoYes (an authorization receipt)

These ten values are the complete set: K-Block never records an action with any other status. There is no separate "outcome unknown" status; see Failed.

Decision and status are different things

Each action also has a decision, fixed when the call arrives: allow, require_approval or deny. The dashboard shows it in the Decision column as Allowed, Requires approval or Denied.

The status approved has two origins, and only the decision tells them apart:

  • decision allow: the policy allowed the call without a person. The Gateway executes it in the same request, so you rarely see it in this state for long.
  • decision require_approval: an approver approved it. It runs when the agent repeats the identical call, or while the agent is still waiting for the decision.

Lifecycle

                 ┌──> denied
                 │
 call arrives ───┼──> approved (decision allow) ──────────┐
                 │                                        │
                 └──> pending_approval ──┬──> approved ───┼──> executing ──┬──> succeeded
                                         │                │                └──> failed
                                         ├──> rejected    ├──> expired
                                         ├──> expired     └──> cancelled
                                         └──> cancelled

An action of a decision-only tool never reaches executing: when the caller asks again for an approved action, it becomes authorized instead, and its receipt covers the decision, not an execution.

denied, rejected, expired, cancelled, succeeded, failed and authorized are final: nothing moves an action out of them. An identical call made later without an idempotency key becomes a new action with a new decision. An identical call that reuses the idempotency key of a closed action gets that action's stored outcome back instead. While an action is pending_approval or approved, an identical call without an idempotency key, or with the same one, resumes it rather than creating a new one.

Transitions

FromToWhat causes it
(new call)deniedThe policy denies the call, or a check fails first: no policy, no delegation granting the action, no principal, no eligible approvers, an invalid amount, the engine refusing the evidence, and similar.
(new call)approvedThe policy allows the call (decision allow).
(new call)pending_approvalThe policy requires approval. An approval request is created with the eligible approvers and an expiry.
pending_approvalapprovedAn eligible approver signs an approval. See Review and decide.
pending_approvalrejectedAn eligible approver signs a rejection.
pending_approvalexpiredNobody decided before the request expired (APPROVAL_EXPIRED), or the action was superseded (SUPERSEDED).
pending_approval or approvedcancelledAn owner or admin submits a cancellation signed with the organization's principal key.
approvedexpiredThe approved call was not executed before the action expired (TASK_EXPIRED), or it was superseded (SUPERSEDED).
approvedexecutingThe Gateway checks everything again and consumes the approval (or the allow decision) exactly once, even when the same call arrives several times at once.
approvedauthorizedDecision only: the Gateway checks everything again, as for an execution, and hands the authorization to the caller exactly once, with a receipt.
executingsucceededThe upstream call returned a result and it was recorded.
executingfailedThe upstream reported an error or the Gateway could not complete (UPSTREAM_FAILED), or the execution was interrupted and recovered later (INTERRUPTED).

An executing action cannot be cancelled.

When actions expire

An action's expiry is set when it is decided: the rule's own approval expiry if it has one, otherwise the organization's Default approval lifetime (seconds) in Settings (24 hours unless an owner or admin changed it). It is never later than the end of the agent's delegation, nor, for a call an observe window relaxed, the end of that window. K-Block closes a due action as expired within about 15 seconds, so for those few seconds it can still show Pending approval or Approved. If the agent repeats the call first, the action is closed at once.

When actions are superseded

An open action is closed as expired with code SUPERSEDED when it can no longer run as it was decided. For example: the tool's upstream binding was changed and re-authorized, the delegation it relied on was revoked, the organization's principal identity was replaced, or (for allow decisions) the policy inputs changed. A policy rollback or emergency stop can also close open actions. The identical call then gets a new decision instead of resuming the old one.

Codes on closed actions

Expired, failed and denied actions carry an error_code that says why; rejected, cancelled and succeeded actions have none. The dashboard shows the code under the status badge and explains the common ones on the action page.

StatusCodeMeaning
expiredAPPROVAL_EXPIREDNobody decided the approval request in time. Nothing ran.
expiredTASK_EXPIREDThe call was approved, but not executed before it expired. Nothing ran.
expiredSUPERSEDEDIt could no longer run as decided (see above). Nothing ran.
failedUPSTREAM_FAILEDRecorded for every completed failure, including failures on the Gateway's side. When the Gateway detected the failure, error_detail starts with the precise code, as CODE: message.
failedINTERRUPTEDThe execution started but its outcome was never recorded (for example, the Gateway stopped). Whether the upstream acted is unknown.
denieda reason codeWhy the decision refused the call, for example POLICY_DENIED or NO_DELEGATION. When the workflow engine refused the evidence, the code is the engine's own error code.

See Error codes for every reason code.

Failed

failed means the execution started and did not end in a recorded success. Check error_code before acting:

  • UPSTREAM_FAILED means the upstream server reported an error, or the Gateway could not complete the call. A detail such as UPSTREAM_UNREACHABLE: … names the precise cause. Several of these causes do not mean that nothing happened: after a timeout, GATEWAY_ERROR, or a result that could not be accepted or recorded (RESULT_NOT_STORABLE, ATTESTATION_*, OUTPUT_*), the upstream may have acted, and RESULT_NOT_STORABLE can even follow an upstream success.
  • INTERRUPTED means the outcome is unknown: the upstream may have carried out the call. Check the upstream system before the agent retries.

K-Block recovers interrupted executions automatically: the action shows Executing until recovery marks it Failed with code INTERRUPTED, normally no later than about 15 minutes after the execution started. If an action still shows Executing long after that, contact K-Block support with the action's ID (the last part of the action page's address).

Receipts by status

A receipt is a signed record of how the action ended. It is issued for these final statuses:

StatusReceiptReceipt outcome
succeededYessucceeded
failedYes; for INTERRUPTED only when K-Block can still sign one at recoveryfailed
rejectedYesfinal
cancelledYesfinal
authorizedYes: an authorization receipt, which proves the authorization, not an executionpending (no approval was required: the receipt ends at the PROPOSAL) or granted (it ends at the person's APPROVAL)
deniedNo: nothing was signed—
expiredNo—
pending_approval, approved, executingNot yet—

The receipts list, the receipt page's header and the Receipt card on the action page show a final outcome as the action's status (Rejected or Cancelled). The Receipt card on the receipt page shows Final with the action's status beside it. An authorization receipt's pending or granted is shown as Authorized (decision only), with the signed outcome beside it on the receipt page: it is the state of the receipt's last signed object, not a request still waiting. See Receipt fields.

A receipt is hosted for the organization's retention period; after that, K-Block Cloud keeps only its record (IDs, outcome, SHA-256), and a bundle downloaded before then stays verifiable.

What the agent sees

The Gateway answers the agent with its own status names. The TypeScript client uses the Gateway's names, except that a successful call is completed.

Action statusGateway answer (status / code)Client result status
denieddenied / the reason codedenied
pending_approvalapproval_pending / APPROVAL_PENDINGapproval_pending
approvedthe call executes; a check that fails before anything is consumed answers with its own refusal (for example denied / UPSTREAM_CHANGED)—
executingreplay / EXECUTION_IN_PROGRESSreplay
succeededthe tool's result, also when the call is repeated with the same idempotency keycompleted
failedupstream_error with the recorded code, also when repeated with the same idempotency keyupstream_error
rejectedrejected / REJECTEDrejected
cancelledcancelled / CANCELLEDcancelled
expiredexpired / APPROVAL_EXPIRED, TASK_EXPIRED or SUPERSEDEDexpired
authorizedPOST /v1/authorize answers "allowed": true, status authorized, "execution": "caller"; repeated with the same idempotency key after its expires_at, "allowed": false, expired / AUTHORIZATION_EXPIREDauthorized (TypeScript authorizeAction)

For a decision-only tool, an approved action is handed to the caller (authorized) when the caller asks again, instead of executing.

A request that finds the action already executed by another request is answered replay / REPLAY. The refusals plan_limit, invalid_request, unauthorized and unavailable record no new action. See Error codes.

Approval request statuses

An action with decision require_approval has one approval request. The Approvals page shows its status with these labels:

Request statusLabelMeaning
pendingPendingWaiting for a decision
approvedApprovedOne eligible approver approved
rejectedRejectedOne eligible approver rejected
expiredExpiredIt expired, or its action was superseded (also by a policy rollback or emergency stop)
cancelledCancelledIts action was cancelled while the request was pending

One decision closes a request: there is no quorum, and the first valid decision wins.

A request stays approved after its action has run, and also when the approved action later expired, was superseded or was cancelled without running. To know whether an approved call actually ran, look at the action's status. The approval request's page shows the action's closing code (for example TASK_EXPIRED) when an approved call expired without running.

Execution statuses

The action page lists the execution, created when the Gateway consumes an approved action:

Execution statusMeaning
startedThe upstream call is in progress (the action is executing)
succeededThe upstream call succeeded
failedIt failed or was interrupted

Known display quirk

In the Actions list, the explanation shown when you hover the code UPSTREAM_FAILED says that the upstream reported an error, even when the Gateway detected the failure itself. The action page names the precise code from the start of the detail; use it.