Skip to content
Get a free API key — 7-day trial, no card

/docs/examples

Code examples

curl, Python and JavaScript, run against a test copy of the service before publishing.

Every example here ran in the rehearsal against a test copy of the service on 2 Oct 2026; the outputs below are from that run. Set ERS_API_KEY to your key; ERS_BASE defaults to https://entryriskscore.com. None of this tells anyone to trade: the code reads a measurement and leaves every decision to you.

curl

#!/bin/sh
# First request: the current state of BTCUSDT, all profiles and sides.
# ERS_BASE defaults to the live service; ERS_API_KEY comes from the dashboard (API & MCP).
BASE="${ERS_BASE:-https://entryriskscore.com}"
curl -s "$BASE/api/v1/state?symbol=BTCUSDT&profile=scalp&side=LONG" -H "X-API-Key: $ERS_API_KEY"
echo

Python (requests): one request

"""One request with Python requests: the scalp LONG state of BTCUSDT."""
import os

import requests

BASE = os.environ.get('ERS_BASE', 'https://entryriskscore.com')
r = requests.get(f'{BASE}/api/v1/state', params={'symbol': 'BTCUSDT', 'profile': 'scalp', 'side': 'LONG'},
                 headers={'X-API-Key': os.environ['ERS_API_KEY']}, timeout=10)
r.raise_for_status()
body = r.json()
row = body['data'][0]
print(row['symbol'], row['side'], row['profile'], row['status'], row['score'], row['as_of'])
print('meaning:', body['meta']['score_meaning'])
print('next update:', body['meta']['next_update_at'])

Output:

BTCUSDT LONG scalp NORMAL 9.2 2026-10-02T08:00:00Z
meaning: Risk Score N/100 = riskier to enter than N% of that coin's own moments (history up to 90 days). Not a probability.
next update: 2026-10-02T08:05:00Z

Python: polling loop with next_update_at and Retry-After

"""Polling loop that respects next_update_at and Retry-After (one request per 5-minute update)."""
import os
import time
from datetime import datetime, timezone

import requests

BASE = os.environ.get('ERS_BASE', 'https://entryriskscore.com')
KEY = os.environ['ERS_API_KEY']
ROUNDS = int(os.environ.get('ERS_ROUNDS', '0'))          # 0 = run until stopped


def wait_until(iso_utc, margin_s=20):
    if not iso_utc:
        return 300
    due = datetime.strptime(iso_utc, '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).timestamp()
    return max(5, due + margin_s - time.time())


n = 0
while True:
    r = requests.get(f'{BASE}/api/v1/high-risk', params={'profile': 'scalp'}, headers={'X-API-Key': KEY}, timeout=10)
    if r.status_code == 429:
        pause = int(r.headers.get('Retry-After', '60'))
        print('429', r.json()['error']['code'], '-> waiting', pause, 's')
        time.sleep(pause)
        continue
    r.raise_for_status()
    body = r.json()
    names = [f"{x['symbol']} {x['side']} {round(x['score'])}/100" for x in body['data']]
    print(body['meta'].get('next_update_at'), 'HIGH now:', ', '.join(names) or 'none')
    n += 1
    if ROUNDS and n >= ROUNDS:
        break
    time.sleep(wait_until(body['meta'].get('next_update_at')))

Output (one round):

2026-10-02T08:05:00Z HIGH now: 1000PEPEUSDT LONG 93/100, ARBUSDT SHORT 90/100, BTCUSDT SHORT 84/100, ENAUSDT SHORT 92/100, ETHUSDT LONG 88/100, LINKUSDT SHORT 82/100, NEARUSDT LONG 81/100, SOLUSDT LONG 82/100, SOLUSDT SHORT 91/100, TRXUSDT SHORT 80/100

Risk check before your own entry logic (Python)

Returns the measured state of one coin and side. It does not decide anything: your own rules do.

"""A risk check to run before your own entry logic. It returns the measured state only; it is not a recommendation to
trade and decides nothing for you."""
import os

import requests

BASE = os.environ.get('ERS_BASE', 'https://entryriskscore.com')


def entry_risk(symbol, side, profile='scalp', key=None):
    r = requests.get(f'{BASE}/api/v1/state', params={'symbol': symbol, 'side': side, 'profile': profile},
                     headers={'X-API-Key': key or os.environ['ERS_API_KEY']}, timeout=10)
    r.raise_for_status()
    body = r.json()
    row = body['data'][0] if body['data'] else {}
    return {'status': row.get('status'), 'score': row.get('score'), 'as_of': row.get('as_of'),
            'health': body['meta']['health'], 'meaning': body['meta']['score_meaning']}


if __name__ == '__main__':
    print(entry_risk('ETHUSDT', 'LONG'))

Output:

{'status': 'HIGH', 'score': 88.2, 'as_of': '2026-10-02T08:00:00Z', 'health': 'OK', 'meaning': "Risk Score N/100 = riskier to enter than N% of that coin's own moments (history up to 90 days). Not a probability."}

Risk check before your own entry logic (JavaScript, Node 18+)

// A risk check before your own entry logic (Node 18+, built-in fetch). Returns the measured state only.
const BASE = process.env.ERS_BASE || 'https://entryriskscore.com';

export async function entryRisk(symbol, side, profile = 'scalp', key = process.env.ERS_API_KEY) {
  const url = `${BASE}/api/v1/state?symbol=${symbol}&side=${side}&profile=${profile}`;
  const r = await fetch(url, { headers: { 'X-API-Key': key } });
  if (r.status === 429) {
    return { error: 'rate_limited', retryAfterS: Number(r.headers.get('retry-after') || 60) };
  }
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
  const body = await r.json();
  const row = body.data[0] || {};
  return { status: row.status, score: row.score, asOf: row.as_of, health: body.meta.health };
}

console.log(await entryRisk('ETHUSDT', 'LONG'));

Output:

{
  status: 'HIGH',
  score: 88.2,
  asOf: '2026-10-02T08:00:00Z',
  health: 'OK'
}

Verify a ledger day's SHA-256 (Python)

"""Verify a published ledger day: the SHA-256 of the exact bytes must equal the published hash, and the entry must
point to the previous entry's hash."""
import hashlib
import os
import sys

import requests

BASE = os.environ.get('ERS_BASE', 'https://entryriskscore.com')
listing = requests.get(f'{BASE}/api/v1/public/ledger', timeout=10).json()
entries = listing.get('entries') or []
if not entries:
    print('No ledger entries published yet.')
    sys.exit(0)
day = sys.argv[1] if len(sys.argv) > 1 else entries[0]['day']
raw = requests.get(f'{BASE}/api/v1/public/ledger/{day}.json', timeout=10).content
published = next(e['sha256'] for e in entries if e['day'] == day)
print(day, 'sha256 ok' if hashlib.sha256(raw).hexdigest() == published else 'MISMATCH')

Output in the rehearsal (no entry existed yet; the first one publishes on 3 Oct 2026 at 00:10 UTC):

No ledger entries published yet.
DATA NOTICEEntry Risk Score is a data service that measures entry-timing risk on Binance USDT-M futures. It is not a signal, not investment advice, and makes no promise of returns. Published rates describe the past and do not guarantee future results. You are solely responsible for your trading decisions.