Skip to main content
REST is the simplest way to place your first order: one signed request per call, no socket to manage. This quickstart gets you from nothing to a live order on testnet in three steps.
For production or low-latency trading, use the WebSocket track — the primary interface. Requests target testnet (https://api.testnet.arcus.xyz); new accounts start empty — fund yours with the Testnet Deposit button (~$1,000), or an on-chain deposit for more. See Authentication for signing.

Step 1: Install

Only published libraries — no Arcus package required.

Step 2: Get an API key

Your API key is an Ed25519 keypair; the server stores only the public half, and the key is registered to your wallet by a one-time EIP-712 typed-data signature (eth_signTypedData_v4) — see POST /v1/createApiKey for the domain and types (the legacy EIP-191 scheme is deprecated but still accepted during the migration window). The Arcus web app does all of this for you and is the quickest way to get a key; you can also do it entirely in code.
  1. Open the API Keys page — testnet, or mainnet for production — and connect the wallet you’ll trade from.
  2. Enter a name and click Generate. The app creates the keypair in your browser.
  3. Copy the API Signing Key now — it’s the private half, shown once, and cannot be recovered. Pick a Subaccount # (default 0) and Days Valid (up to 180), then click Authorize and confirm the signature in your wallet.
That registers the key — nothing to run. Load the signing key you copied and skip to Step 3:
The steps below read the master address as wallet.address; with a web-app key, use your wallet_address wherever you see it.

Option B — Generate in code

Generate a fresh keypair and register it with one createApiKey call — the same operation the web app performs:

Step 3: Place an order

Each order is signed as a typed payload whose ct equals the X-Timestamp header (Unix nanoseconds) — see Authentication for the scheme and field reference.
Which signing scheme each method uses is covered in Authentication.
In the request body, quantity and price stay decimal strings (not floats). The integer q/p in the signed payload are derived from them via tickSize / stepSize; the two must agree, so reuse the same values.
Market orders must use timeInForce: IOC (other values are rejected with must be IOC for MARKET orders) and still carry a price — it acts as a protective slippage bound that must be within 10% of the current mark price (for TPSL market orders, within 10% of the trigger price), or the order is rejected. Because of this bound a MARKET order behaves like a marketable limit order, so many integrations simply send an aggressive LIMIT order instead.

Step 4: Place a batch

A batch signs each order individually under one shared X-Timestamp — see Authentication → Batches for the header rules.
batchCancelOrders works the same way — each element signs its own cancelOrder payload (op 2).

Next steps

Order placement is asynchronous — the response acknowledges receipt, and the order’s lifecycle (fills, cancels) streams on the orders and userFills WebSocket channels. To follow orders in real time, move to the WebSocket track.