{"openapi":"3.1.0","info":{"title":"warden api","version":"0.1.0","description":"governance intelligence. rule changes are being voted on right now across defi protocols — this api maps them to wallet exposure: this rule is changing, this is the source, this is your exposure, this is the simulated effect. data aggregation and simulation only — not financial advice. endpoints are unauthenticated and rate limited (default 30 req/min per client; responses carry the ietf RateLimit and RateLimit-Policy headers, plus legacy x-ratelimit-limit and x-ratelimit-remaining). errors are { error, code, hint }. versioning + deprecation: see x-api-lifecycle — every response carries x-api-version, and a request may send api-version to pin its version line (a line no longer served answers 400 unsupported_version). deprecated operations are flagged here and answer with Deprecation (rfc 9745) and Sunset (rfc 8594) headers. the api is pre-1.0: shapes may change, breaking changes land in the changelog at /llms.txt first. handing a result to a human? every scan has a human-viewable page at /w/{address} (accepts an ens name) — link people there, not to the json."},"servers":[{"url":"https://try.warden.cash"}],"x-api-lifecycle":{"version":"0.1.0","versionHeader":"x-api-version","pinHeader":"api-version","versioning":"semver in openapi info.version, echoed on every api response as the x-api-version header. pre-1.0: a minor bump may change shapes.","pinning":"send api-version on a request to pin the version line you built against, e.g. \"0.1\" or \"0.1.0\". the line is major.minor before 1.0 and the major after. a line this api no longer serves answers 400 unsupported_version instead of a changed shape. no header = the current version.","signals":["the operation is marked deprecated: true in /api/openapi.json","responses carry a Deprecation header (rfc 9745) once deprecated","responses carry a Sunset header (rfc 8594) with the removal date once one is set","the change is listed in /llms.txt before it ships"],"changelog":"https://try.warden.cash/llms.txt"},"paths":{"/api":{"get":{"operationId":"getApiIndex","summary":"machine-readable index of every public endpoint","responses":{"200":{"description":"endpoint catalog with examples and links to this spec.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"}}}}}},"/api/health":{"get":{"operationId":"getHealth","summary":"liveness probe","responses":{"200":{"description":"service is up.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"ok"},"service":{"type":"string"}}}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"}}}}}},"/api/proposals":{"get":{"operationId":"listProposals","summary":"rule-change feed — global, or matched to a wallet","description":"without address: the cached cross-protocol feed of live governance proposals (no impact data, mode \"global\"). with address: proposals that touch that wallet, each carrying simulated impact, sorted most material first.","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"name":"address","in":"query","required":false,"description":"wallet (or ens name) to match proposals against. omit for the global feed.","schema":{"type":"string"}},{"name":"view","in":"query","required":false,"description":"'compact' strips proposal bodies down to what an agent triages on. default 'full'.","schema":{"type":"string","enum":["full","compact"],"default":"full"}},{"name":"limit","in":"query","required":false,"description":"max proposals returned. default 50, capped at 200.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"protocol","in":"query","required":false,"description":"comma list of protocols to scan, e.g. lido,aave. narrows positions and proposals to that slice AND skips the other modules’ rpc — the cheap way to re-fetch just a degraded protocol. unknown slug → invalid_input.","schema":{"type":"string","example":"lido,aave"}},{"name":"minImpact","in":"query","required":false,"description":"keep only proposals at least this material. ranks by simulated impact (critical>high>medium>low>none), so it needs a wallet — the global feed carries no impact.","schema":{"type":"string","enum":["critical","high","medium","low","none"]}},{"name":"status","in":"query","required":false,"description":"comma list of lifecycle states to keep, e.g. active,pending. forward-looking triage usually wants active.","schema":{"type":"string","example":"active,pending"}},{"name":"since","in":"query","required":false,"description":"drop proposals first seen before this ISO date — for watchdog loops that already processed older ones.","schema":{"type":"string","format":"date","example":"2026-06-01"}}],"responses":{"200":{"description":"proposal feed envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalsResponse"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"400":{"description":"invalid input — code is invalid_address, invalid_input, or unsupported_version (a pinned api-version this api no longer serves). fix the request, do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"429":{"description":"rate limited (default 30 req/min per client). retry-after header says when to come back.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"upstream source unavailable — safe to retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}}}}},"/api/proposals/{id}":{"get":{"operationId":"getProposal","summary":"one proposal by id","description":"with ?address= the proposal carries that wallet's impact when it touches their positions. when it does not (or no address is given), the global version is returned with mode \"global\".","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"name":"id","in":"path","required":true,"description":"proposal id as returned by the feed endpoints.","schema":{"type":"string"}},{"name":"address","in":"query","required":false,"description":"wallet (or ens name) to compute impact for.","schema":{"type":"string"}},{"name":"view","in":"query","required":false,"description":"'compact' strips proposal bodies down to what an agent triages on. default 'full'.","schema":{"type":"string","enum":["full","compact"],"default":"full"}}],"responses":{"200":{"description":"proposal detail envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalDetailResponse"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"400":{"description":"invalid input — code is invalid_address, invalid_input, or unsupported_version (a pinned api-version this api no longer serves). fix the request, do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"404":{"description":"no proposal with that id (code not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"429":{"description":"rate limited (default 30 req/min per client). retry-after header says when to come back.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"upstream source unavailable — safe to retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}}}}},"/api/scan/{address}":{"get":{"operationId":"scanWallet","summary":"full wallet scan — positions plus matched rule changes","description":"the primary endpoint: positions detected for the wallet and every governance proposal that touches them, with simulated impact. accepts an ens name in place of the address. results are cached ~60s; refreshedAt is the truth. mode \"mock\" marks demo wallets — never treat mock data as real exposure. filter with protocol/minImpact/status/since to pull just the slice you care about. the response carries webUrl — the human-viewable page for the same scan. show a person that link, not this json.","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"name":"address","in":"path","required":true,"description":"wallet address — evm (0x…), solana, cosmos, or xrpl — or an ens name (vitalik.eth), resolved server-side.","schema":{"type":"string"}},{"name":"view","in":"query","required":false,"description":"'compact' strips proposal bodies down to what an agent triages on. default 'full'.","schema":{"type":"string","enum":["full","compact"],"default":"full"}},{"name":"protocol","in":"query","required":false,"description":"comma list of protocols to scan, e.g. lido,aave. narrows positions and proposals to that slice AND skips the other modules’ rpc — the cheap way to re-fetch just a degraded protocol. unknown slug → invalid_input.","schema":{"type":"string","example":"lido,aave"}},{"name":"minImpact","in":"query","required":false,"description":"keep only proposals at least this material. ranks by simulated impact (critical>high>medium>low>none), so it needs a wallet — the global feed carries no impact.","schema":{"type":"string","enum":["critical","high","medium","low","none"]}},{"name":"status","in":"query","required":false,"description":"comma list of lifecycle states to keep, e.g. active,pending. forward-looking triage usually wants active.","schema":{"type":"string","example":"active,pending"}},{"name":"since","in":"query","required":false,"description":"drop proposals first seen before this ISO date — for watchdog loops that already processed older ones.","schema":{"type":"string","format":"date","example":"2026-06-01"}}],"responses":{"200":{"description":"scan envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletScanResponse"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"400":{"description":"invalid input — code is invalid_address, invalid_input, or unsupported_version (a pinned api-version this api no longer serves). fix the request, do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"429":{"description":"rate limited (default 30 req/min per client). retry-after header says when to come back.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"upstream source unavailable — safe to retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}}}}},"/api/positions/{address}":{"get":{"operationId":"listPositions","summary":"positions only — the lightweight half of a scan","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"name":"address","in":"path","required":true,"description":"wallet address — evm (0x…), solana, cosmos, or xrpl — or an ens name (vitalik.eth), resolved server-side.","schema":{"type":"string"}},{"name":"protocol","in":"query","required":false,"description":"comma list of protocols to scan, e.g. lido,aave. narrows positions and proposals to that slice AND skips the other modules’ rpc — the cheap way to re-fetch just a degraded protocol. unknown slug → invalid_input.","schema":{"type":"string","example":"lido,aave"}}],"responses":{"200":{"description":"positions envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PositionsResponse"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"400":{"description":"invalid input — code is invalid_address, invalid_input, or unsupported_version (a pinned api-version this api no longer serves). fix the request, do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"429":{"description":"rate limited (default 30 req/min per client). retry-after header says when to come back.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"upstream source unavailable — safe to retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}}}}},"/api/ens/resolve":{"get":{"operationId":"resolveEns","summary":"ens name → address","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"name":"name","in":"query","required":true,"description":"ens name, e.g. vitalik.eth","schema":{"type":"string"}}],"responses":{"200":{"description":"resolution result. address is null when the name is valid but unregistered.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":["string","null"]}}}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"}}},"400":{"description":"invalid input — code is invalid_address, invalid_input, or unsupported_version (a pinned api-version this api no longer serves). fix the request, do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}},"429":{"description":"rate limited (default 30 req/min per client). retry-after header says when to come back.","headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"upstream source unavailable — safe to retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"x-api-version":{"$ref":"#/components/headers/x-api-version"},"Deprecation":{"$ref":"#/components/headers/Deprecation"},"Sunset":{"$ref":"#/components/headers/Sunset"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}}}}}}},"components":{"headers":{"x-api-version":{"description":"the api version that served this response (semver, matches info.version).","schema":{"type":"string","example":"0.1.0"}},"Deprecation":{"description":"rfc 9745. present only once the operation is deprecated: the date it was deprecated, as a structured-field date (@unix-seconds).","schema":{"type":"string","example":"@1798761600"}},"Sunset":{"description":"rfc 8594. present only once a removal date is set: the http-date after which the operation may stop responding.","schema":{"type":"string","example":"Fri, 01 Jan 2027 00:00:00 GMT"}},"RateLimit":{"description":"draft-ietf-httpapi-ratelimit-headers-11. r = requests left, t = seconds until r goes up (the window slides).","schema":{"type":"string","example":"\"default\";r=29;t=60"}},"RateLimit-Policy":{"description":"draft-ietf-httpapi-ratelimit-headers-11. q = quota, w = window in seconds. one policy for every throttled route.","schema":{"type":"string","example":"\"default\";q=30;w=60"}},"X-RateLimit-Limit":{"description":"legacy twin of RateLimit-Policy q. kept for existing clients.","schema":{"type":"integer","example":30}},"X-RateLimit-Remaining":{"description":"legacy twin of RateLimit r. kept for existing clients.","schema":{"type":"integer","example":29}},"Retry-After":{"description":"on a 429: whole seconds to wait before retrying. never 0.","schema":{"type":"integer","minimum":1,"example":12}}},"parameters":{"ApiVersion":{"name":"api-version","in":"header","required":false,"description":"pin the version line you built against: \"0.1\" or \"0.1.0\" before 1.0, the major after. a line this api no longer serves answers 400 unsupported_version instead of a changed shape. omit it to get the current version.","schema":{"type":"string","example":"0.1.0"}}},"schemas":{"ErrorEnvelope":{"type":"object","required":["error","code","hint"],"properties":{"error":{"type":"string","description":"human-readable message"},"code":{"type":"string","enum":["invalid_address","invalid_input","unsupported_version","not_found","rate_limited","upstream_unavailable","internal_error"]},"hint":{"type":"string","description":"what to do next. stable per code — safe to show an agent or a person."}}},"ScanDegradation":{"type":"object","required":["module","component","message"],"description":"a source or adapter that failed during this scan. results are still valid but coverage has gaps — a missing protocol here means \"could not be checked\", never \"no position\".","properties":{"module":{"type":"string","description":"e.g. aave, lido"},"component":{"type":"string","enum":["source","exposure"]},"message":{"type":"string"}}},"SourceLink":{"type":"object","required":["url","label"],"properties":{"url":{"type":"string"},"label":{"type":"string","description":"e.g. \"view on snapshot\""}}},"ProposalVotes":{"type":"object","properties":{"for":{"type":"number"},"against":{"type":"number"},"abstain":{"type":"number"},"total":{"type":"number"},"quorumRequired":{"type":"number"},"quorumReached":{"type":"boolean"}}},"ProposalTimeline":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"ProposalImpact":{"type":"object","required":["level","summary"],"properties":{"level":{"type":"string","enum":["critical","high","medium","low","none"]},"summary":{"type":"string"},"details":{"type":"string"},"affectedAssets":{"type":"array","items":{"type":"string"}},"estimatedChange":{"type":"string","description":"e.g. \"+$120/yr\", \"HF 1.21 → 1.18\""},"estimatedImpactUsd":{"type":"number"},"analysisStatus":{"type":"string","enum":["simulated","awaiting_analysis"],"description":"simulated = backed by a verified parameter change; awaiting_analysis = matched but not yet quantified."}}},"Proposal":{"type":"object","required":["id","protocol","title","summary","description","status","votes","timeline"],"properties":{"id":{"type":"string"},"protocol":{"type":"string","description":"e.g. aave, compound, lido, jito"},"title":{"type":"string"},"summary":{"type":"string"},"description":{"type":"string","description":"full proposal body — can be long."},"proposer":{"type":"string"},"status":{"type":"string","enum":["active","passed","closed","pending","executed","canceled"]},"votes":{"$ref":"#/components/schemas/ProposalVotes"},"timeline":{"$ref":"#/components/schemas/ProposalTimeline"},"sourceLinks":{"type":"array","items":{"$ref":"#/components/schemas/SourceLink"},"description":"where the scan came from — primary source first."},"snapshotUrl":{"type":"string","description":"legacy — prefer sourceLinks."},"discussionUrl":{"type":"string","description":"legacy — prefer sourceLinks."},"changeType":{"type":"string","enum":["shape","parameter"],"description":"shape = the structure of exposure changes (deprecation, migration, delisting). parameter = numbers move, structure does not."},"effectiveDate":{"type":"string","format":"date-time","description":"when the change executes, if the source knows it."}}},"UserProposalImpact":{"allOf":[{"$ref":"#/components/schemas/Proposal"},{"type":"object","required":["impact"],"properties":{"impact":{"$ref":"#/components/schemas/ProposalImpact"}}}]},"CompactProposal":{"type":"object","required":["id","protocol","title","status","summary","votingEnds"],"properties":{"id":{"type":"string"},"protocol":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"summary":{"type":"string","description":"whitespace-collapsed, capped at ~280 chars."},"changeType":{"type":"string","enum":["shape","parameter"]},"effectiveDate":{"type":"string","format":"date-time"},"votingEnds":{"type":"string","format":"date-time"},"sourceLinks":{"type":"array","items":{"$ref":"#/components/schemas/SourceLink"}},"snapshotUrl":{"type":"string"},"discussionUrl":{"type":"string"},"impact":{"$ref":"#/components/schemas/ProposalImpact"}}},"Position":{"type":"object","required":["id","protocol","asset","amount","user_address"],"properties":{"id":{"type":"string"},"protocol":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"user_address":{"type":"string"},"valueUsd":{"type":"number"},"healthFactor":{"type":"number"},"debt":{"type":"string"},"collateral":{"type":"string"},"apy":{"type":"number"}}},"ProposalsResponse":{"type":"object","required":["mode","view","count","total","proposals","refreshedAt","completeness"],"properties":{"address":{"type":"string","description":"present when scanned against a wallet."},"mode":{"type":"string","enum":["mock","live","global"],"description":"mock = demo wallet, not real exposure. global = no wallet attached."},"view":{"type":"string","enum":["full","compact"]},"count":{"type":"integer","description":"proposals in this response (after limit)."},"total":{"type":"integer","description":"proposals available before limit."},"proposals":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/UserProposalImpact"},{"$ref":"#/components/schemas/Proposal"},{"$ref":"#/components/schemas/CompactProposal"}]}},"refreshedAt":{"type":"string","format":"date-time"},"completeness":{"type":"string","enum":["complete","partial"],"description":"'partial' when coverage had gaps (see `degraded`), else 'complete'. the boolean to branch on."},"degraded":{"type":"array","items":{"$ref":"#/components/schemas/ScanDegradation"},"description":"present when wallet-scan coverage had gaps; absent = full coverage."}}},"ProposalDetailResponse":{"type":"object","required":["mode","proposal","refreshedAt"],"properties":{"address":{"type":"string"},"mode":{"type":"string","enum":["mock","live","global"]},"proposal":{"oneOf":[{"$ref":"#/components/schemas/UserProposalImpact"},{"$ref":"#/components/schemas/Proposal"},{"$ref":"#/components/schemas/CompactProposal"}]},"refreshedAt":{"type":"string","format":"date-time"}}},"PositionsResponse":{"type":"object","required":["address","mode","count","positions","refreshedAt","completeness"],"properties":{"address":{"type":"string"},"mode":{"type":"string","enum":["mock","live"]},"count":{"type":"integer"},"positions":{"type":"array","items":{"$ref":"#/components/schemas/Position"}},"refreshedAt":{"type":"string","format":"date-time"},"completeness":{"type":"string","enum":["complete","partial"],"description":"'partial' when coverage had gaps (see `degraded`), else 'complete'."},"degraded":{"type":"array","items":{"$ref":"#/components/schemas/ScanDegradation"}}}},"WalletScanResponse":{"type":"object","required":["address","mode","view","positions","proposals","refreshedAt","completeness","webUrl"],"properties":{"address":{"type":"string","description":"evm addresses come back 0x-checksummed; others pass through verbatim."},"webUrl":{"type":"string","description":"human-viewable page for this scan (https://try.warden.cash/w/{address}). hand this to a person instead of the json url."},"mode":{"type":"string","enum":["mock","live"]},"view":{"type":"string","enum":["full","compact"]},"completeness":{"type":"string","enum":["complete","partial"],"description":"'partial' when coverage had gaps (see `degraded`), else 'complete'. the boolean to branch on; `degraded` is the detail."},"positions":{"type":"array","items":{"$ref":"#/components/schemas/Position"}},"proposals":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/UserProposalImpact"},{"$ref":"#/components/schemas/CompactProposal"}]}},"refreshedAt":{"type":"string","format":"date-time"},"degraded":{"type":"array","items":{"$ref":"#/components/schemas/ScanDegradation"},"description":"present when coverage had gaps; absent = full coverage."}}}}}}