SatsAPI Documentation

SatsAPI is a Bitcoin market intelligence API that uses the Lightning Network L402 protocol for pay-per-call pricing. No registration, no API keys, no subscriptions. You pay in satoshis, you get data.

The API provides 8 endpoints covering real-time price data, mempool analysis, on-chain metrics, derivatives, AI-generated signals and full market summaries. Every response is structured for both human developers and autonomous AI agents.

Current status
SatsAPI is live on mainnet. L402 payment enforcement is active — all endpoints require a Lightning payment to access.

Base URL

endpoint
https://satsapi.dev

All endpoints are served over HTTPS. HTTP requests are redirected to HTTPS.

Quick Start

Three steps to get data. No setup, no account:

bash
# Step 1 — request returns 402 + invoice
curl -s https://satsapi.dev/v1/price
# → { "invoice": "lnbc30n1p...", "payment_hash": "fa7f01...", "amount_sats": 3 }

# Step 2 — pay the invoice with any Lightning wallet
# (Phoenix, Alby, Breez, lncli…)

# Step 3 — retry with payment_hash as query param
curl -s "https://satsapi.dev/v1/price?payment_hash=fa7f01..." | jq .

Error Codes

StatusCodeDescription
402payment_requiredResponse body contains invoice and payment_hash. Pay the invoice, then retry with ?payment_hash=.
429rate_limit_exceededToo many requests. Check Retry-After header.
500upstream_errorExternal data source temporarily unavailable.
503service_unavailableAPI temporarily offline.

Rate Limits

Rate limits are enforced per IP address:

TierEndpointsLimit
Standard/v1/price · /v1/mempool · /v1/tx · /v1/onchain · /v1/derivatives60 req/min
AI/v1/news · /v1/signal10 req/min
Heavy/v1/summary5 req/min

Authentication L402

SatsAPI uses the L402 protocol (HTTP 402 Payment Required) for authentication. Instead of API keys, you pay a tiny Lightning Network invoice per request. The payment hash becomes your proof of payment — no sessions, no cookies, no tokens to store.

L402 is designed for machine-to-machine micropayments — AI agents can pay for API calls autonomously without human intervention.

No account required
There is no registration, no email, no credit card, no API key. The Lightning invoice is the credential. The payment_hash is the proof.

Payment Flow

SatsAPI implementation note
SatsAPI uses a simplified L402 variant. Authentication is passed as a ?payment_hash= query parameter — not as an Authorization header. This makes integration trivial from any HTTP client without special libraries.
01

Make the initial request

Call any endpoint as a standard GET request. No headers required.

02

Receive HTTP 402 + invoice

The server responds with status 402. The JSON body contains invoice (BOLT11), payment_hash and amount_sats.

03

Pay the Lightning invoice

Use any Lightning wallet — Phoenix, Alby, Breez, lncli — or any library. Payment settles in milliseconds.

04

Retry with ?payment_hash=

Resend the same request with the payment_hash from step 2 appended as a query parameter. The server verifies payment on phoenixd and returns the data.

402 Response Body

402 Payment Requiredapplication/json
{
  "error": "Payment Required",
  "amount_sats": 3,
  "invoice": "lnbc30n1p5xyzabc...",
  "payment_hash": "fa7f01e2d3c4b5a6...",
  "message": "Pay 3 sats to access this endpoint. Then retry with ?payment_hash=fa7f01..."
}

Authenticated Retry

bash
# After paying the invoice, retry with the payment_hash
curl "https://satsapi.dev/v1/price?payment_hash=fa7f01e2d3c4b5a6..."

# Response: 200 OK with full data

Compatible Tools

ToolTypeUse case
Phoenix WalletMobilePay invoices manually on iOS/Android. Copy the invoice from the 402 response body.
AlbyBrowser ext.Browser-based Lightning wallet. Supports WebLN for programmatic payments from frontend.
lncliCLILND command-line client. lncli payinvoice <bolt11>
lngetCLIDrop-in L402 curl replacement. Handles 402 → pay → retry automatically.
WebLNJS libraryBrowser-based Lightning API. await webln.sendPayment(invoice)
LNCJS libraryLightning Node Connect. Node.js / browser library for server-side programmatic payments.

