MOONEUM
Business crypto trading platform

Trade API

Get a quote, place an order from the org's treasury wallets, and track it to a fill — with the same policy checks and approval chains as the in-app desk.

Requires a key or token scoped to Trade. Orders execute from your org's treasury wallets — there's no separate trading balance to fund, and no custodial pot to reconcile against.

The public API places MARKET orders

Limit and exchange orders exist in the trade desk's data model — you'll see them in reads and the event stream if a teammate places one from the in-app desk — but order creation through this API is MARKET-only today: execute now, at the best available route. Use the desk UI for limit and exchange execution.

Quotes & orders

Get a quote

const tokens = await client.listTradeTokens('ethereum'); // tradable tokens for the chain
const quote = await client.getTradeQuotes({
  chain: 'ethereum',
  from: 'ETH',
  to: 'USDC',
  amount: '2.5',
});
// -> { amountIn, amountInUsd?, bestQuote: { dex, amountOut, priceImpact, amountOutUsd?, ... } }

Create and submit the order

Two-step, like every write on the platform: create a draft, then submit it into the policy/approval pipeline.

const order = await client.createTradeOrder({
  walletId,
  chain: 'ethereum',
  tokenInSymbol: 'ETH',
  tokenOutSymbol: 'USDC',
  tokenIn: '0x…', // token addresses, from listTradeTokens()
  tokenOut: '0x…',
  amountIn: '2.5',
  amountInRaw: '2500000000000000000',
  slippageBps: 50,
});
await client.submitTradeOrder(order.id);

Bitcoin routes via THORChain

BTC pairs have no EVM liquidity, so BTC-involving orders route through THORChain automatically — same API shape. A BTC sell produces a deposit transaction your org broadcasts from its own wallet; the platform never holds a Bitcoin key.

Track a fill

Simplest to build — ask the order for its own status.

const order = await client.getTradeOrder(orderId);
// order.status -> DRAFT | PENDING_APPROVAL | APPROVED | BROADCAST | CONFIRMED | FAILED | REJECTED

const { items } = await client.listTradeOrders({
  status: 'PENDING_APPROVAL',
  limit: 50,
});

The full create → approve → sign → broadcast sequence (shared by every vertical) is in Approvals & signing.

Alerts & recurring orders

const alerts = await client.listTradeAlerts();
// -> [{ id, symbol, conditions, combinator: 'ALL' | 'ANY', enabled, wasMet, ... }]

// Recurring orders — the standard shape for DCA
await client.createRecurringTradeOrder({
  walletId,
  chain: 'ethereum',
  tokenInSymbol: 'USDC',
  tokenOutSymbol: 'ETH',
  amountIn: '5000',
  interval: 'WEEKLY',
});

Price alerts are per-user and multi-condition (combinator: 'ALL' requires every condition, 'ANY' requires one) — the exact per-condition shape varies by type, so see the API reference for POST /trade/alerts before building against it. Each recurring order run re-enters the same policy/approval pipeline as a manual order, and Trade.AlertTriggered fires over webhooks/WebSockets when an alert condition is met. Policy rules for pairs, order types, and max slippage apply throughout — see the permissions reference for the grants involved.