{"openapi":"3.1.0","info":{"title":"Munchausen Lab Crypto Analytics API","version":"8.0.0","description":"Crypto analytics via x402 pay-per-call. Canonical specification: /openapi.json. Runtime handlers define this contract; package version is independent.","x-guidance":"Call paid endpoints without payment for a 402 challenge. Retry using an x402-compatible client. Payment guard precedes handler validation and rate limits. Canonical JSON inputs use strings; runtime also string-coerces truthy values. No external payments were validated by the local contract tests.","contact":{"name":"Munchausen Lab","url":"https://munchausen-lab.pages.dev","email":"munchausen_project@proton.me"}},"servers":[{"url":"https://munchausen-x402.munlab.workers.dev"}],"paths":{"/api/quote":{"get":{"operationId":"getQuote","summary":"Real-time market quote ($0.01)","description":"BTC/ETH/SOL market data. Known runtime limitation: a cached symbol subset can trigger internal (500), because response construction accesses all three coins; subset filtering is not guaranteed. Missing price data returns HTTP 200 with price_api_unavailable. KV limiter: 10 calls per IP/endpoint, 60-second TTL refreshed on accepted calls; unknown IP bypasses it. Rate headers are static, not remaining quota.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.010000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"limit":10,"windowSeconds":60,"scope":"IP/endpoint","slidingTtl":true},"parameters":[{"name":"symbol","in":"query","required":false,"schema":{"type":"string","default":"btc,eth,sol"},"description":"Comma-separated btc,eth,sol. Lowercased, trimmed, empty/unsupported entries discarded. If none remain, defaults to all three. No topic parameter."}],"responses":{"200":{"description":"Quote data or price_api_unavailable fallback","content":{"application/json":{"schema":{"type":"object"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"429":{"$ref":"#/components/responses/PaidRateLimit"},"500":{"$ref":"#/components/responses/Internal"},"502":{"$ref":"#/components/responses/PaymentFailure"}}}},"/api/analyze":{"get":{"operationId":"analyze","summary":"LLM market analysis ($0.05)","description":"Market-wide BTC/ETH/SOL analysis; no topic, depth, or body input. LLM unavailable yields fallback analysis. KV limiter: 10 calls per IP/endpoint, 60-second TTL refreshed on accepted calls; unknown IP bypasses it. Rate headers are static.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"limit":10,"windowSeconds":60,"scope":"IP/endpoint","slidingTtl":true},"responses":{"200":{"description":"Analysis and prices, including fallback when LLM unavailable","content":{"application/json":{"schema":{"type":"object"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"429":{"$ref":"#/components/responses/PaidRateLimit"},"500":{"$ref":"#/components/responses/Internal"},"502":{"$ref":"#/components/responses/PaymentFailure"}}}},"/api/report":{"get":{"operationId":"report","summary":"Full structured market report ($0.25)","description":"Market-wide report sections and market_data; no topic, depth, or body input. No citations field. LLM unavailable yields fallback report. KV limiter: 10 calls per IP/endpoint, 60-second TTL refreshed on accepted calls; unknown IP bypasses it. Rate headers are static.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.250000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"limit":10,"windowSeconds":60,"scope":"IP/endpoint","slidingTtl":true},"responses":{"200":{"description":"Structured report and market_data, including fallback","content":{"application/json":{"schema":{"type":"object"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"429":{"$ref":"#/components/responses/PaidRateLimit"},"500":{"$ref":"#/components/responses/Internal"},"502":{"$ref":"#/components/responses/PaymentFailure"}}}},"/api/scrape":{"post":{"operationId":"scrape","summary":"URL to clean extracted text ($0.005)","description":"JSON object input. No per-route rate limiter; generic rate headers do not imply an enforced quota. URL validation checks HTTP(S) prefix only, not full URI syntax; redirects followed. Wrong JSON shape (e.g. null) may return 500.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.005000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"enforced":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","pattern":"^[hH][tT][tT][pP][sS]?://","description":"HTTP(S) URL prefix, case-insensitive"}},"required":["url"]}}}},"responses":{"200":{"description":"Extracted text (up to 20000 characters), status/content_type/length/truncated; title optional. Upstream non-OK HTTP status is returned in status, not propagated as HTTP error.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"invalid_url — missing URL or not an HTTP(S) prefix"},"402":{"$ref":"#/components/responses/PaymentRequired"},"500":{"$ref":"#/components/responses/Internal"},"502":{"$ref":"#/components/responses/PaymentFailure"}}}},"/api/fact-check":{"post":{"operationId":"factCheck","summary":"Claim verification with LLM verdict ($0.02)","description":"JSON object input. No per-route rate limiter; generic rate headers do not imply an enforced quota. LLM knowledge-based analysis, no live web verification or citations promised. No maximum claim length enforced. Wrong JSON shape (e.g. null) may return 500.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.020000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"enforced":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claim":{"type":"string","minLength":8,"description":"At least 8 characters; runtime counts UTF-16 code units and does not trim whitespace."}},"required":["claim"]}}}},"responses":{"200":{"description":"claim/verdict/confidence/reasoning/key_considerations/checked_at/method; unverifiable fallback if LLM unavailable","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"invalid_claim — missing claim or fewer than 8 UTF-16 code units"},"402":{"$ref":"#/components/responses/PaymentRequired"},"500":{"$ref":"#/components/responses/Internal"},"502":{"$ref":"#/components/responses/PaymentFailure"}}}},"/api/token-safety":{"post":{"operationId":"tokenSafety","summary":"EVM token rug-pull risk score ($0.01)","description":"JSON object input. No per-route rate limiter; generic rate headers do not imply an enforced quota. Canonical address or legacy token alias. Truthy address takes precedence; when absent/falsy, token is used. Prefer one string field. Wrong JSON shape (e.g. null) may return 500.","tags":["paid"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.010000"},"protocols":[{"x402":{}}]},"x-rate-limit":{"enforced":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"Canonical EVM token contract address"},"token":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"Legacy alias"}},"anyOf":[{"required":["address"]},{"required":["token"]}]}}}},"responses":{"200":{"description":"Heuristic DEX risk screening; no pairs returns verdict unknown and score null","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"invalid_address — missing or malformed EVM token address"},"402":{"$ref":"#/components/responses/PaymentRequired"},"500":{"$ref":"#/components/responses/Internal"},"502":{"description":"data_unavailable — upstream DEX non-OK response; payment_verification_error — guard failure"}}}},"/api/token-safety/free":{"get":{"operationId":"tokenSafetyFree","summary":"FREE basic rug-risk score (5/day/IP)","description":"Canonical address query input, no GET body. KV quota: 5 calls/IP/UTC date. Counter increments before validation, so invalid/upstream-failed calls count. KV failures fail open (best effort). Generic rate headers are not this daily quota.","tags":["free"],"security":[],"x-rate-limit":{"limit":5,"window":"UTC day","scope":"IP","failOpen":true},"parameters":[{"name":"address","in":"query","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"EVM token contract address"}],"responses":{"200":{"description":"Basic heuristic risk score; no pairs returns verdict unknown and score null","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"invalid_address — missing or malformed address"},"429":{"description":"free_limit_reached — 5 calls per UTC day per IP exceeded"},"500":{"description":"internal — unhandled upstream/network or response parse error"},"502":{"description":"data_unavailable — upstream DEX non-OK response"}}}}},"components":{"responses":{"PaymentRequired":{"description":"Payment missing or rejected. JSON body v1 challenge and PAYMENT-REQUIRED header v2 challenge on unpaid requests. X-PAYMENT/payment-signature header (or legacy payment query) accepted by guard."},"PaidRateLimit":{"description":"rate_limit — paid endpoint KV limit exceeded (10/IP/endpoint, refreshed 60s TTL)"},"Internal":{"description":"internal — unhandled handler error; facilitator_auth_not_configured when facilitator credentials are missing"},"PaymentFailure":{"description":"payment_verification_error — facilitator/guard failure"}}}}