# MT5 REST API quickstart with curl

> Tickwire's MT5 REST API takes a few curl calls to go from a free sandbox key to a placed and closed order, with a safe retry and a live price stream.

Source: https://tickwire.io/blog/mt5-rest-api-quickstart-curl/

Tickwire blog, published 2026-10-29. General information, not investment advice.

The fastest way to try an MT5 REST API is with curl and a free sandbox account. Tickwire runs a real MetaTrader 5 terminal per account and puts a REST and WebSocket API in front of it, so every step below is a plain HTTPS call. You need no Windows PC, no card and no broker login to start.

Each step is copied from the [quickstart](https://tickwire.io/docs/quickstart/). When your code works in the sandbox, you connect a broker account and change only the key and the account id. MT4 works the same way: send `"platform": "mt4"` in step 1.

## 1. Get a sandbox key and account

```bash
export TW=https://api.tickwire.io
curl -s -X POST "$TW/v1/sandbox/signup" -H "content-type: application/json" -d '{"platform": "mt5"}'
```

```json
{
  "sandbox": true,
  "apiKey": "twsk_4b1e…",
  "account": { "id": "acc_7Qx", "server": "Tickwire-Sandbox", "login": "1000",
               "state": "DEPLOYED", "connectionStatus": "CONNECTED" }
}
```

The key is shown once. Keep it in an environment variable, not in your code:

```bash
export TW_KEY=twsk_4b1e…
```

## 2. Check the account is ready

```bash
curl -s "$TW/users/current/accounts/acc_7Qx" -H "auth-token: $TW_KEY"
```

Look for `"connectionStatus": "CONNECTED"` and a `health` status of `healthy`. A sandbox account is ready at once. A broker account usually takes under a minute. If no price is moving, which usually means the market is closed, the status is `degraded` with `"prices_live": false` and the reason `prices_stale`. Reads still work, but a new market order gets `409 quote_stale` and nothing is sent. See [Health](https://tickwire.io/docs/health/).

## 3. Read the balance and a price

```bash
curl -s "$TW/users/current/accounts/acc_7Qx/account-information" -H "auth-token: $TW_KEY"
curl -s "$TW/users/current/accounts/acc_7Qx/symbols/EURUSD/current-price" -H "auth-token: $TW_KEY"
```

The first answer has `balance`, `equity`, `freeMargin`, `leverage` and `brokerTime`. The broker's time is its own local time, not UTC. See [Time zones](https://tickwire.io/docs/time-zones/).

Brokers name symbols differently, such as `EURUSDm`. List the exact names with `GET …/symbols`, and read lot sizes from `GET …/symbols/EURUSD/specification`.

## 4. Place an order

```bash
curl -s -X POST "$TW/users/current/accounts/acc_7Qx/trade" \
  -H "auth-token: $TW_KEY" \
  -H "Idempotency-Key: first-order-1" \
  -H "X-Actor: quickstart" -H "X-Reason: trying Tickwire" \
  -H "content-type: application/json" \
  -d '{"actionType": "ORDER_TYPE_BUY", "symbol": "EURUSD", "volume": 0.01}'
```

```json
{
  "numericCode": 10009,
  "stringCode": "TRADE_RETCODE_DONE",
  "message": "Request completed",
  "orderId": "46870472",
  "positionId": "46870472",
  "outcome": "applied"
}
```

Three headers matter here:

- `Idempotency-Key` makes the order safe to retry. Send the same command again and you get the same answer, with no second position.
- `X-Actor` says who sent it: a person, a script or an agent.
- `X-Reason` says why. Both go into the audit log.

Volume is in lots. Add `stopLoss` and `takeProfit` as prices, not as distances.

## 5. Close it

```bash
curl -s -X POST "$TW/users/current/accounts/acc_7Qx/trade" \
  -H "auth-token: $TW_KEY" \
  -H "Idempotency-Key: first-close-1" \
  -H "X-Actor: quickstart" -H "X-Reason: done" \
  -H "content-type: application/json" \
  -d '{"actionType": "POSITION_CLOSE_ID", "positionId": "46870472"}'
```

## 6. Stream prices with WebSocket

```bash
websocat "wss://api.tickwire.io/users/current/accounts/acc_7Qx/ws?auth-token=$TW_KEY"
{"type":"subscribe","marketData":[{"symbol":"EURUSD","subscriptions":[{"type":"quotes"}]}]}
```

You get a full sync, then price and health frames. Streaming is lighter than polling, and WebSocket frames don't count toward the [rate limits](https://tickwire.io/docs/rate-limits/). See [Streaming](https://tickwire.io/docs/streaming/).

## 7. Read candles

```bash
curl -s "$TW/users/current/accounts/acc_7Qx/historical-market-data/symbols/EURUSD/timeframes/1h/candles?limit=100" \
  -H "auth-token: $TW_KEY"
```

Up to 1000 candles per call. MT5 has 21 timeframes, from `1m` to `1mn`. See [Candles and timeframes](https://tickwire.io/blog/candles-and-timeframes-api/).

## Try the hard cases

The sandbox has magic logins that act out real problems. Create an account with one of these logins to test your error handling before it costs money:

| Login | What happens |
|---|---|
| `1032` | The order outcome is `unknown` |
| `1019` | Rejected for not enough money |
| `1040` | The terminal disconnects and reconnects |
| `1050` | Quotes freeze, and market orders answer `409 quote_stale` |
| `1061` | Wrong login |

The full list is on the [sandbox page](https://tickwire.io/docs/sandbox/#magic-logins). The one to handle with care is `unknown`: the order may have run. Read positions before you do anything else, and never resend it with a new key. Our post on [retries that never trade twice](https://tickwire.io/blog/retries-never-trade-twice/) explains why.

## Then connect a broker account

Create a live API key in the dashboard, then add your account with `POST /users/current/accounts`, giving the login, the password and the server name from the terminal's login dialog. The password is write-only: it is never returned or logged. If broker detection is still running you get `202` with a `Retry-After` header. Send the same request again with the same `transaction-id`. The [quickstart](https://tickwire.io/docs/quickstart/) has the full call. Test on a demo account first.

## Frequently asked questions

### Does MetaTrader 5 have a REST API?

Not built in. The terminal is a desktop app. Tickwire runs a real MT5 terminal for each account in the cloud and gives it a REST and WebSocket API, so you can call it with curl or any HTTP client.

### Do I need Windows to use this MT5 REST API?

No. The terminal runs on Tickwire's servers. You call it from a Mac, Linux, a phone or any server that can make HTTPS requests.

### Is the sandbox free?

Yes. One call gives you a sandbox key and account with no card and no broker login. Sandbox keys start with twsk_ and can't touch a live account.

### What happens if my request times out during an order?

Send the same request again with the same Idempotency-Key. If the first one went through, you get its answer back, never a second order. If the answer says unknown, read positions before you do anything else.

### Does the same quickstart work for MT4?

Yes. Send platform mt4 in the sandbox signup. The endpoints and fields are the same. A few MT5 features, such as market depth and tick history, answer not_supported_on_mt4. See the [MT4 API documentation guide](https://tickwire.io/blog/mt4-api-documentation-guide/).

### Where is the full endpoint list?

In the [API reference](https://tickwire.io/docs/reference/). The [MT5 API page](https://tickwire.io/mt5-api/) gives the overview, and [pricing](https://tickwire.io/pricing/) shows the cost per account.