Endpoint Reference

GET /v1/demo

GET https://satsapi.dev/v1/demo FREE · 5 req/hour

Free demo endpoint returning real BTC price data — no Lightning wallet required. Limited to 5 calls per hour per IP. Designed for developers who want to try the API before setting up a Lightning payment.

Try it now

curl https://satsapi.dev/v1/demo

Example response

"endpoint": "/v1/demo",
"cost_sats": 0,
"demo": true,
"data": {
  "price_usd":       69259,
  "change_24h_pct":  3.13,
  "volume_24h_usd":  49921543297,
  "market_cap_usd":  1384996162769,
  "timestamp":       "2026-03-09T14:52:39.810Z"
},
"upgrade": {
  "message": "Get RSI, MACD, signals, mempool, on-chain data and more — pay per call in sats.",
  "docs":    "https://satsapi.dev/docs"
}

Rate limit: 5 requests/hour per IP. No payment required. Real data from CoinGecko.

GET /v1/price

GET https://satsapi.dev/v1/price 3 sats · 60 req/min

Returns the current BTC/USD price with key technical indicators: RSI-14, 50-day and 200-day moving averages, MACD bias, 24h change, high/low, volume and trend classification. Data sourced from CryptoCompare.

Response Fields

FieldTypeDescription
symbolstringAlways "BTC/USD"
pricenumberCurrent price in USD
change_24hstring24h price change as percentage string (e.g. "-1.24%")
high_24hnumber24h high price in USD
low_24hnumber24h low price in USD
volume_24hstring24h trading volume (formatted, e.g. "$13.5B")
ma_50number50-day simple moving average
ma_200number200-day simple moving average
rsi_14number14-period RSI (0–100)
trendstring"BULLISH" | "BEARISH" | "NEUTRAL"
macd_biasstring"BULLISH" | "BEARISH" | "NEUTRAL"

Example Response

200 OKapplication/json
{
  "endpoint": "/v1/price",
  "cost_sats": 3,
  "data": {
    "symbol": "BTC/USD",
    "price": 84231.50,
    "change_24h": "-1.24%",
    "high_24h": 85900.00,
    "low_24h": 83100.00,
    "volume_24h": "$42.1B",
    "ma_50": 87420.15,
    "ma_200": 71380.44,
    "rsi_14": 44.2,
    "trend": "BEARISH",
    "macd_bias": "BEARISH"
  },
  "timestamp": "2026-03-07T20:00:00.000Z"
}

GET /v1/mempool

GET https://satsapi.dev/v1/mempool 2 sats · 60 req/min

Returns current mempool state: pending transaction count, congestion level, recommended fees for different confirmation targets, and last block data. Sourced from mempool.space.

Response Fields

FieldTypeDescription
pending_txsnumberNumber of unconfirmed transactions
congestionstring"LOW" | "MEDIUM" | "HIGH"
fees.fast_10minstringRecommended fee for ~10 min confirmation
fees.medium_30minstringRecommended fee for ~30 min confirmation
fees.slow_1hstringRecommended fee for ~1 hour confirmation
last_block.heightnumberHeight of the most recently mined block
last_block.tx_countnumberTransactions in the last block

GET /v1/tx/:txid

GET https://satsapi.dev/v1/tx/:txid 2 sats · 60 req/min

Looks up a Bitcoin transaction by TXID. Returns confirmation status, block position, fee details, input/output counts and transferred value. Sourced from mempool.space.

Path Parameters

ParameterTypeDescription
txidstring64-character hex transaction ID

Response Fields

FieldTypeDescription
statusstring"CONFIRMED" | "PENDING"
confirmationsnumberNumber of confirmations. 0 if unconfirmed.
block_heightnumber|nullBlock height where tx was included. null if pending.
fee_satsnumberTotal fee in satoshis
fee_ratestringFee rate in sat/vByte
inputsnumberNumber of inputs
outputsnumberNumber of outputs
value_btcstringTotal output value in BTC

