Docs

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.

ModoEn líneaPrimera ordenIdeal para
always_onUna 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)InmediataCuentas que deben actuar al instante en que algo ocurre: señales copiadas, una apertura de mercado
warm_on_demandCuando operas, y luego se desconecta sola cuando está inactivaTras una conexión breveLa mayoría de las integraciones y los servicios de señales
coldSolo cuando lo pidesDespués de que la pones en líneaCuentas 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_demand se 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 cold y stateDetail lo indica. Sus credenciales se conservan. POST /v1/accounts/{id}/warm o POST /v1/accounts/prepare la recuperan como warm_on_demand, y una orden en ella responde 409 ACCOUNT_NOT_READY hasta 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

EstadoSignificado
readyEn línea y aceptando órdenes.
executingEn línea; se está enviando una orden en este momento.

Conectando: espera

EstadoSignificado
provisioning, starting, connectingPoniéndose en línea e iniciando sesión en el broker.
synchronizingSesión iniciada; los precios todavía están llegando. Las órdenes se rechazan hasta ready, para que ninguna salga con precios incompletos.
reconnectingLa conexión con el broker se cayó y se está restableciendo.
degradedEn 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

EstadoSignificado
createdConectada, todavía nunca puesta en línea.
standbyFuera 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).
coolingDesconectándose.
offlineDesconectada (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

EstadoSignificadoQué hacer
invalid_credentialsEl 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_disabledEl 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_2faLa cuenta requiere un segundo factor.Desactiva la verificación en dos pasos para esta cuenta, o usa otra.
needs_certificateEl broker requiere un certificado de cliente.Contáctanos.
errorAlgo 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, y observedAt dice cuándo. GET /v1/accounts/{id} y la lista de cuentas llevan las mismas cifras, con figuresObservedAt. Una cuenta nunca leída tiene cifras null.
  • Con fresh=true, se consulta a la terminal ahora (source: "live"). La cuenta debe estar ready: fuera de línea, executing una orden o degraded es 409 ACCOUNT_NOT_READY. Una terminal que todavía corre un worker anterior responde 501 CAPABILITY_UNAVAILABLE en su lugar; es raro en la práctica; mientras tanto, omite fresh para 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).
  • marginLevel es null mientras no se usa margen. El equity sobre un margen nulo no está definido; no es cero.
  • credit y profit se completan para cada cuenta en línea; null solo para una nunca leída.
  • marginMode es netting (una posición por símbolo) o hedging (una por orden), null hasta que la terminal lo haya informado.
  • Los webhooks no llevan cifras. account.state_changed se 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.

En esta página