DocumentationApplications & proxy

Proxy HOLD and resubmission

Use the correct approval contract for held requests and generated tool calls.

Updated 2026-09-22 Read as Markdown
On this page

Two approval boundaries

A pre-request HOLD can stop the request before forwarding it to the model. A post-inference tool-call HOLD concerns a generated action after a provider response exists. Their replay rules are different; do not treat a retried model request as deterministic tool execution.

Async pre-request HOLD

Send these headers on the original request:

X-Kastra-Hold-Mode: async
X-Kastra-Operation-Id: one-stable-id-per-user-action

A matching supported HOLD returns HTTP 202, X-Policy-Decision: HOLD, and a provider-shaped error with code hold_pending, checkpoint information, and resubmission guidance. Retain the checkpoint ID. The action has not been authorized by the fact that the server accepted the request.

Read checkpoint status using the original authorized credential. An authorized human resolves the checkpoint. Proceed only after its effective decision permits it; handle denial, expiry, cancellation, and abandonment explicitly.

Resubmit the identical action

Keep the original request bytes, API key, environment, request path, effective principal/customer, canonical policy attributes, and operation ID unchanged. JSON reformatting can change the replay identity. Assign a new operation ID to each distinct user action, and reuse that ID only for its post-approval resubmission.

The current implementation binds approval replay to those request dimensions and consumes an approval once. This does not authenticate a caller-supplied principal; credential identity binding remains a separate concern. Idempotency-Key and X-Kastra-Operation-Id serve different purposes and are not substitutes.

Waiting and post-inference holds

Without async mode, a supported request HOLD may wait within the server’s bounded surface timeout. A wait timeout is not necessarily the checkpoint’s final outcome. Inspect checkpoint status before retrying.

Post-inference tool-call holds authorize a specific generated call and use a separate replay identity. The upstream model can generate a different call on a retry; that call needs its own evaluation. Do not claim that async request headers make every output HOLD resumable under the same contract.

Verify before rollout

Test two identical prompts from different users sharing an API key, two distinct actions from the same user, changed context on retry, and duplicate resubmission. Confirm that approval for one action cannot silently authorize another. These behaviors require a server version containing the current replay-identity implementation.

Self-hosted execution journal profile

The assisted appliance workflow can enable a durable execution journal for bounded non-streaming requests, one pre-inference approval stage, timeout denial and no post-inference approval. In this profile, X-Kastra-Operation-Id must be a canonical UUID. Preserve it and the exact request bytes across the original pending review and its resume.

Inspect X-Kastra-Execution-State and the operation record. Current OWNER/ADMIN members can inspect GET /api/v1/proxy-executions/{operationID} and reconcile uncertain outcomes with POST /api/v1/proxy-executions/{operationID}/reconcile, supplying outcome and evidence_reference. The supported outcomes are confirmed_executed and confirmed_not_executed. Reconciliation records the operator’s evidence; it does not authorize replay.

Terminal, uncertain, reconciled and restored operations never dispatch again under the same operation identity. completed means the server observed a complete successful upstream response and recorded the governed response; it does not attest delivery to the client. This profile is opt-in and self-hosted only, not a guarantee for ordinary SaaS proxy retries. Appliance status and qualification.