GET /v1/onchain

GET https://satsapi.dev/v1/onchain 15 sats · 60 req/min

Aggregated on-chain intelligence: Fear & Greed index, BTC market dominance, circulating supply, network hashrate and an AI-derived market phase. Sources: alternative.me (Fear & Greed), CoinGecko (dominance/supply).

Response Fields

FieldTypeDescription
fear_and_greed.valuenumberIndex value 0–100
fear_and_greed.labelstring"Extreme Fear" | "Fear" | "Neutral" | "Greed" | "Extreme Greed"
fear_and_greed.trendstring"IMPROVING" | "DETERIORATING" | "STABLE"
dominance.btc_dominancestringBTC market cap dominance percentage
supply.circulating_btcnumberCurrent circulating supply
network.hashrate_ehnumberHash rate in exahashes/second
market_phase.phasestringDetected market phase classification

GET /v1/derivatives

GET https://satsapi.dev/v1/derivatives 15 sats · 60 req/min

Perpetual futures market data: funding rate, open interest trend, long/short ratio and leverage risk assessment.

⚠ Estimated data — read before using
Major derivatives exchanges (Binance, Bybit, OKX) block requests from cloud server IP ranges, including Railway where SatsAPI is hosted. This endpoint returns estimated values derived from price momentum and CryptoCompare data — not real exchange data. The response always includes estimated: true and a data_note field explaining this. Do not use this endpoint for precise funding rate or open interest figures.

Response Fields

FieldTypeDescription
funding_rate.current_pctnumberEstimated 8-hour funding rate as percentage
funding_rate.biasstring"BULLISH" | "NEUTRAL" | "BEARISH" | "SHORTS_PAYING"
open_interest.trendstring"INCREASING" | "DECREASING" | "STABLE"
long_short.long_pctnumberEstimated percentage of accounts with long positions
leverage_riskstring"LOW" | "MEDIUM" | "HIGH" | "EXTREME"
estimatedbooleanAlways true — data is estimated from momentum
data_notestringExplanation of estimation methodology

GET /v1/news

GET https://satsapi.dev/v1/news 50 sats · 10 req/min · cached 6h

AI-generated news sentiment analysis powered by Claude. Fetches the latest Bitcoin headlines from the CoinDesk RSS feed, analyzes them for market sentiment, and returns a structured summary with sentiment score, top 3 key events, and market impact narrative.

Caching — 6 hours
This endpoint is cached for 6 hours to reduce Claude API costs. The cached field indicates whether the response is fresh or served from cache. The cached_at timestamp tells you when the cache was last refreshed.

Response Fields

FieldTypeDescription
sentimentstring"BULLISH" | "NEUTRAL" | "BEARISH"
scorenumberSentiment score 0.0–1.0
summarystringAI-generated 2-3 sentence market narrative
top_eventsstring[]Array of 3 key news events
cachedbooleantrue if response served from 6h cache
cached_atstringISO timestamp of last cache refresh

GET /v1/signal

GET https://satsapi.dev/v1/signal 150 sats · 10 req/min

Multi-factor AI trading signal. Aggregates price, mempool, on-chain and derivatives data and sends it to Claude for analysis. Returns a BUY / SELL / HOLD signal with confluence score, detailed reasoning and an ATR-based trade setup when applicable.

Response Fields

FieldTypeDescription
signalstring"BUY" | "SELL" | "HOLD"
confluencenumberPercentage of factors aligned (0–100)
confidencenumberModel confidence 0.0–1.0
risk_levelstring"LOW" | "MEDIUM" | "HIGH" | "EXTREME"
reasoningstringAnalyst-grade explanation of the signal
trade_setupobject|nullEntry, stop-loss and target levels. null if no clear setup.
technicals.rsi_1dnumberDaily RSI
technicals.rsi_4hnumber4-hour RSI
technicals.atr_14dnumber14-day Average True Range in USD

GET /v1/summary ★

GET ★ https://satsapi.dev/v1/summary 200 sats · 5 req/min · cached 10min

