{"openapi":"3.1.0","info":{"title":"Wicked Sanity","description":"Pay-per-call hallucination / eval-check API for agents mid-loop. 'grounded' mode checks faithfulness to supplied context (a solved, scoreable problem). 'open' mode checks consistency with live web evidence found at request time, which is not the same as objective truth. See README for the full scope and limitations.","version":"0.1.0"},"paths":{"/check":{"post":{"tags":["check"],"summary":"Verify one claim","description":"Verify a single claim before you act on it. **grounded**: faithfulness to the `context` you supply (real HHEM-2.1-Open entailment inference). **open**: consistency with live web evidence retrieved at request time via Tavily, then the same entailment model -- this is NOT objective truth, and returns `insufficient_evidence` when nothing relevant is found. Free with a valid `x-api-key` (rate-limited); otherwise a real x402 `402` challenge (USDC, see `GET /v1/status`).","operationId":"post_check_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckRequest"}}},"required":true},"responses":{"200":{"description":"Verdict(s) computed by real model inference at request time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckEnvelope"}}}},"401":{"description":"No valid `x-api-key` and x402 payments are not configured on this deployment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment Required (x402). Keyless callers get this challenge: the base64 JSON payment requirements are in the `payment-required` response header (scheme `exact`, USDC, see `GET /v1/status` for network/price). The amount is a per-request base fee plus a price per claim checked (open mode has its own per-claim price) and is computed from the request body, so retry with the SAME body. Sign the EIP-3009 authorization and retry the same request with an `X-PAYMENT` header; any x402 client SDK does this automatically."},"422":{"description":"Invalid request body (e.g. missing context for grounded mode).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded for this `x-api-key`; honour the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/check/batch":{"post":{"tags":["check"],"summary":"Verify up to 50 claims against shared context","description":"Same as `POST /check`, for a multi-sentence output: check 1-50 claims against one shared `context` in a single call (one payment / one rate-limit hit). Grounded-mode claims are scored in batched model passes; open mode runs one live search per claim. Results are returned in input order.","operationId":"post_check_batch_check_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckBatchRequest"}}},"required":true},"responses":{"200":{"description":"Verdict(s) computed by real model inference at request time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckBatchEnvelope"}}}},"401":{"description":"No valid `x-api-key` and x402 payments are not configured on this deployment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment Required (x402). Keyless callers get this challenge: the base64 JSON payment requirements are in the `payment-required` response header (scheme `exact`, USDC, see `GET /v1/status` for network/price). The amount is a per-request base fee plus a price per claim checked (open mode has its own per-claim price) and is computed from the request body, so retry with the SAME body. Sign the EIP-3009 authorization and retry the same request with an `X-PAYMENT` header; any x402 client SDK does this automatically."},"422":{"description":"Invalid request body (e.g. missing context for grounded mode).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded for this `x-api-key`; honour the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/checks/{check_id}":{"get":{"tags":["check"],"summary":"Retrieve a prior check","description":"Fetch the full stored result of an earlier check, for audit/dispute. Scoped to the `x-api-key` that created it (404 for anyone else). Keyless x402 payers already receive the full result inline in the POST response and cannot re-fetch it by id in v1.","operationId":"get_check_checks__check_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"check_id","in":"path","required":true,"schema":{"type":"string","title":"Check Id"}}],"responses":{"200":{"description":"The stored check.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckEnvelope"}}}},"404":{"description":"No such check for this caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/status":{"get":{"summary":"V1 Status","operationId":"v1_status_v1_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"CheckBatchEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CheckResponse"},"type":"array","title":"Data","description":"One result per input claim, in the same order."},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"type":"object","required":["data","meta"],"title":"CheckBatchEnvelope"},"CheckBatchRequest":{"properties":{"claims":{"items":{"type":"string"},"type":"array","maxItems":50,"minItems":1,"title":"Claims","description":"1-50 claims, all checked against the same shared `context`."},"context":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Context","description":"Source text the claim must be faithful to: a string, or a list of strings (joined). Required for `grounded`, ignored for `open`. Max 100,000 characters total."},"mode":{"type":"string","enum":["grounded","open"],"title":"Mode","description":"`grounded`: check the claim against the `context` you supply (context is required). `open`: check the claim against live web evidence retrieved at request time (context is ignored) -- consistency with current web content, NOT objective truth.","default":"grounded"}},"type":"object","required":["claims"],"title":"CheckBatchRequest","examples":[{"claims":["The Eiffel Tower is in Paris.","The Eiffel Tower is in Berlin."],"context":"The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.","mode":"grounded"}]},"CheckEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/CheckResponse"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"type":"object","required":["data","meta"],"title":"CheckEnvelope"},"CheckRequest":{"properties":{"claim":{"type":"string","minLength":1,"title":"Claim","description":"The single claim to verify."},"context":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Context","description":"Source text the claim must be faithful to: a string, or a list of strings (joined). Required for `grounded`, ignored for `open`. Max 100,000 characters total."},"mode":{"type":"string","enum":["grounded","open"],"title":"Mode","description":"`grounded`: check the claim against the `context` you supply (context is required). `open`: check the claim against live web evidence retrieved at request time (context is ignored) -- consistency with current web content, NOT objective truth.","default":"grounded"}},"type":"object","required":["claim"],"title":"CheckRequest","examples":[{"claim":"The Eiffel Tower is in Paris.","context":"The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.","mode":"grounded"},{"claim":"Antonio Guterres is the current UN Secretary-General.","mode":"open"}]},"CheckResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Check id. Retrievable later via GET /checks/{id} with the same x-api-key."},"verdict":{"type":"string","enum":["supported","unsupported","contradicted","insufficient_evidence"],"title":"Verdict","description":"`supported`: consistent with the context/evidence. `contradicted`: clearly inconsistent with it. `unsupported`: not supported but not clearly contradicted (ambiguous -- treat as unverified). `insufficient_evidence`: nothing usable was found to check against (open mode) -- NOT a verdict on the claim's truth either way."},"confidence_score":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence Score","description":"The raw HHEM consistency score in [0, 1] for (context/evidence, claim): near 1.0 = the claim is consistent with the source, near 0.0 = inconsistent. It is NOT confidence-in-the-verdict: a `contradicted` verdict will have a score near 0. It is 0.0 when `insufficient_evidence` (no score was computed)."},"evidence":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Evidence","description":"Audit trail: the supplied-context snippet (grounded), or the Tavily citations (url, title, content, relevance_score) plus the evidence text actually scored (open)."},"model_used":{"type":"string","title":"Model Used","description":"Exact model + pinned revision that produced this verdict."},"latency_ms":{"type":"integer","title":"Latency Ms","description":"Server-side scoring time. For batch items: the whole batch call's time."},"checked_at":{"type":"string","format":"date-time","title":"Checked At"}},"type":"object","required":["id","verdict","confidence_score","evidence","model_used","latency_ms","checked_at"],"title":"CheckResponse"},"ErrorResponse":{"properties":{"error":{"type":"string","title":"Error"},"source":{"type":"string","title":"Source","description":"Where the error originated, e.g. `auth`, `validation`, `server`."}},"type":"object","required":["error","source"],"title":"ErrorResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ResponseMeta":{"properties":{"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Count","description":"Number of results (batch only)."}},"additionalProperties":true,"type":"object","required":["timestamp"],"title":"ResponseMeta"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"Optional. A valid key gives free, rate-limited access. Without one, pay per call via x402.","in":"header","name":"x-api-key"}}}}