Cuentas
Cómo conectar cuentas de MT5, mantenerlas en línea y qué significa cada estado.
Una cuenta es un login de MT5 que conectaste a fxapis. Su estado te dice si puede operar ahora mismo; su modo decide cuándo está en línea.
Modos
Se define al conectar la cuenta y se puede cambiar en cualquier momento con
POST /mode.
| Modo | En línea | Primera orden | Ideal para |
|---|---|---|---|
always_on | Una vez puesta en línea, se queda en línea: nunca se desconecta por inactividad, y vuelve sola en minutos si su terminal se detiene (un login rechazado o la 2FA te esperan a ti) | Inmediata | Cuentas que deben actuar al instante en que algo ocurre: señales copiadas, una apertura de mercado |
warm_on_demand | Cuando operas, y luego se desconecta sola cuando está inactiva | Tras una conexión breve | La mayoría de las integraciones y los servicios de señales |
cold | Solo cuando lo pides | Después de que la pones en línea | Cuentas que operas según un horario |
warm_on_demand es el valor razonable (el valor predeterminado de la API es cold,
así que defínelo). La primera orden tras un rato tranquilo espera mientras la cuenta se
conecta —unos 10 segundos según nuestra medición— y cada orden posterior es inmediata.
Para evitar incluso esa espera, pon las cuentas en línea con anticipación con
POST /v1/accounts/prepare.
Un cambio de modo se aplica la próxima vez que la cuenta se pone en línea. Para aplicar
always_on de inmediato, pon la cuenta en línea después de cambiarlo.
Ventanas de inactividad, llamadas del conector y estacionamiento
- Una terminal
warm_on_demandse detiene tras la ventana de inactividad del plan: 15 minutos, salvo que el plan diga otra cosa. - Una llamada del conector (MCP) que nombra la cuenta, o cualquier llamada del conector mientras su terminal está en marcha, cuenta como uso, igual que una orden.
- En los planes que estacionan cuentas (tras el número de días del plan), una cuenta sin
órdenes, llamadas del conector ni arranques durante ese tiempo queda estacionada: su
terminal se detiene, su modo pasa a
coldystateDetaillo indica. Sus credenciales se conservan.POST /v1/accounts/{id}/warmoPOST /v1/accounts/preparela recuperan comowarm_on_demand, y una orden en ella responde409 ACCOUNT_NOT_READYhasta entonces.
Estados
Tu código puede actuar según cuatro grupos. Los valores exactos son los que devuelve la API.
En línea: puede operar
| Estado | Significado |
|---|---|
ready | En línea y aceptando órdenes. |
executing | En línea; se está enviando una orden en este momento. |
Conectando: espera
| Estado | Significado |
|---|---|
provisioning, starting, connecting | Poniéndose en línea e iniciando sesión en el broker. |
synchronizing | Sesión iniciada; los precios todavía están llegando. Las órdenes se rechazan hasta ready, para que ninguna salga con precios incompletos. |
reconnecting | La conexión con el broker se cayó y se está restableciendo. |
degraded | En línea pero con problemas: precios lentos o desactualizados. Normalmente se recupera sola; reiníciala si no. |
Fuera de línea: sin conexión con el broker en este momento
| Estado | Significado |
|---|---|
created | Conectada, todavía nunca puesta en línea. |
standby | Fuera de línea y se sabe que funciona. Una cuenta warm_on_demand se pone en línea con su siguiente orden; cualquier cuenta se pone en línea cuando lo pides (/warm). |
cooling | Desconectándose. |
offline | Desconectada (la contraseña guardada se borró), o su terminal dejó de responder (la contraseña se conserva: vuelve a ponerla en línea). |
Requiere atención: una persona debe corregir algo
| Estado | Significado | Qué hacer |
|---|---|---|
invalid_credentials | El broker rechazó el inicio de sesión: una contraseña incorrecta, o un login que no existe en ese servidor. | Revisa problem.otherServers y prueba el más probable con POST /v1/accounts/{id}/server; o envía la contraseña de trading corregida a POST /v1/accounts/{id}/password. |
trading_disabled | El broker desactivó el trading para este login. | Pide al broker, o al dueño de la cuenta, que active el trading. (Una contraseña de inversor, en cambio, llega a ready y sus órdenes se rechazan). |
needs_2fa | La cuenta requiere un segundo factor. | Desactiva la verificación en dos pasos para esta cuenta, o usa otra. |
needs_certificate | El broker requiere un certificado de cliente. | Contáctanos. |
error | Algo temporal salió mal. | Se puede reintentar: vuelve a ponerla en línea. |
Los cuatro primeros no mejoran con reintentos, y los inicios de sesión fallidos repetidos son la forma en que un broker bloquea una cuenta. Por eso dejamos de intentarlo: poner en línea una de estas cuentas devuelve 409 hasta que se corrija la causa.
Qué está mal, en palabras: problem
Cada cuenta lleva problem: null mientras está bien o en camino, y en otro caso qué
está mal y cómo corregirlo, lo mismo que muestra la consola.
"problem": {
"code": "LOGIN_REFUSED",
"title": "The broker refused the login",
"explanation": "JustMarkets-Demo3 did not accept login 2002126135 with this password. Either the password is not the account's trading password …, or this login does not exist on JustMarkets-Demo3 …",
"detail": "the broker refused the login on mt5ldn5.srip.net:8750: -6 Terminal: Authorization failed",
"otherServers": ["JustMarkets-Demo", "JustMarkets-Demo2", "JustMarkets-Live"],
"actions": [
{ "kind": "switch_server", "server": "JustMarkets-Demo" },
{ "kind": "switch_server", "server": "JustMarkets-Demo2" },
{ "kind": "replace_credentials" }
]
}Un broker responde "authorization failed" tanto para una contraseña incorrecta como para
un login que vive en otro servidor, y los brokers tienen varios servidores con nombres
casi idénticos. otherServers lista los otros servidores del broker, del más probable
al menos: servidores en los que han iniciado sesión cuentas aquí, luego el servidor
principal del broker y luego los nombres más parecidos. Muéstraselos a tu usuario, o
prueba el primero con POST /v1/accounts/{id}/server: reutiliza la contraseña guardada.
Cuando una terminal no encuentra el servidor de la cuenta —un nombre que no es un
servidor de MT5, como la etiqueta que un broker usa para un tipo de cuenta—, una cuenta
que lo intentó y nunca inició sesión lleva "code": "SERVER_NOT_FOUND", con los
servidores reales del broker en otherServers y una acción switch_server para cada
uno. POST /v1/accounts/{id}/server con el correcto conserva la contraseña guardada.
Escribe el servidor exactamente como lo muestra el diálogo File → Login de MetaTrader o
el correo de bienvenida del broker.
Cuando las cuentas no pueden ponerse en línea por un problema de nuestro lado, las
cuentas en camino a estar en línea (created, standby, starting, offline,
error) llevan "code": "PLATFORM_ISSUE" sin actions: no hay que cambiar nada de la
cuenta, y reintentar no ayudará. Un POST /v1/accounts/{id}/warm fallido dice lo mismo
en su mensaje. Se resuelve solo una vez que se corrige;
status.fxapis.com tiene las novedades. Un login
rechazado, la 2FA, un certificado o el trading desactivado conservan sus propios
códigos: esos vienen del broker.
Alertas en la consola
Cuando una cuenta entra en uno de los estados anteriores, la consola abre una alerta: la
campana en la parte superior de cada página de la consola cuenta las que no has leído,
Notifications las lista con lo que dijo el broker y la única corrección (en la
página de la cuenta, donde está en la tarjeta del problema), y la página de la cuenta
muestra la misma tarjeta. Una alerta se cierra sola cuando la cuenta sale de ese
estado; las resueltas siguen en la lista una semana. Un error solo se muestra si dura
dos minutos: la mayoría se resuelven en segundos. Todos en el workspace las ven; solo
los owners y admins pueden hacer la corrección. Solo dentro de la app: no se envía nada
por correo y no hay API para ellas; las integraciones usan el webhook
account.state_changed o problem.
POST /v1/accounts/{id}/server
Mueve la cuenta a otro servidor, conservando la contraseña guardada: para un login
agregado con el nombre de servidor equivocado, así nadie vuelve a escribir la
contraseña. Con connect: true (el valor predeterminado) se pone en línea de inmediato
y la respuesta llega en segundos; consulta la cuenta o sus eventos. 409
ACCOUNT_EXISTS cuando ese login ya está conectado en ese servidor; 409
NO_PASSWORD cuando no hay contraseña guardada (usa /password).
curl -X POST https://api.fxapis.com/v1/accounts/$ID/server \
-H "Authorization: Bearer $FXAPIS_KEY" -H "content-type: application/json" \
-d '{"server":"JustMarkets-Demo"}'GET /v1/brokers/servers
Un selector de servidores para tu propio formulario de conexión, para que quienes
conectan elijan su servidor en lugar de escribirlo exactamente. Busca por lo que
escriben —el nombre de un broker (vantage), el inicio de un servidor
(JustMarkets-De), con o sin guiones y espacios— desde dos caracteres, con debounce:
curl "https://api.fxapis.com/v1/brokers/servers?q=justmarkets" -H "Authorization: Bearer $FXAPIS_KEY"{ "data": [
{ "name": "JustMarkets-Demo", "company": "Just Global Markets Ltd.", "kind": "demo", "proven": true },
{ "name": "JustMarkets-Live", "company": "Just Global Markets Ltd.", "kind": "live", "proven": false }
] }Primero vienen los servidores en los que han iniciado sesión cuentas en fxapis
(proven), luego los nombres que empiezan con lo escrito, luego el tipo pedido y luego
el servidor principal del broker. También se encuentra un broker que nadie ha usado aquí
todavía: con menos de cinco coincidencias y al menos tres caracteres escritos, se
consulta una vez la búsqueda de brokers (esa respuesta puede tardar uno o dos
segundos), y una búsqueda que no encontró nada no se repite durante 24 horas. limit
define cuántos se devuelven (1–50, 20 por defecto). Deja siempre que la gente use
exactamente lo que escribió: un servidor que no aparece en la lista se puede conectar
igual. Sin q, devuelve los servidores más usados aquí.
GET /v1/accounts/{id}/events
El historial de la cuenta en palabras, del más reciente al más antiguo —agregada,
iniciando sesión, rechazada por el broker, en línea, movida a otro servidor,
desconectada—, cada uno con un tone (success, info, warning, danger), un
title, un detail opcional y quién lo hizo (key, member, staff, system). La
lista de actividad de la consola es este endpoint. limit hasta 200 (50 por defecto).
Endpoints
Las formas completas de solicitudes y respuestas están en la referencia de la API. Lo que sigue es lo que la referencia no puede decirte.
POST /v1/accounts
Conecta la cuenta y guarda su contraseña, cifrada. Todavía no inicia sesión.
El mismo login y server solo se pueden conectar una vez por workspace —una segunda
copia significaría dos lugares capaces de operar el mismo dinero—, así que un duplicado
se rechaza con 409 mientras siga conectado. Un login que desconectaste antes se
vuelve a conectar en su lugar: consulta /disconnect.
Si la contraseña no se puede guardar de forma segura, la cuenta no se crea y recibes 503, en lugar de una cuenta que nunca podría ponerse en línea.
POST /v1/accounts/{id}/warm
Pone la cuenta en línea. Devuelve 202 de inmediato con un pollUrl; consúltalo
hasta que el estado sea ready.
Se puede llamar repetidamente sin riesgo: para una cuenta que ya está en línea devuelve
alreadyRunning: true y no hace nada más.
POST /v1/accounts/{id}/cool
Desconecta la cuenta. Sigue conectada a fxapis, en standby, y vuelve con la siguiente
orden o cuando lo pides. Funciona desde cualquier estado: a una cuenta en created o
en un estado que requiere atención y que todavía tiene una terminal en marcha se le
detiene, y conserva el estado que indica lo que aún necesita.
Se rechaza con 409 mientras se envía una orden: detenerse a mitad de una orden dejaría su resultado incierto. Espera un momento e inténtalo de nuevo.
Las posiciones abiertas no se ven afectadas. Los stop loss y take profit viven en el broker y siguen funcionando mientras la cuenta está fuera de línea.
POST /v1/accounts/{id}/restart
Desconecta la cuenta y la vuelve a poner en línea: para una cuenta que está en línea
pero se comporta mal (degraded, precios desactualizados). El mismo 409 mientras
hay una orden en curso.
POST /v1/accounts/{id}/disconnect
Desconecta la cuenta y borra la contraseña guardada. La cuenta y su historial se
conservan, en offline. Para volver a conectarla, envía el mismo login y servidor a
POST /v1/accounts con la contraseña: vuelve la misma cuenta, con 200.
Úsalo cuando un cliente se va. Una contraseña que ya no necesitas es una que nosotros ya no deberíamos guardar.
DELETE /v1/accounts/{id}
Elimina la cuenta para siempre: su terminal se detiene, su contraseña se borra y el registro se va con sus órdenes, deals y posiciones. No se puede deshacer: desconéctala en su lugar si quieres que el historial siga siendo legible. La respuesta indica cuánto se eliminó con ella.
Se rechaza con 409 mientras hay una orden en curso (ACCOUNT_EXECUTING), mientras
una orden multicuenta que la incluye no ha terminado (ACCOUNT_IN_WAVE), y cuando
nuestra última revisión encontró posiciones abiertas (ACCOUNT_HAS_POSITIONS). Las
posiciones abiertas siguen abiertas en el broker con sus stops, pero una vez eliminada
la cuenta no se pueden mostrar ni cerrar aquí: ciérralas primero, o envía
?force=true para eliminarla de todos modos.
Los hooks de alertas dejan de enviar a la cuenta, y un hook que se queda sin cuentas se apaga. El uso de este mes no se ve afectado. El mismo login y servidor se pueden volver a conectar después, como una cuenta nueva con un id nuevo.
POST /v1/accounts/{id}/password
Reemplaza la contraseña guardada: después de que cambió en el broker, o cuando la
cuenta está en invalid_credentials. Agrega server para corregir el nombre del
servidor. Cualquier terminal en marcha se detiene primero, y se espera a que termine
(409 mientras hay una orden en curso); la cuenta queda en created. Luego ponla en
línea con POST /v1/accounts/{id}/warm y consulta el estado: eso es un inicio de sesión
nuevo con la nueva contraseña. No hace falta desconectar nada entre medio.
POST /v1/accounts/{id}/mode
Cambia el modo. Se aplica la próxima vez que la cuenta se pone en línea.
GET /v1/accounts/{id}/status
El económico, hecho para consultar repetidamente. Cada dos segundos está bien.
GET /v1/accounts/{id}/figures
Balance, equity, margen, margen libre, nivel de margen, crédito y ganancia abierta, como strings decimales en la moneda de la cuenta, leídos de su terminal de MetaTrader.
curl -sS "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/figures" -H "Authorization: Bearer $FXAPIS_KEY"
# → { "data": { "accountId": "…", "balance": "10000.50000000", "equity": "10037.75000000",
# "margin": "120.00000000", "freeMargin": "9917.75000000", "marginLevel": "8364.79166667",
# "credit": "0.00000000", "profit": "37.25000000", "currency": "USD", "leverage": 500,
# "marginMode": "hedging", "observedAt": "2026-10-15T12:00:00.120Z", "ageMs": 4210,
# "source": "snapshot" } }- Sin
fresh, responde la última lectura (source: "snapshot"). Mientras la cuenta está en línea esa lectura se toma cada 15 segundos, yobservedAtdice cuándo.GET /v1/accounts/{id}y la lista de cuentas llevan las mismas cifras, configuresObservedAt. Una cuenta nunca leída tiene cifrasnull. - Con
fresh=true, se consulta a la terminal ahora (source: "live"). La cuenta debe estarready: fuera de línea,executinguna orden odegradedes409 ACCOUNT_NOT_READY. Una terminal que todavía corre un worker anterior responde501 CAPABILITY_UNAVAILABLEen su lugar; es raro en la práctica; mientras tanto, omitefreshpara esa cuenta. Las llamadas dentro del mismo segundo comparten una lectura, y solo una lectura que llega a la terminal se descuenta del presupuesto en vivo de la cuenta (Errores). marginLevelesnullmientras no se usa margen. El equity sobre un margen nulo no está definido; no es cero.credityprofitse completan para cada cuenta en línea;nullsolo para una nunca leída.marginModeesnetting(una posición por símbolo) ohedging(una por orden),nullhasta que la terminal lo haya informado.- Los webhooks no llevan cifras.
account.state_changedse dispara con un cambio de estado, y el balance y el equity cambian sin uno. Léelos aquí.
Consultar bien el estado
import time, httpx
def wait_until_ready(client, account_id, timeout=120):
"""Polls until the account is ready, or until it is clear it will not be."""
NEEDS_ATTENTION = {"invalid_credentials", "needs_2fa", "needs_certificate", "trading_disabled"}
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
state = client.get(f"/v1/accounts/{account_id}/status").json()["data"]
if state["state"] == "ready":
return state
if state["state"] in NEEDS_ATTENTION:
# Not retryable: report the reason now instead of timing out later.
raise RuntimeError(f"{account_id} needs attention: {state['state']} — {state['detail']}")
time.sleep(2)
raise TimeoutError(f"{account_id} did not reach ready within {timeout}s (last: {state['state']})")Dos hábitos que ahorran tickets de soporte:
Detente ante un estado que "requiere atención". Consultar durante dos minutos en
invalid_credentials no te dice nada que la primera respuesta no te haya dicho.
Deja más tiempo del que parece necesario. Unos 10 segundos según nuestra medición, y un broker ocupado puede tardar más. Un tiempo de espera de 120 segundos no cuesta nada cuando todo va bien.