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.

A terminal window with curl commands and JSON answers, next to a small price chart.

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. 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

export TW=https://api.tickwire.io
curl -s -X POST "$TW/v1/sandbox/signup" -H "content-type: application/json" -d '{"platform": "mt5"}'
{
  "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:

export TW_KEY=twsk_4b1e…

2. Check the account is ready

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.

3. Read the balance and a price

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.

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

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}'
{
  "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

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

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. See Streaming.

7. Read candles

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.

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:

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

The full list is on the sandbox page. 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 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 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.

Where is the full endpoint list?

In the API reference. The MT5 API page gives the overview, and pricing shows the cost per account.

Trading carries risk, and you can lose money. This post explains software and how it behaves; it is not investment advice.

Try it on your own account

7-day free trial. See pricing or read the quickstart.