Overview

Endpoint

  • Mainnet REST Endpoint

    • Spot: https://mainnet-gw.sodex.dev/api/v1/spot

    • Perps: https://mainnet-gw.sodex.dev/api/v1/perps

  • Mainnet WebSocket Endpoint

    • Spot: wss://mainnet-gw.sodex.dev/ws/spot

    • Perps: wss://mainnet-gw.sodex.dev/ws/perps

  • Testnet REST Endpoint

    • Spot: https://testnet-gw.sodex.dev/api/v1/spot

    • Perps: https://testnet-gw.sodex.dev/api/v1/perps

  • Testnet WebSocket Endpoint

    • Spot: wss://testnet-gw.sodex.dev/ws/spot

    • Perps: wss://testnet-gw.sodex.dev/ws/perps

API keys and nonces

API keys

A master account can approve or revoke API keys to sign on behalf of the master account or any of the sub-accounts. Each master account can have at most 5 API keys.

In Sodex, we currently support EVM address as the API key. Users can sign the transaction with their EVM private key. Note that API keys are only used to sign. To query the account data associated with a master or sub-account, you must pass in the actual account ID of that account.

Sodex nonces

Similar to Hyperliquid, on Sodex, the 100 highest nonces are stored per address. Every new transaction must have nonce larger than the smallest nonce in this set and also never have been used before. Nonces are tracked per API key, which is the user address if signed with private key of the address, or the agent address if signed with an API wallet.

Nonces must be within (T - 2 days, T + 1 day), where T is the Unix millisecond timestamp on the block of the transaction.

The following steps may help port over an automated strategy from a centralized exchange:

  1. Use an API wallet per trading process. Note that nonces are stored per API key (i.e. private key), so separate sub-accounts signed by the same API wallet will share the nonce tracker of the API wallet. It's recommended to use separate API wallets for different sub-accounts.

  2. The trading logic tasks send orders and cancels to the batching task.

  3. For each batch of orders or cancels, fetch and increment an atomic counter that ensures a unique nonce for the address. The atomic counter can be fast-forwarded to current Unix milliseconds if needed.

This structure is robust to out-of-order transactions within 2 seconds, which should be sufficient for an automated strategy geographically near an API server.

Typed signature

In Sodex, we use EIP712arrow-up-right for Typed structured data hashing and signing. We use different domains for different actions.

Other actions

For mainnet use 286623 for domain.chainId, for testnet use 138565 for domain.chainId. For spot actions, use spot for domain.name and for perps actions, futures for domain.name.

After you get the signature bytes sig, append byte 1 before the sig bytes to get typed signature. For example, your signed signature is 0x789a6bcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab, the correct typed signature is 0x01789a6bcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab.

How to compute payloadHash

payloadHash = Keccak256(json.Marshal(payload))

The payload is a JSON object with two fields:

  • For spot: type is one of "newOrder", "cancelOrder", "transferAsset", "scheduleCancel", "revokeAPIKey", and more.

  • For perps: type is one of "newOrder", "cancelOrder", "updateLeverage", "updateMargin", "transferAsset", "scheduleCancel", "revokeAPIKey", and more.

You must use your private key of the master account to sign revokeAPIKey action.

Important rules for producing a correct payloadHash:

  1. Compact JSON — no whitespace or newlines. Use json.Marshal in Go, or JSON.stringify without extra arguments in JavaScript.

  2. Key order must match the Go struct field order — the server verifies signatures by parsing the request body into Go structs and re-marshaling via json.Marshal, which serializes fields in struct definition order. If your JSON keys are in a different order, the hash will differ and signature verification will fail.

    • Refer to the struct definitions in sodex-go-sdk-publicarrow-up-right for the authoritative field order.

    • For example, PerpsOrderItem fields must appear in this order: clOrdID, modifier, side, type, timeInForce, price, quantity, funds, stopPrice, stopType, triggerType, reduceOnly, positionSide.

  3. DecimalString fields are JSON strings, not numbers — fields typed as DecimalString in the schema (e.g. price, quantity, funds, stopPrice) must be serialized as quoted strings in the signing payload (e.g. "quantity":"0.001", not "quantity":0.001). The HTTP request body uses the same format.

  4. omitempty fields must be omitted when unset — optional pointer fields in the Go struct (those with json:",omitempty") must not appear in the JSON when they have no value. Non-optional fields (e.g. modifier, reduceOnly, positionSide) must always be present, even with zero values.

Example — perps market buy order signing payload:

Note: the HTTP request body contains only the params object (without the type wrapper), using the same field order and types as the signing payload.

Reference Pages

Go SDK Signing Guidechevron-rightAPI Rate Limitschevron-rightREST API v1chevron-rightWebSocket API v1chevron-right

Last updated