Skip to main content

K-Line API — API reference

Historical K-line query

This module queries persisted OHLCV candlestick data. It is suitable for chart initialization, filling gaps after client disconnects, and loading historical data before subscribing to real-time updates.

Queries must specify the chain, pool, token side, and K-line interval. The endpoint returns an array; when no data matches, it usually returns an empty array.

Query OHLCV data

Request

GET /kline/api/v1/kline/ohlcv

Query parameters

ParameterTypeRequiredDefaultDescription
intervalstringYes-K-line interval: 1s, 1m, 15m, 1h, 4h, 1d, 1w, 1M, 1Y.
fromintegerYes-Query start time, Unix seconds or milliseconds.
tointegerYes-Query end time, Unix seconds or milliseconds.
limitintegerNo1000Maximum row count, from 1 to 5000.
chain_typestringYes-Chain type, normalized automatically.
chain_idintegerYes-Positive chain ID.
pool_addressstringYes-Pool contract address.
tokenstringNobasebase or quote.

curl example

curl -H "X-API-Key: $API_KEY" "https://api.gelabs.org/kline/api/v1/kline/ohlcv?interval=1h&from=1776679200&to=1776765600&limit=500&chain_type=evm&chain_id=1&pool_address=0xabc123def456&token=base"

Successful response

data is an OHLCV array and is not wrapped in items:

{
"code": 0,
"message": "ok",
"data": [
{
"pool_id": 42,
"interval": "1h",
"open_time": 1776679200,
"open": 3500.12,
"high": 3520,
"low": 3480.5,
"close": 3510.88,
"volume": 1234567.89
}
]
}

Response fields

FieldTypeAlways returnedDescription
pool_idintegerYesInternal pool ID.
intervalstringYesK-line interval.
open_timeintegerYesCandle start time, Unix seconds.
opennumber / nullYesOpen price.
highnumber / nullYesHigh price.
lownumber / nullYesLow price.
closenumber / nullYesClose price.
volumenumber / nullYesVolume.

Cache notes

This endpoint does not currently declare a fixed HTTP cache header. Business clients may apply short caching by interval; for high-real-time scenarios, combine HTTP historical queries with WebSocket updates for the latest candle.

Common error response

Missing or invalid parameters usually return:

{
"code": 10001,
"message": "Invalid query params",
"error": {
"type": "ValidationError",
"details": {
"fieldErrors": {
"interval": ["Required"],
"pool_address": ["Required"]
}
}
}
}

Market APIs

Market APIs use the K-Line unified success wrapper, while data contains the corresponding market data.

This module queries market information for pools and tokens, such as pool details, top holders, and token metadata by contract address.

Note: Market APIs are mainly for auxiliary display and debugging. They do not represent the internal K-Line collection state.

Get pool market details

Request

GET /kline/api/v1/market/pools/{network}/{address}
ParameterLocationTypeRequiredDescription
networkpathstringYesNetwork identifier, 1-100 characters.
addresspathstringYesPool contract address, 1-200 characters.
includequerystringNoExtra included fields, comma-separated.
include_volume_breakdownquerystringNo"true" or "false".
include_compositionquerystringNo"true" or "false".

curl example

curl -H "X-API-Key: $API_KEY" "https://api.gelabs.org/kline/api/v1/market/pools/eth/0xabc123def456?include=base_token,quote_token&include_volume_breakdown=true&include_composition=false"

Cache notes

This endpoint does not currently promise a fixed cache duration in the documentation.

Common error response

Request failures, rate limits, or internal exceptions usually return:

{
"code": 99001,
"message": "Internal server error",
"error": { "type": "InternalServerError" }
}

Get token top holders

Request

GET /kline/api/v1/market/tokens/{network}/{address}/top-holders
ParameterLocationTypeRequiredDescription
networkpathstringYesNetwork identifier, 1-100 characters.
addresspathstringYesToken contract address, 1-200 characters.
holdersquerystringNoPositive integer string or max.
include_pnl_detailsquerystringNo"true" or "false".

curl example

curl -H "X-API-Key: $API_KEY" "https://api.gelabs.org/kline/api/v1/market/tokens/eth/0xabc123def456/top-holders?holders=10&include_pnl_details=false"

Cache notes

This endpoint does not currently promise a fixed cache duration in the documentation. Control call frequency according to display requirements.

Common error response

{
"code": 99001,
"message": "Internal server error",
"error": { "type": "InternalServerError" }
}

Get token metadata by contract address

Request

GET /kline/api/v1/market/coins/{network}/{address}
ParameterLocationTypeRequiredDescription
networkpathstringYesPlatform identifier, 1-100 characters.
addresspathstringYesToken contract address, 1-200 characters.

