# `CCXT.WS.Subscription.SubBased`
[🔗](https://github.com/ZenHive/ccxt_client/blob/main/lib/ccxt/ws/subscription/sub_based.ex#L1)

HTX/Huobi-style subscribe frame.

    %{"sub" => "market.btcusdt.ticker"}

HTX requires **one subscribe frame per channel** — `subscribe/2` returns
a `[map()]` with one entry per channel (or an empty list for an empty
input). `CCXT.WS.subscribe/3` handles both single-map and list returns.

Frames intentionally omit an `"id"` field. zen_websocket's
`RequestCorrelator.extract_id/1` (deps/zen_websocket) treats any outbound
frame with a non-nil `"id"` as a JSON-RPC request and parks the caller in
a `GenServer.call` pending a correlated reply; HTX's subscribe ack is
fire-and-forget and does not round-trip through the correlator, so a
present `id` field hangs the caller until the default request timeout.
Omitting it restores immediate `:ok` return from `CCXT.WS.subscribe/3`.

Config keys:
- `:op_field` — default `"sub"`; the unsubscribe frame swaps to `"unsub"`
  automatically (overridable via `:unsub_field`)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
