AlcorDocs

Market API

Prices, depth, pools and order books for bots, updated every block, with a WebSocket stream.

Prices, depth, pools and order books for bots and apps, computed from on-chain state that is updated every block, with the swap contracts' own math. Use it to know what tokens are worth, what a pair trades at, what a given amount fetches, and how much a market takes before its price gives way. To build a swap transaction, use Swap route v3.

https://<chain>.alcor.exchange/api/v3/market/, with <chain> one of wax, eos, telos, proton.

  • Every answer carries block: the last block the data reflects.
  • Prices and values are decimal strings with 8 significant digits. Amounts are decimal strings in the token's precision.
  • Token ids are <symbol>-<contract> in lower case, e.g. tlm-alien.worlds.
  • Errors are JSON, {"error": "<message>"}: HTTP 400 for a bad parameter, 404 for an unknown network, token, pool or market.

How token prices are made

Prices are in the chain's system token (WAX, EOS, TLOS, XPR), read off the AMM pools' spot prices. The system token is worth 1; every other token is priced through a pool whose other side is already priced. Of all the paths from the system token to a token, the price comes through the one whose weakest pool holds the most value, and a path through a pool below the liquidity threshold does not price at all, so a thin pool cannot set a token's price. A token traded only on order books has no price. USD prices multiply by the system token's USD price from CoinGecko. Prices are recomputed with every block that changes a pool.

Market tokens

Every token: the system token first, then the priced tokens by liquidity, then the unpriced ones.

GET https://wax.alcor.exchange/api/v3/market/tokens

Example

curl https://wax.alcor.exchange/api/v3/market/tokens
{
  "block": 451200345,
  "systemToken": "wax-eosio.token",
  "systemUsdPrice": "0.04512",
  "tokens": [
    {
      "id": "wax-eosio.token",
      "symbol": "WAX",
      "contract": "eosio.token",
      "decimals": 8,
      "price": "1",
      "priceUsd": "0.04512",
      "liquidity": null,
      "liquidityUsd": null,
      "pools": 1873,
      "orderbooks": 412
    },
    {
      "id": "tlm-alien.worlds",
      "symbol": "TLM",
      "contract": "alien.worlds",
      "decimals": 4,
      "price": "0.22424356",
      "priceUsd": "0.010117869",
      "liquidity": "1250340.5",
      "liquidityUsd": "56415.363",
      "pools": 37,
      "orderbooks": 3
    }
  ]
}

Response fields

NameTypeDescription
blocknumberLast block the data reflects
systemTokenstringToken every price is quoted in
systemUsdPricestringUSD price of the system token, null when unknown
tokensarrayTokens, see below

Each token

NameTypeDescription
id, symbol, contract, decimalsThe token
pricestringSystem tokens per one token, null when unpriced
priceUsdstringUSD per one token
liquiditystringWhat backs the price: system-token value in the weakest pool on the path the price comes through. null for the system token
liquidityUsdstringThe same in USD
poolsnumberPools trading the token
orderbooksnumberOrder book markets trading the token

Market token

One token, as in Market tokens.

GET https://wax.alcor.exchange/api/v3/market/tokens/<token_id>

Example

curl https://wax.alcor.exchange/api/v3/market/tokens/tlm-alien.worlds
{
  "block": 451200345,
  "token": {
    "id": "tlm-alien.worlds",
    "symbol": "TLM",
    "contract": "alien.worlds",
    "decimals": 4,
    "price": "0.22424356",
    "priceUsd": "0.010117869",
    "liquidity": "1250340.5",
    "liquidityUsd": "56415.363",
    "pools": 37,
    "orderbooks": 3
  }
}

Pair price

The price of a pair, and with amount, the price of trading that much of it.

mid comes from the token prices. With amount (in base), sell sells it for quote, and buy spends what the sell receives to buy base back. Both go through the AMM and the order books, split across routes, exactly as a swap would, so the gap between their prices is what a round trip of that size costs.

GET https://wax.alcor.exchange/api/v3/market/price

Parameters

NameTypeRequiredDescription
basestringyesBase token id
quotestringyesQuote token id
amountstringnoAmount of base to sell, e.g. 1000

Example

