openapi: 3.1.0
info:
contact:
email: backend@cybertinolab.com
name: Cyber team
description: "Surf data API gateway providing typed endpoints for crypto market data, project analytics, social signals, on-chain queries, and more. All endpoints use credit-based billing with per-request rate limiting.\n\n## Parameter Naming Conventions\n\nAll endpoints follow a standardized naming scheme. Use these canonical names when calling the API.\n\n### Asset Identification\n\n| Param | Type | Description | Example |\n|-------|------|-------------|---------|\n| `symbol` | string | Uppercase ticker symbol(s), comma-separated | `BTC`, `ETH,SOL` |\n| `q` | string | Free-text search keyword | `bitcoin` |\n| `id` | string | Surf entity UUID for direct lookup | `550e8400-...` |\n| `address` | string | On-chain contract or wallet address. Also accepts ENS names (e.g. `vitalik.eth`) which resolve automatically. | `0xdead...`, `vitalik.eth` |\n\n### Time & Aggregation\n\n| Param | Type | Description | Example |\n|-------|------|-------------|---------|\n| `time_range` | string or int | Lookback window | `7d`, `30d`, `365d`, `max` |\n| `interval` | string | Candlestick / indicator interval | `1h`, `1d`, `1w` |\n| `granularity` | string | Data aggregation granularity | `day`, `block`, `hour` |\n\n### Filtering & Sorting\n\n| Param | Type | Description | Example |\n|-------|------|-------------|---------|\n| `chain` | string | Blockchain name (canonical long-form only) | `ethereum`, `solana`, `base` |\n| `currency` | string | Quote currency | `usd`, `eur`, `btc` |\n| `metric` | string | Metric name (endpoint-specific enum) | `nupl`, `tvl` |\n| `type` | string | Category selector (endpoint-specific enum) | `us-btc-spot` |\n| `sort` | string | Sort direction | `asc`, `desc` |\n\n### Pagination\n\nAll list endpoints support:\n- `limit` (int, default: 20, max: 100) — results per page\n- `offset` (int, default: 0) — pagination offset\n\n### Supported Chains\n\nUse canonical long-form names only. Short aliases (eth, sol, matic, etc.) are **not accepted**.\n\n| Chain | Value |\n|-------|-------|\n| Ethereum | `ethereum` |\n| Polygon | `polygon` |\n| BNB Chain | `bsc` |\n| Solana | `solana` |\n| Avalanche | `avalanche` |\n| Arbitrum | `arbitrum` |\n| Optimism | `optimism` |\n| Fantom | `fantom` |\n| Base | `base` |\n| Linea | `linea` |\n| Cyber | `cyber` |\n\nNot all chains are available on every endpoint. Check each endpoint's `chain` enum for supported values.\n\n## Authentication\n\nAll data endpoints require a Bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer <API_KEY>\n```\n\n## Error Responses\n\nAll endpoints return errors in a consistent format:\n\n```json\n{\n \"error\": {\n \"code\": \"FORBIDDEN\",\n \"message\": \"insufficient credits\"\n }\n}\n```\n\n| HTTP Status | Meaning |\n|-------------|---------|\n| `400` | Bad request — invalid or missing parameters |\n| `401` | Unauthorized — missing or invalid API key |\n| `404` | Not found — the requested entity does not exist |\n| `422` | Validation error — parameter value is out of range or invalid |\n| `429` | Rate limited — too many requests, retry after the indicated interval |\n| `502` | Upstream error — a data source is temporarily unavailable |\n\n## Credits\n\nEach API call costs a certain number of credits. The cost is returned in every response under `meta.credits_used`. Check your remaining balance via `GET /v1/me/credit-balance`.\n"
title: Hermod DEX Exchange API
version: sha-80d3407
servers:
- url: /
tags:
- description: Access real-time trading data from major exchanges including Binance, OKX, Bybit, and more. Query live ticker prices, order book depth, OHLCV candlestick charts, and perpetual contract data such as funding rates, open interest, and long/short ratios.
name: Exchange
paths:
/gateway/v1/exchange/candles:
get:
description: 'Returns persisted OHLCV candles for a covered spot market.
**Intervals:** `5m`, `4h`, and `1w`. bitFlyer is currently reliable for weekly (`1w`) OHLCV only.
**Pagination:** use `from`/`to` to bound the time range and `limit` to cap returned candles. Results are ordered newest first.
**Synthetic candles:** `include_synthetic=true` by default, so carry-forward candles for no-trade intervals are included for continuous charts. Set `include_synthetic=false` for raw exchange-only candles.'
operationId: exchange-candles
parameters:
- description: Exchange identifier
explode: false
in: query
name: exchange
required: true
schema:
description: Exchange identifier
enum:
- bithumb
- upbit
- hashkey
- bitflyer
examples:
- bithumb
type: string
- description: Trading pair in base/quote form, e.g. BTC/KRW
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair in base/quote form, e.g. BTC/KRW
examples:
- BTC/KRW
type: string
- description: Candle interval
explode: false
in: query
name: interval
schema:
default: 5m
description: Candle interval
enum:
- 5m
- 4h
- 1w
examples:
- 5m
type: string
- description: Start of time range. Accepts Unix seconds or date string
explode: false
in: query
name: from
schema:
description: Start of time range. Accepts Unix seconds or date string
examples:
- '2026-06-24T09:00:00Z'
type: string
- description: End of time range. Accepts Unix seconds or date string
explode: false
in: query
name: to
schema:
description: End of time range. Accepts Unix seconds or date string
examples:
- '2026-06-24T10:00:00Z'
type: string
- description: Whether to include carry-forward candles for no-trade intervals. Defaults to true for continuous charts; set false for raw exchange-only candles.
explode: false
in: query
name: include_synthetic
schema:
default: true
description: Whether to include carry-forward candles for no-trade intervals. Defaults to true for continuous charts; set false for raw exchange-only candles.
examples:
- true
type: boolean
- description: Max number of candles to return. Weekly candles allow up to 300 rows for a 5-year chart; intraday intervals are capped at 100.
explode: false
in: query
name: limit
schema:
default: 100
description: Max number of candles to return. Weekly candles allow up to 300 rows for a 5-year chart; intraday intervals are capped at 100.
examples:
- 100
format: int64
maximum: 300
minimum: 1
type: integer
- description: Pagination offset
explode: false
in: query
name: offset
schema:
default: 0
description: Pagination offset
examples:
- 0
format: int64
minimum: 0
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DataResponseExchangeCandleItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Historical Candles
tags:
- Exchange
/gateway/v1/exchange/coverage:
get:
description: 'Returns covered spot markets with latest ticker metrics, candle availability, technical score, and data status.
**Ticker fields:** latest price, 24h open/high/low, previous close, signed 24h price and percent change, and 24h base/quote volume when the exchange provides them.
Use this endpoint to discover which Asian exchange markets have persisted market data. Use the returned `pair` values with `/exchange/candles` for historical OHLCV.
**bitFlyer note:** bitFlyer coverage is currently strongest for weekly (`1w`) OHLCV; latest ticker and shorter candle intervals may be unavailable.'
operationId: exchange-coverage
parameters:
- description: Exchange identifier. When omitted, returns all supported exchanges.
explode: false
in: query
name: exchange
schema:
description: Exchange identifier. When omitted, returns all supported exchanges.
enum:
- bithumb
- upbit
- hashkey
- bitflyer
examples:
- bithumb
type: string
- description: Free-text search over pair, base currency, or quote currency
explode: false
in: query
name: q
schema:
description: Free-text search over pair, base currency, or quote currency
examples:
- BTC
type: string
- description: Quote currency filter
explode: false
in: query
name: quote
schema:
description: Quote currency filter
examples:
- KRW
type: string
- description: Market type
explode: false
in: query
name: type
schema:
default: spot
description: Market type
enum:
- spot
examples:
- spot
type: string
- description: Market status filter
explode: false
in: query
name: status
schema:
description: Market status filter
enum:
- active
- inactive
examples:
- active
type: string
- description: Market data coverage status filter
explode: false
in: query
name: data_status
schema:
description: Market data coverage status filter
enum:
- covered
- official_empty_all
- official_empty_ticker
- official_empty_5m
- official_empty_weekly
- stale_gt_7d
- stale_30m_to_7d
- recent_but_lt_min_ta_candles
- missing_4h
- missing_latest_ta
examples:
- covered
type: string
- description: Sort field
explode: false
in: query
name: sort_by
schema:
default: pair
description: Sort field
enum:
- pair
- price
- change_24h
- volume_24h
- technical_score
- latest_candle_at
- status
examples:
- pair
type: string
- description: Sort order
explode: false
in: query
name: order
schema:
default: asc
description: Sort order
enum:
- asc
- desc
examples:
- asc
type: string
- description: Results per page
explode: false
in: query
name: limit
schema:
default: 20
description: Results per page
examples:
- 20
format: int64
maximum: 100
minimum: 1
type: integer
- description: Pagination offset
explode: false
in: query
name: offset
schema:
default: 0
description: Pagination offset
examples:
- 0
format: int64
minimum: 0
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DataResponseExchangeCoverageItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Market Coverage
tags:
- Exchange
/gateway/v1/exchange/depth:
get:
description: 'Returns order book bid/ask levels with computed stats.
**Included fields:** spread, spread percentage, mid-price, and total bid/ask depth.
Use `limit` to control the number of price levels (1–100, default 20). Set `type=swap` to query perpetual contract order books instead of spot.'
operationId: exchange-depth
parameters:
- description: Trading pair (e.g. BTC/USDT)
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT)
examples:
- BTC/USDT
type: string
- description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
explode: false
in: query
name: type
schema:
default: spot
description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
enum:
- spot
- swap
- perpetual
- perp
examples:
- spot
type: string
- description: Number of price levels (1-100)
explode: false
in: query
name: limit
schema:
default: 20
description: Number of price levels (1-100)
examples:
- 20
format: int64
maximum: 100
minimum: 1
type: integer
- description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
explode: false
in: query
name: exchange
schema:
default: binance
description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
enum:
- binance
- okx
- bybit
- bitget
- coinbase
- kraken
- gate
- mexc
- upbit
- bitstamp
- deribit
- bitmex
- bithumb
- hyperliquid
examples:
- binance
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleListResponseExchangeDepthItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Order Book Depth
tags:
- Exchange
/gateway/v1/exchange/funding-history:
get:
description: 'Returns historical funding rate records for a perpetual contract.
**Pagination:** use `from` to set the start time and `limit` to control result count. For longer history, pass the last returned timestamp as the next `from` value.
**Note:** not all exchanges support historical queries via `from`; some only return recent data regardless.
For the latest funding rate snapshot, see `/exchange/perp?fields=funding`.'
operationId: exchange-funding-history
parameters:
- description: Trading pair (e.g. BTC/USDT)
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT)
examples:
- BTC/USDT
type: string
- description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601). Not all exchanges support historical queries; some only return recent data regardless of this value.
explode: false
in: query
name: from
schema:
description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601). Not all exchanges support historical queries; some only return recent data regardless of this value.
examples:
- '2026-03-01'
type: string
- description: Max number of records. For longer history, paginate using the last returned timestamp as the next from value.
explode: false
in: query
name: limit
schema:
default: 100
description: Max number of records. For longer history, paginate using the last returned timestamp as the next from value.
examples:
- 100
format: int64
maximum: 500
minimum: 1
type: integer
- description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
explode: false
in: query
name: exchange
schema:
default: binance
description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
enum:
- binance
- okx
- bybit
- bitget
- gate
- htx
- mexc
- bitfinex
- bitmex
- hyperliquid
examples:
- binance
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleListResponseExchangeFundingHistoryItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Funding Rate History
tags:
- Exchange
/gateway/v1/exchange/klines:
get:
description: 'Returns OHLCV candlestick data with period summary stats (high, low, total volume).
**Intervals:** 15 options from `1m` to `1M`.
**Pagination:** use `from` to set the start time and `limit` to control candle count. For longer ranges, pass the last returned candle''s timestamp as the next `from` value. Exchange-side limits vary (200–1000 per request).
Set `type=swap` to query perpetual contract candles instead of spot.'
operationId: exchange-klines
parameters:
- description: Trading pair (e.g. BTC/USDT)
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT)
examples:
- BTC/USDT
type: string
- description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
explode: false
in: query
name: type
schema:
default: spot
description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
enum:
- spot
- swap
- perpetual
- perp
examples:
- spot
type: string
- description: Candle size — bucket duration for each returned OHLCV row. This endpoint uses `interval` only; it does NOT accept `time_range`. Use `from` + `limit` to control the window.
explode: false
in: query
name: interval
schema:
default: 1h
description: Candle size — bucket duration for each returned OHLCV row. This endpoint uses `interval` only; it does NOT accept `time_range`. Use `from` + `limit` to control the window.
enum:
- 1m
- 3m
- 5m
- 15m
- 30m
- 1h
- 2h
- 4h
- 6h
- 8h
- 12h
- 1d
- 3d
- 1w
- 1M
examples:
- 1h
type: string
- description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601)
explode: false
in: query
name: from
schema:
description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601)
examples:
- '2026-03-01'
type: string
- description: Max number of candles to return. Exchange may cap lower (e.g. 200-1000). For longer ranges, paginate using the last returned timestamp as the next from value.
explode: false
in: query
name: limit
schema:
default: 100
description: Max number of candles to return. Exchange may cap lower (e.g. 200-1000). For longer ranges, paginate using the last returned timestamp as the next from value.
examples:
- 100
format: int64
maximum: 1000
minimum: 1
type: integer
- description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
explode: false
in: query
name: exchange
schema:
default: binance
description: 'Exchange identifier. Note: hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC); pass USDC-quoted pairs when querying hyperliquid.'
enum:
- binance
- okx
- bybit
- bitget
- coinbase
- kraken
- gate
- htx
- kucoin
- mexc
- upbit
- bitfinex
- bitstamp
- deribit
- bitmex
- bithumb
- hyperliquid
examples:
- binance
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleListResponseExchangeKlineResponse'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange OHLCV Candlesticks
tags:
- Exchange
/gateway/v1/exchange/long-short-ratio:
get:
description: 'Returns historical long/short ratio for a perpetual contract.
**Included fields:** ratio value, long account percentage, short account percentage.
**Granularity:** `interval` supports `1h`, `4h`, `1d`.
**Pagination:** use `from` for start time and `limit` for result count. For longer history, pass the last returned timestamp as the next `from` value.
**Note:** not all exchanges support historical queries via `from`; some only return recent data regardless.
Just pass the base pair (e.g. `pair=BTC/USDT`). For aggregated cross-exchange long/short ratio, see `/market/futures`.'
operationId: exchange-long-short-ratio
parameters:
- description: Trading pair (e.g. BTC/USDT)
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT)
examples:
- BTC/USDT
type: string
- description: 'Bucket size for each point in the series: `1h`, `4h`, or `1d`. This endpoint uses `interval` only; it does NOT accept `time_range`. Use `from` + `limit` to control the window.'
explode: false
in: query
name: interval
schema:
default: 1h
description: 'Bucket size for each point in the series: `1h`, `4h`, or `1d`. This endpoint uses `interval` only; it does NOT accept `time_range`. Use `from` + `limit` to control the window.'
enum:
- 1h
- 4h
- 1d
examples:
- 1h
type: string
- description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601). Binance only retains the last 30 days of data; other exchanges may have different limits.
explode: false
in: query
name: from
schema:
description: Start of time range. Accepts Unix seconds or date string (YYYY-MM-DD, ISO8601). Binance only retains the last 30 days of data; other exchanges may have different limits.
examples:
- '2026-03-01'
type: string
- description: Max number of records. For longer history, paginate using the last returned timestamp as the next from value.
explode: false
in: query
name: limit
schema:
default: 50
description: Max number of records. For longer history, paginate using the last returned timestamp as the next from value.
examples:
- 50
format: int64
maximum: 500
minimum: 1
type: integer
- description: Exchange identifier
explode: false
in: query
name: exchange
schema:
default: binance
description: Exchange identifier
enum:
- binance
- okx
- bybit
- bitget
examples:
- binance
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleListResponseExchangeLongShortRatioItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Long/Short Ratio History
tags:
- Exchange
/gateway/v1/exchange/markets:
get:
description: 'Returns trading pairs available on an exchange.
**Filters:** `type` (`spot`, `swap`, `future`, `option`) or free-text `search`.
**Included fields:** pair name, base/quote currencies, market type, active status, and default fee rates.
Use the returned `pair` values as the `pair` parameter in other exchange endpoints.'
operationId: exchange-markets
parameters:
- description: Exchange identifier. When omitted, searches across all supported exchanges.
explode: false
in: query
name: exchange
schema:
description: Exchange identifier. When omitted, searches across all supported exchanges.
enum:
- binance
- okx
- bybit
- bitget
- coinbase
- kraken
- gate
- htx
- kucoin
- mexc
- upbit
- bitfinex
- bitstamp
- deribit
- bitmex
- bithumb
- hyperliquid
examples:
- binance
type: string
- description: Market type filter. Use perpetual or perp for perpetual contracts (alias for swap).
explode: false
in: query
name: type
schema:
description: Market type filter. Use perpetual or perp for perpetual contracts (alias for swap).
enum:
- spot
- swap
- future
- option
- perpetual
- perp
examples:
- spot
type: string
- description: Filter by base currency
explode: false
in: query
name: base
schema:
description: Filter by base currency
examples:
- ETH
type: string
- description: Filter by quote currency
explode: false
in: query
name: quote
schema:
description: Filter by quote currency
examples:
- USDT
type: string
- description: Fuzzy search in pair/base/quote
explode: false
in: query
name: search
schema:
description: Fuzzy search in pair/base/quote
examples:
- ETH
type: string
- description: Max results
explode: false
in: query
name: limit
schema:
default: 100
description: Max results
examples:
- 100
format: int64
maximum: 5000
minimum: 1
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleListResponseExchangeMarketItem'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Trading Pairs
tags:
- Exchange
/gateway/v1/exchange/perp:
get:
description: 'Returns a perpetual futures snapshot for a trading pair: funding rate, open interest, mark/index price.
**Available fields** (via `fields`):
- `funding` — current funding rate, next settlement, mark/index price
- `oi` — open interest in contracts and USD
Just pass the base pair (e.g. `pair=BTC/USDT`). The swap settle suffix is added automatically from the quote currency, e.g. `BTC/USDT:USDT` or `BTC/USDC:USDC`.'
operationId: exchange-perp
parameters:
- description: Trading pair (e.g. BTC/USDT). The swap settle suffix is added automatically from the quote currency, e.g. BTC/USDT:USDT or BTC/USDC:USDC.
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT). The swap settle suffix is added automatically from the quote currency, e.g. BTC/USDT:USDT or BTC/USDC:USDC.
examples:
- BTC/USDT
type: string
- description: 'Comma-separated fields to include: ''funding'' (current funding rate), ''oi'' (open interest). Defaults to all fields.'
explode: false
in: query
name: fields
schema:
default: funding,oi
description: 'Comma-separated fields to include: ''funding'' (current funding rate), ''oi'' (open interest). Defaults to all fields.'
examples:
- funding,oi
type: string
- description: Exchange identifier. Hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC).
explode: false
in: query
name: exchange
schema:
default: binance
description: Exchange identifier. Hyperliquid uses USDC-settled perps (e.g. BTC/USDC:USDC).
enum:
- binance
- okx
- bybit
- bitget
- htx
- bitfinex
- bitmex
- hyperliquid
examples:
- binance
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DataObjectResponseExchangePerpResponse'
description: OK
default:
content:
application/json:
schema:
$ref: '#/components/schemas/DataAPIError'
description: Error
security:
- AccessToken: []
summary: Exchange Perpetual Contract Snapshot
tags:
- Exchange
/gateway/v1/exchange/price:
get:
description: 'Returns the real-time ticker for a trading pair.
**Included fields:** last price, bid/ask, 24h high/low, 24h volume, 24h price change.
Set `type=swap` to query perpetual contract prices instead of spot. For historical price trends, use `/market/price`.'
operationId: exchange-price
parameters:
- description: Trading pair (e.g. BTC/USDT)
explode: false
in: query
name: pair
required: true
schema:
description: Trading pair (e.g. BTC/USDT)
examples:
- BTC/USDT
type: string
- description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
explode: false
in: query
name: type
schema:
default: spot
description: 'Market type: spot for spot trading, swap/perpetual/perp for perpetual contracts'
enum:
- spot
# --- truncated at 32 KB (60 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/surf/refs/heads/main/openapi/surf-exchange-api-openapi.yml