CCXT.HTTP (ccxt_client v0.6.1)

Copy Markdown View Source

HTTP client for exchange API requests.

Wraps Req with circuit breaker integration, error normalization, and telemetry. All exchange HTTP communication goes through this module.

Why Manual Query Encoding?

Uses URI.encode_query/1 instead of Req's :params step because:

  1. Signing requires raw params — signing patterns need params before URL encoding
  2. Sorted encoding — some exchanges require alphabetically sorted params
  3. Consistency — both public and private requests use the same encoding

Features

  • Circuit breaker — per-exchange, trips on 500+ and transport errors
  • Error normalization — HTTP/exchange errors to CCXT.Error structs
  • Body-level error detection — many exchanges return HTTP 200 with error in body
  • HTML response detection — geo-blocks and Cloudflare return HTML instead of JSON
  • Safe retry — only GET/HEAD, never POST/PUT/DELETE
  • Telemetry — emits [:ccxt, :request, :start | :stop | :exception]

Usage

{:ok, exchange} = CCXT.Exchange.new("bybit")

# Public endpoint
{:ok, response} = CCXT.HTTP.request(exchange, :get, "/v5/market/tickers",
  params: %{"category" => "spot", "symbol" => "BTCUSDT"}
)

Summary

Types

HTTP response with status, headers, and decoded body

Functions

Makes an HTTP request to an exchange API.

Types

response()

@type response() :: %{status: integer(), headers: response_headers(), body: term()}

response_headers()

@type response_headers() :: %{optional(String.t()) => [String.t()]}

HTTP response with status, headers, and decoded body

Functions

request(exchange, method, path, opts \\ [])

@spec request(CCXT.Exchange.t(), atom(), String.t(), keyword()) ::
  {:ok, response()} | {:error, CCXT.Error.t()}

Makes an HTTP request to an exchange API.

Parameters

  • exchange - Exchange configuration struct
  • method - HTTP method (:get, :post, :put, :delete)
  • path - API endpoint path (e.g., "/v5/market/tickers")

Options

  • :params - Query parameters or request body (default: %{})
  • :headers - Additional request headers (default: [])
  • :timeout - Request timeout in milliseconds (default: from CCXT.Defaults)
  • :base_url - Override base URL (default: uses exchange.base_urls)

Any additional options are passed through to Req (useful for :plug in tests).

Returns

  • {:ok, response} - Successful response with :status, :headers, :body
  • {:error, %CCXT.Error{}} - Normalized error

signed_request(exchange, signed, base_url, opts \\ [])

@spec signed_request(
  CCXT.Exchange.t(),
  CCXT.Signing.signed_request(),
  String.t(),
  keyword()
) ::
  {:ok, response()} | {:error, CCXT.Error.t()}

Executes a pre-signed request.

Used by CCXT.Dispatch for private endpoints after CCXT.Signing.sign/4 has built the signed URL, headers, and body.

Parameters

  • exchange - Exchange configuration struct
  • signed - Signed request from CCXT.Signing.sign/4 with :url, :method, :headers, :body
  • base_url - Base URL to prepend to the signed path
  • opts - Options passed through to Req (:timeout, :plug for tests, etc.)