API DOCS

Three proprietary BTC options signals delivered via WebSocket, REST, and webhooks. Built for AI trading bots and human developers alike.

AI Agent? Skip this page. Load https://api.orangepulseapp.com/skill into your context — it's a compressed, token-efficient version of everything here. Or install the CLI: npm install -g orangepulse && orangepulse skill

Base URL

https://api.orangepulseapp.com

Response format

All responses are JSON. All timestamps are ISO 8601 UTC. null values mean the signal hasn't computed yet — skip that cycle and retry on next tick.

AUTHENTICATION

Every request (except /health, /skill, /docs.txt) requires your API key in the request header.

Header

X-API-Key: op_your_key_here

Example

curlcurl https://api.orangepulseapp.com/v1/signals/all \
  -H "X-API-Key: op_your_key_here"

Key format

All API keys begin with op_ followed by a 48-character hex string. Keys are issued instantly on payment confirmation and emailed to you.

ErrorMeaning
Missing X-API-Key headerNo key was sent with the request
Invalid API keyKey doesn't exist or was mistyped
API key disabledSubscription cancelled or key revoked
API key expired30-day crypto subscription has elapsed

QUICKSTART

Option A — CLI (fastest)

bash# Install
npm install -g orangepulse

# Authenticate
orangepulse auth op_your_key

# Fetch snapshot of all signals
orangepulse signals all

# Live WebSocket stream
orangepulse watch

Option B — JavaScript (WebSocket)

javascriptconst ws = new WebSocket('wss://api.orangepulseapp.com/ws');

ws.onopen = () => {
  ws.send(JSON.stringify({ type: 'auth', key: 'op_your_key' }));
};

ws.onmessage = ({ data }) => {
  const msg = JSON.parse(data);

  if (msg.type === 'connected') {
    // Subscribe to specific signals
    ws.send(JSON.stringify({
      type: 'subscribe',
      signals: ['btc_pulse_index', 'btc_options_pulse', 'btc_touch_pulse']
    }));
  }

  if (msg.type === 'signal') {
    const { signal, payload } = msg;
    // payload.regime, .confidence, .alert
    console.log(signal, payload);
  }
};

// Keepalive ping every 30s
setInterval(() => ws.send(JSON.stringify({ type: 'ping' })), 30000);

Option C — Python (REST polling)

pythonimport requests, time

API_KEY  = "op_your_key"
BASE_URL = "https://api.orangepulseapp.com"
HEADERS  = {"X-API-Key": API_KEY}

while True:
    res  = requests.get(f"{BASE_URL}/v1/signals/all", headers=HEADERS)
    data = res.json()

    idx = data["btc_pulse_index"]
    if idx["alert"]:          # check alert field first
        handle_alert(idx["alert"])
    if idx["confidence"] > 0.75:
        trade_on_regime(idx["regime"])

    time.sleep(5)              # respect your tier's poll interval

BTC PULSE INDEX™

A composite 0–100 sentiment score synthesizing six live BTC options market signals into one regime indicator.

GET /v1/signals/btc-pulse-index
Returns the current BTC Pulse Index reading with regime classification and confidence score.

Response fields

FieldTypeDescription
valuefloatComposite score 0–100. >60 = bullish, 40–60 = neutral, <40 = bearish
regimestring"bullish" | "bearish" | "neutral"
confidencefloat0.0–1.0. Only act on signals above 0.75
prev_valuefloatValue from previous tick
deltafloatChange since last tick. Positive = rising momentum
alertstring|nullNon-null when a threshold is crossed. Check this field first.
timestampstringISO 8601 UTC

Example response

json{
  "signal":     "btc_pulse_index",
  "value":      74.2,
  "regime":     "bullish",
  "confidence": 0.87,
  "prev_value": 71.5,
  "delta":      2.7,
  "alert":      null,
  "timestamp":  "2026-03-29T18:00:00Z"
}

BTC OPTIONS PULSE™

Real-time BTC options market microstructure — IV skew, term structure, net flow direction, put/call ratio, and IV rank.

GET /v1/signals/btc-options-pulse
Returns current options market conditions and flow analysis.

Response fields

FieldTypeDescription
iv_skewstring"put_heavy" | "call_heavy" | "neutral"
term_structurestring"contango" | "backwardated" | "flat"
net_flowstring"bullish" | "bearish" | "neutral" — net options buying pressure
scorefloat-1.0 to +1.0. Negative = bearish options pressure
put_call_ratiofloat>1.2 = fear, <0.8 = greed
iv_rankfloat0–100. >80 = expensive options, <20 = cheap
alertstring|nullNon-null on significant flow event
timestampstringISO 8601 UTC

BTC TOUCH PULSE™

Detects when BTC price touches key support or resistance levels and classifies the market reaction in real time.

GET /v1/signals/btc-touch-pulse
Returns the most recent key level touch event and reaction classification.

Response fields

