# Conecta cuentas de MT5 con login, contraseña y servidor

URL: https://docs.fxapis.com/es/guides/connect-accounts

> Cómo conectar una cuenta de MetaTrader 5 a la API de fxapis: encontrar el nombre exacto del servidor, contraseña de trading frente a contraseña de inversor…



Conectar una cuenta de MT5 requiere tres datos de su dueño —el **login**, la
**contraseña de trading** y el **nombre del servidor**— y una llamada a la API.
Tener bien esos tres datos, y manejar la contraseña con cuidado en el camino, es la
mayor parte de lo que hace funcionar una pantalla de conexión. Esta guía cubre ambas
cosas. fxapis funciona con cualquier broker o prop firm de MT5, demo o real; lo que
cambia entre brokers está en [Compatibilidad con brokers](/es/guides/broker-compatibility).

```bash
curl -sS -X POST "https://api.fxapis.com/v1/accounts" \
  -H "Authorization: Bearer $FXAPIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "login": "81234567",
    "server": "VantageMarkets-Live",
    "password": "the-trading-password",
    "mode": "warm_on_demand",
    "label": "member_4821"
  }'
```

**201** devuelve la cuenta con su `id` y `state: "created"`. Todavía no inicia sesión:
eso ocurre cuando la cuenta se pone en línea por primera vez, y por eso conviene
[comprobar las credenciales de inmediato](#check-the-credentials-immediately).
Referencia: [Connect an MT5 account](/api-reference/accounts/connect-an-mt5-account).

## Los tres datos que necesitas [#the-three-things-you-need]

### Login [#login]

El número de cuenta de MT5, solo dígitos, enviado como **string**: `"81234567"`. Un
login con cualquier cosa que no sean dígitos se rechaza con **400**
`INVALID_REQUEST`. No es una dirección de correo ni el nombre de usuario en el portal
de clientes del broker: muchos brokers tienen ambos, y la gente los confunde.

### Contraseña: de trading, no de inversor [#password-trading-not-investor]

Cada cuenta de MT5 tiene dos contraseñas:

| Contraseña                          | Qué permite                   | ¿Funciona con fxapis?                                       |
| ----------------------------------- | ----------------------------- | ----------------------------------------------------------- |
| Contraseña **de trading** (maestra) | Iniciar sesión, leer y operar | **Sí**: es la que debes enviar                              |
| Contraseña **de inversor**          | Iniciar sesión y solo leer    | No: el inicio de sesión funciona pero se rechaza el trading |

La contraseña de inversor es el error clásico, porque al principio nada falla. La
cuenta llega a `ready` y su primera orden se rechaza. Pide la contraseña de trading
con ese nombre en tu pantalla de conexión, y explica por qué.

### Servidor: exactamente como lo muestra MetaTrader [#server-exactly-as-metatrader-shows-it]

El nombre del servidor identifica el servidor de trading del broker donde vive la
cuenta: `VantageMarkets-Demo`, `VantageMarkets-Live`, `ICMarkets-Live02`. Debe
coincidir **exactamente**, incluidas mayúsculas, guiones y cualquier número al final.

Dónde puede encontrarlo el dueño de la cuenta:

* **MetaTrader 5 en el escritorio:** la ventana *Navigator* lista cada cuenta con su servidor; el
  diálogo de inicio de sesión (*File → Login to Trade Account*) también lo muestra.
* **MetaTrader 5 en el móvil:** la pantalla de la cuenta, en la configuración de la app, muestra el
  servidor debajo del número de cuenta.
* **El correo de la cuenta del broker:** los brokers envían el login y el servidor cuando se abre una
  cuenta.

Consejos sobre los nombres que vale la pena poner en tu pantalla de conexión:

* **Real y demo son servidores distintos.** Las cuentas `…-Demo` y `…-Live` no se pueden intercambiar.
* **Los servidores numerados son servidores distintos.** `…-Live02` no es `…-Live`, y una cuenta
  existe exactamente en uno de ellos.
* **Un broker puede tener varias marcas y regiones**, cada una con sus propios servidores. El
  servidor de la cuenta es aquel en el que se abrió, no el de la página principal del broker.
* **Recorta lo que escribe el usuario.** Un espacio al final, por copiar y pegar, es otro nombre de
  servidor. Guardamos el valor exactamente como se envía.
* **Ofrece sugerencias, pero acepta lo que se escribió.** `GET /v1/brokers/servers?q=` busca en el
  catálogo de servidores de brokers mientras el usuario escribe —primero vienen los servidores en
  los que ya inician sesión cuentas en fxapis—, así que un autocompletado atrapa la mayoría de los
  errores de escritura. Aun así, los brokers agregan y renombran servidores, así que nunca obligues a
  elegir de la lista: un servidor que no aparece se puede conectar igual. Consulta
  [Cuentas](/es/accounts) para la búsqueda.
* **Un servidor equivocado se puede corregir sobre la marcha.** Cuando un inicio de sesión falla en
  el servidor indicado, `problem.otherServers` de la cuenta sugiere alternativas probables, y
  `POST /v1/accounts/{id}/server` mueve la cuenta al correcto, probando ahí la contraseña guardada: no
  se vuelve a enviar.

<Callout type="warn" title="Prueba primero con cuentas demo">
  Las API keys etiquetadas `fx_test_` también llegan a brokers reales. Construye tu flujo de conexión
  con cuentas **demo** de brokers antes de conectar el dinero real de nadie.
</Callout>

## Elegir un modo [#choosing-a-mode]

`mode` decide cuándo está en línea la cuenta. El valor predeterminado es `cold`, así que defínelo:

| Modo             | Úsalo para                                                                                                                                                  |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `warm_on_demand` | La mayoría de las integraciones. Se pone en línea para una orden (o cuando la preparas) y se desconecta tras 15 minutos de inactividad.                     |
| `always_on`      | Cuentas que deben actuar al instante en cualquier momento: cuentas maestras de un copiador, cuentas bajo monitoreo de riesgo en vivo. Una función del plan. |
| `cold`           | Cuentas que pones en línea tú mismo, según un horario.                                                                                                      |

Puedes cambiarlo después con
[`POST /v1/accounts/{id}/mode`](/api-reference/lifecycle/change-how-eagerly-the-account-stays-connected).
Consulta [Cuentas → Modos](/es/accounts#modes).

## Manejar las credenciales en tu app [#handling-credentials-in-your-app]

La contraseña de MT5 es la llave del dinero de alguien. fxapis la cifra al recibirla
con una clave única para esa cuenta, nunca la devuelve en ningún endpoint y la borra
cuando la cuenta se desconecta; consulta [Seguridad](/es/security). Tu parte del trabajo es
asegurarte de que pase por tus sistemas sin dejar rastro:

* **Envíala desde tu backend, directo a fxapis, en la misma solicitud que la recibió.** Tu API key
  nunca debe estar en un navegador ni en una app móvil, así que el formulario envía a tu servidor y tu
  servidor llama a `POST /v1/accounts`.
* **Nunca la guardes**: ni en tu base de datos, ni en una caché, ni en un trabajo de una cola, ni en un
  evento de analítica, ni en un ticket de soporte. Guarda en su lugar el `id` de la cuenta de fxapis;
  es todo lo que necesitas a partir de ahí.
* **Nunca la registres en logs.** Desactiva el registro del cuerpo de las solicitudes en la ruta de
  conexión, y asegúrate de que las herramientas de reporte de errores no capturen el cuerpo cuando la
  llamada falla.
* **Solo por HTTPS**, y nunca en una URL ni en un query string, donde los proxies y los navegadores
  guardan copias.
* **No reintentes la llamada de conexión desde un trabajo en segundo plano.** Eso significaría guardar
  la contraseña para reintentar después. Si fxapis responde **503** `SECRET_STORE_UNAVAILABLE`, no se
  creó nada: reintenta un par de veces en la misma solicitud y luego pide al usuario que lo intente de
  nuevo.

```python
# fxapis = httpx.Client(base_url="https://api.fxapis.com", headers={"Authorization": f"Bearer {KEY}"})
@app.post("/connect-mt5")
def connect_mt5(form: ConnectForm, user: User):
    response = fxapis.post("/v1/accounts", json={
        "login": form.login.strip(),
        "server": form.server.strip(),
        "password": form.password,          # used once, here, and never kept
        "mode": "warm_on_demand",
        "label": f"user_{user.id}",
    }, timeout=30)
    if response.status_code == 409:         # ACCOUNT_EXISTS: already connected in your workspace
        return {"error": "This account is already connected."}
    response.raise_for_status()
    account = response.json()["data"]
    user.fxapis_account_id = account["id"]  # the id, not the password
    fxapis.post(f"/v1/accounts/{account['id']}/warm")
    return {"accountId": account["id"]}
```

Un login y un servidor se pueden conectar **una vez por workspace**. Un segundo intento
devuelve **409** `ACCOUNT_EXISTS`: dos conexiones significarían dos lugares capaces de
operar el mismo dinero. Si dos de tus usuarios reclaman la misma cuenta de MT5, es un
asunto para tu equipo de soporte, no para un reintento.

Conectar más cuentas de las que permite tu plan devuelve **402** `QUOTA_EXCEEDED`.
Otros tres **402** vienen del plan, antes de que la contraseña vaya a ningún lado:
`FEATURE_NOT_IN_PLAN` para `always_on` en un plan que no lo incluye y, en una prueba,
`DEMO_ONLY` para una cuenta real y `TRIAL_ACCOUNT_USED` para un login demo que otra
prueba ya usó.

## Comprueba las credenciales de inmediato [#check-the-credentials-immediately]

Una cuenta nueva todavía no ha iniciado sesión. Si esperas a su primera operación para
descubrir que la contraseña está mal, el fallo llega en el peor momento. Ponla en línea
mientras el usuario todavía está en la pantalla de conexión:

1. `POST /v1/accounts/{id}/warm`: responde **202** de inmediato.
2. Consulta `GET /v1/accounts/{id}/status` cada dos segundos hasta que `state` sea `ready` o un
   estado que requiere atención. Unos 10 segundos según nuestra medición; deja hasta dos minutos.
3. Muestra el resultado.

```ts
const NEEDS_ATTENTION = ["invalid_credentials", "trading_disabled", "needs_2fa", "needs_certificate"];

async function checkCredentials(accountId: string): Promise<string> {
  const deadline = Date.now() + 120_000;
  while (Date.now() < deadline) {
    const res = await fetch(`${API}/v1/accounts/${accountId}/status`, { headers: { Authorization: `Bearer ${KEY}` } });
    const { data } = await res.json();
    if (data.state === "ready" || NEEDS_ATTENTION.includes(data.state)) return data.state;
    await new Promise((r) => setTimeout(r, 2000));
  }
  return "timeout";
}
```

En tu interfaz, consulta tu propio backend desde el navegador, y deja que el backend
llame a fxapis. Una vez hecha la comprobación, una cuenta `warm_on_demand` se vuelve a
desconectar sola tras 15 minutos; no hace falta nada más.

## Los estados que requieren atención [#the-needs-attention-states]

| Estado                | Qué significa                                           | Dile al usuario                                                                                                           |
| --------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `invalid_credentials` | El broker rechazó el inicio de sesión.                  | El login, la contraseña o el servidor están mal. Revisa la contraseña **de trading** y el nombre exacto del servidor.     |
| `trading_disabled`    | El broker desactivó el trading para este login.         | Pide al broker 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 al iniciar sesión. | Hay que desactivar el inicio de sesión en dos pasos para esta cuenta; una API no puede completarlo.                       |
| `needs_certificate`   | El broker requiere un certificado de cliente.           | Contacta a soporte.                                                                                                       |
| `error`               | Algo temporal salió mal.                                | Inténtalo de nuevo; volver a poner la cuenta en línea es seguro.                                                          |

Los cuatro primeros no se arreglan solos, y **los inicios de sesión fallidos repetidos
son la forma en que un broker bloquea una cuenta**. Por eso fxapis deja de intentarlo:
poner en línea una cuenta así devuelve **409** `NEEDS_OPERATOR`, y `prepare` lo informa
como `needs_operator`, sin contactar al broker. No metas estos estados en un bucle de
reintentos. Todos los estados están en [Cuentas → Estados](/es/accounts#states).

## Corregir las credenciales [#correcting-credentials]

Cuando una contraseña estaba mal, o el miembro la cambió en el broker, reemplázala en la cuenta
existente: su id, su historial y su configuración se conservan:

```bash
curl -sS -X POST "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/password" \
  -H "Authorization: Bearer $FXAPIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "password": "the-members-corrected-password" }'
```

Agrega `"server"` para corregir el nombre del servidor al mismo tiempo. Cualquier terminal en
marcha se detiene primero y se espera a que termine (se rechaza con **409** `ACCOUNT_EXECUTING`
mientras hay una orden en curso), se guarda la contraseña nueva y solo entonces se borra la
anterior. Funciona en cualquier estado de la cuenta, incluso mientras está en línea. La cuenta queda
en `created`: ponla en línea de inmediato y consulta su estado, exactamente como en la pantalla de
conexión, para que el miembro sepa enseguida si la nueva contraseña funciona.

Un login que se **desconectó** también se puede volver a conectar sin más con `POST /v1/accounts`:
vuelve la misma cuenta con la contraseña nueva, y la respuesta es **200** en lugar de **201**.

## Desconectar [#disconnecting]

```bash
curl -sS -X POST "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID/disconnect" \
  -H "Authorization: Bearer $FXAPIS_KEY"
```

`disconnect` desconecta la cuenta y **borra la contraseña guardada** de inmediato; la
respuesta dice `"credentialsRemoved": true`. El registro de la cuenta y todo su
historial de trading se conservan, en estado `offline`, para tus registros y para
cualquier disputa. Llámalo cuando un usuario quita su cuenta o deja tu producto: una
contraseña que ya no necesitas es una que nadie debería seguir guardando.

Si solo quieres la cuenta fuera de línea por ahora, usa
[`POST /v1/accounts/{id}/cool`](/api-reference/lifecycle/take-an-account-offline) en su lugar:
conserva la contraseña para que la cuenta pueda volver. Las posiciones abiertas no se tocan en
ninguno de los dos casos; los stop loss y take profit viven en el broker y siguen funcionando.

## Eliminar [#deleting]

```bash
curl -sS -X DELETE "https://api.fxapis.com/v1/accounts/$ACCOUNT_ID" \
  -H "Authorization: Bearer $FXAPIS_KEY"
```

Eliminar quita la cuenta **y su historial** para siempre: para un usuario que pidió ser olvidado, o
para un registro creado con el nombre de servidor equivocado. La respuesta lista cuántas órdenes,
deals y posiciones se fueron con ella. Se rechaza mientras hay una orden en curso
(`ACCOUNT_EXECUTING`), mientras una orden multicuenta que la incluye no ha terminado
(`ACCOUNT_IN_WAVE`), y mientras nuestra última revisión encontró posiciones abiertas
(`ACCOUNT_HAS_POSITIONS`): ciérralas primero, o agrega `?force=true` para eliminarla con ellas todavía
abiertas en el broker. El mismo login y servidor se pueden volver a conectar después, como una cuenta
nueva.

## Conectar muchas cuentas [#connecting-many-accounts]

* Conecta las cuentas con una llamada cada una, a medida que los usuarios se registran.
* Pon en línea hasta 200 en una llamada con
  [`POST /v1/accounts/prepare`](/api-reference/lifecycle/bring-several-accounts-online-at-once); cada
  una recibe su propio resultado (`starting`, `already_running`, `needs_operator`…).
* `GET /v1/accounts` lista cada cuenta con su `state`, así que un trabajo nocturno puede encontrar las
  que requieren atención y avisar a sus dueños.

## Relacionado [#related]

* [Señales y click-to-trade](/signals): una integración completa de cara a los miembros.
* [Compatibilidad con brokers](/es/guides/broker-compatibility): cualquier broker de MT5, y lo que cambia entre ellos.
* [Cuentas](/es/accounts): modos, estados y cada endpoint del ciclo de vida.
* [Seguridad](/es/security): cómo se guardan y se borran las contraseñas.
* Guías por lenguaje: [Python](/guides/python), [Node.js](/guides/nodejs), [PHP](/guides/php),
  [C#](/guides/csharp), [Go](/guides/go), [Java](/guides/java), [Ruby](/guides/ruby).