curl example

curl -H "X-API-Key: $API_KEY" "https://api.gelabs.org/kline/api/v1/market/coins/ethereum/0xabc123def456"

Cache notes

This proxy endpoint does not currently promise a fixed cache duration in the documentation. Token metadata usually changes infrequently, so clients may cache it according to business needs.

Common error response

{
"code": 99001,
"message": "Internal server error",
"error": { "type": "InternalServerError" }
}

K-Line WebSocket

K-Line real-time push uses a single WebSocket entry point. After connecting, clients dynamically subscribe or unsubscribe to multiple pools with JSON messages.

Keep HTTP historical query support on the client side. On first load or after reconnecting, query historical data first, then use WebSocket updates for the latest candle.

Connection requirements

Connection URL

GET /kline/api/v1/kline/ws

Required headers

HeaderRequiredDescription
Upgrade: websocketYesStandard WebSocket upgrade header.
Connection: UpgradeYesStandard WebSocket upgrade header.
X-API-KeyYesPublic API key for API authentication and billing identification.

Note: X-API-Key is the only required business request header for external integration. No additional business headers are required from integrators.

When the WebSocket upgrade headers are missing, the endpoint returns HTTP 426:

{
"code": 4000,
"message": "WebSocket upgrade required",
"error": { "type": "BadRequestError" }
}

When X-API-Key is missing or authentication fails, the endpoint usually returns HTTP 401 or 403, depending on gateway configuration:

{
"code": 20001,
"message": "Unauthorized",
"error": { "type": "UnauthorizedError" }
}

Protocol constants

ConstantString valueDirectionDescription
WS_TYPE_PINGpingClient → serverApplication heartbeat.
WS_TYPE_PONGpongServer → clientHeartbeat response.
WS_TYPE_SUBSCRIBEsubscribeClient → serverSubscribe to a pool.
WS_TYPE_UNSUBSCRIBEunsubscribeClient → serverUnsubscribe from a pool.
WS_TYPE_SUBSCRIBEDsubscribedServer → clientSubscription acknowledgement.
WS_TYPE_UNSUBSCRIBEDunsubscribedServer → clientUnsubscription acknowledgement.
WS_TYPE_OHLCVohlcvServer → clientReal-time or snapshot K-line push.
WebSocket codeDescription
0Success
4001Invalid message, such as invalid JSON or missing fields
4002Unknown command
4500Internal error, currently reserved

Client message format

{
"id": "req-001",
"type": "subscribe",
"data": {}
}
FieldTypeRequiredDescription
idstringYesRequest correlation ID.
typestringYesping, subscribe, or unsubscribe.
dataobjectDepends on commandCommand payload.

subscribe.data

FieldTypeRequiredDescription
chain_typestringYesChain type, normalized automatically.
chain_idnumberYesChain ID.
pool_addressstringYesPool address; internal pool key is lowercased.
tokenstringNobase or quote; default is base.
intervalsstring[]NoValid intervals. Missing or empty array means all intervals. Invalid values are silently ignored.

Note: intervals must be a JSON array, not a comma-separated string.

unsubscribe.data

FieldTypeRequiredDescription
chain_typestringYesChain type, normalized automatically.
chain_idnumberYesChain ID.
pool_addressstringYesPool address.
tokenstringNobase or quote; default is base.

Server message format

{
"id": "req-001",
"time": 1776682800000,
"type": "subscribed",
"code": 0,
"data": {},
"msg": "ok"
}
FieldTypeAlways returnedDescription
idstringYesRequest ID for command responses; active pushes use "".
timenumberYesServer Unix millisecond timestamp.
typestringYespong, subscribed, unsubscribed, ohlcv, or error.
codenumberYesWebSocket business code.
dataobject / nullYesPayload.
msgstringYesHuman-readable message; real-time pushes use ok, snapshots use snapshot.

Subscribe and unsubscribe examples

Heartbeat

{ "id": "hb-001", "type": "ping", "data": {} }

Response:

{
"id": "hb-001",
"time": 1776682800000,
"type": "pong",
"code": 0,
"data": {},
"msg": "ok"
}

Subscribe

{
"id": "sub-001",
"type": "subscribe",
"data": {
"chain_type": "evm",
"chain_id": 1,
"pool_address": "0xabc123def456",
"token": "base",
"intervals": ["1m", "1h", "4h"]
}
}

Successful response:

