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/v1Autenticación
Cada solicitud necesita el header Authorization con tu clave como token
Bearer:
Authorization: Bearer fb_live_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxGenera 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
429con el headerRetry-After. - Los headers
X-RateLimit-LimityX-RateLimit-Remainingacompañ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.
| Campo | Tipo | Descripción |
|---|---|---|
balance | number | Saldo real |
balance_bonus | number | Saldo de bono/afiliado |
balance_demo | number | Saldo de la cuenta demo |
currency | string | Moneda (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ámetro | Tipo | Descripción |
|---|---|---|
limit | number | Elementos por página (1–100, por defecto 50) |
cursor | number | ID de operación para paginar (usa next_cursor de la respuesta anterior) |
from | ISO 8601 | Fecha/hora inicial (ej.: 2026-07-01T00:00:00Z) |
to | ISO 8601 | Fecha/hora final |
asset | string | Filtra por activo (ej.: ETHUSDT) |
result | string | win, lose o draw |
demo | string | true o false |
Campos de cada operación:
| Campo | Tipo | Descripción |
|---|---|---|
id | number | Identificador de la operación |
asset | string | Activo negociado |
direction | string | buy (alza) o sell (baja) |
amount | number | Monto invertido |
entry_price | number | Precio de entrada |
exit_price | number | null | Precio de salida |
payout_percent | number | Payout aplicado (%) |
profit | number | null | Ganancia (positivo) o pérdida (negativo) |
result | string | win, lose o draw |
demo | boolean | Si fue operación demo |
opened_at | ISO 8601 | Apertura |
closed_at | ISO 8601 | Cierre |
{
"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
| HTTP | code | Significado |
|---|---|---|
| 401 | UNAUTHORIZED | Header Authorization ausente o mal formado |
| 401 | INVALID_API_KEY | Clave inválida o revocada |
| 403 | FORBIDDEN_SCOPE | La clave no tiene el scope read |
| 400 | VALIDATION_ERROR | Parámetro de query inválido |
| 429 | RATE_LIMITED | Límite de solicitudes excedido |