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
| Class | Description |
|---|---|
GodarkClient | WebSocket trading + order/position streams on /ws/v1 |
GodarkRestClient | Bearer-authenticated REST trading, order lookup, leverage, account/position snapshots, and public-market queries; trading bodies use one-shot HPKE |
MarketDataClient | Public 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
| Method | Docs 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 callbacks | Orders Channel |
| Position update callbacks | Positions 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.