Place limit orders

Submit one or more limit orders to the orderbook. Can be used for both options and perpetual futures.

Authentication Options:

  • Signature: Include signature and signature_deadline fields in each order (both required)
  • One-click session: Include x-one-click header with session hash (signature fields not required)

Important Constraints:

  • All orders in a batch must be from the same maker (single maker per request)
  • All orders in a batch must be for the same market (BTC, ETH, or ARB - determined by trading pair)
  • When NOT using one-click sessions, both signature and signature_deadline are required fields
  • Order size: Both options and perpetual orders use contracts (base contracts) as the canonical size field. For perpetuals, the legacy amount field (USD notional) is still accepted for backward compatibility — supply exactly one of contracts or amount (prefer contracts). The notional amount model is deprecated and will be removed in a future release; migrate to contracts
  • The taker field must be the zero address (0x0000000000000000000000000000000000000000) indicating any taker can fill the order
  • There is a per-pair open order cap — submitting orders beyond the limit results in rejection with reason max orders per market exceeded
  • Submitting an empty array returns a 400 error
  • EIP-712 signature field order must match exactly as shown in the examples
  • Price Increment: Order price must be divisible by the minimum price increment for the base asset (see GET /api/v1/exchange_infoorderConstraints.priceIncrements). This applies to all orders including liquidation orders.
  • Size Increment: Order size in contracts (canonical for both options and perpetuals; or the legacy amount for perpetuals) must be at least the per-asset minimum and a whole multiple of the size increment (see GET /api/v1/exchange_infoorderConstraints.options.sizeIncrements or orderConstraints.perpetuals.sizeIncrements). Perpetual minimum order size equals the size increment, in base contracts: BTC 0.0001, ETH 0.001, ARB 1. This applies to all orders including liquidation orders.

EIP-712 Signature Example (TypeScript)

import { parseUnits, zeroAddress } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

// Domain parameters for EIP-712 signature
const EIP712Domain = {
  chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet)
  name: 'Premia',
  verifyingContract: '0x...', // ClearingHouseProxy address from deployment
  version: '1'
};

// Type definition for limit orders
const UserLimitOrder = [
  { name: 'deadline', type: 'uint256' },
  { name: 'instrumentName', type: 'string' },
  { name: 'size', type: 'uint256' },
  { name: 'price', type: 'uint256' },
  { name: 'taker', type: 'address' },
  { name: 'maker', type: 'address' },
  { name: 'direction', type: 'uint8' },
  { name: 'isLiquidation', type: 'bool' },
  { name: 'isPostOnly', type: 'bool' },
  { name: 'mmp', type: 'bool' }
];

// Example order data (Options)
const optionsOrder = {
  instrument_name: 'BTC_USDC-31OCT25-130000-C',
  type: 'good_til_cancelled',
  contracts: 1.5,
  direction: 'buy',
  price: 1000.5,
  post_only: true,
  mmp: false,
  liquidation: false,
  maker: '0xYourAddress', // Your Ethereum address
  taker: null // Set to a specific address or null for any taker
};

// Example order data (Perpetuals)
const perpsOrder = {
  instrument_name: 'BTC_USDC-PERPETUAL',
  type: 'good_til_cancelled',
  contracts: 0.2,
  direction: 'buy',
  price: 45000,
  post_only: false,
  mmp: false,
  liquidation: false,
  maker: '0xYourAddress', // Your Ethereum address
  taker: null // Set to a specific address or null for any taker
};

// Calculate deadline (30 seconds from now)
const deadline = Math.floor(Date.now() / 1000) + 30;

// Setup wallet
const account = privateKeyToAccount('0xYourPrivateKey');

// Choose which order to use (options or perps)
const order = optionsOrder; // or perpsOrder for perpetuals

// Sign the typed data
const signature = await account.signTypedData({
  domain: EIP712Domain,
  types: { UserLimitOrder },
  primaryType: 'UserLimitOrder',
  message: {
    deadline,
    instrumentName: order.instrument_name,
    size: parseUnits((order.contracts ?? order.amount).toString(), 6), // Canonical `contracts`; legacy notional `amount` still accepted for perps
    price: parseUnits(order.price.toString(), 6),
    taker: order.taker ?? zeroAddress,
    maker: order.maker,
    direction: order.direction === 'buy' ? 0 : 1,
    isLiquidation: order.liquidation,
    isPostOnly: order.post_only,
    mmp: order.mmp
  }
});

// Final request payload
const requestPayload = {
  ...order,
  signature,
  signature_deadline: deadline
};
Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Body Params
string
required
^[A-Z]+_[A-Z]+-[0-9]{2}[A-Z]{3}[0-9]{2}-[0-9]+-[CP]$

Instrument name in the format {base}_{quote}-{maturity}-{strike}-{type}

string
enum
required

Order type

Allowed:
double
required
≥ 0.000001

Number of option contracts

string
enum
required

Order direction

Allowed:
double
required
≥ 0.000001

Limit price

boolean
required

If true, ensures the order will only be added to the order book and not match against existing orders. Orders that would immediately match will be rejected.

boolean
required

Opts this order into Market Maker Protection (MMP). When true, this order is tracked against MMP risk thresholds and will be automatically cancelled if MMP triggers. When MMP is frozen (after a trigger), new orders with mmp: true are rejected while orders with mmp: false can still be placed. The mmp value is part of the EIP-712 signature and cannot be changed after signing. See POST /mmp_config for full MMP documentation.

boolean
required

Internal field used for liquidation orders. Regular traders should set this to false.

string
required
^0x[a-fA-F0-9]{40}$

Ethereum address in hexadecimal format

string
^0x0{40}$

Must be the zero address (0x0000000000000000000000000000000000000000), indicating any taker can fill the order

string
^0x[a-fA-F0-9]{130}$

EIP-712 signature (required when not using x-one-click session)

int64
1704067200 to 2019686400

Signature deadline in Unix seconds (required when not using x-one-click session)

string
length ≤ 36

Optional user identifier for tracking and analytics purposes

Responses

Language
Credentials
Header
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json