REST API

Technical indicators

Twenty classic indicator types, computed on demand on the candles of the price reference. Up to fifty instances per call, each with its own parameters. Accuracy is calibrated against TradingView to within 0.1%, except on the two cumulative indicators and on three deliberate convention differences.

#The call

POST/v1/indicatorsdata_type · indicators

The only endpoint of the API to take a JSON body: it describes a computation, not a read. The values are neither stored nor cached. They are produced on every call from the closed candles.

ParameterTypeDefaultDescription
symbolstringrequiredOne of the twenty perpetuals. 32 characters at most.
timeframestringrequired1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w. This is the only route that accepts the week.
resultsinteger1Number of values returned per indicator. 1 gives the latest value on a closed candle.
indicatorsarrayrequiredNon-empty list of { id, type, parameters } objects. Fifty entries at most.
curl -X POST "https://api.bytnode.com/v1/indicators" \
  -H "X-API-KEY: $BYTNODE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "BTCUSDT",
    "timeframe": "1h",
    "results": 60,
    "indicators": [
      { "id": "rsi_fast", "type": "rsi", "period": 7 },
      { "id": "rsi_slow", "type": "rsi", "period": 21 },
      { "id": "macd", "type": "macd", "fast": 12, "slow": 26, "signal": 9 },
      { "id": "bb_mid", "type": "bb", "period": 20, "std": 2.0 }
    ]
  }'

1m5m15m30m1h4h1d1w

#The twenty indicators

TypeInstancesParameters (default, minimum)Output
rsimultiperiod (14, ≥ 2)value
emamultiperiod (20, ≥ 2)value
smamultiperiod (20, ≥ 2)value
bbmultiperiod (20, ≥ 2), std (2.0, ≥ 0.5)upper, middle, lower
atrmultiperiod (14, ≥ 2)value
stochmultik (14, ≥ 2), d (3, ≥ 2), smooth (3, ≥ 2)k, d
macdmonofast (12, ≥ 2), slow (26, ≥ 5), signal (9, ≥ 2); fast < slowmacd, signal, histogram
obvmonononevalue
adxmultiperiod (14, ≥ 2)value
sarmonoacceleration (0.02, ≥ 0.01), maximum (0.2, ≥ 0.05); acceleration ≤ maximumvalue
ccimultiperiod (20, ≥ 2)value
willrmultiperiod (14, ≥ 2)value
mfimultiperiod (14, ≥ 2)value
rocmultiperiod (10, ≥ 2)value
admonononevalue
adoscmonofast (3, ≥ 2), slow (10, ≥ 5); fast < slowvalue
keltnermultiperiod (20, ≥ 2), multiplier (2.0, ≥ 0.5)upper, middle, lower
donchianmultiperiod (20, ≥ 2)upper, middle, lower
ichimokumonotenkan (9, ≥ 2), kijun (26, ≥ 5), senkou (52, ≥ 10)tenkan_sen, kijun_sen, senkou_a, senkou_b
vwmamultiperiod (20, ≥ 2)value

#The identifiers

Each instance carries an id that you choose, and that serves as the key in the response. Its form is constrained, so that three RSIs of different periods stay distinguishable without a house convention.

Fourteen multi-instance types

Up to three instances per type, with the suffixes _fast, _mid and _slow (rsi_fast, ema_slow).

rsiemasmabbatrstochadxcciwillrmfirockeltnerdonchianvwma

Six single-instance types

The identifier is exactly the name of the type: macd, ichimoku. One instance per call.

macdobvsaradadoscichimoku

A duplicated or malformed identifier, or one incompatible with its type, returns 400.

#The ceiling rule

An indicator needs a warm-up (candles prior to the first publishable value). The rule is:

Rule
results + warmup(type, parameters) <= 1000

Beyond that, the request returns 422. On types with a linear warm-up, the message states the maximum period usable for the number of results requested.

TypeWarm-up
rsi, atr, keltner5 × period
ema3 × period
sma, bb, cci, willr, roc, donchian, vwma, mfiperiod
stochk + d + smooth
macd3 × slow + signal
adosc6 × slow
adx14 × period
sar200, constant
ichimokumax(tenkan, kijun, senkou) + kijun
obv, adnone

#The response

200
{
  "status": "ok",
  "timestamp": 1775648290510,
  "data_type": "indicators",
  "data": {
    "symbol": "BTCUSDT",
    "timeframe": "1h",
    "results": 60,
    "indicators": {
      "rsi_fast": { "type": "rsi", "period": 7, "values": [62.3, 58.1] },
      "macd": {
        "type": "macd", "fast": 12, "slow": 26, "signal": 9,
        "values": { "macd": [142.5], "signal": [98.2], "histogram": [44.3] }
      },
      "bb_mid": {
        "type": "bb", "period": 20, "std": 2.0,
        "values": { "upper": [72110.4], "middle": [71420.8], "lower": [70731.2] }
      }
    }
  }
}
  • The keys of data.indicators are your identifiers.
  • Each entry restates its type and its effective parameters, defaults filled in: you always know what was computed.
  • The values go from oldest to newest.
  • An undefined value comes out as null, never as NaN.
  • Multi-key outputs follow the order declared by the type, not that of the computation engine.

#Convention differences

These differences come from measurements, not from preferences. Knowing them saves looking for a bug where there is none.

OBV and AD are cumulative totals with no origin

Both accumulate from the first candle of the loaded window. Their absolute level is not reproducible from one request to the next: two different windows give two different levels, and none matches the level on a third-party chart. Only the slope, the variations and the divergences with price are usable. adosc does not have this flaw: it is insensitive to the origin.

Ichimoku: one bar of difference with TradingView

The two senkou are projected kijun bars forward (26 by default). TradingView shifts by 25. A one-bar difference is therefore expected.

The chikou_span is not exposed: its definition looks into the future, it would be null on the latest candles, and therefore always null with results: 1.

Keltner: a single length

This is the modern variant, exponential moving average plus ATR, with a single length for both. TradingView exposes a separate EMA(20) and ATR(10). A deliberate difference.

VWMA is not the VWAP

vwma is a volume-weighted moving average, computed on the candles of the price reference. /v1/vwap aggregates, on the contrary, the trades of every venue. Different sources and different windows: a gap between the two is not an inconsistency.

Donchian includes the current candle

The window is inclusive, in line with the highest and lowest functions of chart scripting languages.

MFI is not a volume RSI

It is implemented as a simple rolling sum, without the smoothing the RSI uses: its warm-up equals its period, not five times its period.

#Errors

The order of validation is fixed: timeframe, then number of results, then symbol, then parsing of the indicators, then the ceiling rule, then reading the candles. The first failure wins.

CaseCode
Missing or invalid key403
Invalid timeframe, results below 1, unknown symbol400
Empty indicators list, entry that is not an object400
Missing id or type key, malformed id, unsupported type400
Unknown parameter for the type, wrong type, below the minimum400
macd or adosc with fast ≥ slow, sar with acceleration '>' maximum400
Duplicated identifier400
Malformed body, more than 50 indicators, field too long422
results + warm-up exceeds 1000422
Insufficient data for this timeframe, stablecoins included422
Rate exceeded429