Python SDK

Encrypted Python client for the GoDark API. Package name: godark.

Requirements: Python 3.10+
Status: Beta — clone the public examples repo to get started.

Get the SDK

Clone gdx-python-sdk-examples. The repo vendors the godark SDK source under sdk/, so no private PyPI registry is required. A compatible prebuilt wheel may also be included under wheels/; it is an optional convenience, not guaranteed for every Python/platform combination, and setup falls back to the vendored source:

git clone https://github.com/gq-godark/gdx-python-sdk-examples.git
cd gdx-python-sdk-examples
cp .env.example .env
# set GODARK_API_KEY_ID, GODARK_API_SECRET, GODARK_PASSPHRASE

bash scripts/setup_venv.sh
source .venv/bin/activate
cd examples && python quickstart.py

You can also point an LLM / coding agent at the cloned repo and ask it to build a strategy using your credentials in .env. See the repo README for full setup, examples, and packaging details.

Public PyPI release is not yet available; until then this repo is the supported distribution.

Quickstart

Set credentials, then place a limit order over encrypted WebSocket (GodarkClient). Subscribe to orders before placing so book confirmation can wait on private updates. Limit prices must stay near the oracle or the venue rejects — see Error Codes.

import asyncio
import os

from godark import Environment, GodarkClient, OrderType, Side, TimeInForce

SYMBOL = "BTC-USDC-PERP"


async def main() -> None:
    kwargs = dict(
        api_key_id=os.environ["GODARK_API_KEY_ID"],
        api_secret=os.environ["GODARK_API_SECRET"],
        passphrase=os.environ["GODARK_PASSPHRASE"],
        the default environment preset,
    )
    if edge := os.environ.get("GODARK_EDGE_URL", "").strip():
        kwargs["base_url"] = edge

    async with GodarkClient(**kwargs) as client:
        await client.subscribe(["orders"])
        ack = await client.place_order(
            SYMBOL,
            Side.SELL,
            OrderType.LIMIT,
            "0.01",
            price="68000.0",  # within ~10% of oracle
            time_in_force=TimeInForce.GTC,
        )
        print("placed", ack.order_id)
        await asyncio.sleep(0.5)
        cancel = await client.cancel_order(str(ack.order_id), SYMBOL)
        print("cancelled", cancel.order_id)


asyncio.run(main())

See WebSocket Trading and Place Order for request fields.

Clients

ClassDescription
GodarkClientWebSocket trading + order/position streams on /ws/v1
GodarkRestClientBearer-authenticated REST trading, order lookup, leverage, account/position snapshots, and public-market queries; trading bodies use one-shot HPKE
MarketDataClientPublic market snapshots on /ws/v1 by default; set GODARK_MARKET_DATA_USE_GOMARKET=1 or GODARK_MARKET_DATA_WS_URL to opt in to /ws/gomarket order-book feeds

GodarkRestClient places / cancels / modifies with bearer + one-shot HPKE. GodarkClient uses a sealed HPKE WebSocket session for the same ops.

With api_key_id + api_secret + passphrase, both clients mint POST /api/v1/auth/token (client_credentials) first. WebSocket login uses the returned access_token — the secret is never sent on the socket. Legacy opaque api_key= (for example a custom host test-key-*) is still sent as-is.

Public place/modify/mass-quote/batch-modify/TP-SL prices and sizes are decimal strings only (for example "68000.0", "0.01"). This covers quantity, price, min_fill_size, quote_notional, trigger_price, take_profit_price, stop_loss_price, new_price, new_quantity, and new_trigger_price. Passing int, float, or bool raises TypeError. The SDK validates and pads each value to the instrument's price_decimals / quantity_decimals before sealing (PlaceOrderInput.price field 23, quantity field 24).

GodarkRestClient.get_order and await_terminal_status fill status when the edge returns an {encrypted, hint, order_id} pointer. Status comes from the decrypted open-order book, a terminal ack cache, or order history.

Server-side client_order_id lookup follows a successful WebSocket place. GodarkClient.place_order(..., client_order_id=) then POSTs /api/v1/orders/_register_coid with that id, the decimal order_id, and correlation_id as the decimal u128 of the same id in the place header. The edge arms that correlation only on a WebSocket place. A REST place does not, so GodarkRestClient.place_order does not register a client order id and does not treat a local map as if the edge stored one. A 400 from _register_coid is raised. Reads and cancels by client order id use GET /api/v1/orders?client_order_id=.

