For the complete documentation index, see llms.txt. This page is also available as Markdown.

Trade over REST

Zero to a live order over REST — the fastest path to your first Native Core trade.

One signed request per call, and the call blocks for the outcome — no socket to manage. This page takes you from nothing to a working order.

The examples below use mainnet, API_URL=https://api.native.org. To integrate against testnet, swap in https://api-test.native.org and sign with the testnet chain id — see environments.

1. Get an API wallet

An API wallet is an agent keypair you generate locally, authorized by one owner-signed approveAgent. It places and cancels orders but can never move funds. Three steps — covered in full, with the connection-bundle shape, under creating an API wallet:

  1. Generate an agent keypair locally; its 20-byte address is the agent.

  2. Deposit the quote asset you'll trade from your main wallet — your account is created on the first deposit.

  3. Approve the agent: your main wallet signs one approveAgent (EIP-712). The Native web app does all three for you and hands back the agent key.

You end up holding the agent private key (your only signing secret) and your owner accountAddress. See Account Types if you were granted a credit account.

2. Find your market

Markets and their precision are public. You need the market_id and its decimals to build an order.

curl -sS -X POST "$API_URL/info" -H 'content-type: application/json' \
  -d '{"type":"markets"}'

Note the market_id, price_decimals, and base_quantity_decimals for the pair you want to trade.

3. Get your agent_epoch

Every trading write signed by an API wallet must carry agent_epoch — the current generation of your wallet's approval. Read it once at startup:

Use the epoch of the slot whose agent matches your API-wallet address. Omit agent_epoch and the write is rejected with DirectSignerIsActiveAgent.

4. Sign and place an order

signature signs a canonical binary payload built from action + nonce + agent_epoch — not the JSON text. Two ways to produce it:

  • Python SDK — signs, manages nonces, and reconciles for you. Recommended.

  • By hand — the full byte layout and a TypeScript signer are in Transaction Signing.

The assembled request:

Always set a cloid — it is how you reconcile a timeout (step 5). Send price and quantity as strings at the market's precision.

5. Read the outcome

/trade is synchronous: the call blocks until the transaction executes and returns the outcome. Typical latency is a block or two; the wait budget is 3 seconds, so set your client timeout above that.

Read both fields. submission_status: "accepted" means the transaction landed; response.status is what actually happened to the order — open (rested), filled, cancelled, or {"error":"<code>"} if it failed at execution. A failed order still reports accepted, so branching on submission_status alone will read it as a success.

The other two outcomes — rejected and timeout — each need their own handling, and a timeout can double-fill you if you resubmit the wrong kind. The full decision playbook is one page:

Handle outcomes & timeouts

That is a full round trip. The order is working — list it with openOrders, and cancel with a cancel action.

Streaming its lifecycle instead of polling? Stream over WebSocket.

Next steps

Last updated