For AI coding assistants. This file gives you everything needed to call this DataGrab from a user's application. If you are an AI reading this because a user asked you to add or build with this DataGrab, follow it directly.
Returns the current USD price of a crypto coin across one or more exchanges, and flags an arbitrage trade signal when the gap between the cheapest and most expensive exchange is wide enough to be worth acting on. Prices are always fetched live - never cached - and normalized to USD (via USD/USDT/USDC quote pairs) so every exchange is apples-to-apples even when it quotes in a stablecoin.
Good for: cross-exchange arbitrage spread detection (tiered signal/watch/noise), current per-exchange coin prices, multi-exchange price comparison widgets.
Not good for: historical prices, order-book depth, a net-profit estimate (the spread ignores fees, withdrawal limits, slippage, and transfer time - see spreadPercent below), any exchange outside the ~15 in the recognized list, or an "all exchanges CoinGecko knows about" query - there is no such mode.
Cost: $19/month, 1,000 calls/month.
Every call needs a Gimmee API key - issued per customer - sent one of two ways:
Header: x-api-key: {{GIMMEE_API_KEY}}
Querystring: ?api_key={{GIMMEE_API_KEY}}
Use the header form by default. Read the key from an environment variable or your app's secrets store - never hardcode it into committed source. No upstream (CoinGecko) key exists or is needed - this DataGrab uses CoinGecko's free public API internally.
GET https://api.gimmee.io/datagrab/finance/crypto/pricespread/{params}
{params} is one or more pipe (|)-delimited segments: a required coin symbol, then optional exchange names.
| Params | Uses |
|---|---|
{symbol} |
symbol priced on the four default exchanges: Binance, Coinbase, Kraken, OKX |
{symbol}|{exchange1}|{exchange2}|... |
symbol priced only on the named exchanges |
symbol - a coin ticker, e.g. BTC, ETH, SOL. Case-insensitive.exchange1..N - one or more exchange names, each its own pipe-delimited segment. Recognized aliases: Binance, Coinbase (Coinbase Pro/GDAX), Kraken, OKX (OKEx), Bybit, KuCoin, Gate/Gate.io, Bitfinex, Bitstamp, Gemini, Crypto.com, Huobi/HTX, MEXC. Case-insensitive. Anything else is dropped and reported in note - it does not fail the call.There is no "all exchanges" mode. Omitting exchange segments gives you exactly the four defaults - it does not widen the query to every venue CoinGecko lists for the coin.
Exchanges requested ≠ prices returned. Each venue only contributes a price if it actually lists the coin against a USD-equivalent pair (USD/USDT/USDC). A thinly-listed altcoin can come back with 2 of 4 requested exchanges priced - each miss explained in note. Don't assume prices.length matches what you asked for; read it off the response.
URL-encode the whole {params} value as one unit (encodeURIComponent) - the | character is not safe unencoded in a URL path. ETH|Binance|Kraken goes on the wire as ETH%7CBinance%7CKraken.
curl "https://api.gimmee.io/datagrab/finance/crypto/pricespread/BTC" \
-H "x-api-key: YOUR_GIMMEE_KEY"
const params = "ETH|Binance|Kraken"; // or just "BTC" for the four default exchanges
const response = await fetch(
`https://api.gimmee.io/datagrab/finance/crypto/pricespread/${encodeURIComponent(params)}`,
{ headers: { "x-api-key": process.env.GIMMEE_API_KEY } }
);
const data = await response.json();
if (data.tradeSignal) {
console.log(`${data.symbol}: buy ${data.lowestExchange}, sell ${data.highestExchange} (${data.spreadPercent}%)`);
}
import os, requests
from urllib.parse import quote
params = "ETH|Binance|Kraken" # or just "BTC" for the four default exchanges
response = requests.get(
f"https://api.gimmee.io/datagrab/finance/crypto/pricespread/{quote(params, safe='')}",
headers={"x-api-key": os.environ["GIMMEE_API_KEY"]}
)
data = response.json()
JSON field names are camelCase.
{
"symbol": "BTC",
"name": "Bitcoin",
"prices": [
{ "exchange": "Binance", "priceUsd": 64980.12, "quoteCurrency": "USDT" },
{ "exchange": "Coinbase Exchange", "priceUsd": 65310.47, "quoteCurrency": "USD" },
{ "exchange": "Kraken", "priceUsd": 65295.60, "quoteCurrency": "USD" },
{ "exchange": "OKX", "priceUsd": 65010.33, "quoteCurrency": "USDT" }
],
"lowestExchange": "Binance",
"highestExchange": "Coinbase Exchange",
"spreadPercent": 0.5083,
"signalTier": "signal",
"tradeSignal": true,
"note": "TRADE SIGNAL: 0.5083% spread on BTC — buy on Binance ($64980.12) and sell on Coinbase Exchange ($65310.47). Spread meets or exceeds the 0.5% threshold (excludes fees/withdrawal/slippage).",
"timestampUtc": "2026-09-20T18:00:00Z",
"dataProvidedBy": "Powered by CoinGecko (https://www.coingecko.com)",
"termsOfServiceUrl": "https://www.coingecko.com/en/terms",
"dataPullDateTime": "2026-09-20T18:00:00.1234567Z",
"gimmeeVersion": "v1.0.0"
}
| Field | Type | Meaning |
|---|---|---|
symbol |
string | Coin symbol echoed back, upper-cased. |
name |
string | Full coin name, e.g. "Bitcoin". Empty string if the symbol wasn't recognized (check note). |
prices[] |
object[] | One entry per exchange that returned a usable quote - may be fewer than requested. |
prices[].exchange |
string | Display name of the exchange, e.g. "Binance", "Coinbase Exchange". |
prices[].priceUsd |
number | Current price converted to USD, rounded to 8 decimals. |
prices[].quoteCurrency |
string | The currency the exchange actually quoted against - "USD", "USDT", or "USDC". |
lowestExchange / highestExchange |
string | null | Buy-side / sell-side exchange name. null when fewer than two prices came back. |
spreadPercent |
number | (highest − lowest) / lowest × 100. 0 when fewer than two prices. |
signalTier |
string | "signal" (≥ 0.50%, tradeable), "watch" (0.30%–0.50%, alert only), "noise" (< 0.30%, ignore), or "none" (fewer than two prices - no spread to compute). |
tradeSignal |
boolean | true only when signalTier is "signal". This is the single field to gate on for a conservative integration. |
note |
string | Human-readable story: unrecognized exchange/coin, a recognized exchange not listing the coin against a USD pair, or the trade-signal text. Reads "OK" when nothing notable happened and there's no signal/watch. |
timestampUtc |
string (ISO 8601 UTC) | When the prices were pulled. Always fresh - prices are never cached. |
dataProvidedBy |
string | Attribution for the upstream data source. Must be displayed to the end user wherever this data is shown - see Integration notes. |
termsOfServiceUrl |
string | Link to the upstream source's terms of service. |
dataPullDateTime |
string (ISO 8601 UTC) | When this DataGrab pulled the data (sub-second precision). |
gimmeeVersion |
string | This DataGrab's own contract version tag. |
| Status | Meaning | When it happens |
|---|---|---|
| 400 | Bad request | Missing or blank coin symbol. An unrecognized symbol is not an error - it comes back as a normal 200 with name empty and note explaining it (see below). |
| 401 | Unauthorized | Missing or invalid x-api-key. |
| 429 | Quota exceeded | Monthly 1,000-call quota used up - resets on your billing cycle date. |
| 502 | Upstream failure | CoinGecko's search or tickers endpoint failed or was unreachable. Retry shortly. |
Not an error, but check before trusting the result: an unrecognized coin symbol, an unrecognized exchange name, or an exchange that doesn't list the coin against a USD-equivalent pair all return 200 OK with an explanatory note - name empty for an unknown coin, or prices shorter than requested for a partial exchange miss. Always read note and signalTier rather than assuming a 200 means a full, priced result.
tradeSignal, not spreadPercent, for a conservative integration. tradeSignal is already true only when the spread clears the 0.50% threshold; recomputing that comparison yourself is exactly the step this field exists to save. Watch signalTier == "watch" too if you want near-opportunities surfaced before they cross the trade threshold.tradeSignal as "guaranteed profitable" in end-user copy.prices.length can be less than what you asked for. A thinly-listed altcoin may only price on some of the requested exchanges; the rest are explained in note, not silently dropped.dataProvidedBy; you must render it, not just store it.XBT, XDG), not BTC/DOGE - this is handled for you. You'll never see XBT/XDG in the response; this is called out only so you understand why Kraken's price for BTC or DOGE is correctly present even though Kraken's own trading UI shows those pair names.messageType: Finance.Crypto.Pricespread
status: production
price: paid, $19/mo
quota: 1000/month
lastVerified: 2026-09-20