GDPR Compliance

We use cookies to ensure you get the best experience on our website. By continuing to use our site, you accept our use of cookies (and chaos).

to-top

PoofBit API

Use the Poof Chaos Index and the Poof Index in your bots, dashboards and AI agents.

The Poof Chaos Index (PCI) is a market-wide, direction-neutral measure of turbulence from 0 to 100, computed from public market data. It is designed to be read next to Fear & Greed: sentiment tells you which way the crowd leans, PCI tells you how violently the market is moving.

The Poof Index assesses single coins from 11 to 111: the higher, the deeper the coin is in a poof state. Everything is available as JSON over HTTPS and as tools for AI agents over MCP.

Get an API key

Free and instant. Every request to /api/* and /mcp needs a key. Need higher limits? Create an account to get account tokens (120/min) and a watchlist.

Quick start

Plain JSON over HTTPS. Put your key in an environment variable and send it as a Bearer token:

export POOFBIT_KEY=pb_your_key_here
curl -H "Authorization: Bearer $POOFBIT_KEY" https://poofbit.com/api/pci

Authentication

Send your key with every request, in either header:

  • Authorization: Bearer YOUR_KEY (preferred)
  • X-API-Key: YOUR_KEY

Keys are never accepted in the URL, because URLs end up in logs and browser history. We store only a hash of your key, so a lost key can't be recovered: create a new one.

A missing, unknown or revoked key returns 401 with a WWW-Authenticate: Bearer header:

{ "error": "Missing or invalid API key", "docs": "https://poofbit.com/docs#authentication" }

Going over the rate limit returns 429.

Free vs account

TierWhere to get itLimits
freeThe form above, no account 30 requests per minute and 1,000 per day
accountYour account page, after confirming your email; up to 5 tokens 120 requests per minute and 20,000 per day, plus the watchlist

Account tokens look and work exactly like API keys (same headers). Limits count per key; days are UTC. Every keyed response tells you where you stand:

  • X-RateLimit-Limit: requests allowed per minute for this key.
  • X-RateLimit-Remaining: requests left in the current minute.
  • X-RateLimit-Tier: free or account.

GET /api/pci

Returns the current Poof Chaos Index with its zone, the weighted components, the Fear & Greed reading, the combined quadrant, the daily history and the Global Poof Index.

FieldTypeDescription
pciintegerThe index, 0 (calm) to 100 (maximum turbulence).
zoneobjectZone the value falls into.
zone.keystringStable machine-readable identifier.
zone.namestringDisplay name.
zone.emojistringDisplay emoji.
componentsarrayThe weighted inputs behind the value.
components[].keystringStable component identifier.
components[].labelstringDisplay name.
components[].weightnumberShare of the index, 0 to 1. Weights sum to 1.
components[].risknumberComponent reading, 0 (calm) to 1 (extreme). Contributes 100 Γ— weight Γ— risk points.
components[].detailstringHuman-readable description of the measured value.
fear_greedobject | nullCrypto Fear & Greed reading; null when unavailable.
fear_greed.valueinteger0 (extreme fear) to 100 (extreme greed).
fear_greed.classificationstringText classification, e.g. "Greed".
quadrantobject | nullPCI combined with Fear & Greed; null when fear_greed is null.
quadrant.keystringStable identifier.
quadrant.emojistringDisplay emoji.
quadrant.namestringDisplay name.
quadrant.textstringShort interpretation.
historyarrayOne entry per recorded day, oldest first; the last entry is today's current value.
history[].datestringUTC date, YYYY-MM-DD.
history[].pciintegerIndex value for that day.
history[].sourcestringlive for values recorded on the day, reconstructed for earlier days rebuilt from historical market data.
history_daysintegerNumber of entries in history (up to one year plus today).
stalebooleantrue when the data missed three refreshes in a row (market data normally refreshes every 5 minutes).
updated_atstringISO 8601 UTC time the data was last refreshed.
methodologystringPCI formula version, currently "v2". History only contains values of this version.
gpciobject | nullThe Global Poof Index: how much of the market is in a poof state. null while it cannot be computed.
gpci.valueinteger11 (boringly solid) to 111 (total poof), on the Poof Index scale.
gpci.zoneobjectkey, name, emoji of the Poof Index zone it falls into.
gpci.share_in_poofnumberShare of coins in Red Flag Parade or worse, weighted by the square root of market cap (each coin capped at 15 %), 0 to 1.

Example response:

{
  "pci": 34,
  "zone": { "key": "choppy", "name": "Choppy Waters", "emoji": "🌊" },
  "components": [
    { "key": "volatility", "label": "Volatility", "weight": 0.3, "risk": 0.31, "detail": "Median daily swing β‰ˆ 3.6%" },
    { "key": "breadth", "label": "Breadth of big moves", "weight": 0.2, "risk": 0.26, "detail": "13 of 50 coins moved more than 5%" },
    { "key": "dispersion", "label": "Dispersion", "weight": 0.15, "risk": 0.4, "detail": "Spread of 24h moves 3.1%" },
    { "key": "swing", "label": "Market cap swing", "weight": 0.15, "risk": 0.22, "detail": "Top 48 market cap +1.1% in 24h" },
    { "key": "volume", "label": "Volume surge", "weight": 0.1, "risk": 0.45, "detail": "24h volume is 2.6% of the top 48 market cap" },
    { "key": "mania", "label": "Memecoin mania", "weight": 0.1, "risk": 0.52, "detail": "Trending coins average Poof Index 52" }
  ],
  "fear_greed": { "value": 59, "classification": "Greed" },
  "quadrant": { "key": "calm-greed", "emoji": "😌", "name": "Calm Greed", "text": "Complacency mode. The quiet before the poof." },
  "history": [
    { "date": "2026-10-07", "pci": 29, "source": "reconstructed" },
    { "date": "2026-10-08", "pci": 31, "source": "live" },
    { "date": "2026-10-09", "pci": 34, "source": "live" }
  ],
  "history_days": 3,
  "stale": false,
  "updated_at": "2026-10-09T12:00:00+00:00",
  "methodology": "v2",
  "gpci": { "value": 24, "zone": { "key": "sus", "name": "Slightly Sus", "emoji": "🀨" }, "share_in_poof": 0.08 }
}

GET /api/coins

Coins with their Poof Index, filtered, sorted and paged like the Poof Index table: the same parameters, the same result. Invalid parameter values fall back to the defaults (never an error). Repeat a parameter to pass several values.

ParameterValuesDescription
tabtop | all | trendingTop 50 by market cap (default), the top 250, or trending coins.
qtextSearch in name and ticker.
zonesolid | sus | flip | red | poofOnly these zones (repeatable).
sortpoof | mcap | pc24h | pc7d | price | nameDefault poof: highest Poof Index first. Coins without a value come last.
dirasc | descDefault desc (asc for name).
poof_min, poof_max11–111Poof Index range.
capgt10b | 1b-10b | 100m-1b | lt100mMarket cap buckets (repeatable).
ch24_min, ch24_max, ch7_min, ch7_maxnumber24h and 7d price change ranges, percent.
futures1Only coins with a Binance perpetual.
flaghot | longs | shorts | leveragePositioning flags, any of (repeatable).
beta_min, beta_maxnumberMarket beta range.
hide_stables1Leave out stablecoins, wrapped tokens and pegged assets.
page1 and upPage number; past the last page gives the last one.
per_page25 | 50 | 100Page size, default 50.
limit1–50Older way to set the page size, used when per_page is not given. Out-of-range values are clamped.
FieldTypeDescription
coinsarrayCoin objects of this page, see below.
tab, sort, dirstringThe values actually used.
page, per_pageintegerThe page returned and its size.
totalintegerCoins left after the filters, over all pages.
pagesintegerNumber of pages (at least 1).
filtersobjectThe filters actually used: q, zone, cap, futures, flag, hide_stables, and the *_min / *_max ranges (null when unset).
stalebooleantrue when the list missed three refreshes in a row.
updated_atstringISO 8601 UTC time the data was last refreshed.
methodologystringPoof Index version, currently "v3".
coins[].idstringCoinGecko id, use it with /api/coins/{id}.
coins[].name, coins[].symbolstringDisplay name and upper-case ticker.
coins[].pricenumber | nullPrice in USD.
coins[].market_capnumber | nullMarket cap in USD.
coins[].rankinteger | nullMarket cap rank.
coins[].change_24hnumber | nullPrice change over 24h, percent.
coins[].poofinteger | nullPoof Index, 11 (boringly solid) to 111 (total poof); null until the coin has 31 daily closes (sorted last).
coins[].zoneobject | nullkey, name, emoji of the Poof Index zone; null with poof.
coins[].componentsarrayOne entry per signal: key, label, value (the measured signal) and contribution (how far it pushes the index, in log-odds; positive = up). Empty without a value.
coins[].change_7dnumber | nullPrice change over 7d, percent.
coins[].has_futuresbooleanThe coin has a Binance perpetual.
coins[].flagsarrayPositioning flags (hot, longs, shorts, leverage).
coins[].market_betanumber | nullBeta against the top-10 market. Context, not part of the index.
curl -H "Authorization: Bearer $POOFBIT_KEY" "https://poofbit.com/api/coins?tab=all&zone=red&zone=poof&futures=1&sort=mcap&per_page=25"

Example response (one coin shown):

{
  "coins": [
    {
      "id": "bitcoin", "name": "Bitcoin", "symbol": "BTC",
      "price": 65000.0, "market_cap": 1300000000000, "rank": 1, "change_24h": 1.0,
      "poof": 14, "change_7d": 2.1, "has_futures": true, "flags": [], "market_beta": 1.0,
      "zone": { "key": "solid", "name": "Boringly Solid", "emoji": "🧱" },
      "components": [
        { "key": "vol30", "label": "30-day volatility", "value": 0.021, "contribution": -0.32 },
        { "key": "dd90", "label": "Drop from 90-day high", "value": 0.08, "contribution": -0.72 }
      ]
    }
  ],
  "tab": "all", "sort": "mcap", "dir": "desc",
  "page": 1, "per_page": 25, "total": 7, "pages": 1,
  "filters": { "q": "", "zone": ["red", "poof"], "futures": true, "...": "..." },
  "stale": false,
  "updated_at": "2026-10-09T12:00:00+00:00",
  "methodology": "v3"
}

GET /api/coins/{id}

One coin by CoinGecko id (lowercase letters, digits and dashes, e.g. bitcoin): the coin object from /api/coins plus its history.

FieldTypeDescription
historyarrayDaily Poof Index, up to 31 points: the last 30 days plus today, oldest first. Empty when the price history is unavailable; shorter for young coins.
history[].datestringUTC date, YYYY-MM-DD.
history[].poofintegerPoof Index for that day.
past.yesterday, past.last_week, past.last_monthinteger | nullPoof Index 1, 7 and 30 days ago; null when unknown.
methodologystringPoof Index version, currently "v3"; the whole history is computed with it.
positioningobject | nullContext, not scored: the coin's Binance perpetual for the last closed UTC day (day); null without a perp or when older than 3 days.
positioning.funding_rate, funding_7dnumber | nullFunding as a fraction per 8 hours (the day's rates / 3) and its 7-day mean.
positioning.open_interest_usd, oi_change_28dnumber | nullOpen interest at the day's close, and its change over 28 days (1.0 = +100 %).
positioning.ls_accounts, ls_top_positions, taker_rationumber | nullLong/short ratio of all accounts, of top traders' positions, and taker buy/sell volume.
positioning.liq_long10, liq_short10number | nullEstimate: share of open interest a stated leverage model puts within 10 % below / above the price.
positioning.flagsarrayUp to three plain flags, e.g. "Funding hot", "Leverage piling up".
market_betaobject | nullContext, not scored: {beta, correlation, days} of daily returns against the top-10 market over 60 days; null below 61 daily closes.
marketsobject | nullContext, not scored: where the coin trades. null when nothing from the last 14 days is known; each section is empty when its data is older.
markets.nativebooleanThe native coin of its own chain (no contract of its own).
markets.contracts[]array{chain, chain_name, address, explorer_url}: the contract on each chain (CoinGecko platform id); explorer_url is null for chains we do not map.
markets.cex[]arrayUp to 5 centralized exchanges by 24h volume, each with its biggest pair: {exchange, exchange_id, base, target, volume_usd, trade_url, trust_score}.
markets.dex[]arrayUp to 3 DEX pools by liquidity across the coin's chains: {dex, network, chain, chain_name, pair, liquidity_usd, volume_24h_usd, pool_address, url} (GeckoTerminal).
markets.updated_atstringUTC day of the newest section. Links go to third-party sites and are not an endorsement.

An invalid or unknown id returns 404 {"error": "Unknown coin"}.

curl -H "Authorization: Bearer $POOFBIT_KEY" https://poofbit.com/api/coins/bitcoin

Watchlist

The coins on your account's watchlist. Needs an account token; anonymous keys get 403:

{ "error": "Watchlist needs an account token" }

GET /api/watchlist

{"coins", "stale", "updated_at", "methodology"}, with the same coin objects as /api/coins.

PUT /api/watchlist/{id}

DELETE /api/watchlist/{id}

Add or remove one coin by CoinGecko id. Both answer {"ok": true} and are safe to repeat. Unknown id on PUT: 404 (DELETE answers ok for any id). Adding beyond 50 coins: 409.

curl -H "Authorization: Bearer $POOFBIT_TOKEN" https://poofbit.com/api/watchlist
curl -X PUT -H "Authorization: Bearer $POOFBIT_TOKEN" https://poofbit.com/api/watchlist/bitcoin
curl -X DELETE -H "Authorization: Bearer $POOFBIT_TOKEN" https://poofbit.com/api/watchlist/bitcoin

MCP for AI agents

PoofBit is a remote Model Context Protocol server, so Claude, Cursor and other agents can read the indexes as tools. Endpoint https://poofbit.com/mcp (Streamable HTTP), same API key and rate limit as the REST API. Use the https URL in production; some clients (mcp-remote) refuse plain http unless you pass --allow-http.

Claude Code

claude mcp add --transport http poofbit https://poofbit.com/mcp --header "Authorization: Bearer YOUR_KEY"

Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "poofbit": {
      "url": "https://poofbit.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_KEY" }
    }
  }
}

Claude Desktop and other stdio-only clients

Bridge with mcp-remote (needs Node.js). Add to claude_desktop_config.json; the key goes in an environment variable so the header has no space in it:

{
  "mcpServers": {
    "poofbit": {
      "command": "npx",
      "args": ["mcp-remote", "https://poofbit.com/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": { "AUTH_HEADER": "Bearer YOUR_KEY" }
    }
  }
}

The key goes in the Authorization: Bearer … header, as in every snippet above. The URL is /mcp (a trailing slash also works). If your client says the server needs OAuth or authentication, the API key is missing, wrong or revoked: check the header.

Tools

ToolInputReturns
get_chaos_indexnoneThe current Poof Chaos Index and Global Poof Index, same as /api/pci.
list_coinstab, sort, limitCoins with their Poof Index, same as /api/coins. limit defaults to 10 here.
get_poof_indexcoin_idOne coin with history and context (positioning, market beta, where it trades), same as /api/coins/{id}.
explain_methodologynoneFormulas, weights, zones, quadrants, data sources and caveats.
get_watchlistnoneYour watchlist, same as /api/watchlist. Account tokens only; anonymous keys get an error result.

Try asking: β€œWhat's the Poof Chaos Index right now and which top-50 coins have the highest poof risk?”

Reading the index

Poof Chaos Index (market-wide, 0–100)

How turbulent the market has been over the last 24 hours and 7 days, 0–100, direction-neutral: a crash and a pump are equally chaotic: it describes now, not next week. Read it next to Fear & Greed as a second, independent axis. Computed over the top 50 coins by market cap, leaving out stablecoins and wrapped or staked tokens.

Zones

PCIZoneColor
0–20😴 Zen Mode zen #34a853
21–40🌊 Choppy Waters choppy #aef359
41–60🎒 Rollercoaster coaster #FFD200
61–80πŸŒͺ️ High Chaos chaos #fb6b1e
81–100πŸ”₯ Total Meltdown meltdown #ea4335

Quadrants

PCI is direction-neutral, so it is combined with Fear & Greed to tell calm from panic.

ConditionQuadrant
Fear & Greed β‰₯ 50, PCI > 50πŸ€ͺ Euphoric Chaos euphoric
Everyone's a genius and nobody's selling. Classic top-risk territory.
Fear & Greed β‰₯ 50, PCI ≀ 50😌 Calm Greed calm-greed
Complacency mode. The quiet before the poof.
Fear & Greed < 50, PCI > 50🩸 Capitulation Chaos capitulation
Blood in the streets. Fortunes are made (and lost) here.
Fear & Greed < 50, PCI ≀ 50🀫 Quiet Fear quiet-fear
Nobody cares. Historically, that's when patient people accumulate.

Components

ComponentWeightMeasures
Volatility30%Median day-to-day price swings of the top 50 coins over the last 7 days.
Breadth of big moves20%Share of the top 50 that moved more than 5% in 24h, up or down.
Dispersion15%How differently the top 50 moved in 24h. Coins pulling in opposite directions = chaos.
Market cap swing15%How much the combined market cap of the top 50 moved in 24h.
Volume surge10%The top 50's 24h trading volume compared to their market cap.
Memecoin mania10%Average Poof Index of trending coins. Hot garbage trending = mania.

Global Poof Index (market-wide, 11–111)

How much of the market is in a poof state right now. It has no model of its own: it averages the Poof Index of the first 100 coins of the PCI universe that have one, weighted by the square root of market cap (no coin above 15%), with a power mean that lets a few coins deep in a poof pull it up. Shown on the Poof Index scale and zones. Next to it: the share of the market in Red Flag Parade or worse. It describes the present state only and gives no early warning: PCI stays the turbulence gauge (see Does it work?).

Poof Index (one coin, 11–111)

An assessment of a coin's current poof state, learned from 9 years of Binance daily prices, delisted coins included. Six signals from the coin's daily closes go through a logistic model, then a calibration: L (0–100) is the share of similar past coin-states that were in a poof. The index is 11 + L, rounded; 11 is the floor, because crypto is never 0% poof.

SignalMeasuresHigher signal
30-day volatilityHow violently the price moved day to day over the last 30 days.raises the index
Drop from 90-day highHow far the price is below its highest close of the last 90 days.raises the index
Drop from 1-year highHow far the price is below its highest close of the last year.raises the index
7-day moveHow far the price moved over the last 7 days.lowers the index
30-day moveHow far the price moved over the last 30 days.lowers the index
Coin ageHow long the coin has had a price. Young coins go poof more often.lowers the index

A coin needs 31 daily closes for a value; until then lists show β€œβ€”β€. β€œWhy N?” on a coin page shows how far each signal pushes the index up or down compared with a typical coin. Coin age counts from the first daily close we know: a coin known for a year or more counts as old, because our price history starts there.

Poof IndexZoneColor
11–20🧱 Boringly Solid solid #34a853
21–35🀨 Slightly Sus sus #aef359
36–55🎲 Coin Flip flip #FFD200
56–75🚩 Red Flag Parade red #fb6b1e
76–111πŸ’¨ Total Poof poof #ea4335

Context (shown, not scored)

  • Size β€” Smaller market cap = easier to push around.
  • Dilution β€” Fully diluted value vs market cap: how many tokens are still waiting to be dumped on you.
  • Crash from ATH β€” How far the price has fallen from its all-time high.
  • Volume anomaly β€” Trading volume vs market cap. Too much smells like wash trading.

Positioning (context, not scored)

Coins with a Binance perpetual show funding, open interest, long/short and taker ratios, and an estimated liquidation pressure: a model that spreads each day's new open interest over 10x / 25x / 50x leverage (50 / 30 / 20 %) at that day's price. Flags: Funding hot (7-day mean β‰₯ 0.05 % per 8 h), Shorts paying (≀ βˆ’0.03 %), Leverage piling up (open interest +100 % in 28 days), Crowded longs / Crowded shorts (long/short accounts β‰₯ 3 / ≀ 0.5), Long liquidations stacked below (half the open interest within 10 % below). The market beta is the 60-day beta against the top-10 coins. None of this feeds the Poof Index: tested, it did not make the index better.

Every payload carries methodology ("v3" for the Poof Index, "v2" for PCI) so you can tell formula versions apart. The Poof Index describes now, not next week.

Does it work?

Poof Index

Tested walk-forward, year by year from 2021 to 2025: each year was scored by a model trained only on the years before it.

  • What it does: it tells coins in a poof state from the rest with an AUC of 0.695. It flagged 9% of 1,221 collapses before they were obvious (before the drawdown passed 50%), a median 36 days earlier, with 1.5% false alarms. It never flagged BTC, ETH or SOL. Lead times are from the backtest, not a promise.
  • A heavier model: a heavier research model tested alongside (not shipped) flagged 17%, 26 days earlier, at 1.75% false alarms.
  • What it can't: LUNA and FTX gave no warning: what broke them was outside price data. Hacks, frauds, unlocks and exchange trouble show up only once the price moves.
  • Levels drift: the share of coins in a poof state ran from 2% to 38% a year, so the same number overstates the risk in a calm year and understates it in a crash.

Global Poof Index

It describes the present state only. Its correlation with the share of the market in a poof state at the time is 0.40 [0.11, 0.59], against 0.15 for PCI (55 monthly points). Against what happened over the following 90 days it did worse than PCI (0.12 vs 0.43): PCI stays the turbulence gauge and G-PCI is not an early-warning signal.

Poof Chaos Index

We backtested PCI on a year of daily CoinGecko data for 150 coins, fitted every constant on the first 8 months and tested once on the last 4 (June–October 2026). 95% confidence intervals in brackets.

IndexScoreTest
PCI v20.845[0.634, 0.884] correlation with the same 7 days of turbulence (previous formula 0.796)
PCI v2, next week0.42correlation with the next 7 days: no better than assuming last week continues (0.44)
  • Survivorship: the backtest only had coins that are still around.
  • Calm test quarter: expect lower accuracy in a stressed market; one year of data is one market regime.
  • Memecoin mania has no history to calibrate on yet; its scale will be re-anchored on live data.

Code examples

curl

curl -s -H "Authorization: Bearer $POOFBIT_KEY" https://poofbit.com/api/pci

Python

import os
import requests

key = os.environ["POOFBIT_KEY"]
headers = {"Authorization": f"Bearer {key}"}
data = requests.get("https://poofbit.com/api/pci", headers=headers, timeout=10).json()
print(data["pci"], data["zone"]["name"])

JavaScript

const res = await fetch("https://poofbit.com/api/pci", {
  headers: { Authorization: `Bearer ${process.env.POOFBIT_KEY}` },
});
const data = await res.json();
console.log(data.pci, data.zone.name);

Errors & caching

  • 401: missing, unknown or revoked key. See Authentication.
  • 403: the watchlist needs an account token.
  • 404: unknown coin id (/api/coins/{id} and watchlist).
  • 409: the watchlist is full (50 coins).
  • 429: rate limit exceeded. Wait Retry-After seconds.
  • 503 with {"error": "..."}: the data is temporarily unavailable. Retry in a minute.
  • Successful responses carry Cache-Control: private, max-age=60, except /api/watchlist, which is private, no-cache. Market data refreshes every 5 minutes.
  • Request bodies are limited to 64 KB.
  • stale: true means the data missed three refreshes in a row; updated_at says when it was last refreshed.

Rate limits

  • Free keys: 30 requests per minute and 1,000 per day. Account tokens: 120 per minute and 20,000 per day. REST and MCP count together; days are UTC.
  • Over the per-minute limit you get 429 {"error": "Rate limit exceeded", "retry_after": 12} and a Retry-After header.
  • Over the daily limit you get 429 {"error": "Daily limit exceeded", "retry_after": 3600}, with Retry-After counting down to 00:00 UTC.
  • Data freshness is 5 minutes, so polling more than once a minute returns nothing new.
  • Up to 3 new keys per network per hour.

Satire. Not financial advice. Poof risk and the Poof Chaos Index are computed mechanically from public market data (CoinGecko, alternative.me); they are not claims that any project is a scam. Do your own research, then do it again.