API Documentation

REST API for real-time Bitcoin on-chain intelligence. All endpoints return JSON.

Overview

Base URL: https://dashboard.btcwhalealerts.com/v1
Auth: Bearer token or HMAC signature (see below)
Format: JSON (UTF-8)
Tier: Research (T3) — 149 CHF/month, 100,000 requests/month, 60 requests/minute

Free trial: All new users get 90 days of Research-tier access automatically via Telegram login on the dashboard.

Authentication

Two auth methods are supported. Pick the one that fits your client.

Method 1: Bearer Token (simple)

Pass the full token in the Authorization header:

Authorization: Bearer swi_live_<keyid>_<secret>

Tokens have the format swi_live_<keyid>_<secret> — e.g. swi_live_ExampleKeyId_ExampleSecretNotARealKey (illustration only, not a live token). The public keyid identifies the key; the secret authenticates it. The token is stored hashed on our side — we never log the plaintext.

Method 2: HMAC Signature (enterprise)

For clients that require signed requests (no secret leakage even if TLS is MITM'd):

Authorization: Bearer swi_live_<keyid>
X-Timestamp: 1776368400
X-Signature: sha256=<hex(hmac_sha256(secret, "{ts}.{method}.{path}.{body}"))>

Timestamp must be within ±300 seconds of server time. Body is the raw request body (empty string for GET).

export SWI_TOKEN="swi_live_xxx_yyy"
curl "https://dashboard.btcwhalealerts.com/v1/stats" \
     -H "Authorization: Bearer $SWI_TOKEN" | jq

Rate Limits

Every response includes these headers:

When exceeded, you get HTTP 429 Too Many Requests with a Retry-After header (seconds). The monthly counter resets on the 1st of each month UTC.

Errors

All errors follow this shape:

{
  "error": {
    "code": "invalid_key",
    "message": "API key not found or revoked"
  }
}
HTTPcodeMeaning
400invalid_address, invalid_txidMalformed input
401missing_auth, invalid_key, invalid_secret, hmac_failedAuth failure
404not_foundResource doesn't exist or is outside our dataset
429rate_limit_exceededQuota exhausted — check Retry-After
500internal_errorServer error (please report)

Endpoints

GET /v1/ping public

Health check. Returns {"ok": true, "time": "..."}. No auth required.

GET /v1/stats auth

Coverage + activity snapshot.

Response

{
  "addresses_monitored": 831315,
  "whale_trades_total": 3108897,
  "whales_today": 898,
  "volume_today_btc": 532528.2,
  "btc_price_usd": 75256.0,
  "fear_greed_index": 23,
  "fear_greed_label": "Extreme Fear"
}
GET /v1/whales/recent auth

Recent whale transactions, reverse-chronological. Filterable by flow type and size.

Parameters

ParamTypeDefaultDescription
limitint50Max rows (capped at 500)
min_btcfloat100Minimum total_btc threshold
flowstringto_exchange · from_exchange · wallet_to_wallet · exchange_to_exchange
beforestringOpaque pagination cursor from the previous page's next_cursor field. Works for the full historical dataset.
since_idintLegacy frontier-streaming cursor (only rows since 2026-04 with populated id). Use before for historical pagination.
langstringenIntent-text language (en, de, es)

Response (1 row shown)

{
  "data": [{
    "id": 4912345,
    "txid": "abc123...",
    "timestamp": "2026-04-16T20:09:15+00:00",
    "total_btc": 847.5,
    "from_address": "bc1q...",
    "to_address": "3Abc...",
    "recipient_trust": 0.94,
    "score": 9,
    "flow_type": "to_exchange",
    "flags": "mega_whale,exchange_flow",
    "block_height": 945128,
    "intent": {
      "code": "distribution",
      "text": "Likely distribution — whale moved to exchange",
      "confidence": 0.9,
      "emoji": "🔴"
    }
  }],
  "count": 1
}

Intent codes: distribution · accumulation · exchange_shift · treasury_move · cold_storage · new_whale · otc_likely · neutral. See Intent classification.

GET /v1/whale/{txid} auth

Detailed metadata for a single transaction. Returns 404 if the transaction is not in our whale dataset (i.e. below the capture threshold).

GET /v1/address/{addr} auth

Aggregated metrics for a Bitcoin address: balance, total in/out, first/last seen, trust index, spike score, entity label (if known). Returns 404 if address is not in our watchlist.

GET /v1/sentiment auth

Confidence-weighted community sentiment across 7 sources (Telegram, Reddit, Bluesky, Farcaster, News, Google Trends, Fear & Greed).

Parameters

ParamTypeDefaultDescription
hoursint24Lookback window in hours (max 720 = 30 days)

Response

{
  "window_hours": 24,
  "overall": {
    "score": 0.248,   // range -1.0 (bearish) to +1.0 (bullish)
    "label": "neutral",
    "mentions": 368
  },
  "platforms": {
    "telegram": {"score": 0.15, "mentions": 120},
    "reddit":   {"score": 0.32, "mentions": 62},
    "bluesky":  {"score": 0.23, "mentions": 90},
    "farcaster":{"score": 0.35, "mentions": 64},
    "news":     {"score": 0.23, "mentions": 58},
    "google_trends":{"score": 0.31, "mentions": 10},
    "fear_greed":   {"score": -0.54, "mentions": 1}
  }
}

Intent Classification

Every whale transaction comes with a heuristic intent classification — a single-sentence interpretation of what the move likely signals. This is transparent and deterministic (no ML black-box): rules based on flow type, entity labels, amount, and recipient trust score.

CodeEmojiMeaningTrigger
distribution🔴Whale moved to exchange — potential sell pressureflow to exchange
accumulation🟢Withdrawal from exchange — potential hodlflow from exchange
exchange_shift🔄Exchange-to-exchange shift — OTC / custody rerouteboth sides exchange
cold_storage❄️Exchange → unknown address ≥500 BTClarge, no recipient entity
treasury_move🏦Internal move between known entitiesboth sides known (non-exchange)
new_whale🆕Recipient not previously trackedtrust=0, amount ≥200 BTC
otc_likely💼Round amount, w2w, largeheuristic: 500/1000/2500 BTC etc.
neutralNo strong signaldefault

Versioning

This is API v1. Breaking changes go into v2. We commit to maintaining v1 for at least 12 months after v2 ships.

Support

Issues, feature requests, or bulk/enterprise inquiries: dev@btcwhalealerts.com