Docs

Quickstart

From an API key to a filled order, in about five minutes.

You need an API key (create one in the console), an MT5 account number, its trading password, and the server name exactly as MetaTrader shows it — VantageMarkets-Demo, ICMarkets-Demo. Use a demo account the first time.

The investor password will not work. It can read an account but cannot trade, and the login succeeds — so the failure arrives later, as a rejected order.

Set your key

export FXAPIS_KEY="fx_live_7f3a9c21_your-secret-here"
export FXAPIS_API="https://api.fxapis.com"

Keys are server-to-server credentials. Keep them out of browsers, apps and repositories. See Authentication.

Connect the account

# Keeps the new account's id for the next steps (uses jq; or copy data.id by hand).
export FXAPIS_ACCOUNT=$(curl -sS -X POST "$FXAPIS_API/v1/accounts" \
  -H "Authorization: Bearer $FXAPIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "login": "26177561",
    "server": "VantageMarkets-Demo",
    "password": "your-mt5-trading-password",
    "mode": "warm_on_demand",
    "label": "Demo — strategy A"
  }' | jq -r .data.id)

This stores the account and does not log in yet. The password is encrypted under a key bound to this one account and is never returned by any endpoint.

Bring it online

curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/warm" \
  -H "Authorization: Bearer $FXAPIS_KEY"

until curl -sS "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/status" \
        -H "Authorization: Bearer $FXAPIS_KEY" | grep -q '"ready"'
do sleep 2; done

warm answers 202 at once, while the account logs in at the broker. Its state moves through starting, connecting and synchronizing to ready, in about 10 seconds in our measurement. Only ready accepts orders.

Place an order

curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/orders/market" \
  -H "Authorization: Bearer $FXAPIS_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "symbol": "EURUSD", "side": "buy", "volume": "0.01" }'
201 Created
{
  "data": {
    "id": "b1c7…9e2a",
    "symbol": "EURUSD",
    "side": "buy",
    "volume": "0.01",
    "state": "filled",
    "filledPrice": "1.13426",
    "brokerOrderId": "2109584418"
  }
}

Volumes and prices are strings, never floats. Keep the Idempotency-Key if you retry: the same key never places a second order. An order ends filled, rejected, or unknown while it is reconciled against the broker — see Trading.

Close it

# Positions refresh by themselves about every 15 s; reconcile refreshes them now.
curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/reconcile" -H "Authorization: Bearer $FXAPIS_KEY"
export POSITION_TICKET=$(curl -sS "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/positions" \
  -H "Authorization: Bearer $FXAPIS_KEY" | jq -r '.data[0].brokerPositionId')

curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/positions/$POSITION_TICKET/close" \
  -H "Authorization: Bearer $FXAPIS_KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" -d '{}'

A warm_on_demand account goes offline by itself after a quiet spell with no orders; POST /cool takes it offline now. Stop losses and take profits live at the broker and keep working while the account is offline.

If it does not reach ready

StateMeaningWhat to do
invalid_credentialsThe broker rejected the loginFix the password and reconnect. Do not retry — repeated failures are how a broker locks an account.
needs_2faThe account requires a second factorNot supported headlessly. Disable 2FA or use another account.
needs_certificateThe broker requires a client certificateContact us.
trading_disabledLogin worked, trading is offThe broker has disabled trading for this login. (An investor password instead reaches ready and its orders are rejected.) Ask the broker to enable trading.
errorSomething temporaryRetryable. Bring it online again.

Next

On this page