curl "https://wax.alcor.exchange/api/v3/market/price?base=tlm-alien.worlds&quote=wax-eosio.token&amount=1000"
{
  "block": 451200345,
  "base": { "id": "tlm-alien.worlds", "symbol": "TLM", "contract": "alien.worlds", "decimals": 4 },
  "quote": { "id": "wax-eosio.token", "symbol": "WAX", "contract": "eosio.token", "decimals": 8 },
  "mid": "0.22424356",
  "sell": {
    "input": "1000.0000",
    "output": "223.12345678",
    "price": "0.22312346",
    "priceImpact": "0.5"
  },
  "buy": {
    "input": "223.12345678",
    "output": "990.1234",
    "price": "0.22534914",
    "priceImpact": "0.49"
  }
}

Response fields

NameTypeDescription
blocknumberLast block the data reflects
base, quoteobjectThe tokens: id, symbol, contract, decimals
midstringQuote per one base, from the token prices. null when either token is unpriced
sellobjectOnly with amount: selling it. null when no route can
buyobjectOnly with amount: buying base back with what the sell receives. null when no route can

sell and buy

NameTypeDescription
inputstringAmount spent
outputstringAmount received
pricestringQuote per one base, as executed, fees included
priceImpactstringPercent below the spot prices of the routes taken, as in the route API

Depth

How much input the market takes before its price gives way.

For each impact level, in percent, about the largest trade of input whose average price, fees included, is at most that far below reference. The reference is the pair's mid price; for a pair without one, it is the price of a small trade. Trades are routed through the AMM and the order books, split across routes, as a swap would.

A level's amounts are null when not even a small trade stays within it: a level below the cheapest route's fee never does. Amounts are accurate to about 1%.

A depth search is expensive, so answers are cached for 10 seconds per pair and levels.

GET https://wax.alcor.exchange/api/v3/market/depth

Parameters

NameTypeRequiredDescription
inputstringyesToken id to sell
outputstringyesToken id to receive
impactstringnoComma-separated levels in percent, up to 10, each between 0 and 100. Default 0.5,1,2,5

Example

curl "https://wax.alcor.exchange/api/v3/market/depth?input=wax-eosio.token&output=tlm-alien.worlds&impact=0.5,1,2,5"
{
  "block": 451200345,
  "input": { "id": "wax-eosio.token", "symbol": "WAX", "contract": "eosio.token", "decimals": 8 },
  "output": { "id": "tlm-alien.worlds", "symbol": "TLM", "contract": "alien.worlds", "decimals": 4 },
  "reference": "4.4594368",
  "referenceKind": "mid",
  "levels": [
    { "impact": "0.5", "input": "40778.18000000", "output": "180938.4779" },
    { "impact": "1", "input": "56825.74000000", "output": "250866.6402" },
    { "impact": "2", "input": "88639.27000000", "output": "387371.4417" },
    { "impact": "5", "input": "186153.37000000", "output": "788632.2291" }
  ]
}

Response fields

