{"openapi":"3.1.0","info":{"title":"VerifiedOS Agent API","version":"2.0.0","description":"Deterministic proof-of-claim verification with immutable, hash-chained receipts for compliance and audit. Public tier — authenticate for the complete surface.","x-manifest-version":"3.1.0","x-generated-at":"2026-09-02T13:59:26.534Z"},"servers":[{"url":"https://verifiedos.ai/api/v1"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Bearer vfy_… key or issued access_token"}}},"security":[],"paths":{"/api/v1/health":{"get":{"summary":"Service health and readiness probe for agent circuit breakers.","description":"Service health and readiness probe for agent circuit breakers.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}}}},"/api/v1/auth/signup":{"post":{"summary":"Start passwordless signup. Creates an OTP challenge; does NOT yet create tenant resources or keys. The OTP is delivered to the contact; in local development (SIGNUP_DEV_OTP_ENABLED=1) it is returned inline as development_otp_code and in production never is.","description":"Start passwordless signup. Creates an OTP challenge; does NOT yet create tenant resources or keys. The OTP is delivered to the contact; in local development (SIGNUP_DEV_OTP_ENABLED=1) it is returned inline as development_otp_code and in production never is.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"owner_first_name":{"type":"string","description":"string (required)"},"owner_last_name":{"type":"string","description":"string (required)"},"owner_email":{"type":"string","description":"string (optional, max 254)"},"owner_phone":{"type":"string","description":"string (optional, max 40)"},"workspace_name":{"type":"string","description":"string (optional, max 160)"},"initial_plan":{"type":"string","description":"free | plus | pro (default free)"}}}}}}}},"/api/v1/auth/signup/verify":{"post":{"summary":"Verify the signup OTP to create tenant resources and bootstrap credentials. THIS is the step that returns your API key.","description":"Verify the signup OTP to create tenant resources and bootstrap credentials. THIS is the step that returns your API key.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"signup_session_id":{"type":"string","description":"string (required, from signup)"},"otp_code":{"type":"string","description":"string (required, exactly 6 digits)"}}}}}}}},"/api/v1/auth/login":{"post":{"summary":"Optional: exchange an existing vfy_ API key for a short-lived bearer access token. Not required for verification — protected routes accept the raw vfy_ key as Bearer directly.","description":"Optional: exchange an existing vfy_ API key for a short-lived bearer access token. Not required for verification — protected routes accept the raw vfy_ key as Bearer directly.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string","description":"string (required, format vfy_…)"}}}}}}}},"/api/v1/verify":{"post":{"summary":"Submit a claim and evidence for deterministic proof-of-claim verification. This is the core operation (claims surface). The response's X-Request-ID header is the request_id for GET /api/v1/verify/{request_id}.","description":"Submit a claim and evidence for deterministic proof-of-claim verification. This is the core operation (claims surface). The response's X-Request-ID header is the request_id for GET /api/v1/verify/{request_id}.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claim_text":{"type":"string","description":"string (required, max 8000 chars)"},"evidence_text":{"type":"string","description":"string (required, max 16000 chars)"},"idempotency_key":{"type":"string","description":"string (required, 1-128 chars — safe retries)"},"metadata":{"type":"string","description":"object (optional, serialized ≤ 4000 chars)"}}}}}}}},"/api/v1/verify/{request_id}":{"get":{"summary":"Fetch a verification result by request id (async / polling pattern). This is the DECISIONS surface: the stored adjudication outcome for a submitted claim. Use the X-Request-ID header from the POST /api/v1/verify response.","description":"Fetch a verification result by request id (async / polling pattern). This is the DECISIONS surface: the stored adjudication outcome for a submitted claim. Use the X-Request-ID header from the POST /api/v1/verify response.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/mcp-verifications":{"post":{"summary":"Verify an agent ACTION: submit an MCP server/tool-call manifest and receive a deterministic security verdict (analysis → evidence → judge → adjudication → proof-of-claim). evidence_text must contain the MCP manifest as JSON (plain or fenced).","description":"Verify an agent ACTION: submit an MCP server/tool-call manifest and receive a deterministic security verdict (analysis → evidence → judge → adjudication → proof-of-claim). evidence_text must contain the MCP manifest as JSON (plain or fenced).","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claim_text":{"type":"string","description":"string (required, max 4096 chars)"},"evidence_text":{"type":"string","description":"string (required, max 65536 chars — the MCP manifest JSON)"},"idempotency_key":{"type":"string","description":"string (required, 1-128 chars)"},"metadata":{"type":"string","description":"object (optional)"}}}}}}}},"/api/v1/mcp-receipts/{receipt_id}":{"get":{"summary":"Fetch the persisted proof-of-claim for an ACTION verification (the receipt_url returned by POST /api/v1/mcp-verifications). Tenant-scoped, auditable.","description":"Fetch the persisted proof-of-claim for an ACTION verification (the receipt_url returned by POST /api/v1/mcp-verifications). Tenant-scoped, auditable.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/receipts":{"get":{"summary":"Query your immutable, hash-chained proof receipts (claims, decisions, and action verifications).","description":"Query your immutable, hash-chained proof receipts (claims, decisions, and action verifications).","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized — invalid or missing credentials"},"429":{"description":"Rate limited — obey Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"seconds"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"unix timestamp"}}}},"security":[{"bearerAuth":[]}]}}},"x-quickstart":{"step_1_start_signup":"POST /api/v1/auth/signup — passwordless (owner name + email or phone + workspace). Response returns signup_session_id; the OTP is delivered to the contact. In local development (SIGNUP_DEV_OTP_ENABLED=1) the response also returns development_otp_code; in production it never does.","step_2_verify_otp_get_credentials":"POST /api/v1/auth/signup/verify with { signup_session_id, otp_code }. THIS returns your API key (vfy_…) and access_token. Already have a key? Skip to step 3 — protected routes accept Bearer <vfy_ key> directly, no login required.","step_3_verify_a_claim":"POST /api/v1/verify with claim_text + evidence_text + idempotency_key. Response carries receipt_id + public_result; the X-Request-ID response header is your request_id for step 4.","step_4_verify_decisions_and_actions":"DECISIONS: GET /api/v1/verify/{request_id} to fetch the stored adjudication outcome, or GET /api/v1/receipts/{receipt_id} to audit the proof record. ACTIONS: POST /api/v1/mcp-verifications with an MCP tool-call manifest in evidence_text to get a deterministic security verdict.","minimal_example":"# ── 1. sign up (passwordless) ─────────────────────────────\ncurl -X POST https://verifiedos.ai/api/v1/auth/signup \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -d '{\"owner_first_name\":\"Ada\",\"owner_last_name\":\"Agent\",\"owner_email\":\"ada@example.com\",\"workspace_name\":\"ada-lab\"}'\n# → signup_session_id: sgn_…  (dev: development_otp_code returned inline)\n\n# ── 2. verify OTP → receive API key + token ───────────────\ncurl -X POST https://verifiedos.ai/api/v1/auth/signup/verify \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -d '{\"signup_session_id\":\"sgn_…\",\"otp_code\":\"123456\"}'\n# → api_key: vfy_… , access_token: oauth_…\n\n# ── 3. verify a claim (idempotent; Bearer = the vfy_ key) ──\ncurl -X POST https://verifiedos.ai/api/v1/verify \\\\\n  -H \"Authorization: Bearer vfy_…\" \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -d '{\"claim_text\":\"Water boils at 100C at sea level\",\"evidence_text\":\"NIST SP 220: ...\",\"idempotency_key\":\"'\"$(uuidgen)\"'\"}'\n# → receipt_id + public_result + attempt_terminal_outcome; header X-Request-ID → req_…\n\n# ── 4a. fetch the decision (adjudication outcome) ──────────\ncurl https://verifiedos.ai/api/v1/verify/req_… -H \"Authorization: Bearer vfy_…\"\n# 4b. verify an action (MCP tool-call manifest)\ncurl -X POST https://verifiedos.ai/api/v1/mcp-verifications \\\\\n  -H \"Authorization: Bearer vfy_…\" -H \"Content-Type: application/json\" \\\\\n  -d '{\"claim_text\":\"tool call is safe\",\"evidence_text\":\"{\\\"name\\\":\\\"filesystem\\\",\\\"version\\\":\\\"1.0.0\\\",\\\"tools\\\":[]}\",\"idempotency_key\":\"'\"$(uuidgen)\"'\"}'"},"x-compliance":{"data_classes_processed":["claim text you submit","evidence text you submit","MCP manifests you submit for action verification","derived verification verdicts and confidence scores","identity: account email, workspace name","billing: wallet balance and transaction records"],"immutable_ledger":"Every verification (claims and MCP action verifications) produces a receipt bound into a hash chain. Receipts are tamper-evident and available for audit.","audit_log_availability":"Every API action that mutates state (verifications, key provisioning, profile changes) writes an immutable audit event.","retention":"Receipts and audit events are retained for audit purposes; sandbox data purged weekly.","deletion":"Contact the operator for account deletion; immutable ledger entries are retained as required for non-repudiation.","residency":"US-East (primary data region).","non_repudiation":"Hash-chained receipts mean neither party can deny a verified claim, decision, or action after the fact."},"x-rate-limit-policy":"Rate limits are enforced per key and returned on every 429 via Retry-After (seconds) and X-RateLimit-Limit/Remaining/Reset headers. Back off on 429; do not pre-compute numeric budgets."}