# Inicio rápido

URL: https://docs.fxapis.com/es/quickstart

> De una API key a una orden ejecutada, en unos cinco minutos.



Necesitas una API key ([créala en la consola](https://fxapis.com/dashboard/keys)),
un número de cuenta de MT5, su contraseña **de trading** y el nombre del servidor
exactamente como lo muestra MetaTrader: `VantageMarkets-Demo`, `ICMarkets-Demo`.
Usa una cuenta demo la primera vez. Funciona con cualquier broker de MT5; consulta
[Compatibilidad con brokers](/es/guides/broker-compatibility).

<Callout type="warn">
  La contraseña de inversor no funciona. Puede leer una cuenta pero no puede operar, y el inicio de
  sesión tiene éxito, así que el fallo llega después, como una orden rechazada.
</Callout>

<Steps>
  <Step>
    ### Configura tu clave [#set-your-key]

    <CodeBlockTabs defaultValue="cURL">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="cURL">
          cURL
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Python">
          Python
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Node.js">
          Node.js
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="cURL">
        ```bash
        export FXAPIS_KEY="fx_live_7f3a9c21_your-secret-here"
        export FXAPIS_API="https://api.fxapis.com"
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Python">
        ```python
        import os, uuid, requests

        API = "https://api.fxapis.com"
        session = requests.Session()
        session.headers["Authorization"] = f"Bearer {os.environ['FXAPIS_KEY']}"
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Node.js">
        ```js
        const API = "https://api.fxapis.com";
        const headers = {
          Authorization: `Bearer ${process.env.FXAPIS_KEY}`,
          "Content-Type": "application/json",
        };
        ```
      </CodeBlockTab>
    </CodeBlockTabs>

    Las claves son credenciales de servidor a servidor. Mantenlas fuera de navegadores,
    apps y repositorios. Consulta [Autenticación](/es/authentication).
  </Step>

  <Step>
    ### Conecta la cuenta [#connect-the-account]

    <CodeBlockTabs defaultValue="cURL">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="cURL">
          cURL
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Python">
          Python
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Node.js">
          Node.js
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="cURL">
        ```bash
        # Guarda el id de la nueva cuenta para los siguientes pasos (usa jq; o copia data.id a mano).
        export FXAPIS_ACCOUNT=$(curl -sS -X POST "$FXAPIS_API/v1/accounts" \
          -H "Authorization: Bearer $FXAPIS_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "login": "26177561",
            "server": "VantageMarkets-Demo",
            "password": "your-mt5-trading-password",
            "mode": "warm_on_demand",
            "label": "Demo — strategy A"
          }' | jq -r .data.id)
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Python">
        ```python
        account = session.post(f"{API}/v1/accounts", json={
            "login": "26177561",
            "server": "VantageMarkets-Demo",
            "password": "your-mt5-trading-password",
            "mode": "warm_on_demand",
            "label": "Demo — strategy A",
        }).json()["data"]
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Node.js">
        ```js
        const { data: account } = await fetch(`${API}/v1/accounts`, {
          method: "POST",
          headers,
          body: JSON.stringify({
            login: "26177561",
            server: "VantageMarkets-Demo",
            password: "your-mt5-trading-password",
            mode: "warm_on_demand",
            label: "Demo — strategy A",
          }),
        }).then((r) => r.json());
        ```
      </CodeBlockTab>
    </CodeBlockTabs>

    Esto guarda la cuenta y **todavía no** inicia sesión. La contraseña se cifra con
    una clave vinculada solo a esta cuenta y ningún endpoint la devuelve jamás.
  </Step>

  <Step>
    ### Ponla en línea [#bring-it-online]

    <CodeBlockTabs defaultValue="cURL">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="cURL">
          cURL
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Python">
          Python
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Node.js">
          Node.js
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="cURL">
        ```bash
        curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/warm" \
          -H "Authorization: Bearer $FXAPIS_KEY"

        until curl -sS "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/status" \
                -H "Authorization: Bearer $FXAPIS_KEY" | grep -q '"ready"'
        do sleep 2; done
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Python">
        ```python
        import time

        session.post(f"{API}/v1/accounts/{account['id']}/warm")
        while session.get(f"{API}/v1/accounts/{account['id']}/status").json()["data"]["state"] != "ready":
            time.sleep(2)
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Node.js">
        ```js
        await fetch(`${API}/v1/accounts/${account.id}/warm`, { method: "POST", headers });
        while ((await fetch(`${API}/v1/accounts/${account.id}/status`, { headers }).then((r) => r.json())).data.state !== "ready") {
          await new Promise((r) => setTimeout(r, 2000));
        }
        ```
      </CodeBlockTab>
    </CodeBlockTabs>

    `warm` responde **202** de inmediato, mientras la cuenta inicia sesión en el broker.
    Su estado pasa por `starting`, `connecting` y `synchronizing` hasta `ready`, en
    unos 10 segundos según nuestra medición. Solo `ready` acepta órdenes.
  </Step>

  <Step>
    ### Envía una orden [#place-an-order]

    <CodeBlockTabs defaultValue="cURL">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="cURL">
          cURL
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Python">
          Python
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Node.js">
          Node.js
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="cURL">
        ```bash
        curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/orders/market" \
          -H "Authorization: Bearer $FXAPIS_KEY" \
          -H "Idempotency-Key: $(uuidgen)" \
          -H "Content-Type: application/json" \
          -d '{ "symbol": "EURUSD", "side": "buy", "volume": "0.01" }'
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Python">
        ```python
        order = session.post(
            f"{API}/v1/accounts/{account['id']}/orders/market",
            headers={"Idempotency-Key": str(uuid.uuid4())},
            json={"symbol": "EURUSD", "side": "buy", "volume": "0.01"},
        ).json()["data"]
        print(order["state"], order["filledPrice"])
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Node.js">
        ```js
        const { data: order } = await fetch(`${API}/v1/accounts/${account.id}/orders/market`, {
          method: "POST",
          headers: { ...headers, "Idempotency-Key": crypto.randomUUID() },
          body: JSON.stringify({ symbol: "EURUSD", side: "buy", volume: "0.01" }),
        }).then((r) => r.json());
        console.log(order.state, order.filledPrice);
        ```
      </CodeBlockTab>
    </CodeBlockTabs>

    ```json title="201 Created"
    {
      "data": {
        "id": "b1c7…9e2a",
        "symbol": "EURUSD",
        "side": "buy",
        "volume": "0.01",
        "state": "filled",
        "filledPrice": "1.13426",
        "brokerOrderId": "2109584418"
      }
    }
    ```

    Los volúmenes y los precios son strings, nunca floats. Conserva el `Idempotency-Key`
    si reintentas: la misma clave nunca abre una segunda orden. Una orden termina en
    `filled`, `rejected`, o `unknown` mientras se concilia con el broker; consulta
    [Trading](/es/trading).
  </Step>

  <Step>
    ### Ciérrala [#close-it]

    <CodeBlockTabs defaultValue="cURL">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="cURL">
          cURL
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="cURL">
        ```bash
        # Las posiciones se actualizan solas cada 15 s aproximadamente; reconcile las actualiza ahora.
        curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/reconcile" -H "Authorization: Bearer $FXAPIS_KEY"
        export POSITION_TICKET=$(curl -sS "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/positions" \
          -H "Authorization: Bearer $FXAPIS_KEY" | jq -r '.data[0].brokerPositionId')

        curl -sS -X POST "$FXAPIS_API/v1/accounts/$FXAPIS_ACCOUNT/positions/$POSITION_TICKET/close" \
          -H "Authorization: Bearer $FXAPIS_KEY" -H "Idempotency-Key: $(uuidgen)" \
          -H "Content-Type: application/json" -d '{}'
        ```
      </CodeBlockTab>
    </CodeBlockTabs>

    Una cuenta `warm_on_demand` se desconecta sola después de un rato tranquilo sin
    órdenes; `POST /cool` la desconecta ahora.
    Los stop loss y take profit viven en el broker y siguen funcionando mientras la
    cuenta está desconectada.
  </Step>
</Steps>

## Si no llega a `ready` [#if-it-does-not-reach-ready]

| Estado                | Significado                                               | Qué hacer                                                                                                                                                                 |
| --------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_credentials` | El broker rechazó el inicio de sesión                     | Corrige la contraseña y vuelve a conectar. No reintentes: los fallos repetidos son la forma en que un broker bloquea una cuenta.                                          |
| `needs_2fa`           | La cuenta requiere un segundo factor                      | No es compatible sin interfaz. Desactiva la 2FA o usa otra cuenta.                                                                                                        |
| `needs_certificate`   | El broker requiere un certificado de cliente              | Contáctanos.                                                                                                                                                              |
| `trading_disabled`    | El inicio de sesión funcionó, el trading está desactivado | El broker desactivó el trading para este login. (Una contraseña de inversor, en cambio, llega a `ready` y sus órdenes se rechazan). Pide al broker que active el trading. |
| `error`               | Algo temporal                                             | Se puede reintentar. Vuelve a ponerla en línea.                                                                                                                           |

## Siguientes pasos [#next]

* **Usa un SDK.** Los [SDKs oficiales de TypeScript y Python](/es/sdks) envuelven estas mismas
  llamadas, con errores tipados y claves de idempotencia incluidas; guías paso a paso para
  [TypeScript](https://fxapis.com/blog/mt5-api-typescript-sdk) y [Python](https://fxapis.com/blog/mt5-api-python-sdk) (en inglés).
* **Ejecuta un ejemplo completo.** [fxapis-examples](https://github.com/FXapis/fxapis-examples) tiene
  este inicio rápido, click-to-trade y un copiador de operaciones en Python, Node/TypeScript y curl, y el
  [starter de Next.js](https://github.com/FXapis/fxapis-nextjs-starter) es una pequeña app funcional
  ([cómo ejecutar los ejemplos](https://fxapis.com/blog/mt5-api-examples-python-node-curl),
  [cómo está hecho el starter](https://fxapis.com/blog/nextjs-mt5-trading-dashboard-starter), en inglés).
* **Deja de hacer polling.** Los [webhooks](/guides/webhooks) envían un `POST` firmado a tu servidor
  cuando una orden se ejecuta, una posición se cierra o una cuenta cambia de estado (en inglés).
* **Profundiza.** [Trading](/es/trading) cubre todos los resultados que puede tener una orden, y las
  [guías](/es/guides) tienen programas completos en siete lenguajes.
