> ## Documentation Index
> Fetch the complete documentation index at: https://public-perps-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Placing Orders

> Place market and limit orders via PerpsClient.placeOrder

Trades are placed through `PerpsClient.placeOrder`, which builds the action, authorizes it through the registered provider plugin, and submits it in one call. Order actions use the plugin's SDK-managed credential, so the user's wallet is not prompted per trade.

<Info>
  The examples on this page use **Hyperliquid** (`provider: 'hyperliquid'`). The trading API is provider-agnostic — replace the `provider` value with any supported venue from `getProviders()`. The `placeOrder` call shape is identical for every provider; each provider signs with its own configured signer.
</Info>

## placeOrder

Once the user has provisioned an agent (see [Signing Model](/providers/hyperliquid/signing-model) and [Hyperliquid / Setup](/providers/hyperliquid/setup)), placing an order is a single call:

```typescript theme={null}
const result = await perps.placeOrder({
  address: userAddress,
  provider: 'hyperliquid',
  market: { marketId: 'BTC', categoryId: 'hyperliquid' },
  side: 'BUY',
  type: 'MARKET',
  size: '0.1',
  price: '95500.00',
  leverage: 10,
});

console.log(result.results);
// [{ action: 'placeOrder', success: true, orderId: '12345678' }]
```

Internally this is the **create -> sign -> execute** pattern from [Action Pattern](/concepts/action-pattern):

```
createAction → ActionStep[] → provider plugin authorizes → executeAction → ActionResult[]
```

The SDK handles all three steps. If the requested `leverage` differs from the current setting, the backend prepends an `updateLeverage` step automatically — both actions are signed and submitted together, so `result.results[]` may contain more than one entry.

## Order Types

### Market Order

Executes immediately at the best available price. The `price` field acts as a slippage limit.

```typescript theme={null}
await perps.placeOrder({
  address: userAddress,
  provider: 'hyperliquid',
  market: { marketId: 'BTC', categoryId: 'hyperliquid' },
  side: 'BUY',
  type: 'MARKET',
  size: '0.1',
  price: '95500.00',   // slippage limit
});
```

### Limit Order

Rests on the orderbook until filled or cancelled.

```typescript theme={null}
await perps.placeOrder({
  address: userAddress,
  provider: 'hyperliquid',
  market: { marketId: 'ETH', categoryId: 'hyperliquid' },
  side: 'BUY',
  type: 'LIMIT',
  size: '1.0',
  price: '3150.00',
  timeInForce: 'GTC',  // Good til cancelled — Hyperliquid's resting form
});
```

On Lighter, the equivalent resting limit order uses `GTT` (Lighter's native resting form) rather than `GTC`.

### Time in Force options

Not every TIF is available on every venue, and `POST_ONLY` rests differently depending on the venue:

| TIF         | Hyperliquid                                                             | Lighter                                                                 |
| ----------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `GTC`       | ✓ Default — rests until filled or cancelled                             | — Use `GTT` instead (see note below)                                    |
| `IOC`       | ✓ Fills immediately, cancels any unfilled portion                       | ✓ Same behavior                                                         |
| `POST_ONLY` | ✓ Maker-only — rests GTC-style, cancelled if it would immediately match | ✓ Maker-only — rests GTT-style, cancelled if it would immediately match |
| `GTT`       | — Use `GTC` instead (see note below)                                    | ✓ Lighter's native resting order — stays until filled or cancelled      |

<Info>
  Some TIFs are venue-specific: **`GTC` is Hyperliquid, `GTT` is Lighter.** `IOC` and `POST_ONLY` work on both venues — but `POST_ONLY` rests GTC-style on Hyperliquid and GTT-style on Lighter.
</Info>

<Warning>
  Lighter has no true good-til-cancelled. A resting order placed on Lighter is reported back (e.g. from `getOrders`) with `timeInForce: 'GTT'`, even if you submitted it as `GTC` — don't rely on reading back the exact TIF you sent on Lighter.
</Warning>

**API Reference:** [POST /createAction · /executeAction](/api-reference/actions)
