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.
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.
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/pciSend your key with every request, in either header:
Authorization: Bearer YOUR_KEY (preferred)X-API-Key: YOUR_KEYKeys 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.
| Tier | Where to get it | Limits |
|---|---|---|
free | The form above, no account | 30 requests per minute and 1,000 per day |
account | Your 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.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.
| Field | Type | Description |
|---|---|---|
pci | integer | The index, 0 (calm) to 100 (maximum turbulence). |
zone | object | Zone the value falls into. |
zone.key | string | Stable machine-readable identifier. |
zone.name | string | Display name. |
zone.emoji | string | Display emoji. |
components | array | The weighted inputs behind the value. |
components[].key | string | Stable component identifier. |
components[].label | string | Display name. |
components[].weight | number | Share of the index, 0 to 1. Weights sum to 1. |
components[].risk | number | Component reading, 0 (calm) to 1 (extreme). Contributes 100 Γ weight Γ risk points. |
components[].detail | string | Human-readable description of the measured value. |
fear_greed | object | null | Crypto Fear & Greed reading; null when unavailable. |
fear_greed.value | integer | 0 (extreme fear) to 100 (extreme greed). |
fear_greed.classification | string | Text classification, e.g. "Greed". |
quadrant | object | null | PCI combined with Fear & Greed; null when fear_greed is null. |
quadrant.key | string | Stable identifier. |
quadrant.emoji | string | Display emoji. |
quadrant.name | string | Display name. |
quadrant.text | string | Short interpretation. |
history | array | One entry per recorded day, oldest first; the last entry is today's current value. |
history[].date | string | UTC date, YYYY-MM-DD. |
history[].pci | integer | Index value for that day. |
history[].source | string | live for values recorded on the day, reconstructed for earlier days rebuilt from historical market data. |
history_days | integer | Number of entries in history (up to one year plus today). |
stale | boolean | true when the data missed three refreshes in a row (market data normally refreshes every 5 minutes). |
updated_at | string | ISO 8601 UTC time the data was last refreshed. |
methodology | string | PCI formula version, currently "v2". History only contains values of this version. |
gpci | object | null | The Global Poof Index: how much of the market is in a poof state. null while it cannot be computed. |
gpci.value | integer | 11 (boringly solid) to 111 (total poof), on the Poof Index scale. |
gpci.zone | object | key, name, emoji of the Poof Index zone it falls into. |
gpci.share_in_poof | number | Share 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 }
}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.
| Parameter | Values | Description |
|---|---|---|
tab | top | all | trending | Top 50 by market cap (default), the top 250, or trending coins. |
q | text | Search in name and ticker. |
zone | solid | sus | flip | red | poof | Only these zones (repeatable). |
sort | poof | mcap | pc24h | pc7d | price | name | Default poof: highest Poof Index first. Coins without a value come last. |
dir | asc | desc | Default desc (asc for name). |
poof_min, poof_max | 11β111 | Poof Index range. |
cap | gt10b | 1b-10b | 100m-1b | lt100m | Market cap buckets (repeatable). |
ch24_min, ch24_max, ch7_min, ch7_max | number | 24h and 7d price change ranges, percent. |
futures | 1 | Only coins with a Binance perpetual. |
flag | hot | longs | shorts | leverage | Positioning flags, any of (repeatable). |
beta_min, beta_max | number | Market beta range. |
hide_stables | 1 | Leave out stablecoins, wrapped tokens and pegged assets. |
page | 1 and up | Page number; past the last page gives the last one. |
per_page | 25 | 50 | 100 | Page size, default 50. |
limit | 1β50 | Older way to set the page size, used when per_page is not given. Out-of-range values are clamped. |
| Field | Type | Description |
|---|---|---|
coins | array | Coin objects of this page, see below. |
tab, sort, dir | string | The values actually used. |
page, per_page | integer | The page returned and its size. |
total | integer | Coins left after the filters, over all pages. |
pages | integer | Number of pages (at least 1). |
filters | object | The filters actually used: q, zone, cap, futures, flag, hide_stables, and the *_min / *_max ranges (null when unset). |
stale | boolean | true when the list missed three refreshes in a row. |
updated_at | string | ISO 8601 UTC time the data was last refreshed. |
methodology | string | Poof Index version, currently "v3". |
coins[].id | string | CoinGecko id, use it with /api/coins/{id}. |
coins[].name, coins[].symbol | string | Display name and upper-case ticker. |
coins[].price | number | null | Price in USD. |
coins[].market_cap | number | null | Market cap in USD. |
coins[].rank | integer | null | Market cap rank. |
coins[].change_24h | number | null | Price change over 24h, percent. |
coins[].poof | integer | null | Poof Index, 11 (boringly solid) to 111 (total poof); null until the coin has 31 daily closes (sorted last). |
coins[].zone | object | null | key, name, emoji of the Poof Index zone; null with poof. |
coins[].components | array | One 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_7d | number | null | Price change over 7d, percent. |
coins[].has_futures | boolean | The coin has a Binance perpetual. |
coins[].flags | array | Positioning flags (hot, longs, shorts, leverage). |
coins[].market_beta | number | null | Beta 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"
}One coin by CoinGecko id (lowercase letters, digits and dashes, e.g. bitcoin):
the coin object from /api/coins plus its history.
| Field | Type | Description |
|---|---|---|
history | array | Daily 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[].date | string | UTC date, YYYY-MM-DD. |
history[].poof | integer | Poof Index for that day. |
past.yesterday, past.last_week, past.last_month | integer | null | Poof Index 1, 7 and 30 days ago; null when unknown. |
methodology | string | Poof Index version, currently "v3"; the whole history is computed with it. |
positioning | object | null | Context, 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_7d | number | null | Funding as a fraction per 8 hours (the day's rates / 3) and its 7-day mean. |
positioning.open_interest_usd, oi_change_28d | number | null | Open interest at the day's close, and its change over 28 days (1.0 = +100 %). |
positioning.ls_accounts, ls_top_positions, taker_ratio | number | null | Long/short ratio of all accounts, of top traders' positions, and taker buy/sell volume. |
positioning.liq_long10, liq_short10 | number | null | Estimate: share of open interest a stated leverage model puts within 10 % below / above the price. |
positioning.flags | array | Up to three plain flags, e.g. "Funding hot", "Leverage piling up". |
market_beta | object | null | Context, not scored: {beta, correlation, days} of daily returns against the top-10 market over 60 days; null below 61 daily closes. |
markets | object | null | Context, 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.native | boolean | The 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[] | array | Up 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[] | array | Up 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_at | string | UTC 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/bitcoinThe coins on your account's watchlist. Needs an account token; anonymous keys get 403:
{ "error": "Watchlist needs an account token" }{"coins", "stale", "updated_at", "methodology"}, with the same coin objects as
/api/coins.
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/bitcoinPoofBit 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 mcp add --transport http poofbit https://poofbit.com/mcp --header "Authorization: Bearer YOUR_KEY"Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"poofbit": {
"url": "https://poofbit.com/mcp",
"headers": { "Authorization": "Bearer YOUR_KEY" }
}
}
}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.
| Tool | Input | Returns |
|---|---|---|
get_chaos_index | none | The current Poof Chaos Index and Global Poof Index, same as /api/pci. |
list_coins | tab, sort, limit | Coins with their Poof Index, same as /api/coins. limit defaults to 10 here. |
get_poof_index | coin_id | One coin with history and context (positioning, market beta, where it trades), same as /api/coins/{id}. |
explain_methodology | none | Formulas, weights, zones, quadrants, data sources and caveats. |
get_watchlist | none | Your 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?β
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.
| PCI | Zone | Color |
|---|---|---|
| 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 |
PCI is direction-neutral, so it is combined with Fear & Greed to tell calm from panic.
| Condition | Quadrant |
|---|---|
| Fear & Greed β₯ 50, PCI > 50 | π€ͺ Euphoric Chaos euphoricEveryone's a genius and nobody's selling. Classic top-risk territory. |
| Fear & Greed β₯ 50, PCI β€ 50 | π Calm Greed calm-greedComplacency mode. The quiet before the poof. |
| Fear & Greed < 50, PCI > 50 | π©Έ Capitulation Chaos capitulationBlood in the streets. Fortunes are made (and lost) here. |
| Fear & Greed < 50, PCI β€ 50 | π€« Quiet Fear quiet-fearNobody cares. Historically, that's when patient people accumulate. |
| Component | Weight | Measures |
|---|---|---|
| Volatility | 30% | Median day-to-day price swings of the top 50 coins over the last 7 days. |
| Breadth of big moves | 20% | Share of the top 50 that moved more than 5% in 24h, up or down. |
| Dispersion | 15% | How differently the top 50 moved in 24h. Coins pulling in opposite directions = chaos. |
| Market cap swing | 15% | How much the combined market cap of the top 50 moved in 24h. |
| Volume surge | 10% | The top 50's 24h trading volume compared to their market cap. |
| Memecoin mania | 10% | Average Poof Index of trending coins. Hot garbage trending = mania. |
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?).
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.
| Signal | Measures | Higher signal |
|---|---|---|
| 30-day volatility | How violently the price moved day to day over the last 30 days. | raises the index |
| Drop from 90-day high | How far the price is below its highest close of the last 90 days. | raises the index |
| Drop from 1-year high | How far the price is below its highest close of the last year. | raises the index |
| 7-day move | How far the price moved over the last 7 days. | lowers the index |
| 30-day move | How far the price moved over the last 30 days. | lowers the index |
| Coin age | How 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 Index | Zone | Color |
|---|---|---|
| 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 |
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.
Tested walk-forward, year by year from 2021 to 2025: each year was scored by a model trained only on the years before it.
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.
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.
| Index | Score | Test |
|---|---|---|
| PCI v2 | 0.845 | [0.634, 0.884] correlation with the same 7 days of turbulence (previous formula 0.796) |
| PCI v2, next week | 0.42 | correlation with the next 7 days: no better than assuming last week continues (0.44) |
curl -s -H "Authorization: Bearer $POOFBIT_KEY" https://poofbit.com/api/pciimport 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"])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);/api/coins/{id} and watchlist).Retry-After seconds.{"error": "..."}: the data is temporarily unavailable. Retry in a minute.Cache-Control: private, max-age=60, except /api/watchlist, which is private, no-cache. Market data refreshes every 5 minutes.stale: true means the data missed three refreshes in a row; updated_at says when it was last refreshed.{"error": "Rate limit exceeded", "retry_after": 12} and a Retry-After header.{"error": "Daily limit exceeded", "retry_after": 3600}, with Retry-After counting down to 00:00 UTC.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.