FuturaDevelopers

Futura Broker API

Read-only REST API to query your account balance and trade history.

The Futura Broker API is a read-only REST API. With an API key you can query your account balance and closed trade history — ideal for spreadsheets, personal dashboards and reports.

API keys are read-only. You cannot open trades, withdraw or transfer through the API. Even so, treat your key like a password: anyone holding the token can read your account's financial data.

Base URL

https://api.futurabroker.com/api/public/v1

Authentication

Every request needs the Authorization header with your key as a Bearer token:

Authorization: Bearer fb_live_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Generate your key directly in the platform, under Settings → Integrations (futurabroker.com/settings?tab=integrations). The full token is shown only once at creation time — store it safely. If you lose it, just revoke the old key and generate another on the same screen. You can keep up to 10 active keys at a time.

Rate limits

  • 60 requests per minute per key. When exceeded, the API responds 429 with a Retry-After header.
  • The X-RateLimit-Limit and X-RateLimit-Remaining headers accompany every response.

Response format

Every response uses the standard envelope:

{
  "success": true,
  "data": { },
  "meta": { "timestamp": "...", "requestId": "..." }
}

On error, success is false and error carries code and message.

Endpoints

GET /ping

Tests connectivity and the validity of your key.

{
  "success": true,
  "data": {
    "pong": true,
    "key_prefix": "a6240e5c7b",
    "scopes": ["read"],
    "server_time": "2026-07-19T06:17:18.476Z"
  }
}

GET /account/balance

Returns the account balances.

FieldTypeDescription
balancenumberReal balance
balance_bonusnumberBonus/affiliate balance
balance_demonumberDemo account balance
currencystringCurrency (e.g. BRL)
{
  "success": true,
  "data": {
    "balance": 1109.13,
    "balance_bonus": 0,
    "balance_demo": 25830.67,
    "currency": "BRL"
  }
}

GET /trades

Closed trade history (result win, lose or draw), sorted from newest to oldest.

Query parameters (all optional):

ParameterTypeDescription
limitnumberItems per page (1–100, default 50)
cursornumberTrade ID for pagination (use next_cursor from the previous response)
fromISO 8601Start date/time (e.g. 2026-07-01T00:00:00Z)
toISO 8601End date/time
assetstringFilter by asset (e.g. ETHUSDT)
resultstringwin, lose or draw
demostringtrue or false

Fields for each trade:

FieldTypeDescription
idnumberTrade identifier
assetstringTraded asset
directionstringbuy (up) or sell (down)
amountnumberInvested amount
entry_pricenumberEntry price
exit_pricenumber | nullExit price
payout_percentnumberApplied payout (%)
profitnumber | nullProfit (positive) or loss (negative)
resultstringwin, lose or draw
demobooleanWhether it was a demo trade
opened_atISO 8601Opening time
closed_atISO 8601Closing time
{
  "success": true,
  "data": {
    "trades": [
      {
        "id": 2703209,
        "asset": "ETHUSDT",
        "direction": "sell",
        "amount": 10,
        "entry_price": 1873.59,
        "exit_price": 1873.7,
        "payout_percent": 80,
        "profit": -10,
        "result": "lose",
        "demo": false,
        "opened_at": "2026-06-03T06:40:07.000Z",
        "closed_at": "2026-06-03T06:41:00.000Z"
      }
    ],
    "next_cursor": 2703206
  }
}

Pagination: when more results exist, next_cursor holds the ID for the next page. Repeat the call passing cursor=<next_cursor> until next_cursor returns null.

Syncing on a schedule? Use from=. Instead of re-paginating your entire history on every run, store the timestamp of the most recent trade you already have and fetch only what's new with ?from=<last timestamp>. A typical sync drops from dozens of requests to one — faster for you, and no risk of hitting the 60 req/min limit. The example below already does this.

Example: Google Sheets (incremental sync)

Paste the script below into Extensions → Apps Script in your spreadsheet, replace the token and run syncTrades. The first run imports the full history; subsequent runs fetch only new trades and append them to the sheet. Add a trigger (Apps Script → Triggers) to run it periodically.

const API_BASE = 'https://api.futurabroker.com/api/public/v1'
const API_KEY = 'fb_live_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

// Fetch with automatic backoff: on rate limit (429), wait for Retry-After and
// retry the SAME page — so a large history syncs fully without breaking, just
// slower.
function fetchWithRetry(url, headers) {
  for (let attempt = 0; attempt < 6; attempt++) {
    const resp = UrlFetchApp.fetch(url, { headers: headers, muteHttpExceptions: true })
    if (resp.getResponseCode() === 429) {
      const h = resp.getHeaders()
      const wait = Number(h['Retry-After'] || h['retry-after'] || 60)
      Utilities.sleep((wait + 1) * 1000)
      continue
    }
    return JSON.parse(resp.getContentText())
  }
  throw new Error('Persistent rate limit — please try again later')
}

function syncTrades() {
  const props = PropertiesService.getScriptProperties()
  // Last-sync state: newest trade timestamp + its ID (the ID prevents
  // duplicating the trade sitting exactly on the from= boundary).
  const lastDate = props.getProperty('last_date')
  const lastId = Number(props.getProperty('last_id') || 0)
  const headers = { Authorization: 'Bearer ' + API_KEY }
  const sheet = SpreadsheetApp.getActiveSheet()

  if (sheet.getLastRow() === 0) {
    sheet.appendRow(['Date', 'Asset', 'Direction', 'Amount', 'Entry', 'Exit', 'Result', 'Profit'])
  }

  const fresh = []
  let maxId = lastId
  let newestDate = lastDate
  let cursor = null
  do {
    let url = API_BASE + '/trades?limit=100'
    if (lastDate) url += '&from=' + encodeURIComponent(lastDate)
    if (cursor) url += '&cursor=' + cursor

    const body = fetchWithRetry(url, headers)
    if (!body.success) throw new Error(body.error.message)

    body.data.trades.forEach(function (t) {
      if (t.id <= lastId) return // already synced in a previous run
      fresh.push([
        t.closed_at, t.asset, t.direction, t.amount,
        t.entry_price, t.exit_price, t.result, t.profit,
      ])
      if (t.id > maxId) maxId = t.id
      if (!newestDate || t.opened_at > newestDate) newestDate = t.opened_at
    })
    cursor = body.data.next_cursor
  } while (cursor)

  if (fresh.length > 0) {
    // Trades arrive newest-first; reverse to keep the sheet chronological.
    fresh.reverse()
    sheet.getRange(sheet.getLastRow() + 1, 1, fresh.length, fresh[0].length).setValues(fresh)
    props.setProperty('last_date', newestDate)
    props.setProperty('last_id', String(maxId))
  }
}

Error codes

HTTPcodeMeaning
401UNAUTHORIZEDMissing or malformed Authorization header
401INVALID_API_KEYInvalid or revoked key
403FORBIDDEN_SCOPEKey lacks the read scope
400VALIDATION_ERRORInvalid query parameter
429RATE_LIMITEDRequest limit exceeded

On this page