Docs

Instruments and symbols

Name a market once — XAUUSD, US30, BTCUSD — and trade each account's own broker symbol for it. List any connected broker's symbols, contract specifications and market hours.

The same market has a different name at almost every broker. Gold is XAUUSD at one, XAUUSD.a at another, XAUUSDm or GOLD at a third. The Dow is US30, DJ30, WS30 or US30.cash. If your members trade at different brokers, or on different account types at one broker, a signal cannot name the broker's symbol.

So fxapis separates the two:

  • An instrument is a market named once, from a fixed list: XAUUSD, EURUSD, US30, BTCUSD, and so on.
  • A symbol is what one broker calls it, exactly as an order must send it.

Name an instrument in a signal and in each order, and fxapis trades every account's own symbol for it.

The instruments

curl -sS "https://api.fxapis.com/v1/instruments" -H "Authorization: Bearer $FXAPIS_KEY"
{
  "data": [
    { "instrument": "EURUSD", "name": "Euro vs US Dollar", "category": "forex" },
    { "instrument": "XAUUSD", "name": "Gold vs US Dollar", "category": "metals" },
    { "instrument": "US30", "name": "Dow Jones Industrial Average", "category": "indices" },
    { "instrument": "USOIL", "name": "WTI Crude Oil", "category": "energies" },
    { "instrument": "BTCUSD", "name": "Bitcoin vs US Dollar", "category": "crypto" }
  ]
}

The list covers the forex majors, crosses and common exotics, metals, the main stock indices, oil and gas, and the main cryptocurrencies. Filter with ?category=forex|metals|indices|energies|crypto. It needs no account and no broker, so it is the list to build a signal editor from.

Trading an instrument

Send instrument instead of symbol. Everything else is unchanged:

curl -sS -X POST "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/orders/market" \
  -H "Authorization: Bearer $FXAPIS_KEY" \
  -H "Idempotency-Key: signal_9931:member_4821" \
  -H "Content-Type: application/json" \
  -d '{ "instrument": "XAUUSD", "side": "buy", "volume": "0.05", "stopLoss": "2338.50", "takeProfit": "2371.00" }'

The order records both names: symbol is what was traded at this account's broker, and instrument is what you asked for.

{ "data": { "id": "…", "symbol": "XAUUSD.a", "instrument": "XAUUSD", "state": "filled", "filledPrice": "2351.20" } }

The translation never reaches the broker and adds no time to the order. It is decided from a list fxapis already holds, and it is refused, before anything is sent, when it cannot be made safely:

CodeStatusMeaning
INSTRUMENT_NOT_OFFERED422This account's broker does not offer the instrument, or this account cannot trade it.
INSTRUMENT_AMBIGUOUS422The broker has more than one plausible symbol (for example a cash index and a future). details lists them; send the one you mean as symbol.
UNKNOWN_INSTRUMENT400Not an instrument on the list. Send a broker symbol instead.
SYMBOLS_NOT_SYNCED409The account has never been online, so its broker's symbols are not known yet. Bring it online once.

symbol still works exactly as before; send one or the other, not both. Pending orders take instrument the same way.

How a symbol is chosen

When an account comes online, fxapis reads every symbol its broker offers it, with each symbol's contract specification, and maps the instruments onto them:

  • The instrument's own name wins. A broker that has XAUUSD is traded as XAUUSD, even if it also has XAUUSD.r.
  • Otherwise, a name brokers use for it, with the broker's suffix removed: XAUUSD.a, XAUUSDm, GOLD, US30.cash, DJ30.
  • The contract has to agree. Where a market has one standard contract (100 ounces of gold per lot, 100,000 units of a currency pair), a symbol with a different contract size is never chosen, however good its name. Gold quoted per gram is never taken for gold per ounce.
  • Two plausible symbols are not guessed between. The instrument is marked ambiguous with both candidates, and an order naming it is refused until you name one.
  • A symbol the account cannot trade (disabled, or close-only) is never chosen.

See the result for any account:

curl -sS "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/instruments" -H "Authorization: Bearer $FXAPIS_KEY"
{
  "data": [
    { "instrument": "XAUUSD", "status": "mapped", "symbol": "XAUUSD.a", "reason": "its name once the broker's suffix is removed, contract size agrees", "candidates": [] },
    { "instrument": "US30", "status": "ambiguous", "symbol": null, "candidates": [
      { "symbol": "US30.cash", "confidence": 0.95, "reason": "its name once the broker's suffix is removed" },
      { "symbol": "US30.fut", "confidence": 0.95, "reason": "its name once the broker's suffix is removed" }
    ] },
    { "instrument": "BTCUSD", "status": "missing", "symbol": null, "candidates": [] }
  ],
  "meta": { "syncedAt": "2026-10-03T00:42:48Z", "server": "VantageInternational-Live 11", "symbolCount": 812 }
}

