{"openapi":"3.1.0","info":{"title":"CoinGecko over Airnode","version":"1.0.0","description":"CoinGecko is the market data source for crypto prices, market caps and trending coins. This Airnode wraps the read endpoints worth attesting, so a consumer receives the market data with a signature saying this Airnode obtained it from CoinGecko at this time, rather than trusting a scraper's copy.\n\nEvery response carries an EIP-191 signature from the Airnode that served it, so the data can be attributed back to its source rather than trusted on reputation."},"servers":[{"url":"https://airnode-coingecko.fly.dev"}],"paths":{"/":{"get":{"operationId":"getDocumentation","summary":"This document.","description":"Describes the operations this Airnode serves and how to verify what it returns. Free.","responses":{"200":{"description":"An OpenAPI document describing this Airnode.","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"performRequest","summary":"Perform an operation and attest to the response.","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"title":"trendingSearch","description":"The coins, NFTs and categories most searched on CoinGecko right now.","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"trendingSearch","description":"Takes no parameters. Ranked by how much each is being searched. The free browse operation: it is how an agent finds what is moving before pricing it.","x-airnode-returns":{"coins":"array","nfts":"array","categories":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":[],"properties":{}},"responseProjection":{"type":"object","additionalProperties":{"type":"string","pattern":"^/"},"maxProperties":20,"description":"Optional. Maps a name of your choosing to an RFC 6901 JSON Pointer into the upstream response, such as {\"price\": \"/ethereum/usd\"}. data is then the text of a JSON object of those names in Unicode code point order, each value as the upstream wrote it, instead of the whole body, and the projection is part of the signed request identity. No two names take the same pointer, and no pointer is inside another's value. A pointer the response does not have is a 400."}}},{"title":"search","description":"Find a coin's CoinGecko id, which simplePrice and coinsMarkets take, by name or ticker.","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"search","description":"Answers at most 25 coins, ranked by market cap with unranked coins last, so a ticker shared by several coins leads with the largest. Exchanges, categories and NFT collections whose name matches come back alongside. A query that matches nothing answers 200 with every list empty.","x-airnode-returns":{"coins":"array","exchanges":"array","icos":"array","categories":"array","nfts":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["query"],"properties":{"query":{"description":"A name or a ticker symbol, in full or in part. Case does not matter.","type":"string","examples":["pepe","BTC"]}}},"responseProjection":{"type":"object","additionalProperties":{"type":"string","pattern":"^/"},"maxProperties":20,"description":"Optional. Maps a name of your choosing to an RFC 6901 JSON Pointer into the upstream response, such as {\"price\": \"/ethereum/usd\"}. data is then the text of a JSON object of those names in Unicode code point order, each value as the upstream wrote it, instead of the whole body, and the projection is part of the signed request identity. No two names take the same pointer, and no pointer is inside another's value. A pointer the response does not have is a 400."}}},{"title":"simplePrice","description":"The current price of one or more coins in one or more currencies.","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"simplePrice","description":"Names coins by their CoinGecko id, such as bitcoin or ethereum, and the currencies to price them in. search turns a name or a ticker into an id.","x-airnode-price":"0.02 USD per call"},"parameters":{"type":"object","additionalProperties":false,"required":["ids","vs_currencies"],"properties":{"ids":{"description":"Coin ids, comma separated. A CoinGecko id, not a ticker symbol, and search finds one from either.","type":"string","examples":["bitcoin","ethereum"]},"vs_currencies":{"description":"Currencies to price in, comma separated.","type":"string","examples":["usd","eur"]},"include_market_cap":{"description":"Include each coin's market cap alongside its price.","type":"boolean"},"include_24hr_change":{"description":"Include each coin's 24 hour price change as a percentage.","type":"boolean"}}},"responseProjection":{"type":"object","additionalProperties":{"type":"string","pattern":"^/"},"maxProperties":20,"description":"Optional. Maps a name of your choosing to an RFC 6901 JSON Pointer into the upstream response, such as {\"price\": \"/ethereum/usd\"}. data is then the text of a JSON object of those names in Unicode code point order, each value as the upstream wrote it, instead of the whole body, and the projection is part of the signed request identity. No two names take the same pointer, and no pointer is inside another's value. A pointer the response does not have is a 400."}}},{"title":"coinsMarkets","description":"Ranked market data for coins in one currency, richer than simplePrice: price, market cap, rank, 24 hour change and more.","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"coinsMarkets","description":"Omit ids to get the whole market ranked, or name ids to price a specific set.","x-airnode-price":"0.02 USD per call","x-airnode-returns":{"id":"string","symbol":"string","name":"string","image":"string","current_price":"number","market_cap":"number | null","market_cap_rank":"integer | null","fully_diluted_valuation":"number | null","total_volume":"number","high_24h":"number","low_24h":"number","price_change_24h":"number | null","price_change_percentage_24h":"number | null","market_cap_change_24h":"number | null","market_cap_change_percentage_24h":"number | null","circulating_supply":"number","total_supply":"number | null","max_supply":"number | null","ath":"number | null","ath_change_percentage":"number | null","ath_date":"string | null","atl":"number | null","atl_change_percentage":"number | null","atl_date":"string | null","roi":"object | null","last_updated":"string"}},"parameters":{"type":"object","additionalProperties":false,"required":["vs_currency"],"properties":{"vs_currency":{"description":"The single currency to value the market in.","type":"string","examples":["usd"]},"ids":{"description":"Coin ids to limit to, comma separated. A CoinGecko id, not a ticker symbol, and search finds one from either. Omitted, the whole market is returned ranked.","type":"string"},"order":{"description":"How to rank the result.","type":"string","enum":["market_cap_asc","market_cap_desc","volume_asc","volume_desc","id_asc","id_desc"],"default":"market_cap_desc"},"per_page":{"description":"How many results per page.","type":"integer","minimum":1,"maximum":250,"default":100},"page":{"description":"Which page of results.","type":"integer","minimum":1}}},"responseProjection":{"type":"object","additionalProperties":{"type":"string","pattern":"^/"},"maxProperties":20,"description":"Optional. Maps a name of your choosing to an RFC 6901 JSON Pointer into the upstream response, such as {\"price\": \"/ethereum/usd\"}. data is then the text of a JSON object of those names in Unicode code point order, each value as the upstream wrote it, instead of the whole body, and the projection is part of the signed request identity. No two names take the same pointer, and no pointer is inside another's value. A pointer the response does not have is a 400."}}}]}}}},"responses":{"200":{"description":"The upstream response and the attestation over it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attestation"}}}},"400":{"description":"The operation exists but the parameters or the projection are missing, unknown or malformed, a path parameter is empty, . or .. or has such a part between slashes, or the projection names too many fields, an empty or repeated pointer, or a path the response does not have. Also a PAYMENT-SIGNATURE header that does not decode to a payment payload."},"402":{"description":"The operation is paid and no valid payment was supplied. The PAYMENT-REQUIRED header carries the x402 payment requirements to retry against."},"404":{"description":"No such operation."},"502":{"description":"The upstream API could not be reached or refused the request."}}}}},"components":{"schemas":{"Attestation":{"type":"object","required":["airnode","requestHash","timestamp","data","signature"],"properties":{"airnode":{"type":"string","description":"The address whose signature attests to this response."},"requestHash":{"type":"string","description":"Identifies the request this response answers."},"timestamp":{"type":"string","description":"Unix seconds at which the response was signed."},"data":{"type":"string","description":"The upstream response body exactly as received, less a leading byte order mark. With a projection, the text of a JSON object keyed by the names it asked for in Unicode code point order, each value as the upstream wrote it."},"signature":{"type":"string","description":"The attestation itself."}}}}},"x-airnode":{"address":"0x896B7a7F8872639e45F4Fd5F975b1031Ad57bfba","version":"0.2.0","attestation":{"scheme":"eip191-secp256k1","digest":"keccak256(abi.encodePacked(bytes32 requestHash, uint256 timestamp, bytes dataBytes))","dataBytes":"UTF-8 of data","requestHash":"keccak256(utf8(JSON.stringify([operation, parameterEntriesSortedByName]))), where an object value is itself entries sorted by name, at any depth, and an array keeps its order. Names are compared by Unicode code point. A request that carries a projection appends its entries, sorted the same way, as a third element","verify":"Recover the signer of the signature over the digest and check it equals the address above."},"passthrough":{"url":"https://airnode-coingecko.fly.dev/api","routes":{"trendingSearch":{"method":"GET","path":"/search/trending","parameters":{}},"search":{"method":"GET","path":"/search","parameters":{"query":"query"}},"simplePrice":{"method":"GET","path":"/simple/price","parameters":{"ids":"query","vs_currencies":"query","include_market_cap":"query","include_24hr_change":"query"}},"coinsMarkets":{"method":"GET","path":"/coins/markets","parameters":{"vs_currency":"query","ids":"query","order":"query","per_page":"query","page":"query"}}},"parameters":{"x-airnode-sign":"false skips the signature: no attestation headers, and the body streamed through with no size cap.","x-airnode-project":"alias:pointer, once per field to keep and at most 20 times, each pointer an RFC 6901 JSON Pointer into the upstream response that starts with /, is not repeated and is not inside another's value. The body becomes an object of those aliases in Unicode code point order, the signature covers it, and a pointer the response does not have is a 400."},"flow":"Send the request the provider documents, method, path, query and body as they are, to url followed by the route's path. The body comes back as the upstream sent it, with the upstream's status, and on success the attestation is in the X-Airnode-Address, X-Airnode-Request-Hash, X-Airnode-Timestamp and X-Airnode-Signature headers, with the operation served in X-Airnode-Operation. Every query parameter starting with x-airnode- is this Airnode's own, listed under parameters, and never reaches the upstream.","requestHash":"keccak256(utf8(JSON.stringify([\"passthrough\", method, path, queryEntries, headerEntries, body]))), where method is upper case, path is what was sent after url as a URL parser resolves it, the query entries are what was sent with the Airnode's own parameters removed, in the order sent, headerEntries are the headers that the routes declare as parameters and the request sent, each name in lower case and sorted by Unicode code point, with the values of a header sent more than once joined with \", \" in the order sent and the result trimmed of spaces and tabs, and body is the request body as sent, or an empty string. A request that carries a projection appends its entries, sorted by name in Unicode code point order, as a seventh element","dataBytes":"UTF-8 of the response body exactly as received, less a leading byte order mark, or of the projected object"},"payment":{"x402Version":2,"scheme":"exact","accepts":[{"network":"eip155:84532","asset":"0xbeA34973e5f67F18F656A2C6070C64326C791808","symbol":"aUSD","decimals":6}],"payTo":"0x1505FD562AC2Fb4307B85BC6c672FfeafB4d57A7","facilitator":"https://facilitator.xpay.sh","prices":{"simplePrice":"0.02","coinsMarkets":"0.02"},"flow":"An unpaid call to a priced operation returns 402 with the x402 payment requirements, base64-encoded, in the PAYMENT-REQUIRED header. Sign an EIP-3009 authorization matching one entry and retry the call with the payment payload, base64-encoded, in the PAYMENT-SIGNATURE header. The settlement receipt comes back in the PAYMENT-RESPONSE header."}}}