{
"id": "sub-001",
"time": 1776682800000,
"type": "subscribed",
"code": 0,
"data": {
"key": "evm:1:0xabc123def456:base",
"intervals": ["1m", "1h", "4h"]
},
"msg": "ok"
}

If the server already has a latest tick for the pool in memory, it may immediately push an additional ohlcv snapshot.

Unsubscribe

{
"id": "unsub-001",
"type": "unsubscribe",
"data": {
"chain_type": "evm",
"chain_id": 1,
"pool_address": "0xabc123def456",
"token": "base"
}
}

Response:

{
"id": "unsub-001",
"time": 1776682800000,
"type": "unsubscribed",
"code": 0,
"data": {
"key": "evm:1:0xabc123def456:base"
},
"msg": "ok"
}

Push data fields

Real-time and snapshot pushes both use type: "ohlcv":

{
"id": "",
"time": 1776682800000,
"type": "ohlcv",
"code": 0,
"data": {
"chain_type": "evm",
"chain_id": 1,
"pool_address": "0xabc123def456",
"token": "base",
"interval": "1h",
"open_time": 1776679200,
"open": 3500.12,
"high": 3520,
"low": 3480.5,
"close": 3510.88,
"volume": 1234567.89
},
"msg": "ok"
}
FieldTypeAlways returnedDescription
chain_typestring / nullYesChain type.
chain_idnumber / nullYesChain ID.
pool_addressstringYesPool address.
tokenstringYesToken side.
intervalstringYesK-line interval.
open_timenumberYesCandle start time, Unix seconds.
opennumber / nullYesOpen price.
highnumber / nullYesHigh price.
lownumber / nullYesLow price.
closenumber / nullYesClose price.
volumenumber / nullYesVolume.

KlineHub silently ignores binary frames. Clients receive no ohlcv pushes when they have no active pool subscriptions. Repeated subscribe for the same pool overwrites the pool's intervals setting.

WebSocket error messages

{
"id": "sub-001",
"time": 1776682800000,
"type": "error",
"code": 4001,
"data": null,
"msg": "subscribe: missing required fields"
}
ScenariocodeExample msg
JSON parsing failed4001Invalid JSON
Missing id or type4001Missing id or type
subscribe missing fields4001subscribe: missing required fields
unsubscribe missing fields4001unsubscribe: missing required fields
Unknown command4002Unknown command: xxx

Generic WebSocket

The generic WebSocket path is:

GET /kline/api/v1/ws/{topic}

topic is used as the Durable Object instance name. The currently exposed capability only supports application-level ping/pong.

Client message

{ "id": "req-001", "type": "ping", "data": {} }

Server response

{
"id": "req-001",
"time": 1704070800000,
"type": "pong",
"code": 0,
"data": {},
"msg": "ok"
}

Plain HTTP requests to this path return HTTP 426 as plain text:

Expected WebSocket upgrade

Unlike KlineHub, the generic WsServer returns an error message for binary frames, with code set to 4001 and msg set to Binary messages are not supported.

Note: Generic WebSocket is currently suitable only for connectivity or basic message-channel validation. Use /kline/api/v1/kline/ws for K-line real-time market data.


Error handling and best practices

Common HTTP errors

HTTPCommon business codeDescription
40010001 / 10002 / 10005Missing or invalid parameters, or WebSocket preflight error.
40410003 / 60001Route, pool, or resource not found.
40910004Resource conflict, such as duplicate pool creation.
50099001 / 99002 / 99003Internal service, database, or cache error.

Clients should check both the HTTP status code and response body code. Business success is represented by code: 0.

WebSocket integration recommendations

ItemRecommendation
HeartbeatPeriodically send { "id": "hb-001", "type": "ping", "data": {} } and verify pong.
ReconnectUse exponential backoff after disconnects and re-send subscriptions after reconnecting.
Gap fillingAfter reconnecting, call GET /kline/api/v1/kline/ohlcv to fill missing historical data.
IdempotencyTreat the same pool, interval, and open_time as an upsert key.
Subscription stateRepeated subscribe overwrites the pool's intervals; maintain local subscription state.

Timestamp handling

  • HTTP query parameters from and to accept Unix seconds or milliseconds. Values greater than 10000000000 are treated as milliseconds by the server.
  • OHLCV open_time uses Unix seconds; WebSocket envelope time uses Unix milliseconds.
  • Store timestamps in UTC and convert time zones only in the presentation layer.

Price and volume precision

  • open, high, low, close, and volume may be null.
  • Use high-precision decimal types or string storage for prices, volume, and market values when precision matters.
  • Market API data may use different field types from K-Line OHLCV data.

Document version: v1.0.0 | Last updated: 2026-04-28