{"openapi":"3.1.0","info":{"title":"Lazaretto — skill & tool verification API","version":"2026.07.14c","summary":"Deterministic verification of agent skills/tools: known-bad matching + behavioral signals.","contact":{"name":"Lazaretto","url":"https://lazaretto.dev"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://lazaretto.dev"}],"paths":{"/v1/scan":{"post":{"summary":"Scan a target and return a verdict bound to its content hash.","description":"Auth: X-API-Key, OR x402 payment (when enabled). Without valid auth the paid path returns 402 with payment requirements. An `error` verdict returns HTTP 422 and is never billed (§9.5).","security":[{"apiKey":[]},{"x402":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"}}}},"responses":{"200":{"description":"A verdict (clear/flagged/malicious).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanReport"}}}},"401":{"description":"Missing or invalid API key."},"402":{"description":"Payment required (x402 path). Body carries payment requirements."},"422":{"description":"An `error` verdict — analysis could not complete. Never billed."},"429":{"description":"Rate limited."}}}},"/v1/known-bad/{sha256}":{"get":{"summary":"Free loss-leader: exact known-bad hash lookup.","parameters":[{"name":"sha256","in":"path","required":true,"schema":{"type":"string","pattern":"^(sha256:)?[0-9a-f]{64}$"}}],"responses":{"200":{"description":"Whether the hash matches a known-bad indicator.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnownBad"}}}},"400":{"description":"Malformed hash."},"429":{"description":"Rate limited (detection-oracle bound)."}}}},"/v1/health":{"get":{"summary":"Liveness, latency percentiles, IOC coverage/freshness, and usage.","responses":{"200":{"description":"Health + usage snapshot."}}}},"/v1/rules":{"get":{"summary":"Rule categories + ids (never detection logic).","responses":{"200":{"description":"Catalog."}}}},"/v1/credits/topup":{"post":{"summary":"Buy a prepaid credit bundle over x402 (one settlement = many scans).","description":"Body {bundle:\"starter\"|\"pro\"|\"scale\"}. Pay the bundle price via x402; returns a new X-API-Key with credits (or tops up a presented key). One credit = one full scan.","responses":{"200":{"description":"Key + credit balance."},"400":{"description":"Unknown bundle."},"402":{"description":"Payment required."}}}},"/v1/usage":{"get":{"summary":"Remaining credit balance for an X-API-Key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Balance."}}}},"/v1/trial":{"post":{"summary":"Claim free trial credits (no payment) to try the full scan.","description":"Mints a new X-API-Key with a few free full scans. IP-rate-limited and one grant per source per window. Returns the key once. Credits meter exactly like paid ones.","responses":{"200":{"description":"A new key with trial credits."},"429":{"description":"Already claimed / rate limited."},"503":{"description":"Trials unavailable."}}}},"/mcp":{"post":{"summary":"Remote MCP server (Streamable HTTP, JSON-RPC). Zero-install for any MCP-capable agent.","description":"Add this URL as an MCP server. Tools: known_bad_lookup (free) and scan_artifact (metered against a prepaid X-API-Key header; one credit per non-error verdict). JSON-RPC methods: initialize, tools/list, tools/call, ping.","responses":{"200":{"description":"JSON-RPC response."},"202":{"description":"Notification accepted (no body)."},"400":{"description":"Malformed JSON-RPC (parse error, or a batch array)."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key"},"x402":{"type":"http","scheme":"x402","description":"Pay-per-call via the x402 protocol (USDC on Base)."}},"schemas":{"ScanRequest":{"type":"object","required":["target"],"properties":{"target":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["inline","raw_url","npm_package","github_repo","clawhub_skill"]},"ref":{"type":"string","description":"Identifier for non-inline targets."},"content":{"type":"string","description":"Literal content for type=inline."}}},"depth":{"type":"string","enum":["lookup","full"],"default":"full","description":"lookup = hash + IOC match only; full = + behavioral rules."}}},"ScanReport":{"type":"object","properties":{"scan_id":{"type":"string"},"target_hash":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"verdict":{"type":"string","enum":["clear","flagged","malicious","error"]},"confidence":{"type":"string","enum":["high","medium","low"]},"known_bad":{"$ref":"#/components/schemas/KnownBad"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"rules_version":{"type":"string"},"scanned_at":{"type":"string","format":"date-time"},"disclaimer":{"type":"string"}}},"KnownBad":{"type":"object","properties":{"matched":{"type":["boolean","null"],"description":"true=known-bad; false=checked clean; null=could not check (fail-closed)."},"match_type":{"type":"string","enum":["exact_hash","fuzzy_hash","embedded_ioc","known_publisher"]},"sources":{"type":"array","items":{"type":"string"}}}},"Finding":{"type":"object","properties":{"rule_id":{"type":"string"},"category":{"type":"string"},"severity":{"type":"string","enum":["high","medium","low","info"]},"description":{"type":"string"},"evidence":{"type":"object","properties":{"file":{"type":"string"},"line":{"type":"integer"},"snippet":{"type":"string"}}}}}}}}