Decisions and recovery
guard.admit() returns { decision, context? }. A decision contains action, reason, requestId, policyVersion and applicable retryAfterSeconds. The guard emits allow, limit, unavailable or block. An enforced deny rule for a verified crawler can emit block; applications can also pass a block decision to sendDenial().
The Node adapter and sendDenial() use compact { code, requestId } bodies:
| HTTP / code | Cause | Recovery |
|---|---|---|
429 / CRAWLER_LIMIT | Rate budget exhausted | Honor Retry-After; do not rotate IP/identity to evade it. |
503 / CRAWLER_UNAVAILABLE | Admission cannot complete safely, ingress is untrusted or work capacity is exhausted | Honor retry guidance and investigate the decision reason. Protected work must not run. |
403 / CRAWLER_BLOCK | An enforced crawler deny rule or an application-defined block | Resolve policy; repetition does not grant access. |
Reasons include rate_budget_exhausted, admission_unavailable, local_work_unavailable, work_store_unavailable and work_capacity_exhausted. Work rejection throws AdmissionError, not the main SDK's ValironError. Rejections include Cache-Control: no-store; ensure the CDN does not cache caller-specific denials.
Gateway and private work API errors
The gateway also returns { code } for proxy-specific failures: 400 INVALID_GATEWAY_REQUEST, 408 REQUEST_BODY_TIMEOUT, 413 REQUEST_TOO_LARGE, 503 GATEWAY_BODY_BUSY or ORIGIN_CAPACITY_EXHAUSTED, 502 for incomplete/failed origin connections, and 504 ORIGIN_TIMEOUT. WebSocket upgrades return 426 and Expect/Continue returns 417. Failed admission does not forward the request. A timeout after forwarding can leave live origin work and retains its hold; repeating requests must not reclaim it.
The private work API requires service authentication and a valid signed request capability for acquisition. Invalid authentication returns 401; invalid capability scope/expiry returns 403; invalid JSON/fields return 400; oversized bodies return 413; non-JSON bodies return 415. Capacity, fanout and dependency failures return 503. Acquire only starts the operation on HTTP 200. Do not retry an ambiguous acquisition automatically. Release requires the returned permit and confirmed settlement; cross-worker release is idempotent. The exact contract is shipped in gateway/work-api.openapi.json inside the npm package; these endpoints are not part of Valiron's hosted public REST API.
Work holds do not expire automatically. A crash, client disconnect or HTTP timeout must not free capacity while a query might remain alive. Release follows actual operation settlement. For Node callback wrappers, a release error preserves the operation result, leaves the hold and emits work_release_failed through the decision callback. The Python helper surfaces release failures; its context manager is suitable only when returning/raising means the query stopped. For asynchronous drivers, acquire explicitly and release after confirmed completion or cancellation. Managed mode exposes hold inventory, pause, exact-ID reconciliation with confirmed-drain evidence, drained policy activation and resume. Reclaim orphaned holds only after admission is stopped and affected work is confirmed stopped. Missing control state or a mismatched policy fails closed. These controls do not prove that an old query stopped; that confirmation remains operational. Measured DB outcomes can open a shared catalog circuit; controlled probes and explicit recovery preserve shopper/checkout reservations.
Validation boundary
A real Python HTTP origin executing SQLite queries is tested behind gateway/broker replicas, including pre-query rejection, shared limits, scoped capabilities, incomplete uploads, timeouts, truncated responses and disconnects. The protocol is database-independent, but these results do not prove every language, framework, driver, hosted platform or database has been tested.
Local tests cover spoof rejection, source parsing, middleware, shared Redis contention, operation bounds, dependency failure and retention of capacity after disconnect. An isolated Nuxt 4.1.3/Nitro Vue SSR → Node → MariaDB 10.11.8 fixture additionally covers physical checkout pools, actual SQL timeout/disconnect/process-death recovery, cache storms, replay/fanout and Redis outages. A controlled live website test exercised custom crawler requests, source-claim rejection, shared execution counters and refill around a real public-document read. The website test alone does not establish real crawler acceptance, search visibility or Meta previews. Local database results do not establish customer-scale capacity.
Validate every rendering/API/background path, cache behavior, actual query cancellation, store recovery and shopper latency under representative peak load before opening access broadly.
Related: Quickstart, SDK reference, Agent identity, Errors.