FieldTypeDescription
level_touchedfloatBTC price level that was touched
level_typestring"support" | "resistance" | "key_level"
touch_strengthfloat0.0–1.0. >0.8 = strong touch worth acting on
reactionstring"bounce" | "break" | "consolidating"
scorefloat-1.0 to +1.0. Positive = bullish reaction
alertstring|nullNon-null on strong touch or breakout event
timestampstringISO 8601 UTC

ALL SIGNALS

Fetch all three signals in a single HTTP call. Use this on bot startup to initialize state.

GET /v1/signals/all
Returns btc_pulse_index, btc_options_pulse, and btc_touch_pulse in one response. More efficient than three separate calls.

WEBSOCKET

The recommended delivery method. Connect once, receive all signal updates in under 50ms as they're computed. Dramatically reduces API call usage vs polling.

WS wss://api.orangepulseapp.com/ws
Persistent WebSocket connection. Authenticate after connecting, then subscribe to signals.

Protocol

StepYou sendYou receive
1. Auth{"type":"auth","key":"op_..."}{"type":"connected"}
2. Subscribe{"type":"subscribe","signals":["btc_pulse_index",...]}{"type":"subscribed"}
3. Receive{"type":"signal","signal":"btc_pulse_index","payload":{...}}
Keepalive{"type":"ping"} every 30s{"type":"pong"}

Reconnection

Always reconnect on disconnect with exponential backoff — 5s, 10s, 20s, max 60s. Re-authenticate and re-subscribe after reconnecting. Fall back to polling /v1/signals/all every 5s during downtime.

Close codes

CodeMeaning
4001Invalid API key
4002API key disabled or expired

REST API

Poll signals on a schedule. Useful for bots with infrequent decision cycles. All endpoints require X-API-Key header.

Endpoints

Method + PathDescription
GET /healthHealth check — no auth required
GET /v1/signals/btc-pulse-indexBTC PULSE INDEX™
GET /v1/signals/btc-options-pulseBTC Options Pulse™
GET /v1/signals/btc-touch-pulseBTC Touch Pulse™
GET /v1/signals/allAll three signals in one call
POST /v1/webhooksRegister a webhook
DEL /v1/webhooksRemove a webhook
GET /skillSkill file for AI agents
GET /docs.txtPlain text agent docs
GET /llms.txtllms.txt standard

WEBHOOKS

Register a URL to receive signal pushes when thresholds are crossed. Your server receives a POST with a signed payload.

Register

json — POST /v1/webhooks{
  "url":       "https://your-bot.com/webhook",
  "signals":   ["btc_pulse_index", "btc_touch_pulse"],
  "threshold": null
}

Verify signatures

Every webhook includes an X-OrangePulse-Signature header. Verify it to ensure the payload came from OrangePulse:

javascriptconst crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

ERRORS

200OK — signal returned successfully
400Bad request — missing or malformed body fields
401Unauthorized — missing, invalid, expired, or disabled API key
403Forbidden — your subscription tier doesn't include this endpoint
404Not found — check endpoint spelling
429Rate limited — back off and retry after 60 seconds
500Server error — retry with exponential backoff (1s, 2s, 4s, max 30s)

Null values

null on any signal field means that signal hasn't computed yet for this tick. Skip the cycle and retry on the next update — do not act on null values.

RATE LIMITS

TierRequests/minMin poll interval
Starter100/min30 seconds
Pro500/min5 seconds
EliteUnlimited1 second
Credits60/min5 seconds

Rate limits are per API key, sliding 60-second window. Exceeded requests return 429. Wait 60 seconds before retrying. WebSocket connections don't count toward REST rate limits.

FOR AI AGENTS

TL;DR for agents: Load https://api.orangepulseapp.com/skill into context. It contains everything on this page in compressed, token-efficient form.

Three ways agents consume this API

MethodBest forHow
Skill fileLoading full API contextGET /skill → inject into system prompt
CLI toolAgent-executed commandsnpm i -g orangepulse → orangepulse watch
llms.txtAuto-discovery by frameworksGET /llms.txt → standard agent doc format

Recommended agent startup sequence

pseudocode1. GET /health                   → confirm API reachable
2. GET /v1/signals/all            → initialize state
3. Connect WSS /ws               → auth → subscribe → stream
4. On signal push:
     if payload.alert != null    → act immediately
     if payload.confidence > 0.75→ evaluate regime
     if payload value is null    → skip this cycle
5. On WS disconnect:
     fallback to polling /v1/signals/all every 5s
     reconnect with backoff (5s → 10s → 20s → 60s max)

Decision patterns

logic// Strong bullish setup
pulse_index.regime == "bullish" AND confidence > 0.8
AND options_pulse.net_flow == "bullish"
AND touch_pulse.reaction == "bounce"

// Strong bearish setup
pulse_index.regime == "bearish" AND confidence > 0.8
AND options_pulse.iv_skew == "put_heavy"
AND touch_pulse.reaction == "break"

// High volatility — widen stops
options_pulse.iv_rank > 80