The flagship endpoint. Aggregates all 7 other endpoints into a single comprehensive market intelligence report. Includes a 0–100 market score, AI executive summary, full risk matrix, key support/resistance levels and a flat bot_ready object designed for autonomous agent consumption.

Response Fields

FieldTypeDescription
market_scorenumberOverall market score 0–100. <40 bearish · 40–60 neutral · >60 bullish.
market_score_labelstring"BEARISH" | "NEUTRAL" | "BULLISH"
executive_summarystring4-6 sentence analyst-grade narrative of current conditions.
bot_readyobjectFlat typed object with all critical fields. See below. Only available in /v1/summary.
risk_matrixobject[]Array of risk/opportunity items with level and note.

bot_ready Object

Only in /v1/summary
The bot_ready object is exclusive to /v1/summary. It is not returned by /v1/signal. It provides a single flat object with all critical fields as primitives — no nested parsing required.
typescript — bot_ready shape
signal:            "BUY" | "SELL" | "HOLD"
confluence:        number   // 0–100 factor alignment
market_score:      number   // 0–100 overall score
price_usd:         number   // current BTC price
rsi_1d:            number   // daily RSI
rsi_4h:            number   // 4-hour RSI
fear_greed:        number   // 0–100 index value
fear_greed_label:  string   // human-readable classification
funding_bias:      "BULLISH" | "NEUTRAL" | "BEARISH"
long_pct:          number   // % accounts long (estimated)
leverage_risk:     "LOW" | "MEDIUM" | "HIGH" | "EXTREME"
support:           number   // key support level USD
resistance:        number   // key resistance level USD
highest_risk:      string   // top risk/opportunity label

Code Examples

JavaScript / Node.js

Full L402 payment flow

javascript
async function callSatsAPI(path) {
  // 1. Initial request
  let res = await fetch(`https://satsapi.dev${path}`);

  // 2. Handle 402 — pay Lightning invoice
  if (res.status === 402) {
    const body = await res.json();
    // { invoice: "lnbc30n1...", payment_hash: "fa7f01...", amount_sats: 3 }

    // Pay with your Lightning wallet/library
    await wallet.payInvoice(body.invoice);

    // 3. Retry with payment_hash as query param
    res = await fetch(
      `https://satsapi.dev${path}?payment_hash=${body.payment_hash}`
    );
  }

  return res.json();
}

// Usage
const { data } = await callSatsAPI('/v1/price');
console.log(data.price);   // 84231.50
console.log(data.rsi_14);  // 44.2
console.log(data.trend);   // "BEARISH"

Get summary + bot_ready

javascript
const { data } = await callSatsAPI('/v1/summary');
const b = data.bot_ready;

console.log(b.signal);        // "HOLD"
console.log(b.confluence);    // 52
console.log(b.price_usd);     // 84231.50
console.log(b.fear_greed);    // 28
console.log(b.leverage_risk); // "LOW"

Python

python
import requests

def call_sats_api(path: str, wallet=None) -> dict:
    url = f"https://satsapi.dev{path}"

    # 1. Initial request
    r = requests.get(url)

    # 2. Handle 402 payment
    if r.status_code == 402 and wallet:
        body         = r.json()
        invoice      = body["invoice"]
        payment_hash = body["payment_hash"]

        # Pay invoice with any LN wallet/library
        wallet.pay(invoice)

        # 3. Retry with payment_hash as query param
        r = requests.get(url, params={"payment_hash": payment_hash})

    r.raise_for_status()
    return r.json()

# Usage
data = call_sats_api("/v1/signal")["data"]
print(data["signal"])      # "HOLD"
print(data["confluence"])  # 52
print(data["reasoning"])   # "Neutral RSI at 49.3..."

cURL

bash
# Step 1 — get invoice
curl -s https://satsapi.dev/v1/price
# → {"invoice":"lnbc30n1p...","payment_hash":"fa7f01...","amount_sats":3}

# Step 2 — pay invoice with your wallet (Phoenix, lncli, Alby…)