This is worth calling when a member connects: tell them straight away which of your instruments their account can follow.

A broker's symbols

curl -sS "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/symbols?search=gold" -H "Authorization: Bearer $FXAPIS_KEY"
{
  "data": [
    {
      "name": "XAUUSD.a",
      "description": "Gold vs US Dollar",
      "path": "Metals\\XAUUSD.a",
      "digits": 2,
      "contractSize": 100,
      "volumeMin": 0.01,
      "volumeMax": 50,
      "volumeStep": 0.01,
      "tradable": true,
      "currencyBase": "XAU",
      "currencyProfit": "USD",
      "currencyMargin": "USD"
    }
  ],
  "meta": { "syncedAt": "2026-10-03T00:42:48Z", "server": "VantageInternational-Live 11", "symbolCount": 812 },
  "page": { "hasMore": false, "nextCursor": null }
}

Every symbol the broker offers this account, as read when the account was last online, so it answers while the account is offline. Query parameters:

Parameter
searchOnly symbols whose name or description contains this.
tradabletrue for symbols this account can open positions in; false for the rest.
limit, cursorUp to 1,000 a page; pass nextCursor as cursor for the next.

volumeMin, volumeStep and volumeMax are what a member's lot size must respect at that broker. contractSize is what one lot is.

Market hours

Each broker sets its own hours for each symbol: when forex opens on Sunday evening, when gold takes its daily break, whether crypto trades at the weekend. fxapis reads them from the member's broker — MetaTrader's SymbolInfoSessionTrade, for every symbol — so a signal screen can show the member's real hours instead of a guess.

curl -sS "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/sessions?instrument=XAUUSD" -H "Authorization: Bearer $FXAPIS_KEY"
{
  "data": {
    "symbol": "XAUUSD",
    "instrument": "XAUUSD",
    "server": "VantageMarkets-Demo",
    "utcOffsetSeconds": 10800,
    "sessionsSyncedAt": "2026-10-03T02:41:10Z",
    "openNow": false,
    "nextOpen": "2026-10-04T22:01:00Z",
    "nextClose": null,
    "trade": {
      "server": [
        { "day": "monday", "open": "01:01", "close": "23:58" },
        { "day": "tuesday", "open": "01:01", "close": "23:58" }
      ],
      "utc": [
        { "day": "sunday", "open": "22:01", "close": "24:00" },
        { "day": "monday", "open": "00:00", "close": "20:58" }
      ]
    },
    "quote": { "server": [], "utc": [] }
  }
}
  • Name an instrument (this account's symbol for it is used) or the broker's symbol.
  • trade is when orders can be placed; quote is when prices are quoted. Each is given in the broker's server time — as its platform shows them — and in UTC.
  • utcOffsetSeconds is the broker's clock minus UTC, measured from the terminal when the hours were read; many brokers change it with daylight saving, and the daily refresh follows.
  • openNow, nextOpen and nextClose are worked out at the moment you ask. A market open all week (most crypto) has neither a next open nor a next close.
  • close: "24:00" is the end of the day. A market open across midnight shows as two windows.

GET /v1/accounts/{id}/symbols also carries each symbol's sessions, in server time, with meta.utcOffsetSeconds.

The hours are the broker's configured schedule. A holiday the broker does not load into it is not here, and on such a day an order is refused with ORDER_REJECTED (Market closed) — nothing is opened. They are read a minute or so after the account first comes online, then daily; until then the endpoint answers 409 SESSIONS_NOT_SYNCED.

When the list is read

  • When an account comes online, if fxapis has no list for it, the list is from another server name, or it is a day old.
  • When you ask: POST /v1/accounts/{id}/symbols/sync reads it again now. The account has to be online (ready). Most integrations never need this.

An account that has never been online has no list yet. GET /symbols and GET /instruments answer 409 SYMBOLS_NOT_SYNCED, and so does an order naming an instrument. Bringing the account online once while the member is still on the connect screen — which the signals guide already does to check the password — takes care of it.

On this page