Skip to Content
SDK reference

TypeScript SDK

The client, the stream, discovery and errors of the @spectre-trade/terminal package.

Install

npm install @spectre-trade/terminal

Terminal

A client of one running terminal.

Construct it with a token, or let Terminal.discover find the port and the token and verify the API version. All methods are async and throw ApiError for a non-2xx answer and TerminalUnreachableError when there is no answer.

FieldTypeDescription
hoststring
portnumber
timeoutMsnumber
baseUrlstringhttp://127.0.0.1:48180/v1/ — the token is not part of it.

Terminal()

new Terminal(options: TerminalOptions)

discover()

static discover(options: DiscoverOptions = {}): Promise<Terminal>

Find the terminal and check it: the token from options.token or SPECTRE_LOCAL_API_TOKEN (else TokenMissingError), the port from options.port or instance.json (else 48180; LocalApiDisabledError when the file says the API is off), then one GET /v1/meta. An api_version other than "1" is IncompatibleTerminalError; an unauthorized answer is an ApiError whose message says the token may be stale or the API switched off.

OptionsTypeDescription
tokenoptionalstringOverrides SPECTRE_LOCAL_API_TOKEN.
portoptionalnumberOverrides instance.json.
hostoptionalstring
timeoutMsoptionalnumber
instancePathoptionalstringRead this file instead of the OS-specific instance.json path (tests).

meta()

meta(): Promise<Meta>

GET /v1/meta: API version, build, token scopes, limits, stream topics.

HTTP operation: GET /v1/meta

health()

health(): Promise<Health>

GET /v1/health.

HTTP operation: GET /v1/health

connections()

connections(): Promise<List<Connection>>

GET /v1/connections (connections:read).

HTTP operation: GET /v1/connections

connection()

connection(id: number): Promise<Connection>

GET /v1/connections/{id} (connections:read); not_found for an unknown id.

HTTP operation: GET /v1/connections/{id}

instruments()

instruments(options: InstrumentsOptions): Promise<InstrumentsPage>

GET /v1/instruments (market:read): one page of the catalogue of an exchange and market, by connectionId or exchange + market. Follow next_cursor by hand or use iterInstruments.

HTTP operation: GET /v1/instruments

OptionsTypeDescription
connectionIdoptionalnumber
exchangeoptionalstring
marketoptionalstring
qoptionalstringSubstring of the symbol or the base coin, case-insensitive.
limitoptionalnumber1–2000, default 500.
cursoroptionalstringnext_cursor of the previous page.

iterInstruments()

iterInstruments(options: InstrumentsOptions): AsyncGenerator<Instrument, void, undefined>

Every instrument matching the options, page after page.

OptionsTypeDescription
connectionIdoptionalnumber
exchangeoptionalstring
marketoptionalstring
qoptionalstringSubstring of the symbol or the base coin, case-insensitive.
limitoptionalnumber1–2000, default 500.
cursoroptionalstringnext_cursor of the previous page.

intervals()

intervals(): Promise<Intervals>

GET /v1/market/intervals (market:read): candle and cluster intervals.

HTTP operation: GET /v1/market/intervals

candles()

candles(instrument: InstrumentAddress, options: CandlesOptions): Promise<Candles>

GET /v1/market/candles (market:read): candle history, oldest first.

HTTP operation: GET /v1/market/candles

OptionsTypeDescription
intervalstringA code from /v1/market/intervals: 1m, 5m, …
limitoptionalnumberUp to 2000, default 500.
endoptionalnumberRight boundary, UTC milliseconds; default now.
connectionIdoptionalnumber

trades()

trades(instrument: InstrumentAddress, options: TradesOptions = {}): Promise<Trades>

GET /v1/market/trades (market:read): the latest trades of the pair, oldest to newest. A pair without a subscription is opened on demand and the call may take up to 3 s.

HTTP operation: GET /v1/market/trades

OptionsTypeDescription
limitoptionalnumber1–1000 latest, default 100.
sinceTsoptionalnumberNot earlier than this receive time, UTC milliseconds.
connectionIdoptionalnumber

snapshot()