# Step 3 — retry with payment_hash
curl -s "https://satsapi.dev/v1/price?payment_hash=fa7f01..." | jq .data

# Full summary
curl -s "https://satsapi.dev/v1/summary?payment_hash=..." | jq .data.bot_ready

# Transaction lookup
curl -s "https://satsapi.dev/v1/tx/4a5e1e4baab89f3a...?payment_hash=..." | jq .

# Using lnget (handles 402 automatically)
lnget https://satsapi.dev/v1/signal | jq .data.signal

AI Agent Integration

SatsAPI is designed from the ground up for autonomous AI agents. The L402 protocol lets agents pay for data without human intervention, and the bot_ready object in /v1/summary eliminates all parsing complexity.

The bot_ready Object

Every call to /v1/summary returns a flat bot_ready object. All fields are primitives — no nested objects, no arrays, no post-processing required.

Zero parsing required
if (b.signal === 'BUY' && b.confluence > 65 && b.leverage_risk !== 'EXTREME') — that's the entire decision logic for a trading bot.

Autonomous Payment Flow

The full 402 → pay → retry cycle can be automated in ~10 lines. Using lnget, it's a single command:

bash
# lnget handles 402 → pay → retry automatically
lnget https://satsapi.dev/v1/summary | jq .data.bot_ready

Integration Examples

LangChain Tool

javascript
import { Tool } from "langchain/tools";

class BitcoinIntelligenceTool extends Tool {
  name = "bitcoin_market_intelligence";
  description = "Returns BTC market signal (BUY/SELL/HOLD), " +
    "price, RSI, risk and confluence score. " +
    "Call before any Bitcoin-related decision.";

  async _call() {
    // Step 1 — get invoice
    let res = await fetch("https://satsapi.dev/v1/summary");
    if (res.status === 402) {
      const { invoice, payment_hash } = await res.json();
      await this.wallet.payInvoice(invoice); // pay 200 sats
      res = await fetch(
        `https://satsapi.dev/v1/summary?payment_hash=${payment_hash}`
      );
    }
    const { data } = await res.json();
    return JSON.stringify(data.bot_ready);
  }
}

// Agent receives a flat object — no parsing needed:
// { signal:"HOLD", confluence:52, price_usd:84231, fear_greed:28,
//   support:79400, resistance:91200, leverage_risk:"LOW" }

Cron-based trading bot

javascript
// Runs every 4 hours — costs 200 sats/run (~1,200 sats/day)
async function tradingCycle() {
  // Fetch + pay in one helper
  const { data } = await callSatsAPI("/v1/summary");
  const b = data.bot_ready;

  // Only act on high-confluence signals
  if (b.signal === "BUY" && b.confluence >= 65 && b.leverage_risk !== "EXTREME") {
    await exchange.createOrder("BTC/USDT", "buy", b.price_usd * 0.995);
    log(`BUY @ ${b.price_usd} — confluence ${b.confluence}% — stop ${b.support}`);
  }

  if (b.signal === "SELL" && b.confluence >= 70) {
    await exchange.closePositions();
    log(`SELL @ ${b.price_usd} — market score ${b.market_score}/100`);
  }
}

cron.schedule("0 */4 * * *", tradingCycle);

AutoGPT / OpenAgents function definition

python
tools = [{
    "type": "function",
    "function": {
        "name": "get_bitcoin_signal",
        "description": "Get current BTC market signal and risk. Returns bot_ready object.",
        "parameters": { "type": "object", "properties": {} }
    }
}]

def get_bitcoin_signal():
    # Step 1 — request
    r = requests.get("https://satsapi.dev/v1/summary")
    if r.status_code == 402:
        body = r.json()
        wallet.pay(body["invoice"])
        r = requests.get(
          "https://satsapi.dev/v1/summary",
          params={"payment_hash": body["payment_hash"]}
        )
    return r.json()["data"]["bot_ready"]
Risk disclaimer
SatsAPI signals are informational only and do not constitute financial advice. Past signal performance does not guarantee future results. Always implement your own risk management.