{"openapi":"3.1.0","info":{"title":"Ourolens API","version":"1.0.0","description":"Cardano governance, NFT floors and token markets.\n\n**Limits.** 5,000 requests per UTC day with a free key; 100 with no key at all.\nCounted in memory and flushed periodically, so they are enforced per instance and therefore approximate: with 3 instances the worst case a determined burst can reach is 15,000 before it is stopped. Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.\n\n**Stability.** 180 days' notice before any breaking change to a published endpoint or any tightening of a limit on one. Anything that launched free stays free: we will not meter it later.\n\n**Absent is absent.** A field this API has not recorded is omitted; a field that can legitimately have no value is `null` with a stated meaning. No field is ever filled with a plausible `0`.\n\nFull documentation: https://ourolens.com/docs/api"},"servers":[{"url":"https://ourolens.com/api"}],"security":[{},{"bearerAuth":[]}],"tags":[{"name":"governance","description":"Governance actions and DReps. No competing Cardano market API exposes either."},{"name":"nft","description":"NFT collection floors and volumes, from our own listings index."},{"name":"tokens","description":"ADA-paired tokens above the liquidity threshold."},{"name":"meta","description":"Pipeline freshness and this document."}],"paths":{"/v1/governance/proposals":{"get":{"tags":["governance"],"summary":"Governance actions, newest first","description":"Ordered by the block time of the submitting transaction, descending.","parameters":[{"name":"status","in":"query","required":false,"description":"Only actions in this state. An unrecognised value is a 400.","schema":{"type":"string","enum":["active","ratified","enacted","dropped","expired"]}},{"name":"limit","in":"query","required":false,"description":"Page size, 1–100. Default 25. A larger value is a 400, not a clamp.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from a previous page, unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"Governance actions, newest first","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Proposal"}},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null on the last page. Opaque — do not construct or parse it."}},"required":["data","nextCursor"],"additionalProperties":false}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/governance/proposals/{id}":{"get":{"tags":["governance"],"summary":"One governance action","description":"By `gov_action` id.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One governance action","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proposal"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/governance/dreps":{"get":{"tags":["governance"],"summary":"DReps by voting power","description":"Ranked by delegated voting power, highest first. DReps that set CIP-119 `doNotList` are not listed, and DReps outside the synced top set are not listed; both still resolve by id.","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100. Default 25. A larger value is a 400, not a clamp.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from a previous page, unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"DReps by voting power","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Drep"}},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null on the last page. Opaque — do not construct or parse it."}},"required":["data","nextCursor"],"additionalProperties":false}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/governance/dreps/{id}":{"get":{"tags":["governance"],"summary":"One DRep, with profile, power history and votes","description":"Resolves any DRep we hold, including one that set `doNotList` — the flag is on the response so a client can honour it too.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One DRep, with profile, power history and votes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DrepDetail"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/nft/collections":{"get":{"tags":["nft"],"summary":"NFT collections by 24 h volume","description":"Ranked by 24-hour ADA volume, highest first.","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100. Default 25. A larger value is a 400, not a clamp.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from a previous page, unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"NFT collections by 24 h volume","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null on the last page. Opaque — do not construct or parse it."}},"required":["data","nextCursor"],"additionalProperties":false}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/nft/collections/{policyId}":{"get":{"tags":["nft"],"summary":"One NFT collection","description":"By 56-character policy id.","parameters":[{"name":"policyId","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{56}$"}}],"responses":{"200":{"description":"One NFT collection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tokens":{"get":{"tags":["tokens"],"summary":"Tokens by liquidity","description":"Ranked by ADA liquidity, highest first — the same measure the tracked set is defined by.","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100. Default 25. A larger value is a 400, not a clamp.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from a previous page, unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"Tokens by liquidity","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Token"}},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null on the last page. Opaque — do not construct or parse it."}},"required":["data","nextCursor"],"additionalProperties":false}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tokens/{unit}":{"get":{"tags":["tokens"],"summary":"One token","description":"By unit: the 56-character policy id followed by the hex asset name.","parameters":[{"name":"unit","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{56}([0-9a-fA-F]{2})*$"}}],"responses":{"200":{"description":"One token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/status":{"get":{"tags":["meta"],"summary":"Pipeline freshness","description":"The same rows as ourolens.com/status: each data pipeline, how long since it last wrote, and the limit it is judged against.","parameters":[],"responses":{"200":{"description":"Pipeline freshness","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The health check has not published a status yet. Reported as unavailable rather than as all-green.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/openapi.json":{"get":{"tags":["meta"],"summary":"This document","parameters":[],"responses":{"200":{"description":"This document","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"A parameter was not understood. Unrecognised parameters, out-of-range `limit` values and malformed cursors and ids are all errors rather than defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The `Authorization` header was present and not a usable key. Omit it entirely to call at the anonymous rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such endpoint, or no such document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily rate limit reached. `Retry-After` is the seconds until the next UTC midnight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"We could not establish your usage, so the request was declined rather than served on a guess. Not a rate limit — `Retry-After` is seconds, not hours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A free API key, `olens_…`. Omit the header entirely to call at the anonymous rate."}},"schemas":{"Error":{"type":"object","description":"Every failure, at every status, has this body. Nothing on this API returns HTML.","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string"}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"VoteTally":{"type":"object","properties":{"yes":{"type":"integer"},"no":{"type":"integer"},"abstain":{"type":"integer"},"yesPct":{"type":["number","null"],"description":"Share of the lane's power, 0–100, as Koios computes it; null when the lane does not vote on this action type."},"noPct":{"type":["number","null"]}},"required":["yes","no","abstain","yesPct","noPct"],"additionalProperties":false},"CommitteeTally":{"type":"object","properties":{"yes":{"type":"integer"},"no":{"type":"integer"},"abstain":{"type":"integer"},"yesPct":{"type":["number","null"]}},"required":["yes","no","abstain","yesPct"],"additionalProperties":false},"Proposal":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"type":"string","enum":["active","ratified","enacted","dropped","expired"]},"title":{"type":["string","null"],"description":"From the CIP-108 anchor; null when there is no anchor or it carried no title."},"abstract":{"type":["string","null"],"description":"From the CIP-108 anchor. The full body is at `metadataUrl` and is not republished here."},"tx":{"type":"object","properties":{"hash":{"type":"string"},"index":{"type":"integer"}},"required":["hash","index"],"additionalProperties":false},"proposedEpoch":{"type":"integer"},"expiresEpoch":{"type":"integer"},"ratifiedEpoch":{"type":["integer","null"]},"enactedEpoch":{"type":["integer","null"]},"droppedEpoch":{"type":["integer","null"]},"expiredEpoch":{"type":["integer","null"]},"depositLovelace":{"type":"string"},"returnAddress":{"type":"string"},"withdrawalLovelace":{"type":["string","null"],"description":"Absent unless recorded. Only TreasuryWithdrawals actions have one; never 0-filled."},"metadataUrl":{"type":["string","null"]},"metadataHash":{"type":["string","null"]},"metadataVerified":{"type":["boolean","null"],"description":"true: the anchor's blake2b-256 matched. false: it did not. null: not checked. Absent: the document predates the check."},"tally":{"description":"null until the first voting summary has been fetched.","oneOf":[{"type":"object","properties":{"drep":{"$ref":"#/components/schemas/VoteTally"},"pool":{"$ref":"#/components/schemas/VoteTally"},"committee":{"$ref":"#/components/schemas/CommitteeTally"}},"required":["drep","pool","committee"],"additionalProperties":false},{"type":"null"}]},"thresholds":{"type":"object","description":"Required yes share per lane, 0–1. null within it = the lane does not vote on this action type. Absent = not recorded.","properties":{"drep":{"type":["number","null"]},"pool":{"type":["number","null"]},"committee":{"type":["number","null"]}},"required":["drep","pool","committee"],"additionalProperties":false},"blockTime":{"type":"integer"},"updatedAt":{"type":"string"}},"required":["id","type","status","title","abstract","tx","proposedEpoch","expiresEpoch","ratifiedEpoch","enactedEpoch","droppedEpoch","expiredEpoch","depositLovelace","returnAddress","metadataUrl","tally","blockTime","updatedAt"],"additionalProperties":false},"DrepStats":{"type":"object","description":"Rates are 0–1 and null when there was nothing to measure — never 0.","properties":{"votesCast":{"type":"integer"},"eligible":{"type":"integer"},"participation":{"type":["number","null"]},"rationaleRate":{"type":["number","null"]},"alignment":{"type":["number","null"]},"resolvedVotes":{"type":"integer"},"activeSince":{"type":"integer"}},"required":["votesCast","eligible","participation","rationaleRate","alignment","resolvedVotes","activeSince"],"additionalProperties":false},"DrepVote":{"type":"object","properties":{"proposalId":{"type":"string"},"vote":{"type":"string","enum":["Yes","No","Abstain"]},"epoch":{"type":"integer"},"time":{"type":"integer"},"txHash":{"type":"string"},"rationaleUrl":{"type":["string","null"]}},"required":["proposalId","vote","epoch","time","txHash","rationaleUrl"],"additionalProperties":false},"Drep":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"],"description":"CIP-119 givenName; null when the DRep published no anchor or no name."},"votingPowerLovelace":{"type":"string"},"rank":{"type":["integer","null"],"description":"1-based by voting power. null = outside the top set we sync — not 'ranked last'."},"delegators":{"type":["integer","null"],"description":"null when Koios reported no count; never 0-filled."},"active":{"type":"boolean"},"registration":{"type":["string","null"],"description":"Koios drep_status. Absent when the document predates the field."},"expiresEpoch":{"type":["integer","null"]},"doNotList":{"type":"boolean","description":"The DRep asked not to appear in directories (CIP-119). Such DReps are absent from the list endpoint."},"metadataUrl":{"type":["string","null"]},"metadataHash":{"type":["string","null"]},"stats":{"oneOf":[{"$ref":"#/components/schemas/DrepStats"},{"type":"null"}]},"updatedAt":{"type":"string"}},"required":["id","name","votingPowerLovelace","rank","delegators","active","expiresEpoch","doNotList","metadataUrl","updatedAt"],"additionalProperties":false},"DrepDetail":{"allOf":[{"$ref":"#/components/schemas/Drep"},{"type":"object","properties":{"profile":{"description":"CIP-119 profile. Absent when no anchor was fetched; null when one was fetched and did not parse.","oneOf":[{"type":"object","properties":{"objectives":{"type":["string","null"]},"motivations":{"type":["string","null"]},"qualifications":{"type":["string","null"]},"paymentAddress":{"type":["string","null"]},"image":{"type":["string","null"]},"references":{"type":"array","items":{"type":"object","properties":{"uri":{"type":"string"},"label":{"type":["string","null"]}},"required":["uri","label"],"additionalProperties":false}}},"required":["objectives","motivations","qualifications","paymentAddress","image","references"],"additionalProperties":false},{"type":"null"}]},"powerHistory":{"type":"array","description":"The last 10 epochs, ascending. Absent when not recorded.","items":{"type":"object","properties":{"epoch":{"type":"integer"},"lovelace":{"type":"string"}},"required":["epoch","lovelace"],"additionalProperties":false}},"votes":{"type":"array","description":"Newest first, at most 100. Absent when the vote list has never been synced.","items":{"$ref":"#/components/schemas/DrepVote"}},"votesSyncedAt":{"type":["string","null"]}},"required":[],"additionalProperties":false}]},"Collection":{"type":"object","properties":{"policyId":{"type":"string"},"name":{"type":["string","null"]},"listed":{"type":"integer"},"listedUnpriced":{"type":"integer","description":"Listings whose price the marketplace keeps off-chain, so they are not in the floor. Absent = not recorded."},"floorAda":{"type":["number","null"],"description":"Cheapest priced listing. **null means there is no priced listing** — not a floor of zero."},"cheapest":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string"},"priceAda":{"type":"number"},"market":{"type":"string"}},"required":["unit","priceAda","market"],"additionalProperties":false}},"volume24hAda":{"type":"number"},"sales24h":{"type":"integer"},"volume7dAda":{"type":"number"},"sales7d":{"type":"integer"},"volume30dAda":{"type":"number"},"sales30d":{"type":"integer"},"lastSale":{"description":"null = no sale in the 30-day window the index keeps.","oneOf":[{"type":"object","properties":{"unit":{"type":"string"},"priceAda":{"type":"number"},"time":{"type":"integer"},"txHash":{"type":"string"}},"required":["unit","priceAda","time","txHash"],"additionalProperties":false},{"type":"null"}]},"updatedAt":{"type":"string"}},"required":["policyId","listed","floorAda","cheapest","volume24hAda","sales24h","volume7dAda","sales7d","volume30dAda","sales30d","lastSale","updatedAt"],"additionalProperties":false},"Token":{"type":"object","properties":{"unit":{"type":"string"},"policyId":{"type":"string"},"assetNameHex":{"type":"string"},"name":{"type":"string"},"ticker":{"type":["string","null"]},"decimals":{"type":"integer"},"priceAda":{"type":"number"},"priceUsd":{"type":["number","null"],"description":"null = no ADA/USD rate was available when the document was written."},"liquidityAda":{"type":"number"},"pools":{"type":"integer"},"primaryPool":{"type":"object","properties":{"dex":{"type":"string"},"poolId":{"type":"string"}},"required":["dex","poolId"],"additionalProperties":false},"supply":{"type":["string","null"],"description":"Raw on-chain units; divide by 10^decimals. Absent or null = unknown."},"mcapAda":{"type":["number","null"],"description":"Fully diluted, in ADA. Absent or null = the supply is unknown, so there is no market cap. Never 0."},"change24h":{"type":["number","null"],"description":"Percent. Absent = the follower has written no 24 h figure for this token; null = fewer than two candles to compare. Never 0."},"volume24hAda":{"type":"number","description":"Absent = the follower has written no 24 h figure. Absent is not zero volume."},"lastTrade":{"oneOf":[{"type":"object","properties":{"time":{"type":"integer"},"side":{"type":"string","enum":["buy","sell"]},"ada":{"type":"number"},"priceAda":{"type":"number"},"txHash":{"type":"string"}},"required":["time","side","ada","priceAda","txHash"],"additionalProperties":false},{"type":"null"}]},"holders":{"description":"Refreshed at most once a day; `fetchedAt` says when. Absent or null = never fetched.","oneOf":[{"type":"object","properties":{"wallets":{"type":"integer"},"addresses":{"type":"integer"},"txs":{"type":"integer"},"fetchedAt":{"type":"string"}},"required":["wallets","addresses","txs","fetchedAt"],"additionalProperties":false},{"type":"null"}]},"metadata":{"description":"Where `name` and `decimals` came from. Absent or null = neither a registry nor on-chain metadata was found.","oneOf":[{"type":"object","properties":{"source":{"type":"string","enum":["registry","cip68","cip25","none"]},"description":{"type":"string"},"url":{"type":"string"},"fetchedAt":{"type":"string"}},"required":["source","fetchedAt"],"additionalProperties":false},{"type":"null"}]},"logoUrl":{"type":["string","null"]},"updatedAt":{"type":"string"}},"required":["unit","policyId","assetNameHex","name","ticker","decimals","priceAda","priceUsd","liquidityAda","pools","primaryPool","updatedAt"],"additionalProperties":false},"Status":{"type":"object","properties":{"ok":{"type":"boolean"},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"ok":{"type":"boolean"},"ageSec":{"type":["integer","null"],"description":"Seconds since the thing this row watches last wrote. null = it has never written."},"limitSec":{"type":"integer"},"detail":{"type":"string"}},"required":["id","label","ok","ageSec","limitSec","detail"],"additionalProperties":false}},"updatedAt":{"type":"string"}},"required":["ok","checks","updatedAt"],"additionalProperties":false}}}}