NameTypeDescription
blocknumberLast block the data reflects
input, outputobjectThe tokens
referencestringOutput per one input that impact is measured against. null when there is no route
referenceKindstringmid (the pair's mid price) or smallTrade (the price of a small trade)
levelsarrayOne per requested level: impact, and the input sold and output received at that level

Market pools

Every AMM pool, or the pools trading token, by id.

GET https://wax.alcor.exchange/api/v3/market/pools

GET https://wax.alcor.exchange/api/v3/market/pools/<pool_id> answers one pool as {"block", "pool"}.

Parameters

NameTypeRequiredDescription
tokenstringnoOnly pools trading this token id

Example

curl "https://wax.alcor.exchange/api/v3/market/pools?token=tlm-alien.worlds"
{
  "block": 451200345,
  "pools": [
    {
      "id": 0,
      "tokenA": { "id": "wax-eosio.token", "symbol": "WAX", "contract": "eosio.token", "decimals": 8 },
      "tokenB": { "id": "tlm-alien.worlds", "symbol": "TLM", "contract": "alien.worlds", "decimals": 4 },
      "fee": "0.3",
      "tickSpacing": 60,
      "active": true,
      "price": "4.4594368",
      "sqrtPriceX64": "38956049823463529530",
      "tick": 14950,
      "liquidity": "1825937489182",
      "reserveA": "612034.12345678",
      "reserveB": "2730511.4520",
      "tvl": "1224335.3",
      "tvlUsd": "55241.98"
    }
  ]
}

Response fields

NameTypeDescription
idnumberPool id
tokenA, tokenBobjectThe tokens
feestringFee in percent
tickSpacingnumberTick spacing
activebooleanWhether the pool is active
pricestringToken B per one token A
sqrtPriceX64stringCurrent sqrt price, Q64.64
ticknumberCurrent tick
liquiditystringIn-range liquidity
reserveA, reserveBstringToken balances the pool holds
tvlstringBoth reserves in system tokens; null unless both tokens are priced
tvlUsdstringThe same in USD

Market order books

Order book markets. The list comes without orders; a single market comes with its best 20 orders on each side.

GET https://wax.alcor.exchange/api/v3/market/orderbooks answers {"block", "orderbooks"}.

GET https://wax.alcor.exchange/api/v3/market/orderbooks/<market_id> answers {"block", "orderbook"}.

Parameters of the list

NameTypeRequiredDescription
tokenstringnoOnly markets trading this token id

Example

curl https://wax.alcor.exchange/api/v3/market/orderbooks/26
{
  "block": 451200345,
  "orderbook": {
    "id": 26,
    "base": { "id": "wax-eosio.token", "symbol": "WAX", "contract": "eosio.token", "decimals": 8 },
    "quote": { "id": "tlm-alien.worlds", "symbol": "TLM", "contract": "alien.worlds", "decimals": 4 },
    "fee": "0.2",
    "frozen": false,
    "bestBid": "0.22301",
    "bestAsk": "0.2251",
    "bids": [
      { "price": "0.22301", "amount": "15000.0000" },
      { "price": "0.2229", "amount": "4210.5000" }
    ],
    "asks": [
      { "price": "0.2251", "amount": "9800.0000" },
      { "price": "0.22533", "amount": "120000.0000" }
    ]
  }
}

Response fields

NameTypeDescription
idnumberMarket id
base, quoteobjectThe tokens, named as the DEX contract names them
feestringFee in percent
frozenbooleanWhether the market is frozen
bestBid, bestAskstringBest buy and sell prices, in base per one quote
bids, asksarraySingle market only: {price, amount}, best first. Price in base per one quote, amount in quote

Here base and quote follow the DEX contract, which is the reverse of the Market Data tickers: the contract's base (WAX in market 26) is the ticker's target.

Market stream

A plain WebSocket (not Socket.IO) that pushes the market API as the chain moves.

wss://wax.alcor.exchange/api/v3/market/stream

Subscribe with JSON text messages. Each subscription is answered at once with the channel's current state, and then again after every block that changes it.

ChannelSubscribe withPushes
pricebase, quoteThe pair's mid
poolidThe pool, as in Market pools. null once removed
orderbookidThe market with its orders, as in Market order books. null once removed
tokensEvery token on subscribe, then only the tokens whose price moved

Example

const ws = new WebSocket('wss://wax.alcor.exchange/api/v3/market/stream')

ws.onopen = () => {
  ws.send(JSON.stringify({ op: 'subscribe', channel: 'price', base: 'tlm-alien.worlds', quote: 'wax-eosio.token' }))
  ws.send(JSON.stringify({ op: 'subscribe', channel: 'pool', id: 0 }))
  ws.send(JSON.stringify({ op: 'subscribe', channel: 'orderbook', id: 26 }))
  ws.send(JSON.stringify({ op: 'subscribe', channel: 'tokens' }))
}

ws.onmessage = ({ data }) => {
  const message = JSON.parse(data)
  if (message.error) return console.error(message.error)
  console.log(message.channel, message.block, message)
}

// Stop a channel
ws.send(JSON.stringify({ op: 'unsubscribe', channel: 'pool', id: 0 }))

Messages:

{"channel": "price", "base": "tlm-alien.worlds", "quote": "wax-eosio.token", "block": 451200346, "mid": "0.22431"}
{"channel": "pool", "id": 0, "block": 451200346, "pool": { "id": 0, "price": "4.4581", "...": "as in Market pools" }}
{"channel": "orderbook", "id": 26, "block": 451200346, "orderbook": { "id": 26, "...": "as in Market order books" }}
{"channel": "tokens", "block": 451200346, "tokens": [{ "id": "tlm-alien.worlds", "price": "0.22431", "...": "as in Market tokens" }]}

A bad request is answered with {"error": "<message>"} and the connection stays open. One connection holds up to 100 subscriptions. The server pings every 30 seconds.

On this page