# Place a market order

URL: https://docs.fxapis.com/api-reference/trading/place-a-market-order

> Place a market order. Sends a market order and waits for the broker's answer.

`POST https://api.fxapis.com/v1/accounts/{id}/orders/market`

Sends a market order and waits for the broker's answer.

**Send an `Idempotency-Key` header.** Without one, a request that times out leaves you unable to retry safely: you cannot tell whether the order was placed, and guessing wrong opens a second position. With one, retrying is free — the same key returns the same answer and never places a second order.

Three failures are worth telling apart, and the response distinguishes them:

- **`NO_PRICE` (422)** — the broker had no current price for the symbol (market closed, or not offered by this broker), so nothing was sent. Retry once it quotes; the same `Idempotency-Key` may be reused.
- **`SEND_FAILED` (503)** — nothing reached the broker. Resend only when `retryable` is `true`; it is `false` when the order was taken from this request before it could go (cancelled, say), so look at the order first.
- **`ORDER_REJECTED` (422)** — the broker refused it, with a reason and its own return code. `retryable` says whether the reason was transient (a requote, a moved price) or permanent (insufficient margin, a closed market).
- **`ORDER_UNRESOLVED` (503)** — we do not know. The order may be live at the broker. It is in `unknown` while we confirm the result with the broker. **Do not resend it**; poll the order instead.

Authentication: `Authorization: Bearer <API key>`.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string (uuid) | yes |  |
| `idempotency-key` | header | string | no | Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused. |

#### Request body (application/json, required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | no | As the broker names it, e.g. `EURUSD`. Example: `"EURUSD"` |
| `instrument` | string | no | Instead of `symbol`: an instrument from `GET /v1/instruments`, traded under this account's own broker symbol for it (`XAUUSD` may be `XAUUSD.a` or `GOLD` at the broker). The order records both. Refused with `INSTRUMENT_NOT_OFFERED` or `INSTRUMENT_AMBIGUOUS` when the account's broker has no single match. Example: `"XAUUSD"` |
| `side` | "buy" \| "sell" | yes |  |
| `volume` | string | yes | Lots, **as a string** — `"0.10"`, not `0.1`. A JSON number is a double, and a volume that arrives as 0.30000000000000004 is rejected by the broker. Example: `"0.01"` |
| `stopLoss` | string | no | Absolute price, not a distance. Must be below entry for a buy. Example: `"1.12900"` |
| `takeProfit` | string | no | Absolute price, not a distance. Must be above entry for a buy. Example: `"1.14200"` |
| `deviationPoints` | integer | no | Maximum slippage in points. Too small and a fast market returns a requote instead of a fill. Example: `20` |
| `comment` | string | no | Stored on the MT5 order after our 11-character reference, cut to fit MT5's limit: the first 17 characters, plain ASCII. Example: `"signal 42"` |
| `clientOrderId` | string | no | Your reference. Not required to be unique. Example: `"sig-42-user-7"` |

#### Responses

- `201`
- `400`
- `401`
- `402`
- `403`
- `404`
- `409`
- `422`
- `503`

Failures return `{ "error": { "code", "message" } }`; every code is listed at https://docs.fxapis.com/errors.

#### 201 response fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `data` | object | no |  |
| `data.id` | string (uuid) | no |  |
| `data.accountId` | string (uuid) | no |  |
| `data.clientOrderId` | null \| string | no | Your own reference, echoed back. |
| `data.symbol` | string | no | The broker symbol traded. |
| `data.instrument` | null \| string | no | The instrument the order named, when it named one; `symbol` is what it was traded as. Example: `"XAUUSD"` |
| `data.side` | "buy" \| "sell" | no |  |
| `data.type` | "market" \| "limit" \| "stop" \| "stop_limit" | no |  |
| `data.intent` | "open" \| "close" \| "modify" \| "cancel" | no | What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks. |
| `data.brokerPositionId` | null \| string | no | The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known. |
| `data.volume` | null \| string | no | Requested volume, in lots. |
| `data.stopLoss` | null \| string | no | Absolute price, not a distance. |
| `data.takeProfit` | null \| string | no | Absolute price, not a distance. |
| `data.state` | "accepted" \| "validating" \| "sending" \| "working" \| "completed" \| "filled" \| "partially_filled" \| "rejected" \| "failed" \| "unknown" \| "cancelled" \| "expired" | no |  |
| `data.stateDetail` | null \| string | no |  |
| `data.needsReconciliation` | boolean | no | True while we are confirming the result with the broker. Never resend such an order; poll it. |
| `data.retcode` | null \| integer | no | The broker's own MT5 return code, unmodified. 10009 is a completed request. |
| `data.retcodeText` | null \| string | no |  |
| `data.brokerOrderId` | null \| string | no | The broker's ticket. What their statement shows. |
| `data.brokerDealId` | null \| string | no |  |
| `data.filledVolume` | null \| string | no | What actually filled, which can be less than requested. |
| `data.filledPrice` | null \| string | no | What it actually filled at, which is rarely the requested price. |
| `data.sentAt` | null \| string (date-time) | no |  |
| `data.settledAt` | null \| string (date-time) | no | When an answer arrived. |
| `data.reconciledAt` | null \| string (date-time) | no | Set when a result was confirmed with the broker after the fact. |
| `data.createdAt` | string (date-time) | no |  |