{"openapi": "3.0.3", "info": {"title": "Outcome-verified watchdog for scheduled agents", "version": "1.0.0", "description": "Your cron fired. Your agent reported success. The exit code was 0. And the work never happened. Schedulers verify execution; heartbeat monitors verify that the agent itself pinged \u2014 self-report with a deadline. Neither ever looks at the work. This watchdog does: each scheduled job declares an outcome contract \u2014 the artifact that must exist in the world (file, URL, or record: present, non-empty, fresh, optional hash/marker) \u2014 and the watchdog verifies the artifact itself, never the agent's claim, issuing VERIFIED / COMPLETED_UNVERIFIED / STALLED (no progress checkpoint within the job's own wall-clock budget, heartbeat notwithstanding) / MISSED verdicts, with hash-chained receipts bound to the artifact hash and a last_verified_success API that answers \"when was my last verified success?\". Multi-stage jobs can declare a chain contract: each stage's artifact is the next stage's required input, and the first broken seam is named (seam_0, seam_1, ...). A VERIFIED verdict means the watchdog itself fetched, hashed, or read back the declared artifact and found it present, non-empty, and fresh within the run window \u2014 it does not guarantee that a VERIFIED artifact is correct in content beyond the contract's declared checks (existence, non-emptiness, freshness, optional hash/marker/key); contract design is the operator's. The roughly 29% dead-job rate in the launch evidence was reproduced on an evidence-shaped synthetic fleet; it is NOT a field measurement \u2014 the live-fleet census recorded by this service is census v2, a FIELD MEASUREMENT: verdicts computed from each real job's own systemd scheduler record and its real outcome artifact - no fixture jobs were registered, shaped, or run. Its latest run (2026-10-22) enumerated 135 live timers, evaluated 101 due jobs, and measured a dead rate of 0.0099 (verified rate 0.9901); it is published in its monitoring with its method and label. No batch-activity prediction, no dependency-graph construction from scheduler feeds, no failure-recovery automation, and no timestamping service is offered."}, "servers": [{"url": "https://textforagents.com/products/scheduled-agent-outcome-verification"}], "components": {"securitySchemes": {"bearer": {"type": "http", "scheme": "bearer"}}}, "paths": {"/health": {"get": {"summary": "health", "responses": {"200": {"description": "ok"}}}}, "/register": {"post": {"summary": "register an operator account \u2014 returns a one-time claim token; body {name, payer_wallet?, alert_webhook?}", "responses": {"201": {"description": "account + claim_token"}}}}, "/trial/claim": {"post": {"summary": "claim the API token; binds the one-time trial grant (first 100 checks free, once per operator, account + payer wallet bound)", "responses": {"200": {"description": "token + trial state"}}}}, "/artifacts/{path}": {"put": {"security": [{"bearer": []}], "summary": "place a file/record artifact in your scoped artifact store (max 10 MB; traversal/absolute/symlink paths rejected)", "responses": {"200": {"description": "stored with sha256"}}}}, "/verify": {"post": {"summary": "verify an Ed25519-signed verdict receipt (free); body {signed_receipt}", "responses": {"200": {"description": "valid + key fingerprint"}}}}, "/verify-key": {"get": {"summary": "accepted signing-key fingerprints (current + archived)", "responses": {"200": {"description": "keys"}}}}, "/subscribe": {"post": {"security": [{"bearer": []}], "summary": "Operator plan $9/mo (<=100 jobs, hourly cadence cap, 72,000 checks/mo included ceiling) or Fleet plan $29/mo (<=1,000 jobs, hourly cap, 720,000 ceiling); body {tier}", "responses": {"200": {"description": "plan active"}, "402": {"description": "x402 challenge"}}}}, "/account": {"get": {"security": [{"bearer": []}], "summary": "own account state (trial, plan, jobs, checks)", "responses": {"200": {"description": "account"}}}}, "/account/alert": {"post": {"security": [{"bearer": []}], "summary": "set the operator alert webhook \u2014 verdicts needing a human (COMPLETED_UNVERIFIED, STALLED, MISSED) are POSTed there and every delivery attempt is recorded; body {webhook}", "responses": {"200": {"description": "webhook set"}}}}, "/alerts": {"get": {"security": [{"bearer": []}], "summary": "own recorded alert delivery attempts", "responses": {"200": {"description": "alerts"}}}}, "/tokens/rotate": {"post": {"security": [{"bearer": []}], "summary": "rotate own API token (old token revoked in the same call)", "responses": {"200": {"description": "new token"}}}}, "/tokens/revoke": {"post": {"security": [{"bearer": []}], "summary": "revoke own API token", "responses": {"200": {"description": "revoked"}}}}, "/account/data": {"delete": {"security": [{"bearer": []}], "summary": "delete own account data (jobs/runs/artifacts removed, token revoked)", "responses": {"200": {"description": "deleted"}}}}, "/mcp": {"post": {"summary": "MCP surface (initialize / tools/list / tools/call \u2014 the 8 watchdog tools) \u2014 same billing as REST, Bearer token required for tools/call", "responses": {"200": {"description": "JSON-RPC"}}}}, "/tools/register_job": {"post": {"security": [{"bearer": []}], "summary": "Register a scheduled job with an outcome contract (file / URL / record, present + non-empty + fresh, optional hash/marker \u2014 or a chain contract whose stages' artifacts are the next stage's required input). Args: job_id, contract, stall_budget_s?, due_in_s?, alert via account webhook.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/start_run": {"post": {"security": [{"bearer": []}], "summary": "Start a run for a job. Args: job_id.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/checkpoint": {"post": {"security": [{"bearer": []}], "summary": "Report run progress \u2014 the watchdog watches progress checkpoints against the job's own wall-clock budget, never process existence. Args: run_id, note?.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/complete_run": {"post": {"security": [{"bearer": []}], "summary": "Claim completion; the watchdog verifies the declared artifact itself (the claim is never trusted) and issues a signed, hash-chained verdict receipt. Metered check ($0.002 after the one-time 100-check trial / plan rules). Args: run_id, claimed?.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/verify_now": {"post": {"security": [{"bearer": []}], "summary": "Spot-verify a job's artifact now (independent fetch/hash/read-back by the watchdog). Metered check ($0.002 after trial / plan rules). Args: job_id.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/watchdog_tick": {"post": {"security": [{"bearer": []}], "summary": "Run the watchdog sweep: STALLED for active runs with no progress checkpoint inside the job's wall-clock budget, MISSED once per due window with no verified run. Not metered.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/last_verified_success": {"post": {"security": [{"bearer": []}], "summary": "When was this job's last VERIFIED success, and how old is it? Args: job_id.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}, "/tools/list_verdicts": {"post": {"security": [{"bearer": []}], "summary": "List this operator's signed verdict receipts + receipt-chain re-verification result.", "responses": {"200": {"description": "tool result"}, "402": {"description": "x402 challenge"}}}}}}