/docs
Docs
A key, a handful of JSON endpoints, an MCP server with four tools, and two Telegram channels.
Quickstart (5 minutes)
- Get a key. Sign in, open the dashboard, tab API & MCP, press "Create API key". The key is shown once; store it like a password.
- First request. Ask for the current state of one coin:
#!/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"
echoThe answer (shortened, from the rehearsal):
{
"data": [
{
"symbol": "BTCUSDT",
"profile": "scalp",
"side": "LONG",
"status": "NORMAL",
"score": 9.2,
"base_rate": 0.18,
"base_n": 1440,
"history_n": 2000,
"as_of_ms": 1790928000000,
"as_of": "2026-10-02T08:00:00Z"
}
],
"meta": {
"health": "OK",
"plan": "full",
"next_update_at": "2026-10-02T08:05:00Z",
"poll_hint": "Scores change every 5 minutes; poll once per 5 minutes after next_update_at.",
"score_meaning": "Risk Score N/100 = riskier to enter than N% of that coin's own moments (history up to 90 days). Not a probability."
}
}
(meta shortened: it also carries the Data Notice and more)- Read it. status is the level (HIGH, ELEVATED, NORMAL …), score is the Risk Score 0–100, as_of is when it was measured. meta.score_meaning says what the number means; pass it on with the number.
- Poll correctly. Scores change every 5 minutes. Ask again after meta.next_update_at, not in a tight loop; a polling loop that does this is in Code examples.
Concepts
Risk Score N/100 = riskier to enter than N% of that coin's own moments (history up to 90 days). It is a rank within the coin, not a probability of anything.
| Status | Meaning |
|---|---|
| HIGH | score 80 or above: the coin's own riskiest 20% of moments |
| ELEVATED | score 60–79 |
| NORMAL | score below 60 (not HIGH does not mean low risk) |
| WARMING | not enough history for this coin yet |
| STALE | no fresh data for this coin; the score is held back, never estimated |
Profiles are holding periods with an adverse move: scalp 60 min / 1%, intraday 8 h / 2%, daily 24 h / 3%. LONG and SHORT are scored for all three (score v1.1). The adverse move is a drop for LONG and a rise for SHORT.
Base risk (base_rate) is the share of all of this coin's measured moments, HIGH or not, that were followed by the adverse move within the horizon. Components are the three inputs behind the score — 1-hour volatility, funding-rate crowding and the 4-hour move — each as a side-signed percentile within the coin.
Update cycle. The collector snapshots every 5 minutes; as_of is the snapshot time and meta.next_update_at = as_of + 300 s. meta.health is LATE when the newest measurement is more than 12 minutes old.
Ledger. Every UTC day is published from D+2 00:10 UTC: how often HIGH moments were followed by the adverse move, next to all other moments, including the days the score is wrong. Each entry is hash-chained to the one before; verify a day's SHA-256 yourself.
Authentication, quotas and limits
Send the key as X-API-Key: KEY or Authorization: Bearer KEY. One key per account; a new key replaces the old one at once.
| Plan | Coins | Requests per UTC day (REST + MCP) |
|---|---|---|
| Trial | 10 (BTC … NEAR) | 500 |
| Full | 19 | 20,000 |
Per key: 5 requests per second, burst 20. Per IP at the edge: 20 requests per second, burst 40. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 carries Retry-After and error.retry_after_s.
Errors
| HTTP | error.code | What to do |
|---|---|---|
| 401 | missing_key / invalid_key | Send the key in X-API-Key or Authorization: Bearer; check for spaces. |
| 403 | key_revoked / plan_ended / coin_not_in_plan | Create a new key, renew, or ask only for your plan's coins. |
| 404 | not_found / unknown_symbol | Check the path and the symbol (BTCUSDT, not BTC). |
| 422 | invalid_parameter | Fix the named parameter (profile, side, dates, limit). |
| 429 | rate_limited | Wait Retry-After seconds; slow down to under 5 requests per second. |
| 429 | quota_exceeded | The daily quota is used; it resets at 00:00 UTC. |
| 503 | state_unavailable | Retry after a short wait; the status page shows the reason. |
{"error": {"code": "rate_limited", "message": "Too many requests per second.", "retry_after_s": 1}}Troubleshooting
- Certificate errors (e.g. "unable to get local issuer certificate"): update the CA bundle of your system or of Python (pip install -U certifi); the site uses a public certificate that current trust stores verify.
- 401 vs 403: 401 = no key or an unknown key; 403 = a known key that cannot be used for this (revoked, plan ended, coin outside the trial).
- 429 patterns: bursts from parallel workers hit the per-key limit; spread requests or share one cache. quota_exceeded means the day's quota is used.
- Clock skew: compare times in UTC; as_of and next_update_at are UTC with a trailing Z.
- STALE / WARMING: no fresh data, or not enough history for that coin yet; the score is null on purpose.
- Trial coin limits: a trial key answers for BTC, ETH, SOL, XRP, BNB, DOGE, ADA, LINK, AVAX and NEAR; other coins return 403.
Changelog
API v1.2 (2 Oct 2026): /meta lists every field with its unit, the rate limits, deprecated keys and the OpenAPI address; every data response carries meta.next_update_at, meta.next_update_ms and meta.poll_hint; meta.rank_meaning is deprecated (kept until 1 Dec 2026, use score_meaning); an empty ledger answer carries meta.ledger_note; 429 bodies carry retry_after_s; MCP tool results start with one plain sentence per row group; OpenAPI 3.1 at /api/v1/openapi.json. No field was renamed or removed.
API v1.1: Risk Score wording (score_meaning), per-user quota, public board v2.
Telegram
Public channel @entryriskscore: every 6 hours a digest of the 6-hour window that closed 6 hours earlier. Private channel: included with the trial and Full. Connect Telegram in your dashboard; the bot sends a personal invite. A message looks like this:
HIGH ENTRY RISK · ETH LONG Risk of entering now · as of 08:15 UTC ETH LONG — Risk Score 88/100 For entries held 60 min, 8 h or 24 h Up from 42/100 an hour ago Drivers: funding in its top 6% (longs crowded) · up 3.1% in 4 h · 1-h volatility in its top 22% ▸ Base risk · Evidence so far · definition (folded quote, tap to open) entryriskscore.com/app Measured risk, not a forecast or advice.
The folded quote holds the coin's Base risk (share of all its moments, HIGH or not, followed by the adverse move; dates stated), "Evidence so far" (HIGH vs other moments, all 19 coins pooled: the founding measurement until the public ledger has 7 published days, then the ledger) and the Risk Score definition.