FuturaDevelopers

Futura Broker API

API REST de solo lectura para consultar el saldo y el historial de operaciones de tu cuenta.

La Futura Broker API es una API REST de solo lectura. Con una clave de API puedes consultar el saldo y el historial de operaciones cerradas de tu cuenta — ideal para hojas de cálculo, paneles personales e informes.

Las claves son solo de lectura. No es posible abrir operaciones, retirar ni transferir mediante la API. Aun así, trata tu clave como una contraseña: quien tenga el token puede leer los datos financieros de tu cuenta.

Base URL

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

Autenticación

Cada solicitud necesita el header Authorization con tu clave como token Bearer:

Authorization: Bearer fb_live_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Genera tu clave directamente en la plataforma, en Configuración → Integraciones (futurabroker.com/settings?tab=integrations). El token completo se muestra una sola vez al crearse — guárdalo de forma segura. Si lo pierdes, revoca la clave anterior y genera otra en la misma pantalla. Puedes mantener hasta 10 claves activas a la vez.

Límites de uso

  • 60 solicitudes por minuto por clave. Al exceder, la API responde 429 con el header Retry-After.
  • Los headers X-RateLimit-Limit y X-RateLimit-Remaining acompañan cada respuesta.

Formato de las respuestas

Cada respuesta usa el envoltorio estándar:

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

En caso de error, success es false y error incluye code y message.

Endpoints

GET /ping

Prueba la conectividad y la validez de tu clave.

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

GET /account/balance

Devuelve los saldos de la cuenta.

CampoTipoDescripción
balancenumberSaldo real
balance_bonusnumberSaldo de bono/afiliado
balance_demonumberSaldo de la cuenta demo
currencystringMoneda (ej.: BRL)
{
  "success": true,
  "data": {
    "balance": 1109.13,
    "balance_bonus": 0,
    "balance_demo": 25830.67,
    "currency": "BRL"
  }
}

GET /trades

Historial de operaciones cerradas (resultado win, lose o draw), ordenado de la más reciente a la más antigua.

Parámetros de query (todos opcionales):

ParámetroTipoDescripción
limitnumberElementos por página (1–100, por defecto 50)
cursornumberID de operación para paginar (usa next_cursor de la respuesta anterior)
fromISO 8601Fecha/hora inicial (ej.: 2026-07-01T00:00:00Z)
toISO 8601Fecha/hora final
assetstringFiltra por activo (ej.: ETHUSDT)
resultstringwin, lose o draw
demostringtrue o false

Campos de cada operación:

CampoTipoDescripción
idnumberIdentificador de la operación
assetstringActivo negociado
directionstringbuy (alza) o sell (baja)
amountnumberMonto invertido
entry_pricenumberPrecio de entrada
exit_pricenumber | nullPrecio de salida
payout_percentnumberPayout aplicado (%)
profitnumber | nullGanancia (positivo) o pérdida (negativo)
resultstringwin, lose o draw
demobooleanSi fue operación demo
opened_atISO 8601Apertura
closed_atISO 8601Cierre
{
  "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
  }
}

Paginación: cuando existan más resultados, next_cursor contiene el ID de la siguiente página. Repite la llamada pasando cursor=<next_cursor> hasta que next_cursor devuelva null.

¿Sincronizas con frecuencia? Usa from=. En lugar de repaginar todo el historial en cada ejecución, guarda la fecha de la operación más reciente que ya tienes y busca solo lo nuevo con ?from=<última fecha>. Una sincronización típica baja de decenas de solicitudes a una — más rápida para ti y sin riesgo de alcanzar el límite de 60 req/min. El ejemplo de abajo ya lo hace.

Ejemplo: Google Sheets (sincronización incremental)

Pega el script de abajo en Extensiones → Apps Script en tu hoja de cálculo, cambia el token y ejecuta sincronizarOperaciones. La primera ejecución importa el historial completo; las siguientes buscan solo las operaciones nuevas y las añaden al final de la hoja. Programa un activador (Apps Script → Activadores) para ejecutarlo periódicamente.

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

// Fetch con backoff automático: al alcanzar el límite (429), espera el
// Retry-After y reintenta la MISMA página — así un historial grande se
// sincroniza completo sin romperse, solo más lento.
function buscarConReintento(url, headers) {
  for (let intento = 0; intento < 6; intento++) {
    const resp = UrlFetchApp.fetch(url, { headers: headers, muteHttpExceptions: true })
    if (resp.getResponseCode() === 429) {
      const h = resp.getHeaders()
      const espera = Number(h['Retry-After'] || h['retry-after'] || 60)
      Utilities.sleep((espera + 1) * 1000)
      continue
    }
    return JSON.parse(resp.getContentText())
  }
  throw new Error('Límite de solicitudes persistente — inténtalo más tarde')
}

function sincronizarOperaciones() {
  const props = PropertiesService.getScriptProperties()
  // Estado de la última sincronización: fecha de la operación más reciente +
  // su ID (el ID evita duplicar la operación justo en el borde del from=).
  const ultimaFecha = props.getProperty('ultima_fecha')
  const ultimoId = Number(props.getProperty('ultimo_id') || 0)
  const headers = { Authorization: 'Bearer ' + API_KEY }
  const hoja = SpreadsheetApp.getActiveSheet()

  if (hoja.getLastRow() === 0) {
    hoja.appendRow(['Fecha', 'Activo', 'Dirección', 'Monto', 'Entrada', 'Salida', 'Resultado', 'Ganancia'])
  }

  const nuevas = []
  let mayorId = ultimoId
  let fechaMasReciente = ultimaFecha
  let cursor = null
  do {
    let url = API_BASE + '/trades?limit=100'
    if (ultimaFecha) url += '&from=' + encodeURIComponent(ultimaFecha)
    if (cursor) url += '&cursor=' + cursor

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

    body.data.trades.forEach(function (t) {
      if (t.id <= ultimoId) return // ya sincronizada en una ejecución anterior
      nuevas.push([
        t.closed_at, t.asset, t.direction, t.amount,
        t.entry_price, t.exit_price, t.result, t.profit,
      ])
      if (t.id > mayorId) mayorId = t.id
      if (!fechaMasReciente || t.opened_at > fechaMasReciente) fechaMasReciente = t.opened_at
    })
    cursor = body.data.next_cursor
  } while (cursor)

  if (nuevas.length > 0) {
    // Las operaciones llegan de la más reciente a la más antigua; invierte
    // para mantener la hoja en orden cronológico.
    nuevas.reverse()
    hoja.getRange(hoja.getLastRow() + 1, 1, nuevas.length, nuevas[0].length).setValues(nuevas)
    props.setProperty('ultima_fecha', fechaMasReciente)
    props.setProperty('ultimo_id', String(mayorId))
  }
}

Códigos de error

HTTPcodeSignificado
401UNAUTHORIZEDHeader Authorization ausente o mal formado
401INVALID_API_KEYClave inválida o revocada
403FORBIDDEN_SCOPELa clave no tiene el scope read
400VALIDATION_ERRORParámetro de query inválido
429RATE_LIMITEDLímite de solicitudes excedido

En esta página