{"openapi":"3.1.0","info":{"title":"Faro","summary":"A trust API: one red/yellow/green verdict for URLs, payees, and messages.","description":"\nFaro returns **one consistent verdict** — 🟢 green, 🟡 yellow, or 🔴 red — for a\nURL, a payee, or a message, with a plain-language `reason` and a\n`recommended_action` (`allow` / `warn` / `block` / `review`).\n\nA verdict is computed in tiers: fast deterministic checks (Google Safe Browsing,\ndomain age via RDAP, sanctions screening, global payment-handle format) decide the\nclear cases, and an LLM reasons only about the genuinely ambiguous ones — so most\ncalls never touch the model and stay fast and cheap.\n\n**Auth.** Send your key as `Authorization: Bearer <key>`.\n**Caching.** Responses carry `X-Faro-Cache: hit|miss`; every response carries\n`X-Request-ID`.\n","contact":{"name":"Faro","url":"https://farofinance.app/"},"license":{"name":"Proprietary"},"version":"1.3.0"},"paths":{"/v1/pages/claims":{"post":{"tags":["Suite"],"summary":"Start a page claim","operationId":"start_claim_v1_pages_claims_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/claims/{claim_id}/prove":{"post":{"tags":["Suite"],"summary":"Prove control (soft auto-verifies on claim; strict checks DNS TXT)","operationId":"prove_v1_pages_claims__claim_id__prove_post","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProveIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProveOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/claims/{claim_id}/cloudflare/authorize":{"get":{"tags":["Suite"],"summary":"Start Cloudflare OAuth for domain control (scaffold)","operationId":"cloudflare_authorize_v1_pages_claims__claim_id__cloudflare_authorize_get","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cloudflare Authorize V1 Pages Claims  Claim Id  Cloudflare Authorize Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/cloudflare/callback":{"get":{"tags":["Suite"],"summary":"Cloudflare OAuth callback (scaffold)","operationId":"cloudflare_callback_v1_pages_cloudflare_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cloudflare Callback V1 Pages Cloudflare Callback Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/claims/{claim_id}/cloudflare/verify":{"post":{"tags":["Suite"],"summary":"Verify faro-verify TXT via DNS (Cloudflare DoH)","operationId":"cloudflare_verify_v1_pages_claims__claim_id__cloudflare_verify_post","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProveOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/claims/{claim_id}/checks":{"post":{"tags":["Suite"],"summary":"Run sector registry checks via the verify engine","operationId":"checks_v1_pages_claims__claim_id__checks_post","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChecksOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages":{"post":{"tags":["Suite"],"summary":"Publish a Faro page (consent)","operationId":"publish_v1_pages_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Suite"],"summary":"List recently published pages","operationId":"list_pages_v1_pages_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":40,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Pages V1 Pages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pages/{slug}":{"get":{"tags":["Suite"],"summary":"Public page standing","operationId":"get_page_v1_pages__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagePublicOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agents":{"post":{"tags":["Suite"],"summary":"Register a business agent","operationId":"create_agent_v1_agents_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agents/{agent_id}":{"get":{"tags":["Suite"],"summary":"Agent binding lookup","operationId":"get_agent_v1_agents__agent_id__get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guard/checkout":{"post":{"tags":["Suite"],"summary":"Checkout gate — payee + optional buyer agent","operationId":"guard_checkout_v1_guard_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardCheckoutIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Guard Checkout V1 Guard Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/index":{"get":{"tags":["Suite"],"summary":"Trust Index v0 aggregate","operationId":"trust_index_v1_index_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexOut"}}}}}}},"/v1/keepers/cohorts/current":{"get":{"tags":["Suite"],"summary":"Active Keepers cohort","operationId":"current_cohort_v1_keepers_cohorts_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Current Cohort V1 Keepers Cohorts Current Get"}}}}}}},"/v1/keepers/cohorts/{cohort_id}/join":{"post":{"tags":["Suite"],"summary":"Join a Keepers cohort","operationId":"join_cohort_v1_keepers_cohorts__cohort_id__join_post","parameters":[{"name":"cohort_id","in":"path","required":true,"schema":{"type":"string","title":"Cohort Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeeperJoinIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Join Cohort V1 Keepers Cohorts  Cohort Id  Join Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/club/{slug}/badge":{"get":{"tags":["Suite"],"summary":"Live Club / Verified badge (SVG or JSON)","operationId":"club_badge_v1_club__slug__badge_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"svg","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/entitlements":{"post":{"tags":["Suite"],"summary":"Upsert billing entitlement (admin or billing webhook)","operationId":"upsert_entitlement_v1_billing_entitlements_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upsert Entitlement V1 Billing Entitlements Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Suite"],"summary":"List entitlements for email","operationId":"list_entitlements_v1_billing_entitlements_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Entitlements V1 Billing Entitlements Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["System"],"summary":"Liveness check","description":"Returns `{\"status\": \"ok\"}` when the service is up. No auth required.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}},"/v1/verify/url":{"post":{"tags":["Verify"],"summary":"Verify a URL","description":"Check a link before visiting, sharing, or acting on it. Runs Google Safe Browsing and a domain-age (RDAP) check, and — only when those are inconclusive — an LLM that reasons about brand impersonation and deceptive intent.","operationId":"verify_url_v1_verify_url_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValueIn"},"examples":{"clean":{"summary":"A well-known site","value":{"value":"https://www.google.com"}},"phishing":{"summary":"A KYC-impersonation phishing link","value":{"value":"http://sbi-kyc-update.xyz/verify"}}}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"green":{"summary":"A clean, well-established link","value":{"verdict":"green","confidence":0.8,"artifact":{"type":"url","value":"https://www.google.com"},"reason":"No safety problems found for this link.","recommended_action":"allow","signals":[{"name":"safe_browsing_clean","severity":"info","detail":"No Google Safe Browsing match.","source":"safe_browsing"},{"name":"domain_age_days","severity":"info","detail":"Domain has been registered for 9863 day(s).","source":"rdap"}],"request_id":"b1946ac92492d2347c6235b4d2611184","cached":false,"first_seen":"2026-06-01T09:12:44Z","checked_at":"2026-06-19T11:30:05Z"}},"red":{"summary":"A confirmed phishing link","value":{"verdict":"red","confidence":0.97,"artifact":{"type":"url","value":"http://sbi-kyc-update.xyz/verify"},"reason":"Google Safe Browsing flags this URL as Social Engineering.","recommended_action":"block","signals":[{"name":"safe_browsing_threat","severity":"critical","detail":"Google Safe Browsing flags this URL as Social Engineering.","source":"safe_browsing"},{"name":"domain_age_days","severity":"high","detail":"Domain was registered only 3 day(s) ago.","source":"rdap"}],"request_id":"3c59dc048e8850243be8079a5c74d079","cached":false,"first_seen":"2026-06-19T11:31:10Z","checked_at":"2026-06-19T11:31:10Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/payee":{"post":{"tags":["Verify"],"summary":"Verify a payee","description":"Check a payee before sending money. Detects the payment-handle format across global rails (UPI, Venmo, Cash App, Pix, IBAN, email/phone) for transparency, screens against sanctions and OffshoreLeaks, and enriches business names with GLEIF (LEI) and GDELT adverse media. **Honest note:** Faro does not confirm an account exists or belongs to anyone — it reads public signals and advises. Format detection is always informational.","operationId":"verify_payee_v1_verify_payee_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValueIn"},"examples":{"upi":{"summary":"A UPI VPA (India)","value":{"value":"ramesh@okaxis"}},"venmo":{"summary":"A Venmo username (US)","value":{"value":"@jane-doe-99"}},"cashapp":{"summary":"A Cash App $cashtag (US)","value":{"value":"$JaneDoe"}},"sanctioned":{"summary":"A sanctioned name","value":{"value":"Vladimir Putin"}},"business":{"summary":"A legal entity name (GLEIF + enrichment)","value":{"value":"Apple Inc."}}}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"green":{"summary":"A business with a verified LEI","value":{"verdict":"green","confidence":0.85,"artifact":{"type":"payee","value":"Apple Inc."},"reason":"No safety problems found. Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","recommended_action":"allow","signals":[{"name":"payee_format","severity":"info","detail":"Not a recognized payment-handle format; treated as a name or other identifier.","source":"payee_format"},{"name":"sanctions_clean","severity":"info","detail":"No sanctions-list match for this payee name.","source":"opensanctions"},{"name":"lei_verified","severity":"low","detail":"Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","source":"gleif"}],"request_id":"98f13708210194c475687be6106a3b84","cached":false,"first_seen":"2026-06-10T08:00:00Z","checked_at":"2026-06-19T11:32:00Z"}},"red":{"summary":"A sanctions-list match","value":{"verdict":"red","confidence":0.97,"artifact":{"type":"payee","value":"Vladimir Putin"},"reason":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","recommended_action":"block","signals":[{"name":"sanctions_match","severity":"critical","detail":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","source":"opensanctions"}],"request_id":"aab3238922bcc25a6f606eb525ffdc56","cached":false,"first_seen":"2026-06-19T11:33:00Z","checked_at":"2026-06-19T11:33:00Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/message":{"post":{"tags":["Verify"],"summary":"Verify a message","description":"Check inbound text (SMS, chat, email) before acting on it. Extracts any links and verifies each (folding in the worst), then reasons about scam tactics — urgency, impersonation, OTP/PIN solicitation.","operationId":"verify_message_v1_verify_message_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValueIn"},"examples":{"otp_scam":{"summary":"An OTP-solicitation scam","value":{"value":"URGENT: Your account is blocked. Share the OTP we just sent to reactivate."}}}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"yellow":{"summary":"An OTP-phishing message (text only)","value":{"verdict":"yellow","confidence":0.5,"artifact":{"type":"message","value":"URGENT: Your account is blocked. Share the OTP we just sent to reactivate."},"reason":"Pressures you to share a one-time passcode — a hallmark of account-takeover scams.","recommended_action":"warn","signals":[{"name":"llm_assessment","severity":"medium","detail":"Pressures you to share a one-time passcode — a hallmark of account-takeover scams. No legitimate service asks for an OTP.","source":"llm"}],"request_id":"9bf31c7ff062936a96d3c8bd1f8f2ff3","cached":false,"first_seen":"2026-06-19T11:34:00Z","checked_at":"2026-06-19T11:34:00Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/document":{"post":{"tags":["Verify"],"summary":"Verify a document","description":"Upload a document (PDF, Word/Excel/PowerPoint, HTML, …) as multipart form-data under the field `file`. Faro converts it to compact Markdown with MarkItDown, extracts and verifies any embedded links, and — when the deterministic tiers are inconclusive — reasons about document fraud (forged letterheads, fake invoices / payment-redirects, bogus KYC, OTP/credential solicitation). **Honest note:** Faro reads extracted text only — seals, images, and layout are lost, and scanned/image-only files (which need OCR) cannot be read.","operationId":"verify_document_v1_verify_document_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_verify_document_v1_verify_document_post"}}},"required":true},"responses":{"200":{"description":"The verdict for the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"fraud_invoice":{"summary":"An invoice-redirect fraud document","value":{"verdict":"red","confidence":0.85,"artifact":{"type":"document","value":"# Payment Reminder\n\nDear customer, your invoice is overdue. To avoid account suspension, pay immediately to our UPDATED bank details: A/C 50100XXXXXX, IFSC ABCD0001234. Confirm by sharing the OTP sent to your phone."},"reason":"Document shows invoice-redirect fraud: a last-minute change of bank details, payment urgency, and a request to share an OTP.","recommended_action":"block","signals":[{"name":"llm_assessment","severity":"high","detail":"Pressures immediate payment to newly changed bank details and solicits an OTP — classic invoice-redirect / account-takeover fraud.","source":"llm"}],"request_id":"6f4922f45568161a8cdf4ad2299f6d23","cached":false,"first_seen":"2026-06-19T11:36:00Z","checked_at":"2026-06-19T11:36:00Z"}}}}}},"413":{"description":"Uploaded file exceeds the size limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"file_too_large","message":"Uploaded file is too large.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"The document could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"document_unreadable","message":"Could not read this document. It may be encrypted, corrupt, or an unsupported format.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}}}},"/v1/verify":{"post":{"tags":["Verify"],"summary":"Verify any artifact","description":"The generic entry point: the body carries the `type` (`url`, `payee`, or `message`) alongside `value`. Behaves exactly like the typed routes.","operationId":"verify_generic_v1_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyIn"},"examples":{"url":{"summary":"Verify a URL","value":{"type":"url","value":"https://www.google.com"}},"payee":{"summary":"Verify a payee","value":{"type":"payee","value":"ramesh@okaxis"}},"message":{"summary":"Verify a message","value":{"type":"message","value":"Click here to claim your refund: bit.ly/x"}}}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"url_green":{"summary":"A clean URL","value":{"verdict":"green","confidence":0.8,"artifact":{"type":"url","value":"https://www.google.com"},"reason":"No safety problems found for this link.","recommended_action":"allow","signals":[{"name":"safe_browsing_clean","severity":"info","detail":"No Google Safe Browsing match.","source":"safe_browsing"},{"name":"domain_age_days","severity":"info","detail":"Domain has been registered for 9863 day(s).","source":"rdap"}],"request_id":"b1946ac92492d2347c6235b4d2611184","cached":false,"first_seen":"2026-06-01T09:12:44Z","checked_at":"2026-06-19T11:30:05Z"}},"payee_red":{"summary":"A sanctioned payee","value":{"verdict":"red","confidence":0.97,"artifact":{"type":"payee","value":"Vladimir Putin"},"reason":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","recommended_action":"block","signals":[{"name":"sanctions_match","severity":"critical","detail":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","source":"opensanctions"}],"request_id":"aab3238922bcc25a6f606eb525ffdc56","cached":false,"first_seen":"2026-06-19T11:33:00Z","checked_at":"2026-06-19T11:33:00Z"}},"message_yellow":{"summary":"A suspicious message","value":{"verdict":"yellow","confidence":0.5,"artifact":{"type":"message","value":"URGENT: Your account is blocked. Share the OTP we just sent to reactivate."},"reason":"Pressures you to share a one-time passcode — a hallmark of account-takeover scams.","recommended_action":"warn","signals":[{"name":"llm_assessment","severity":"medium","detail":"Pressures you to share a one-time passcode — a hallmark of account-takeover scams. No legitimate service asks for an OTP.","source":"llm"}],"request_id":"9bf31c7ff062936a96d3c8bd1f8f2ff3","cached":false,"first_seen":"2026-06-19T11:34:00Z","checked_at":"2026-06-19T11:34:00Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/payment-intent":{"post":{"tags":["Verify"],"summary":"Verify a payment intent","description":"Verify-before-pay adapter for AP2/x402/ACP flows. Maps payment counterparty context (merchant/payee/recipient/domain) to Faro's existing payee/url checks and returns the standard verdict object. Advisory only: Faro does not settle, authorize, or move funds.","operationId":"verify_payment_intent_v1_verify_payment_intent_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentIntentIn"},"examples":{"ap2_merchant":{"summary":"AP2 mandate with merchant identity","value":{"protocol":"ap2","merchant":"Apple Inc."}},"x402_recipient_and_domain":{"summary":"x402 challenge with recipient + resource domain","value":{"protocol":"x402","recipient":"Vladimir Putin","resource_domain":"wallet.example"}}}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"green":{"summary":"Trusted merchant context","value":{"verdict":"green","confidence":0.85,"artifact":{"type":"payee","value":"Apple Inc."},"reason":"No safety problems found. Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","recommended_action":"allow","signals":[{"name":"payee_format","severity":"info","detail":"Not a recognized payment-handle format; treated as a name or other identifier.","source":"payee_format"},{"name":"lei_verified","severity":"low","detail":"Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","source":"gleif"}],"explanation":"verify-before-pay (ap2) checked payee:Apple Inc.; returning the riskiest verdict.","request_id":"c20ad4d76fe97759aa27a0c99bff6710","cached":false,"first_seen":"2026-06-19T11:40:00Z","checked_at":"2026-06-19T11:40:00Z"}},"red":{"summary":"Risky counterparty in checkout flow","value":{"verdict":"red","confidence":0.97,"artifact":{"type":"payee","value":"Vladimir Putin"},"reason":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","recommended_action":"block","signals":[{"name":"sanctions_match","severity":"critical","detail":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","source":"opensanctions"}],"explanation":"verify-before-pay (x402) checked payee:Vladimir Putin, url:https://wallet.example; returning the riskiest verdict.","request_id":"c51ce410c124a10e0db5e4b97fc2af39","cached":false,"first_seen":"2026-06-19T11:41:00Z","checked_at":"2026-06-19T11:41:00Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/before-pay":{"post":{"tags":["Verify"],"summary":"Verify before pay (protocol payload)","description":"Verify-before-pay for agent-payment protocols, taking the **raw protocol payload**: an x402 `402 Payment Required` challenge body, an AP2 CartMandate/PaymentMandate, or an ACP merchant + checkout context. Faro extracts the counterparty (merchant → payee check, endpoint/site → URL check, receiving address → payee + on-chain screening), verifies each in parallel, and returns the riskiest verdict. A payload Faro cannot parse degrades to 🟡/`review` — never an error, never a false 🟢. Advisory only: Faro does not settle, authorize, or move funds.","operationId":"verify_before_pay_v1_verify_before_pay_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyBeforePayIn"}}},"required":true},"responses":{"200":{"description":"The verdict for the artifact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictResult"},"examples":{"green":{"summary":"Trusted merchant context","value":{"verdict":"green","confidence":0.85,"artifact":{"type":"payee","value":"Apple Inc."},"reason":"No safety problems found. Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","recommended_action":"allow","signals":[{"name":"payee_format","severity":"info","detail":"Not a recognized payment-handle format; treated as a name or other identifier.","source":"payee_format"},{"name":"lei_verified","severity":"low","detail":"Active LEI match found for Apple Inc.: HWUPKR0MPOU8FGXBT394 (US-CA).","source":"gleif"}],"explanation":"verify-before-pay (ap2) checked payee:Apple Inc.; returning the riskiest verdict.","request_id":"c20ad4d76fe97759aa27a0c99bff6710","cached":false,"first_seen":"2026-06-19T11:40:00Z","checked_at":"2026-06-19T11:40:00Z"}},"red":{"summary":"Risky counterparty in checkout flow","value":{"verdict":"red","confidence":0.97,"artifact":{"type":"payee","value":"Vladimir Putin"},"reason":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","recommended_action":"block","signals":[{"name":"sanctions_match","severity":"critical","detail":"Payee matches a sanctioned entity: Vladimir Vladimirovich PUTIN.","source":"opensanctions"}],"explanation":"verify-before-pay (x402) checked payee:Vladimir Putin, url:https://wallet.example; returning the riskiest verdict.","request_id":"c51ce410c124a10e0db5e4b97fc2af39","cached":false,"first_seen":"2026-06-19T11:41:00Z","checked_at":"2026-06-19T11:41:00Z"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/verify/batch":{"post":{"tags":["Verify"],"summary":"Verify a batch of artifacts","description":"Fan up to 50 artifacts through the same verify engine with bounded concurrency. Small batches (≤10) answer inline; larger ones run asynchronously — the 202 response carries a `job_id` to poll at `GET /v1/verify/batch/{job_id}`. Supports `Idempotency-Key`: a replay with the same key and body returns the original outcome. Per-item failures degrade to error entries; they never fail the batch.","operationId":"verify_batch_v1_verify_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchOut"}}}},"202":{"description":"Batch accepted and running asynchronously."},"409":{"description":"Idempotency-Key reused with a different body."},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"unauthorized","message":"Invalid API key.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"invalid_request","message":"Request body failed validation.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}},"429":{"description":"Rate limit exceeded — slow down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"error":"rate_limited","message":"Too many requests. Slow down.","request_id":"b1946ac92492d2347c6235b4d2611184"}}}}}}},"/v1/verify/batch/{job_id}":{"get":{"tags":["Verify"],"summary":"Poll an async batch job","description":"Status and (once completed) results of an async batch. Jobs stay readable for an hour after completion. **Honest note:** jobs run in-process — without Redis a restart loses running jobs, and a multi-worker deployment needs Redis for polls to land anywhere.","operationId":"get_batch_job_v1_verify_batch__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchOut"}}}},"404":{"description":"No such job (it may have expired).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reports":{"post":{"tags":["Reports"],"summary":"Report a bad actor or wrong verdict","description":"Submit first-party feedback when Faro got it wrong or when you know an artifact is malicious. The report is stored on the normalized reputation node, **invalidates any cached green/yellow verdict** for that node, and feeds future checks via tier-2 reputation signals.","operationId":"create_report_v1_reports_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportIn"},"examples":{"scam_url":{"summary":"Report a phishing link Faro missed","value":{"type":"url","value":"http://sbi-kyc-update.xyz/verify","kind":"phishing"}},"false_positive":{"summary":"Faro flagged a legitimate payee incorrectly","value":{"type":"payee","value":"legitimate-vendor@okaxis","kind":"false_positive"}}}}},"required":true},"responses":{"202":{"description":"Report accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAccepted"},"example":{"accepted":true,"artifact_id":"domain:evil-shop.xyz","message":"Report recorded. The next check on this artifact will re-evaluate."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/diligence":{"post":{"tags":["Reports"],"summary":"Generate a cited diligence report","description":"Batch-verify up to 10 artifacts in parallel, then assemble a cited narrative from the observed signals. Every claim in the narrative must trace to a signal id; ungrounded claims are stripped. The LLM narrates evidence only — it never sets a verdict.","operationId":"create_diligence_report_v1_diligence_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiligenceIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiligenceReportOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/me/watch":{"get":{"tags":["Alerts"],"summary":"List watched artifacts","operationId":"list_watches_v1_me_watch_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchListOut"}}}}}},"post":{"tags":["Alerts"],"summary":"Watch an artifact for flag alerts","description":"Register mandate-scoped interest in a normalized artifact node. When the node gains a critical/high signal, Faro POSTs an `artifact.flagged` webhook to your registered endpoints — even if you have not checked this node recently.","operationId":"create_watch_v1_me_watch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]},"delete":{"tags":["Alerts"],"summary":"Remove an artifact watch","operationId":"delete_watch_v1_me_watch_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchIn"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/keys/request":{"post":{"tags":["Keys"],"summary":"Request an API key by email","description":"Sends a one-time magic link to the email address; clicking it issues the key (see `/v1/keys/confirm`). Always returns 202 — the response never reveals whether the address exists.","operationId":"request_key_v1_keys_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRequestIn"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Request Key V1 Keys Request Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/keys/confirm":{"post":{"tags":["Keys"],"summary":"Confirm the magic link and receive the key","description":"Exchanges a valid magic-link token for a new API key. The key is returned **once** — store it now; only its hash is kept server-side.","operationId":"confirm_key_v1_keys_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyConfirmIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyIssued"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me":{"get":{"tags":["Dashboard"],"summary":"Profile for the authenticated API key","description":"Returns the caller's key prefix, email, mode (`live` or `test`), and issue time. Requires a self-serve issued key — admin keys receive 403.","operationId":"get_me_v1_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeOut"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/me/usage":{"get":{"tags":["Dashboard"],"summary":"Per-key call counts","description":"Daily call counts (by artifact type) for the caller's key over a trailing window. Best-effort — derived from the lightweight usage log.","operationId":"get_my_usage_v1_me_usage_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageOut"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me/verdicts":{"get":{"tags":["Dashboard"],"summary":"Recent verdicts for this key","description":"The most recent verdicts the caller's key produced (normalized node, type, verdict, time). Best-effort — derived from the usage log.","operationId":"get_my_verdicts_v1_me_verdicts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerdictsOut"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me/keys/test":{"post":{"tags":["Dashboard"],"summary":"Issue a test (sandbox) key","description":"Issues a `faro_test_*` key for the caller's email. Test keys return deterministic fixtures (no external checks, no cost) and never write to the reputation graph — see the test-mode fixture table in the docs.","operationId":"create_test_key_v1_me_keys_test_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyIssued"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/me/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","description":"List the caller's registered endpoints (secrets are never returned).","operationId":"list_webhooks_v1_me_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WebhookOut"},"type":"array","title":"Response List Webhooks V1 Me Webhooks Get"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook endpoint","description":"Register an HTTPS endpoint to receive signed `artifact.flagged` events. The response includes the signing `secret` **once** — store it now; verify incoming deliveries with the `X-Faro-Signature` header.","operationId":"create_webhook_v1_me_webhooks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me/webhooks/{endpoint_id}":{"delete":{"tags":["Webhooks"],"summary":"Delete a webhook endpoint","operationId":"delete_webhook_v1_me_webhooks__endpoint_id__delete","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me/webhooks/{endpoint_id}/ping":{"post":{"tags":["Webhooks"],"summary":"Send a test event","description":"Deliver a one-off `webhook.ping` to verify the endpoint is wired up.","operationId":"ping_webhook_v1_me_webhooks__endpoint_id__ping_post","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookPingOut"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/me/webhooks/{endpoint_id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Recent delivery attempts","description":"The most recent delivery attempts for an endpoint (debugging).","operationId":"list_webhook_deliveries_v1_me_webhooks__endpoint_id__deliveries_get","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryOut"},"title":"Response List Webhook Deliveries V1 Me Webhooks  Endpoint Id  Deliveries Get"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin or dev-mode credentials cannot use dashboard routes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/jwks.json":{"get":{"tags":["Receipts"],"summary":"Receipt-signing public keys (JWKS)","description":"The Ed25519 public keys receipts and log roots are signed with, as an RFC 7517 key set. Retired keys stay listed after a rotation so older receipts remain verifiable. Public — verification needs no API key.","operationId":"jwks__well_known_jwks_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Jwks  Well Known Jwks Json Get"}}}}}}},"/.well-known/faro-log-roots":{"get":{"tags":["Receipts"],"summary":"Signed daily Merkle roots of the receipt log","description":"One signed root per completed UTC day of the append-only receipt log, in day order — mirror this document freely. `base_tx_hash` is the Base transaction carrying the 32-byte root as calldata; only the root ever goes on-chain. Public — no API key required.","operationId":"log_roots__well_known_faro_log_roots_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogRootsOut"}}}}}}},"/.well-known/faro-eas-schema":{"get":{"tags":["Attestations"],"summary":"Frozen Faro credential EAS schema (Base)","description":"The six-field wire contract and its deterministic schema UID. Public — diligence can recompute the UID and look it up on https://base.easscan.org without trusting this response. `registered` is filled when the SchemaRegistry RPC call succeeds. The chain publishes the credential, never the verdict.","operationId":"eas_schema__well_known_faro_eas_schema_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EasSchemaOut"}}}}}}},"/v1/attestations":{"get":{"tags":["Attestations"],"summary":"Read the current Faro credential for a subject","description":"Looks up the current FaroCredentialAttestation on Base EAS for a subject (`subject_type` + `identifier`, e.g. `x402_endpoint` + `https://api.example.com`). Public — this is a chain read, not a Faro verdict. A hit means a credential was current; it does NOT mean the transaction is safe. Advisory, never blocking.","operationId":"get_attestation_v1_attestations_get","parameters":[{"name":"subject_type","in":"query","required":true,"schema":{"$ref":"#/components/schemas/SubjectType"}},{"name":"identifier","in":"query","required":true,"schema":{"type":"string","title":"Identifier"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttestationOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{receipt_id}":{"get":{"tags":["Receipts"],"summary":"Fetch a trust receipt","description":"The signed receipt issued for a verify response (see the `X-Faro-Receipt-Id` response header), with its transparency-log position and — once the day's root is published — a Merkle inclusion proof. The payload carries hashes only, never artifact contents. Verify offline with `scripts/verify_receipt.py`.","operationId":"get_receipt_v1_receipts__receipt_id__get","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiptOut"}}}},"404":{"description":"No such receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Receipts are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/credential-status/{list_id}":{"get":{"tags":["Credentials"],"summary":"Credential revocation status list","description":"Bitstring status list for Faro Verified credentials (W3C-style, off-chain). A set bit at an index means the credential at that index is revoked. Public.","operationId":"credential_status__well_known_credential_status__list_id__get","parameters":[{"name":"list_id","in":"path","required":true,"schema":{"type":"string","title":"List Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Credential Status  Well Known Credential Status  List Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credentials":{"post":{"tags":["Credentials"],"summary":"Issue a Faro Verified credential (admin)","description":"Sign an off-chain, non-transferable credential bound to `subject`. Requires an admin API key. Uses the same Ed25519 signer as receipts.","operationId":"issue_credential_v1_credentials_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Issue Credential V1 Credentials Post"}}}},"403":{"description":"Admin key required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Credentials disabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credentials/{credential_id}":{"get":{"tags":["Credentials"],"summary":"Fetch a Faro Verified credential","operationId":"get_credential_v1_credentials__credential_id__get","parameters":[{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","title":"Credential Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Credential V1 Credentials  Credential Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credentials/{credential_id}/verify":{"post":{"tags":["Credentials"],"summary":"Verify a credential (signature + revocation + subject binding)","operationId":"verify_credential_route_v1_credentials__credential_id__verify_post","parameters":[{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","title":"Credential Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Verify Credential Route V1 Credentials  Credential Id  Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credentials/{credential_id}/revoke":{"post":{"tags":["Credentials"],"summary":"Revoke a credential (admin)","operationId":"revoke_credential_v1_credentials__credential_id__revoke_post","parameters":[{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","title":"Credential Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Revoke Credential V1 Credentials  Credential Id  Revoke Post"}}}},"403":{"description":"Admin key required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Action":{"type":"string","enum":["allow","warn","block","review"],"title":"Action"},"AgentIn":{"properties":{"entity_id":{"type":"string","title":"Entity Id"},"name":{"type":"string","maxLength":128,"minLength":2,"title":"Name"},"endpoint":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Endpoint"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"}},"type":"object","required":["entity_id","name"],"title":"AgentIn"},"AgentOut":{"properties":{"agent_id":{"type":"string","title":"Agent Id"},"entity_id":{"type":"string","title":"Entity Id"},"name":{"type":"string","title":"Name"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"acts_for":{"type":"string","title":"Acts For"},"standing":{"type":"string","enum":["green","yellow","red","unclaimed"],"title":"Standing"},"binding_valid":{"type":"boolean","title":"Binding Valid"}},"type":"object","required":["agent_id","entity_id","name","endpoint","scopes","key_prefix","acts_for","standing","binding_valid"],"title":"AgentOut"},"AgentPayProtocol":{"type":"string","enum":["ap2","x402","acp"],"title":"AgentPayProtocol"},"Artifact":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType","description":"The kind of artifact that was verified."},"value":{"type":"string","title":"Value","description":"The normalized artifact string that was checked."}},"type":"object","required":["type","value"],"title":"Artifact"},"ArtifactType":{"type":"string","enum":["url","payee","message","document"],"title":"ArtifactType"},"AttestationOut":{"properties":{"found":{"type":"boolean","title":"Found"},"current":{"type":"boolean","title":"Current","default":false},"subject_type":{"anyOf":[{"$ref":"#/components/schemas/SubjectType"},{"type":"null"}]},"subject_hash":{"type":"string","title":"Subject Hash"},"page_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Uri"},"evidence_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence Hash"},"check_set_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Check Set Version"},"issued_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Issued At"},"expiration_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expiration Time"},"expired":{"type":"boolean","title":"Expired","default":false},"revoked":{"type":"boolean","title":"Revoked","default":false},"attester":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attester"},"attester_checked":{"type":"boolean","title":"Attester Checked","default":false},"uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uid"},"txid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Txid"},"schema_uid":{"type":"string","title":"Schema Uid"},"easscan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Easscan"},"checked_at":{"type":"string","format":"date-time","title":"Checked At"},"cached":{"type":"boolean","title":"Cached","description":"Always false — this is a chain read.","default":false}},"type":"object","required":["found","subject_hash","schema_uid","checked_at"],"title":"AttestationOut","description":"The current Faro credential for a subject — or found=false."},"BatchIn":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BatchItemIn"},"type":"array","minItems":1,"title":"Items","description":"Artifacts to verify."},"mode":{"type":"string","enum":["auto","sync","async"],"title":"Mode","description":"auto: small batches answer inline, larger ones run as a job; sync: force inline (small batches only); async: always run as a job.","default":"auto"}},"type":"object","required":["items"],"title":"BatchIn"},"BatchItemIn":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType"},"value":{"type":"string","minLength":1,"title":"Value"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region","description":"Optional ISO 3166-1 alpha-2 region hint for this item."}},"type":"object","required":["type","value"],"title":"BatchItemIn"},"BatchItemOut":{"properties":{"index":{"type":"integer","title":"Index"},"status":{"type":"string","enum":["ok","error"],"title":"Status"},"result":{"anyOf":[{"$ref":"#/components/schemas/VerdictResult"},{"type":"null"}]},"receipt_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Receipt Id"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["index","status"],"title":"BatchItemOut"},"BatchOut":{"properties":{"status":{"type":"string","enum":["completed","running"],"title":"Status"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id","description":"Set for async batches — poll GET /v1/verify/batch/{job_id}."},"poll":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Poll"},"results":{"anyOf":[{"items":{"$ref":"#/components/schemas/BatchItemOut"},"type":"array"},{"type":"null"}],"title":"Results"}},"type":"object","required":["status"],"title":"BatchOut"},"Body_verify_document_v1_verify_document_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"The document to verify (multipart form-data)."}},"type":"object","required":["file"],"title":"Body_verify_document_v1_verify_document_post"},"CheckResult":{"properties":{"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["ok","warn","fail","skipped"],"title":"Status"},"detail":{"type":"string","title":"Detail"},"source":{"type":"string","title":"Source"},"verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verdict"}},"type":"object","required":["name","status","detail","source"],"title":"CheckResult"},"ChecksOut":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"status":{"type":"string","enum":["pending","control_verified","checked","published","abandoned"],"title":"Status"},"standing":{"type":"string","enum":["green","yellow","red","unclaimed"],"title":"Standing"},"standing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Standing Reason"},"checks":{"items":{"$ref":"#/components/schemas/CheckResult"},"type":"array","title":"Checks"}},"type":"object","required":["claim_id","status","standing","standing_reason","checks"],"title":"ChecksOut"},"ClaimIn":{"properties":{"identifier":{"type":"string","maxLength":256,"minLength":2,"title":"Identifier"},"sector":{"type":"string","maxLength":32,"minLength":2,"title":"Sector"},"display_name":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Display Name"},"email":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Email"}},"type":"object","required":["identifier","sector"],"title":"ClaimIn"},"ClaimOut":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"entity_id":{"type":"string","title":"Entity Id"},"identifier":{"type":"string","title":"Identifier"},"sector":{"type":"string","enum":["d2c","b2b","marketplace","services","cross_border"],"title":"Sector"},"status":{"type":"string","enum":["pending","control_verified","checked","published","abandoned"],"title":"Status"},"known_history":{"type":"boolean","title":"Known History","default":false},"history_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"History Summary"},"proof_mode":{"type":"string","title":"Proof Mode","default":"soft"},"control_verified":{"type":"boolean","title":"Control Verified","default":false},"proof_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proof Token"}},"type":"object","required":["claim_id","entity_id","identifier","sector","status"],"title":"ClaimOut"},"DiligenceArtifactIn":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType","description":"Which kind of artifact to verify."},"value":{"type":"string","maxLength":8192,"minLength":1,"title":"Value","description":"Artifact value to check."}},"type":"object","required":["type","value"],"title":"DiligenceArtifactIn"},"DiligenceIn":{"properties":{"artifacts":{"items":{"$ref":"#/components/schemas/DiligenceArtifactIn"},"type":"array","maxItems":10,"minItems":1,"title":"Artifacts","description":"Artifacts to verify in parallel (max 10)."}},"type":"object","required":["artifacts"],"title":"DiligenceIn","description":"Body for `POST /v1/diligence` — batch verify + cited narrative report."},"DiligenceReportOut":{"properties":{"request_id":{"type":"string","title":"Request Id"},"narrative":{"type":"string","title":"Narrative","description":"Markdown narrative; every claim cites signal ids."},"grounded":{"type":"boolean","title":"Grounded","description":"True when all narrative claims passed the groundedness gate."},"verdicts":{"items":{"$ref":"#/components/schemas/VerdictResult"},"type":"array","title":"Verdicts"},"signals":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Signals","description":"Flat catalog of citable signals referenced in the narrative."},"ungrounded_claims":{"items":{"type":"string"},"type":"array","title":"Ungrounded Claims","description":"Claims stripped by the groundedness gate (empty when grounded)."}},"type":"object","required":["request_id","narrative","grounded","verdicts","signals"],"title":"DiligenceReportOut","description":"Rendered diligence report with cited evidence."},"EasSchemaOut":{"properties":{"name":{"type":"string","title":"Name"},"meaning":{"type":"string","title":"Meaning"},"chain_id":{"type":"integer","title":"Chain Id"},"chain":{"type":"string","title":"Chain"},"schema":{"type":"string","title":"Schema"},"schema_uid":{"type":"string","title":"Schema Uid"},"schema_registry":{"type":"string","title":"Schema Registry"},"eas":{"type":"string","title":"Eas"},"indexer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Indexer"},"resolver":{"type":"string","title":"Resolver"},"revocable":{"type":"boolean","title":"Revocable"},"check_set_version":{"type":"integer","title":"Check Set Version"},"default_expiration_days":{"type":"integer","title":"Default Expiration Days"},"subject_types":{"items":{"type":"string"},"type":"array","title":"Subject Types"},"easscan":{"type":"string","title":"Easscan"},"registered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Registered"},"onchain_schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Onchain Schema"},"verifier_rules":{"additionalProperties":true,"type":"object","title":"Verifier Rules"}},"type":"object","required":["name","meaning","chain_id","chain","schema","schema_uid","schema_registry","eas","resolver","revocable","check_set_version","default_expiration_days","subject_types","easscan","verifier_rules"],"title":"EasSchemaOut"},"EntitlementIn":{"properties":{"sku":{"type":"string","title":"Sku"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"entity_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Id"},"key_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Prefix"},"product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Id"},"meta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Meta"}},"type":"object","required":["sku"],"title":"EntitlementIn","description":"Internal/billing webhook upsert — also usable with admin key for demos."},"ErrorEnvelope":{"properties":{"error":{"type":"string","title":"Error","description":"Stable machine-readable error code.","examples":["unauthorized"]},"message":{"type":"string","title":"Message","description":"Human-readable explanation.","examples":["Invalid API key."]},"request_id":{"type":"string","title":"Request Id","description":"The id of the request that failed (also in the `X-Request-ID` header).","examples":["b1946ac92492d2347c6235b4d2611184"]}},"type":"object","required":["error","message","request_id"],"title":"ErrorEnvelope","description":"The consistent error shape returned by every non-2xx response.\n\nNever a leaked stack trace — always `{ error, message, request_id }`. Quote\n`request_id` when reporting a problem; it ties the response to server logs."},"GuardCheckoutIn":{"properties":{"payee":{"type":"string","maxLength":512,"minLength":2,"title":"Payee"},"buyer_agent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Agent Id"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context"}},"type":"object","required":["payee"],"title":"GuardCheckoutIn"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InclusionProofOut":{"properties":{"leaf":{"type":"string","title":"Leaf","description":"The receipt's entry_hash — the Merkle leaf (hex)."},"index":{"type":"integer","title":"Index","description":"Zero-based position of the leaf in the day's tree."},"tree_size":{"type":"integer","title":"Tree Size"},"path":{"items":{"type":"string"},"type":"array","title":"Path","description":"Sibling hashes from leaf to root (hex)."},"root":{"$ref":"#/components/schemas/LogRootOut"}},"type":"object","required":["leaf","index","tree_size","path","root"],"title":"InclusionProofOut"},"IndexOut":{"properties":{"as_of":{"type":"string","format":"date-time","title":"As Of"},"sectors":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Sectors"},"corridors":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Corridors"},"movement":{"additionalProperties":true,"type":"object","title":"Movement"},"note":{"type":"string","title":"Note","default":"Index v0 — aggregate stub; not k-anonymous production data."}},"type":"object","required":["as_of","sectors","corridors","movement"],"title":"IndexOut"},"KeeperJoinIn":{"properties":{"entity_id":{"type":"string","title":"Entity Id"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"}},"type":"object","required":["entity_id"],"title":"KeeperJoinIn"},"KeyConfirmIn":{"properties":{"token":{"type":"string","title":"Token","description":"The signed token from the emailed link."}},"type":"object","required":["token"],"title":"KeyConfirmIn","description":"Body for `POST /v1/keys/confirm` — the token from the magic link."},"KeyIssued":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"The full API key. Store it now; shown only once.","examples":["faro_live_3pZ8..."]},"key_prefix":{"type":"string","title":"Key Prefix","description":"A non-secret prefix for identifying the key later.","examples":["faro_live_3pZ8Qa"]},"email":{"type":"string","title":"Email","description":"The verified email the key was issued to."}},"type":"object","required":["api_key","key_prefix","email"],"title":"KeyIssued","description":"The newly issued key — returned once; only its hash is stored server-side."},"KeyRequestIn":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"Where to send the API-key link.","examples":["dev@acme.com"]},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location","description":"Optional signup metadata (city, country).","examples":["Mumbai, India"]}},"type":"object","required":["email"],"title":"KeyRequestIn","description":"Body for `POST /v1/keys/request` — the email to send a magic link to."},"LogRootOut":{"properties":{"day":{"type":"string","title":"Day","description":"UTC day this root covers, YYYY-MM-DD."},"tree_size":{"type":"integer","title":"Tree Size","description":"Number of receipt entries under this root."},"root_hash":{"type":"string","title":"Root Hash","description":"RFC 6962 Merkle root over the day's entry hashes (hex)."},"chain_head":{"type":"string","title":"Chain Head","description":"entry_hash of the day's last log entry (hex)."},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"jws":{"type":"string","title":"Jws","description":"Detached Ed25519 JWS over the canonical root payload."},"kid":{"type":"string","title":"Kid","description":"JWKS key id that signed this root."},"base_tx_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Tx Hash","description":"Base transaction carrying this root as calldata (null until anchored)."},"anchored_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Anchored At"}},"type":"object","required":["day","tree_size","root_hash","chain_head","generated_at","jws","kid"],"title":"LogRootOut"},"LogRootsOut":{"properties":{"roots":{"items":{"$ref":"#/components/schemas/LogRootOut"},"type":"array","title":"Roots"}},"type":"object","required":["roots"],"title":"LogRootsOut"},"MeOut":{"properties":{"key_prefix":{"type":"string","title":"Key Prefix","description":"Non-secret key identifier, e.g. `faro_live_AbC123`."},"email":{"type":"string","title":"Email","description":"Email the key was issued to."},"mode":{"type":"string","title":"Mode","description":"Key mode: `live` or `test`."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When this key was issued."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Optional human label for the key."}},"type":"object","required":["key_prefix","email","mode","created_at"],"title":"MeOut","description":"Profile for the authenticated API key."},"PagePublicOut":{"properties":{"slug":{"type":"string","title":"Slug"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"sector":{"type":"string","enum":["d2c","b2b","marketplace","services","cross_border"],"title":"Sector"},"standing":{"type":"string","enum":["green","yellow","red","unclaimed"],"title":"Standing"},"standing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Standing Reason"},"published_at":{"type":"string","format":"date-time","title":"Published At"},"badges":{"items":{"type":"string"},"type":"array","title":"Badges"},"trust_graph":{"items":{"type":"string"},"type":"array","title":"Trust Graph"},"agent":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Agent"},"club_member":{"type":"boolean","title":"Club Member","default":false}},"type":"object","required":["slug","display_name","sector","standing","standing_reason","published_at","badges","trust_graph"],"title":"PagePublicOut"},"PaymentIntentIn":{"properties":{"protocol":{"$ref":"#/components/schemas/PaymentProtocol","description":"Payment protocol context (`ap2`, `x402`, or `acp`)."},"merchant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant","description":"Merchant/counterparty name from mandate/checkout metadata."},"payee":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payee","description":"Direct payee identifier, if available."},"recipient":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient","description":"Recipient identifier (common in x402/ACP flows)."},"resource_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Url","description":"Resource URL associated with the paywall or checkout."},"resource_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Domain","description":"Resource domain when only a host/domain is known."},"region":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Region","description":"Optional ISO 3166-1 alpha-2 region hint used only for bare phone-label disambiguation in payee checks."}},"type":"object","required":["protocol"],"title":"PaymentIntentIn","description":"Body for `POST /v1/verify/payment-intent` (verify-before-pay adapter)."},"PaymentProtocol":{"type":"string","enum":["ap2","x402","acp"],"title":"PaymentProtocol"},"ProveIn":{"properties":{"method":{"type":"string","enum":["dns_txt","email","meta_tag","demo","cloudflare"],"title":"Method","default":"demo"},"proof":{"type":"string","maxLength":512,"title":"Proof","default":""}},"type":"object","title":"ProveIn"},"ProveOut":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"status":{"type":"string","enum":["pending","control_verified","checked","published","abandoned"],"title":"Status"},"control_verified":{"type":"boolean","title":"Control Verified"},"proof_mode":{"type":"string","title":"Proof Mode"}},"type":"object","required":["claim_id","status","control_verified","proof_mode"],"title":"ProveOut"},"PublishIn":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"consent":{"type":"boolean","title":"Consent"},"agent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Id"}},"type":"object","required":["claim_id","consent"],"title":"PublishIn"},"PublishOut":{"properties":{"slug":{"type":"string","title":"Slug"},"url_path":{"type":"string","title":"Url Path"},"standing":{"type":"string","enum":["green","yellow","red","unclaimed"],"title":"Standing"},"standing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Standing Reason"},"badges":{"items":{"type":"string"},"type":"array","title":"Badges"},"agent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Id"}},"type":"object","required":["slug","url_path","standing","standing_reason","badges"],"title":"PublishOut"},"ReceiptOut":{"properties":{"receipt_id":{"type":"string","title":"Receipt Id"},"request_id":{"type":"string","title":"Request Id"},"payload":{"additionalProperties":true,"type":"object","title":"Payload","description":"The frozen receipt contract: verdict, confidence, reason_hash, request_id, artifact_hash, timestamp. Hashes only — no PII."},"jws":{"type":"string","title":"Jws","description":"Detached Ed25519 JWS over the canonical payload bytes."},"kid":{"type":"string","title":"Kid","description":"JWKS key id that signed this receipt."},"algorithm":{"type":"string","title":"Algorithm","default":"EdDSA"},"log_index":{"type":"integer","title":"Log Index","description":"This receipt's sequence number in the transparency log."},"prev_hash":{"type":"string","title":"Prev Hash","description":"entry_hash of the previous log entry (hex)."},"entry_hash":{"type":"string","title":"Entry Hash","description":"sha256(prev_hash + '\\n' + payload_hash + '\\n' + jws) — the chain link (hex)."},"day":{"type":"string","title":"Day"},"inclusion_proof":{"anyOf":[{"$ref":"#/components/schemas/InclusionProofOut"},{"type":"null"}],"description":"Merkle proof against the day's signed root; null until the root publishes."},"verify":{"type":"string","title":"Verify","default":"Verify offline: re-serialize `payload` as canonical JSON (sorted keys, minimal separators), re-attach it to the detached `jws`, and check the Ed25519 signature against /.well-known/jwks.json. Then verify `inclusion_proof` against the signed day root at /.well-known/faro-log-roots (and its Base transaction). Reference: scripts/verify_receipt.py."}},"type":"object","required":["receipt_id","request_id","payload","jws","kid","log_index","prev_hash","entry_hash","day"],"title":"ReceiptOut"},"ReportAccepted":{"properties":{"accepted":{"type":"boolean","title":"Accepted","description":"Always `true` on success.","default":true},"artifact_id":{"type":"string","title":"Artifact Id","description":"Normalized reputation node the report attached to.","examples":["domain:evil-shop.xyz"]},"message":{"type":"string","title":"Message","description":"Human-readable confirmation.","examples":["Report recorded. The next check on this artifact will re-evaluate."]}},"type":"object","required":["artifact_id","message"],"title":"ReportAccepted","description":"Acknowledgement that a report was recorded."},"ReportIn":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType","description":"Which kind of artifact `value` is."},"value":{"type":"string","maxLength":8192,"minLength":1,"title":"Value","description":"The artifact to report (URL, payee handle, or message text)."},"kind":{"$ref":"#/components/schemas/ReportKind","description":"Report category. Use `false_positive` when Faro flagged something incorrectly; other kinds mark the artifact as bad."}},"type":"object","required":["type","value","kind"],"title":"ReportIn","description":"Body for `POST /v1/reports` — flag a bad actor or a wrong verdict."},"ReportKind":{"type":"string","enum":["scam","phishing","malware","false_positive","other"],"title":"ReportKind","description":"Why the caller is reporting this artifact."},"Severity":{"type":"string","enum":["info","low","medium","high","critical"],"title":"Severity"},"Signal":{"properties":{"name":{"type":"string","title":"Name","description":"Machine-readable signal id, e.g. `domain_age_days`."},"severity":{"$ref":"#/components/schemas/Severity","description":"How strongly this signal affects the verdict."},"detail":{"type":"string","title":"Detail","description":"Human-readable explanation of what was found."},"source":{"type":"string","title":"Source","description":"Integration that produced the signal, e.g. `safe_browsing`."}},"type":"object","required":["name","severity","detail","source"],"title":"Signal"},"SubjectType":{"type":"string","enum":["domain","ucp_origin","x402_endpoint","agent_operator"],"title":"SubjectType","description":"Namespaces subjectHash so a domain and a UCP origin never collide."},"UsageDayOut":{"properties":{"day":{"type":"string","format":"date","title":"Day","description":"UTC date of the bucket."},"artifact_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Type","description":"`url`, `payee`, `message`, or null for non-verify calls."},"count":{"type":"integer","title":"Count","description":"Number of calls in this bucket."}},"type":"object","required":["day","count"],"title":"UsageDayOut","description":"Calls on one day, for one artifact type."},"UsageOut":{"properties":{"key_prefix":{"type":"string","title":"Key Prefix","description":"The key these counts belong to."},"days":{"type":"integer","title":"Days","description":"Size of the trailing window, in days."},"total":{"type":"integer","title":"Total","description":"Total calls in the window."},"daily":{"items":{"$ref":"#/components/schemas/UsageDayOut"},"type":"array","title":"Daily","description":"Per-day, per-type counts (most recent first)."}},"type":"object","required":["key_prefix","days","total","daily"],"title":"UsageOut","description":"Per-key usage over a trailing window."},"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"},"ValueIn":{"properties":{"value":{"type":"string","title":"Value","description":"The artifact to verify (a URL, payee, or message string)."},"region":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Region","description":"Optional ISO 3166-1 alpha-2 region hint (e.g. `IN`, `US`) used only to interpret a *bare* phone number that has no country code. Labelling context only — it never changes the reputation node, sanctions, or the verdict. A number written in full `+<country code>` form is identified regardless.","examples":["IN"]}},"type":"object","required":["value"],"title":"ValueIn","description":"Body for the typed routes: `{ \"value\": \"...\" }`."},"Verdict":{"type":"string","enum":["green","yellow","red"],"title":"Verdict"},"VerdictOut":{"properties":{"artifact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact","description":"Normalized reputation node, e.g. `domain:evil.example`."},"artifact_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Type","description":"`url`, `payee`, or `message`."},"verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verdict","description":"`green`, `yellow`, or `red`."},"checked_at":{"type":"string","format":"date-time","title":"Checked At","description":"When the call was made."}},"type":"object","required":["checked_at"],"title":"VerdictOut","description":"One recent verdict the key produced."},"VerdictResult":{"properties":{"verdict":{"$ref":"#/components/schemas/Verdict","description":"Traffic-light verdict: green, yellow, or red."},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"Calibrated confidence in the verdict (honest about data completeness)."},"artifact":{"$ref":"#/components/schemas/Artifact"},"reason":{"type":"string","title":"Reason","description":"One plain-language line explaining the verdict — always present."},"recommended_action":{"$ref":"#/components/schemas/Action","description":"What to do next: allow, warn, block, or review."},"signals":{"items":{"$ref":"#/components/schemas/Signal"},"type":"array","title":"Signals","description":"Evidence behind the verdict — deterministic checks, enrichment, reputation."},"explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation","description":"Optional longer context (e.g. session repeat-check notes)."},"request_id":{"type":"string","title":"Request Id","description":"Unique id for this request (also in the `X-Request-ID` response header)."},"cached":{"type":"boolean","title":"Cached","description":"True when served from the verdict cache (`X-Faro-Cache: hit`).","default":false},"first_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen","description":"When Faro first saw this normalized node in the reputation graph."},"checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Checked At","description":"When this verdict was computed."}},"type":"object","required":["verdict","confidence","artifact","reason","recommended_action","request_id"],"title":"VerdictResult","description":"The single verdict object returned by every verify endpoint and SDK method."},"VerdictsOut":{"properties":{"key_prefix":{"type":"string","title":"Key Prefix","description":"The key these verdicts belong to."},"verdicts":{"items":{"$ref":"#/components/schemas/VerdictOut"},"type":"array","title":"Verdicts","description":"Most recent first."}},"type":"object","required":["key_prefix","verdicts"],"title":"VerdictsOut","description":"Recent verdict history for the caller's key."},"VerifyBeforePayIn":{"properties":{"protocol":{"$ref":"#/components/schemas/AgentPayProtocol","description":"Which agent-payment protocol produced `payload` (`ap2`, `x402`, `acp`)."},"payload":{"additionalProperties":true,"type":"object","title":"Payload","description":"The protocol object itself: the 402 challenge JSON (x402), the CartMandate/PaymentMandate (AP2), or the merchant + checkout context (ACP)."},"region":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Region","description":"Optional ISO 3166-1 alpha-2 region hint (e.g. `IN`, `US`) used only to interpret a *bare* phone number that has no country code. Labelling context only — it never changes the reputation node, sanctions, or the verdict. A number written in full `+<country code>` form is identified regardless.","examples":["IN"]}},"type":"object","required":["protocol","payload"],"title":"VerifyBeforePayIn","description":"Body for `POST /v1/verify/before-pay` — the raw protocol payload path.\n\nSend the protocol payload as-is (an x402 402 challenge body, an AP2\nCart/Payment mandate, or an ACP checkout context); Faro's adapter extracts\nthe counterparty artifacts. Prefer this over `/v1/verify/payment-intent`\nwhen you hold the actual protocol object — no field-mapping on your side."},"VerifyIn":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType","description":"Which kind of artifact `value` is."},"value":{"type":"string","title":"Value","description":"The artifact to verify."},"region":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Region","description":"Optional ISO 3166-1 alpha-2 region hint (e.g. `IN`, `US`) used only to interpret a *bare* phone number that has no country code. Labelling context only — it never changes the reputation node, sanctions, or the verdict. A number written in full `+<country code>` form is identified regardless.","examples":["IN"]}},"type":"object","required":["type","value"],"title":"VerifyIn","description":"Body for the generic `POST /v1/verify`: carries the artifact type."},"WatchIn":{"properties":{"type":{"$ref":"#/components/schemas/ArtifactType","description":"Which kind of artifact to watch."},"value":{"type":"string","maxLength":8192,"minLength":1,"title":"Value","description":"Artifact to watch."}},"type":"object","required":["type","value"],"title":"WatchIn","description":"Register interest in an artifact for mandate-scoped alerts."},"WatchListOut":{"properties":{"watches":{"items":{"$ref":"#/components/schemas/WatchOut"},"type":"array","title":"Watches"}},"type":"object","required":["watches"],"title":"WatchListOut"},"WatchOut":{"properties":{"artifact_id":{"type":"string","title":"Artifact Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["artifact_id","message"],"title":"WatchOut"},"WebhookCreateIn":{"properties":{"url":{"type":"string","title":"Url","description":"HTTPS endpoint Faro POSTs signed events to.","examples":["https://hooks.acme.com/faro"]},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events","description":"Events to subscribe to. Defaults to `[\"artifact.flagged\"]`."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Optional human label for this endpoint."}},"type":"object","required":["url"],"title":"WebhookCreateIn","description":"Register a receiver for the caller's key."},"WebhookCreated":{"properties":{"id":{"type":"string","title":"Id","description":"Endpoint id, e.g. `whk_…`."},"url":{"type":"string","title":"Url","description":"Where events are delivered."},"events":{"items":{"type":"string"},"type":"array","title":"Events","description":"Subscribed event types."},"active":{"type":"boolean","title":"Active","description":"Whether deliveries are currently sent."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Optional human label."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the endpoint was registered."},"secret":{"type":"string","title":"Secret","description":"HMAC signing secret (`whsec_…`). Store it now — it is never shown again."}},"type":"object","required":["id","url","events","active","created_at","secret"],"title":"WebhookCreated","description":"Creation response — includes the signing secret, shown exactly once."},"WebhookDeliveryOut":{"properties":{"id":{"type":"string","title":"Id","description":"Delivery id, e.g. `whd_…`."},"event_type":{"type":"string","title":"Event Type","description":"The event delivered."},"status":{"type":"string","title":"Status","description":"`pending`, `delivered`, or `failed`."},"attempts":{"type":"integer","title":"Attempts","description":"Number of POST attempts so far."},"last_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status Code","description":"HTTP status of the most recent attempt."},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error","description":"Most recent failure reason."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the event was enqueued."},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivered At","description":"When it was successfully delivered."}},"type":"object","required":["id","event_type","status","attempts","created_at"],"title":"WebhookDeliveryOut","description":"One delivery attempt record (for debugging)."},"WebhookOut":{"properties":{"id":{"type":"string","title":"Id","description":"Endpoint id, e.g. `whk_…`."},"url":{"type":"string","title":"Url","description":"Where events are delivered."},"events":{"items":{"type":"string"},"type":"array","title":"Events","description":"Subscribed event types."},"active":{"type":"boolean","title":"Active","description":"Whether deliveries are currently sent."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Optional human label."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the endpoint was registered."}},"type":"object","required":["id","url","events","active","created_at"],"title":"WebhookOut","description":"A registered endpoint (no secret)."},"WebhookPingOut":{"properties":{"delivered":{"type":"boolean","title":"Delivered","description":"Whether the receiver returned 2xx."},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code","description":"Receiver's HTTP status."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Failure reason, if any."}},"type":"object","required":["delivered"],"title":"WebhookPingOut","description":"Result of a one-shot test delivery."}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Faro API key. Send as `Authorization: Bearer <key>`. Get a key at https://farofinance.app or via `/v1/keys/request`."}}},"tags":[{"name":"Verify","description":"Get a verdict for a URL, payee, or message — the core of the API."},{"name":"Keys","description":"Self-serve API-key issuance via an email magic link."},{"name":"Reports","description":"Report feedback and generate cited diligence reports."},{"name":"Alerts","description":"Mandate-scoped entity watches for `artifact.flagged` webhooks."},{"name":"System","description":"Health and liveness."},{"name":"Dashboard","description":"Self-serve visibility for your API key — usage and recent verdicts."},{"name":"Webhooks","description":"Register endpoints to receive signed `artifact.flagged` events."},{"name":"Receipts","description":"Signed trust receipts + the transparency log: verify offline against `/.well-known/jwks.json`, prove inclusion against the signed day roots at `/.well-known/faro-log-roots` (anchored to Base)."},{"name":"Attestations","description":"On-chain Faro credential attestations on Base (EAS SchemaRegistry). The chain publishes the credential, never the verdict: an active, unexpired, unrevoked attestation means the subject held a current Faro credential — nothing more. Public read path; a hit is advisory, never a safety guarantee."},{"name":"Suite","description":"Faro Pages, Agent Registry, Guard checkout, Keepers, Verified Club, Trust Index, and billing entitlements — surfaces over the same engine."}],"servers":[{"url":"https://api.farofinance.app","description":"Production"},{"url":"http://localhost:8000","description":"Local development"}]}