{"openapi":"3.1.0","info":{"title":"Telemeter Free Tools API","version":"1.0.0","description":"Public, read-only, keyless REST access to every telemeter.ai free tool. POST a JSON body matching a tool's input schema to /api/tools/{slug} and get the same `{status, data, summary, provenance}` envelope the web page and MCP tool produce. No authentication is required or supported — this is public data, not customer data. Honesty is the contract (ADR 0016): a tool never invents a number. `pending_price`/`unknown_model`/`invalid_input`/`unsupported`/`error` carry `data: null` — never a fabricated value; `stale` is a real, sourced number whose verification is past its window. Every response also carries `provenance` (source, canonical_url, upstream_sources, verified_at, verification_status), so a figure you quote reproduces its source — the pending/stale flag rides inside the payload and cannot be stripped."},"servers":[{"url":"https://telemeter.ai"}],"paths":{"/api/tools/llm-cost-calculator":{"post":{"operationId":"runLlmCostCalculator","summary":"LLM Cost Calculator","description":"Estimate the monthly cost of any model from your token volumes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"inputTokens":{"type":"integer","minimum":0,"maximum":1000000000000},"outputTokens":{"type":"integer","minimum":0,"maximum":1000000000000},"cacheReadTokens":{"type":"integer","minimum":0,"maximum":1000000000000},"cacheCreationTokens":{"type":"integer","minimum":0,"maximum":1000000000000},"reasoningTokens":{"type":"integer","minimum":0,"maximum":1000000000000}},"required":["model","inputTokens","outputTokens"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/llm-token-counter":{"post":{"operationId":"runLlmTokenCounter","summary":"LLM Token Counter","description":"Count the tokens in any prompt — exact for OpenAI models, estimated for Claude and Gemini.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"text":{"type":"string","maxLength":600000},"model":{"type":"string","minLength":1}},"required":["text","model"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/llm-model-comparison":{"post":{"operationId":"runLlmModelComparison","summary":"LLM Model Comparison","description":"Compare every model side by side — price (verified or labelled pending), context window, and capabilities.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"models":{"type":"array","items":{"type":"string","minLength":1}},"tier":{"type":"string","enum":["frontier","flagship","economy"]},"provider":{"type":"string","minLength":1},"kind":{"type":"string","enum":["chat","embeddings","reasoning"]},"capability":{"type":"string","enum":["function_calling","prompt_caching","batch_api"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/otel-validator":{"post":{"operationId":"runOtelValidator","summary":"OTel GenAI Trace Validator","description":"Check an OpenTelemetry span against the gen_ai.* semantic conventions — what conforms, what is missing, what is deprecated.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"trace":{"anyOf":[{"type":"string","minLength":1},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"array","items":{}}]}},"required":["trace"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/prompt-caching-savings":{"post":{"operationId":"runPromptCachingSavings","summary":"Prompt Caching Savings Calculator","description":"See how much prompt caching cuts your bill on any model — from your reusable prefix, request volume, and cache hit rate.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"cachedTokens":{"type":"integer","minimum":0,"maximum":100000000},"freshInputTokens":{"type":"integer","minimum":0,"maximum":100000000},"outputTokens":{"type":"integer","minimum":0,"maximum":100000000},"requests":{"type":"integer","minimum":1,"maximum":10000000000},"hitRate":{"type":"number","minimum":0,"maximum":1}},"required":["model","cachedTokens","freshInputTokens","outputTokens","requests","hitRate"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/self-host-breakeven":{"post":{"operationId":"runSelfHostBreakeven","summary":"Self-Host vs API Breakeven Calculator","description":"Find the monthly token volume where running your own GPUs beats paying per-token API pricing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"inputTokensPerMonth":{"type":"integer","minimum":0,"maximum":100000000000},"outputTokensPerMonth":{"type":"integer","minimum":0,"maximum":100000000000},"gpuHourlyUsd":{"type":"number","minimum":0,"maximum":100000},"gpuCount":{"type":"integer","minimum":1,"maximum":100000},"hoursPerMonth":{"type":"number","minimum":0,"maximum":744},"tokensPerSecond":{"type":"number","minimum":0,"maximum":50000000}},"required":["model","inputTokensPerMonth","outputTokensPerMonth","gpuHourlyUsd","gpuCount","hoursPerMonth"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/eu-ai-act-classifier":{"post":{"operationId":"runEuAiActClassifier","summary":"EU AI Act Risk-Tier Classifier","description":"Classify an AI system into its EU AI Act risk tier — with the governing Article and Annex cited for every outcome.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"prohibited":{"default":[],"type":"array","items":{"type":"string","enum":["social-scoring","manipulation","exploit-vulnerabilities","biometric-categorization","realtime-biometric","emotion-work-education","facial-scraping","predictive-policing"]}},"safetyComponent":{"default":false,"type":"boolean"},"annexIIIArea":{"default":"none","type":"string","enum":["none","biometrics","critical-infrastructure","education","employment","essential-services","law-enforcement","migration","justice-democracy"]},"narrowProceduralException":{"default":false,"type":"boolean"},"profilesNaturalPersons":{"default":false,"type":"boolean"},"transparency":{"default":[],"type":"array","items":{"type":"string","enum":["chatbot","synthetic-content","emotion-biometric"]}},"gpaiProvider":{"default":false,"type":"boolean"},"gpaiSystemicCompute":{"default":false,"type":"boolean"}},"required":["prohibited","safetyComponent","annexIIIArea","narrowProceduralException","profilesNaturalPersons","transparency","gpaiProvider","gpaiSystemicCompute"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/context-window-checker":{"post":{"operationId":"runContextWindowChecker","summary":"Context Window Checker","description":"Check whether a prompt (and its reserved completion) fits any model’s context window.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"inputTokens":{"type":"integer","minimum":0,"maximum":100000000000},"outputTokens":{"default":0,"type":"integer","minimum":0,"maximum":100000000000}},"required":["model","inputTokens","outputTokens"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/cost-spike-simulator":{"post":{"operationId":"runCostSpikeSimulator","summary":"LLM Cost Spike Simulator","description":"Project how your monthly bill moves when traffic, prompt size, or output length grows — and see which lever drives it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"baselineInputTokens":{"type":"integer","minimum":0,"maximum":100000000000},"baselineOutputTokens":{"type":"integer","minimum":0,"maximum":100000000000},"trafficMultiplier":{"default":1,"type":"number","minimum":0,"maximum":10000},"promptMultiplier":{"default":1,"type":"number","minimum":0,"maximum":10000},"outputMultiplier":{"default":1,"type":"number","minimum":0,"maximum":10000}},"required":["model","baselineInputTokens","baselineOutputTokens","trafficMultiplier","promptMultiplier","outputMultiplier"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/gdpr-readiness-checker":{"post":{"operationId":"runGdprReadinessChecker","summary":"GDPR Readiness Checker","description":"See which GDPR obligations apply to your AI processing and where the gaps are — each cited to its Article.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"processesPersonalData":{"default":true,"type":"boolean"},"specialCategoryData":{"default":false,"type":"boolean"},"transfersOutsideEU":{"default":false,"type":"boolean"},"largeScaleOrSensitive":{"default":false,"type":"boolean"},"establishedOutsideEU":{"default":false,"type":"boolean"},"inPlace":{"default":[],"type":"array","items":{"type":"string","enum":["lawfulBasis","specialCategory","privacyNotice","dataSubjectRights","ropa","processorDpa","security","breach","retention","transfers","dpia","dpo","euRep"]}}},"required":["processesPersonalData","specialCategoryData","transfersOutsideEU","largeScaleOrSensitive","establishedOutsideEU","inPlace"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/mcp-schema-token-cost":{"post":{"operationId":"runMcpSchemaTokenCost","summary":"MCP Schema Token-Cost Validator","description":"See how many tokens your MCP tool schemas add to every request — and what that overhead costs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"toolsJson":{"type":"string","minLength":1,"maxLength":600000}},"required":["model","toolsJson"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/pricing-tracker":{"post":{"operationId":"runPricingTracker","summary":"LLM Pricing Tracker","description":"Every verified price change on record — dated, sourced, and diffed against the registry’s own history.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"days":{"default":90,"type":"integer","minimum":1,"maximum":365}},"required":["days"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/prompt-hash":{"post":{"operationId":"runPromptHash","summary":"Prompt Hash Lookup","description":"Compute the canonical template hash for a prompt — the same normalization production ingestion uses to group cost and quality across every filled-in instantiation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"template":{"type":"string","maxLength":200000}},"required":["template"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/agent-cost-decomposer":{"post":{"operationId":"runAgentCostDecomposer","summary":"Agent Cost Decomposer","description":"Paste a multi-step agent trace and see the cost of every step — by model, by driver, and any retry loop burning through it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"trace":{"type":"string","minLength":1,"maxLength":200000}},"required":["trace"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/rag-cost-estimator":{"post":{"operationId":"runRagCostEstimator","summary":"Embedding/RAG Cost Estimator","description":"Project the cost of embedding your corpus once and searching it every month — the embedding spend behind a RAG pipeline, before storage or retrieval compute.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"type":"string","minLength":1},"corpusTokens":{"type":"number","minimum":1,"maximum":1000000000000},"chunkOverlapPct":{"default":0,"type":"number","minimum":0,"maximum":50},"monthlyQueries":{"type":"number","minimum":0,"maximum":1000000000},"avgQueryTokens":{"default":50,"type":"number","minimum":1,"maximum":100000},"reembedsPerYear":{"default":0,"type":"number","minimum":0,"maximum":52}},"required":["model","corpusTokens","chunkOverlapPct","monthlyQueries","avgQueryTokens","reembedsPerYear"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/rate-limit-headroom":{"post":{"operationId":"runRateLimitHeadroom","summary":"Rate-Limit Headroom Calculator","description":"See how close your traffic runs to your RPM/TPM/RPD limits — which one bites first, and how much you can grow before it does.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"limitRpm":{"type":"integer","exclusiveMinimum":0,"maximum":1000000},"limitTpm":{"type":"integer","exclusiveMinimum":0,"maximum":1000000000},"limitRpd":{"type":"integer","exclusiveMinimum":0,"maximum":1000000000},"avgRequestsPerMinute":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"avgTokensPerRequest":{"type":"number","exclusiveMinimum":0,"maximum":10000000},"peakMultiplier":{"default":3,"type":"number","minimum":1,"maximum":20}},"required":["limitRpm","limitTpm","avgRequestsPerMinute","avgTokensPerRequest","peakMultiplier"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/carbon-estimate":{"post":{"operationId":"runCarbonEstimate","summary":"Carbon/Energy Estimator","description":"Project the energy and CO2e of your monthly query volume — as a cited range across published measurements, never a single invented number.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"queriesPerMonth":{"type":"number","exclusiveMinimum":0,"maximum":1000000000},"gridIntensity":{"type":"string","enum":["eu-average","global-average","custom"]},"customGCo2PerKwh":{"type":"number","minimum":1,"maximum":2000}},"required":["queriesPerMonth","gridIntensity"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}},"/api/tools/pricing-api":{"post":{"operationId":"runPricingApi","summary":"LLM Pricing API & Widget","description":"A free, keyless REST API over the model-pricing registry, plus a self-hosted embeddable widget that shows any model’s live price on your own page.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"model":{"default":"gpt-4o","type":"string","minLength":1}},"required":["model"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool ran. status ok/stale carry a computed `data`; pending_price/unknown_model/unsupported/error carry `data: null` (an honest non-answer, never a guessed number). `provenance` is always present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}},"400":{"description":"The body failed the tool's input schema (status: \"invalid_input\"); `data` is null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolEnvelope"}}}}}}}},"components":{"schemas":{"ToolProvenance":{"type":"object","description":"The citation block every response carries (ADR 0016). Handler-derived meta (from the registry record the tool read) completed with the door-level source/tool/canonical_url — no imperative \"cite us\" language.","properties":{"source":{"type":"string","enum":["telemeter.ai"]},"tool":{"type":"string","description":"The tool slug, e.g. \"llm-cost-calculator\"."},"canonical_url":{"type":"string","format":"uri","description":"https://telemeter.ai/tools/{slug}."},"upstream_sources":{"type":"array","items":{"type":"string"},"description":"Where the numbers really came from (source_url[] for registry-backed tools); [] otherwise."},"verified_at":{"type":["string","null"],"format":"date-time","description":"ISO date the upstream data was verified, or null when not applicable."},"verification_status":{"type":"string","enum":["verified","pending","stale","not_applicable"]},"disclaimer":{"type":"string","description":"Present on pending/stale — e.g. \"do not present as a confirmed price\". Ships inside the payload."}},"required":["source","tool","canonical_url","upstream_sources","verified_at","verification_status"]},"ToolEnvelope":{"type":"object","description":"The uniform tool response. Honesty is the contract (ADR 0016): a tool never invents a number. `pending_price`/`unknown_model`/`invalid_input`/`unsupported`/`error` carry `data: null` — never a fabricated value; `stale` is a real, sourced number whose verification is past its window. Every response also carries `provenance` (source, canonical_url, upstream_sources, verified_at, verification_status), so a figure you quote reproduces its source — the pending/stale flag rides inside the payload and cannot be stripped.","properties":{"status":{"type":"string","enum":["ok","stale","pending_price","unknown_model","invalid_input","unsupported","error"],"description":"ok/stale carry data; pending_price/unknown_model/invalid_input/unsupported/error carry data: null."},"data":{"type":["object","null"],"description":"The tool-specific result object on ok/stale; null otherwise — never a fabricated number."},"summary":{"type":"string","description":"A one-line natural-language summary of the result."},"provenance":{"$ref":"#/components/schemas/ToolProvenance"}},"required":["status","data","summary","provenance"]}}}}