snapshot(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Snapshot>

GET /v1/market/snapshot (market:read): best bid/ask, last trade, mark, ticker.

HTTP operation: GET /v1/market/snapshot

OptionsTypeDescription
connectionIdoptionalnumber

orderbook()

orderbook(instrument: InstrumentAddress, options: OrderbookOptions = {}): Promise<Orderbook>

GET /v1/market/orderbook (market:read); unavailable without a full book within 3 s.

HTTP operation: GET /v1/market/orderbook

OptionsTypeDescription
depthoptionalnumber1–200, default 50.
connectionIdoptionalnumber

clusters()

clusters(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Clusters>

GET /v1/market/clusters (market:read): up to ten buckets at the interval selected in the terminal. The first call for an instrument not open in the window may answer not_active (409); a retry a few seconds later finds the clusters.

HTTP operation: GET /v1/market/clusters

OptionsTypeDescription
connectionIdoptionalnumber

accountOrders()

accountOrders(connectionId: number): Promise<AccountOrders>

GET /v1/account/orders (account:read): open orders and trigger orders of one connection, the same cut the terminal window sees. not_found for an unknown connection.

HTTP operation: GET /v1/account/orders

accountPositions()

accountPositions(connectionId: number): Promise<AccountPositions>

GET /v1/account/positions (account:read): open positions of one connection.

HTTP operation: GET /v1/account/positions

accountBalances()

accountBalances(connectionId: number): Promise<AccountBalances>

GET /v1/account/balances (account:read): per currency, the latest value the exchange sent since the API was switched on. A currency nothing happened to since then is absent.

HTTP operation: GET /v1/account/balances

accountFills()

accountFills(connectionId: number, options: AccountFillsOptions = {}): Promise<AccountFills>

GET /v1/account/fills (account:read): the connection's fills since the API was switched on (the last thousand), oldest to newest.

HTTP operation: GET /v1/account/fills

OptionsTypeDescription
limitoptionalnumber1–1000 latest, default 100.
sinceTsoptionalnumberNot earlier than this exchange time, UTC milliseconds.

placeOrder()

placeOrder(options: PlaceOrderOptions): Promise<Accepted>

POST /v1/orders (trading:write): place a limit or market order with the same command the window uses. The answer means accepted by the terminal, not by the exchange: watch account.orders in the stream, or accountOrders, for the order under key. not_tradable (409) for a disabled, read-only or credential-less connection, invalid_request (400) for a foreign instrument or a refused size or price, rate_limited (429) above limits.commands_per_second.

HTTP operation: POST /v1/orders

OptionsTypeDescription
connectionIdnumberThe trading connection; there is no default.
instrumentInstrumentAddress
sideSide
typeOrderTypelimit needs price, market takes none.
priceoptionalDecimal
sizeoptionalDecimalAmount in the base coin; exactly one of size and notional.
notionaloptionalDecimalThe quote amount; exactly one of size and notional.
reduceOnlyoptionalbooleanDefault false.
postOnlyoptionalbooleanDefault false.
timeInForceoptionalTimeInForceAbsent — the venue's default.
clientKeyoptionalstringIdempotency key: a repeat with the same key returns the previous answer and does not duplicate the order (the terminal remembers the last thousand).

cancelOrder()

cancelOrder(options: CancelOrderOptions): Promise<Accepted>

DELETE /v1/orders/{id} (trading:write): cancel one order by the terminal key (t-…) or the exchange's id. The cancellation goes to the exchange directly; the confirmation arrives through the stream.

HTTP operation: DELETE /v1/orders/{id}

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
orderIdstringThe terminal key (t-…) or the exchange's order id.

cancelAll()

cancelAll(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/orders/cancel-all (trading:write): cancel every order of the instrument, as the space bar does.

HTTP operation: POST /v1/orders/cancel-all

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress

closePosition()

closePosition(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/positions/close (trading:write): close the instrument's position the way the window does — a market order for the position size on futures, "cancel all and close" as one atomic command on spot. invalid_request without an open position.

HTTP operation: POST /v1/positions/close

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress

placeTrigger()

placeTrigger(options: PlaceTriggerOptions): Promise<Accepted>

POST /v1/orders/trigger (trading:write): a stop loss, take profit or stop, placed by the same services the window uses. stop_loss and take_profit go on the open position (side, size and rule come from it; invalid_request without one); a stop needs side and notional. key in the answer is the trigger's key (sl_…, tp_…, stop_…), which shows up as client_id of the trigger in accountOrders; cancelling and amending use the numeric id from there. unsupported (501) on a venue without trigger orders in the terminal.

HTTP operation: POST /v1/orders/trigger

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
kindTriggerTypestop_loss and take_profit go on the open position; stop is its own order.
triggerPriceDecimal
sideoptionalSidestop only.
notionaloptionalDecimalstop only: the quote amount.
ruleoptionalTriggerRulestop only; absent means above the market for a buy, below for a sell.
clientKeyoptionalstringIdempotency key, as for Terminal.placeOrder.

cancelTrigger()

cancelTrigger(options: CancelTriggerOptions): Promise<Accepted>

DELETE /v1/orders/trigger/{id} (trading:write): cancel one trigger by its numeric id.

HTTP operation: DELETE /v1/orders/trigger/{id}

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
triggerIdstring | numberThe numeric id of the trigger from accountOrders().triggers.

cancelAllTriggers()

cancelAllTriggers(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/orders/trigger/cancel-all (trading:write): cancel every trigger of the instrument; plain orders stay.

HTTP operation: POST /v1/orders/trigger/cancel-all

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress

amendTrigger()

amendTrigger(options: AmendTriggerOptions): Promise<Accepted>

PATCH /v1/orders/trigger/{id} (trading:write): move a trigger to a new price — the window's sequential replacement, cancel then place. kind is required; a stop also needs its side. key is null.

HTTP operation: PATCH /v1/orders/trigger/{id}

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
triggerIdstring | numberThe numeric id of the trigger from accountOrders().triggers.
kindTriggerType
triggerPriceDecimal
sideoptionalSidestop only.
ruleoptionalTriggerRulestop only.

leverage()

leverage(options: InstrumentCommandOptions): Promise<Leverage>

GET /v1/account/leverage (account:read): leverage and margin mode of a futures instrument, from the terminal's cache. An instrument the terminal has not touched yet is not_active (409): open it in the window or call setLeverage, which is how it enters the cache.

HTTP operation: GET /v1/account/leverage

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress

setLeverage()

setLeverage(options: SetLeverageOptions): Promise<Accepted>

POST /v1/account/leverage (trading:write): set the leverage the way the window does — exactly one of leverage (an integer ≥ 1) and mode (max, smart). The applied value shows in leverage after the exchange answered.

HTTP operation: POST /v1/account/leverage

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
leverageoptionalnumberAn integer of at least 1.
modeoptional"max" | "smart"

setMarginMode()

setMarginMode(options: SetMarginModeOptions): Promise<Accepted>

POST /v1/account/margin-mode (trading:write): cross or isolated. Changing it with an open position is refused by the exchange, as in the window; the accepted answer does not know that yet.

HTTP operation: POST /v1/account/margin-mode

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress
marginModeMarginMode

workspace()

workspace(): Promise<Workspace>

GET /v1/workspace (workspace:read): every window with its tabs, stacks and charts, from the snapshot the window publishes at every structural change. The ids are internal to this run of the terminal.

HTTP operation: GET /v1/workspace

workspaceWindow()

workspaceWindow(options: WindowOptions): Promise<WorkspaceWindow>

GET /v1/workspace/windows/{id} (workspace:read): one window; an unknown id is not_found.

HTTP operation: GET /v1/workspace/windows/{id}

OptionsTypeDescription
windowIdnumber

openStack()

openStack(options: OpenStackOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/stacks (workspace:write): a stack of the instrument in a new tab or a new window, with a chart over it when chart is set. The answer names the window, the tab and the new widgets. An instrument the terminal's catalogue does not know is invalid_request.

HTTP operation: POST /v1/workspace/stacks

OptionsTypeDescription
instrumentInstrumentAddress
connectionIdoptionalnumberChosen by the general rule when omitted.
chartoptionalbooleanA chart of the same instrument over the stack.
targetoptionalOpenTargetnew_tab (default) or new_window.
windowIdoptionalnumberThe window for a new tab; the focused window when omitted.
activateoptionalbooleanfalse opens the tab in the background; a new window always takes focus.

openTab()

openTab(options: OpenTabOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/tabs (workspace:write): a tab with a column per item — a stack and, with chart, a chart over it — in a new tab or a new window. Omitted, name is the only instrument or the first one plus a count. A refusal names the item (items[1]: …) and nothing reaches the window.

HTTP operation: POST /v1/workspace/tabs

OptionsTypeDescription
itemsArray<TabItemOptions | InstrumentAddress>Columns in order, one to fifty; a bare address is a stack without a chart.
nameoptionalstringUp to 64 characters; omitted, the terminal names the tab after the instruments.
targetoptionalOpenTargetnew_tab (default) or new_window.
windowIdoptionalnumberThe window for a new tab; the focused window when omitted.
activateoptionalbooleanfalse opens the tab in the background; a new window always takes focus.

addStacks()

addStacks(options: AddStacksOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/tabs/{tab}/stacks (workspace:write): the same columns after the tab's last one; the tab keeps its name and its column widths. The answer lists only the added widgets.

HTTP operation: POST /v1/workspace/windows/{id}/tabs/{tab}/stacks

OptionsTypeDescription
windowIdnumber
tabIdnumber
itemsArray<TabItemOptions | InstrumentAddress>Columns in order, one to fifty; a bare address is a stack without a chart.

openMultiview()

openMultiview(options: OpenMultiviewOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/multiview (workspace:write): a coin on every venue of «Exchange layout», the same plan as the window's Multiview button. No cell for the coin is not_found.

HTTP operation: POST /v1/workspace/multiview

OptionsTypeDescription
basestringA coin (BTC) or a pair (BTC/USDT).
targetoptionalOpenTargetOmitted: the Multiview «open as» setting decides.
windowIdoptionalnumber
activateoptionalboolean

setStackInstrument()

setStackInstrument(options: StackInstrumentOptions): Promise<WorkspaceOutcome>

PATCH /v1/workspace/stacks/{widget_id} (workspace:write): another instrument in the stack and its charts.

HTTP operation: PATCH /v1/workspace/stacks/{widget_id}

OptionsTypeDescription
widgetIdnumber
instrumentInstrumentAddress
connectionIdoptionalnumber

closeStack()

closeStack(options: StackOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/stacks/{widget_id} (workspace:write): close one stack, as its close button does.

HTTP operation: DELETE /v1/workspace/stacks/{widget_id}

OptionsTypeDescription
widgetIdnumber

closeTab()

closeTab(options: TabOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/windows/{id}/tabs/{tab} (workspace:write): the only tab of a window is invalid_request.

HTTP operation: DELETE /v1/workspace/windows/{id}/tabs/{tab}

OptionsTypeDescription
windowIdnumber
tabIdnumber

activateTab()

activateTab(options: TabOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/tabs/{tab}/activate (workspace:write): select the tab; the window's focus is untouched.

HTTP operation: POST /v1/workspace/windows/{id}/tabs/{tab}/activate

OptionsTypeDescription
windowIdnumber
tabIdnumber

closeWindow()

closeWindow(options: WindowOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/windows/{id} (workspace:write): the main window is invalid_request.

HTTP operation: DELETE /v1/workspace/windows/{id}

OptionsTypeDescription
windowIdnumber

activateWindow()

activateWindow(options: WindowOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/activate (workspace:write): restore if minimised and bring to the front.

HTTP operation: POST /v1/workspace/windows/{id}/activate

OptionsTypeDescription
windowIdnumber

settings()

settings(options: SettingsOptions = {}): Promise<Settings>

GET /v1/settings (settings:read): rows as stored, without the default ladder. Without options: the global rows without a connection. Each row says whether it is writable through updateSettings.

HTTP operation: GET /v1/settings

OptionsTypeDescription
scopeoptional"global" | "order_book"global (default) or order_book.
categoryoptionalstring
keyoptionalstring
connectionIdoptionalnumberThe connection's rows; without it the rows without a connection.
instrumentoptionalInstrumentAddressThe pair's rows (scope order_book).

orderbookSettings()

orderbookSettings(options: InstrumentCommandOptions): Promise<OrderbookSettings>

GET /v1/settings/orderbook (settings:read): the stack settings of an instrument as its stack on the connection sees them — the pair's row, the connection's default, the pair's row without a connection, the global default — with resolved_from on every key.

HTTP operation: GET /v1/settings/orderbook

OptionsTypeDescription
connectionIdnumber
instrumentInstrumentAddress

updateSettings()

updateSettings(changes: SettingChange[]): Promise<SettingsApplied>

PATCH /v1/settings (settings:write): write settings the way the Settings App does. Every change is checked against the terminal's catalogue first (invalid_request naming changes[i], nothing written; leverage is unsupported here — use setLeverage), then applied in order: the same row, window event and service caches as the Settings App. The first failed change rejects the call; earlier ones stay applied.

HTTP operation: PATCH /v1/settings

stream()

stream(options: StreamOptions = {}): Promise<Stream>

Open /v1/stream. Node only: the token goes in the handshake header.

OptionsTypeDescription
timeoutMsoptionalnumberHandshake timeout; defaults to the client's timeoutMs.

StreamProtocol

The socket-free half of the stream protocol: hands out request ids, keeps the requests waiting for a reply, settles them from subscribed / unsubscribed / error frames and turns everything else into the frames a consumer iterates. Pure, so it is unit-testable without a server.

nextRequestId()

nextRequestId(): string

A fresh request_id, unique within this stream.

expect()

expect(requestId: string): Promise<ReplyFrame>

Register a request and get the promise its reply will settle.

pendingCount

pendingCount: number

Requests still waiting for a reply.

route()

route(raw: unknown): StreamFrame | undefined

Classify a decoded frame. Replies to our requests settle the matching promise and return undefined; event, gap and subscription errors are returned for the consumer; anything unknown or malformed is dropped.

abortAll()

abortAll(error: Error): void

Reject every waiting request, e.g. when the socket closes.

Stream

class Stream extends AsyncIterable<StreamFrame>

A live /v1/stream connection.

Obtain one with terminal.stream(). Subscribe with subscribe, then iterate: for await (const frame of stream) yields events, gaps and subscription errors in arrival order, buffered without limit while the consumer is busy (the server protects itself: a client that lags for more than 5 s is closed with 4008). One consumer iterates at a time; a second concurrent next() simply waits its turn.

When the server closes the connection, iteration ends; for 1001, 4008, 4029 and a lost connection (1006) it ends by throwing StreamClosedError. closeCode and closeReason are set either way. Closing from the client (close, or break out of the loop) ends iteration normally.

connect()

static connect(options: StreamConnectOptions): Promise<Stream>

Open the WebSocket and complete the handshake. Rejects with TerminalUnreachableError when the terminal does not accept it: Node's WebSocket reports a refused handshake (terminal down, API off, token rejected) as one generic failure, so the three are not told apart.

OptionsTypeDescription
urlstringws://127.0.0.1:48180/v1/stream.
tokenstring
timeoutMsoptionalnumberHandshake timeout; default 10 000.

url

url: string

The stream URL (never carries the token).

closed

closed: boolean

true once the socket is closed, whoever closed it.

closeCode

closeCode: number | undefined

WebSocket close code, once closed.

closeReason

closeReason: string | undefined

WebSocket close reason, once closed.

subscribe()

subscribe(options: SubscribeOptions): Promise<Subscribed>

Subscribe to a topic of an instrument, or to an account topic of a connection. Resolves with the server's subscribed frame (plus the requested topic and, for market topics, instrument) and rejects with StreamRequestError on the server's error reply; events of other subscriptions keep flowing meanwhile. Note the terminal's limit on new exchange subscriptions per second (/v1/meta); account topics do not touch the exchange and send no snapshot frame — read the current state with the /v1/account/* operations first.

OptionsTypeDescription
topicTopic
instrumentoptionalInstrumentAddressRequired for market topics; ignored for account.*.
connectionIdoptionalnumberRequired for account.*; chosen by the general rule for market topics when omitted.
paramsoptionalBookTopParamsOnly book.top reads them; wire names (depth, interval_ms).

unsubscribe()

unsubscribe(subscription: Subscribed | SubscribedFrame | string): Promise<void>

Remove a subscription immediately. Accepts the value subscribe resolved with or the bare sub id. Resolves on the server's unsubscribed.

close()

close(code: number = CLOSE_NORMAL, reason?: string): Promise<void>

Close the stream. The server completes the close handshake with the client's code; the promise resolves when it has, or after a short grace period if it never does. Safe to call more than once.

Discovery

ConstantsValueDescription
DEFAULT_PORT48180The port the terminal listens on unless SPECTRE_LOCAL_API_PORT overrides it.
TOKEN_ENV"SPECTRE_LOCAL_API_TOKEN"The environment variable the token is read from.

instancePath()

function instancePath(options: DiscoveryEnvironment = {}): string

Path of the terminal's instance.json, per OS:

  • Linux: $XDG_DATA_HOME/spectre-terminal/instance.json, falling back to ~/.local/share/spectre-terminal/instance.json;
  • macOS: ~/Library/Application Support/spectre-terminal/instance.json;
  • Windows: %LOCALAPPDATA%\spectre-terminal\instance.json, falling back to %USERPROFILE%\AppData\Local\....

This mirrors the terminal's own data directory (dirs::data_local_dir).

readPort()

function readPort(options: ReadPortOptions = {}): Promise<number | undefined>

The Local API port published in instance.json.

Resolves to undefined when the file is missing or unreadable (no running terminal, or a terminal that does not publish the field): the caller falls back to DEFAULT_PORT. Throws LocalApiDisabledError when the file exists but local_api_port is null or absent — the terminal is running and the API is switched off. Reads only this one field.

tokenFromEnv()

function tokenFromEnv(env: Record<string, string | undefined> = process.env): string | undefined

The token from SPECTRE_LOCAL_API_TOKEN, or undefined when unset or empty.

Errors

SpectreTerminalError

class SpectreTerminalError extends Error

Base class of every error thrown by this package.

ApiError

class ApiError extends SpectreTerminalError

The terminal answered with a non-2xx status.

code is the stable code from the contract's error envelope (unauthorized, not_found, rate_limited, …); status is the HTTP status. A non-2xx body that is not the envelope gives code "unknown".

FieldTypeDescription
codestringStable error code from the contract, or "unknown".
statusnumberHTTP status of the response.
detailstringThe server's human-readable message, unprefixed.

TerminalUnreachableError

class TerminalUnreachableError extends SpectreTerminalError

No HTTP response at all: connection refused, request timed out, an unexpected redirect, or a WebSocket handshake that did not complete. The original failure is in cause.

LocalApiDisabledError

class LocalApiDisabledError extends SpectreTerminalError

instance.json exists but publishes no Local API port: the terminal is running with the API switched off, or the file was left behind by a terminal that did not shut down cleanly. Either way there is no port to connect to until the API is enabled in the Settings App (General → Local API).

TokenMissingError

class TokenMissingError extends SpectreTerminalError

Neither the token option nor SPECTRE_LOCAL_API_TOKEN provided a token.

IncompatibleTerminalError

class IncompatibleTerminalError extends SpectreTerminalError

/v1/meta reported an API version this client does not speak.

FieldTypeDescription
apiVersionstringThe api_version the terminal reported.
appVersionstringThe app_version the terminal reported.

StreamRequestError

class StreamRequestError extends SpectreTerminalError

The stream answered a subscribe or unsubscribe request with an error frame. code is the contract's error code (not_found, rate_limited, invalid_request, …). Other subscriptions keep flowing.

FieldTypeDescription
codestringStable error code from the contract.
detailstringThe server's human-readable message, unprefixed.

StreamClosedError

class StreamClosedError extends SpectreTerminalError

The stream was closed by the server for a reason the consumer must act on: 1001 — the API was switched off or the token was reissued; 4008 — this client read too slowly; 4029 — the per-token connection limit. It is also raised for 1006 when the connection dropped without a close frame, and by subscribe / unsubscribe on an already closed stream.

FieldTypeDescription
codenumberWebSocket close code.
reasonstringClose reason sent by the server, possibly empty.

Generated from the code of @spectre-trade/terminal at commit 2d1c324.

On this page