On GodarkClient, volume_snapshot and open_interest_snapshot frames nested in a subscribe ack are delivered to on_volume_snapshot / volume_snapshots and on_open_interest_snapshot / open_interest_snapshots. An unknown subscribe channel raises as soon as the edge returns the error. Open-order hydration is available from open_orders_snapshots() and on_open_orders_snapshot.

the default environment preset is the hosted default and an alternate environment preset selects the configured host. Python accepts ws(s) or http(s) edge URLs, rewrites http → ws and https → wss, upgrades a trailing /ws, and otherwise appends /ws/v1. See Base URLs.

GodarkClient methods

MethodDocs reference
connect() / disconnect()Authentication, Encryption
subscribe(...)WebSocket Trading
place_order(...)Place Order, WebSocket Trading
cancel_order(...)Cancel Order
modify_order(...)Modify Order
mass_quote(...)Mass Quote
batch_cancel(...)Cancel Order
Order update callbacksOrders Channel
Position update callbacksPositions Channel

Types and errors

Exported from godark: Environment, Side, OrderType, TimeInForce, OrderStatus, OrderAck, OrderUpdate, PositionUpdate, and error classes (AuthenticationError, SessionError, OrderError, EncryptionError, TimeoutError, ConnectionError).

The HPKE login conn_id is a Python int carrying the unsigned 64-bit wire value.

Environment variables: OS GODARK_*, then OS GDX_*, then .env GODARK_*, then .env GDX_*. The process environment always wins over .env. Quickstart snippets use the canonical GODARK_* names.

Bundled examples

Runnable samples in the examples repo include quickstart.py (connect → subscribe → place → cancel) and full_trader_example.py (modify, mass quote, batch cancel).

See also


Shared trading fields

Prices, sizes, quote notional, trigger, take-profit, and stop-loss are decimal strings.

Place options (names follow each language): reduce_only, post_only, stp_mode (UNSPECIFIED, CANCEL_RESTING, CANCEL_AGGRESSOR, CANCEL_BOTH), quote_notional, peg_offset_bps, trigger_price, take_profit_price, stop_loss_price, slippage_bps, client_order_id.

confirmation: ack returns on the sequencer acknowledgement. book waits for a terminal private order update until the place timeout.

Time in force: GTC, IOC, FOK, GTD. Order types: MARKET, LIMIT, PEG, STOP_MARKET, STOP_LIMIT. Side: BUY, SELL.

Mass quote: 1 to 20 legs. Each leg has side, price, quantity, optional cancel_order_id, time_in_force, expiry_time. post_only omitted uses the venue default.

Batch modify legs: order_id plus at least one of new_price, new_quantity.

WebSocket implements cancel-all, close-all, reverse, and TP/SL amend or cancel. REST implements one-shot encrypted place, cancel, modify, mass quote, batch cancel, batch modify, plus snapshots. REST does not implement cancel-all, close-all, reverse, or TP/SL amend.

A WebSocket place that sets client_order_id registers it after the ack. REST leaves that id unregistered.

Errors: authentication, session, connection, encryption, timeout, and order rejection with a numeric code and symbolic name. See Error Codes.

Python reference

GodarkClient(...) and GodarkRestClient(...) take api_key or api_key_id + api_secret + passphrase, environment, base_url or rest_base_url, account, symbol_map, hpke_static_public_key_hex. The socket client also takes auto_reconnect, transport, stream_buffer_size, place_order_terminal_timeout. Both are async context managers.

Socket: connect, disconnect, logout, place_order, cancel_order, modify_order, update_leverage, cancel_all_orders, close_all, reverse_position, amend_tpsl, cancel_tpsl, mass_quote, batch_cancel, batch_modify, subscribe, unsubscribe.

Callbacks and async iterators cover orders, positions, snapshots, health, balance, margin alerts, funding, volume, open interest, open orders, settlement, leverage, reconnect, and errors.

REST place accepts quantity, price, type, time in force, and client order id. Optional place flags belong on the WebSocket PlaceOrderOptions object. REST also has get_open_orders, get_positions, get_account, order lookup, funding, open interest, volume, update_leverage, mass quote, and batch commands. It does not expose get_leverage.

PlaceOrderOptions fields: reduce_only, post_only, stp_mode, peg_offset_bps, trigger_price, take_profit_price, stop_loss_price, slippage_bps, quote_notional.