Docs

Errores

Cada código de error, qué lo causa y si conviene reintentar.

Cada fallo tiene la misma forma:

{
  "error": {
    "code": "ACCOUNT_EXECUTING",
    "message": "An order is in flight. Stopping now would leave its outcome unknown.",
    "details": []
  },
  "requestId": "3f8a1c92-7b4e-4d81-a2f6-0c5e9b3d7a14"
}

Compara por code. Es estable entre versiones. message está escrito para una persona y va a cambiar (y está en inglés). details aparece en los fallos de validación y nombra los campos; en una orden fallida, details[0] lleva su orderId, su state y retryable.

requestId está en cada respuesta de error y queda registrado en cada fila de auditoría. Inclúyelo en una solicitud de soporte y se puede encontrar la llamada completa.

Los códigos

Autenticación y autorización

CódigoEstadoCausa¿Reintentar?
UNAUTHENTICATED401Clave ausente, mal formada, desconocida, revocada o vencida: deliberadamente un solo código para todas (una excepción: una clave de administrador vencida recibe ADMIN_KEY_EXPIRED)No. Corrige la clave.
MISSING_SCOPE403Clave válida, alcance equivocado. Nombra el alcance que necesita.No. Emite una clave con ese alcance.
KEY_LIMIT_EXCEEDED403Los límites de la clave no permiten esta orden de apertura: demasiado grande, un símbolo o una cuenta que no puede operar, o ya usó su cupo diario. details[0] tiene limit, requested, allowed y, para una cuenta de una orden multicuenta, accountId. No se envió nada. También se responde cuando una clave con límites intenta cambiar, rotar o volver a activar un hook de TradingView que no creó; entonces details está vacío y no cambió nada. No es KEY_LIMIT (409), que se refiere a cuántas claves tiene un workspace.No. Cambia la orden, usa otra clave o cambia los límites de la clave.

Un solo código para cada fallo de autenticación es intencional: distinguir "clave desconocida" de "secreto incorrecto" permitiría a alguien con una lista de claves candidatas separar las reales de las falsas. Consulta Autenticación.

Inicio de sesión de MCP

/mcp y /mcp/insights responden a la solicitud de una app conectada con un desafío WWW-Authenticate en lugar de uno de los códigos anteriores:

RespuestaSignificado
401 con WWW-Authenticate: Bearer resource_metadata="…"No se envió ninguna credencial. Inicia sesión.
401 con error="invalid_token"El inicio de sesión venció o fue revocado, o el token es del otro servidor. Vuelve a iniciar sesión.
403 con error="insufficient_scope"Sesión iniciada, pero sin permiso para operar. Vuelve a conectar; la página de inicio de sesión se abre con Trading preseleccionado.

Consulta Servidor MCP para ver qué provoca cada una.

Solicitudes

CódigoEstadoCausa¿Reintentar?
INVALID_REQUEST400El cuerpo o los parámetros no pasaron la validación (details nombra los campos), el cuerpo no es JSON válido o —en una orden— sus stops están del lado equivocado o un cierre parcial dejaría menos del mínimo del símbolo. También se responde con 413 para un cuerpo demasiado grande y con 415 para el tipo de contenido equivocado.No. Corrige la solicitud.
NOT_FOUND404No existe ese endpoint, o no existe esa API key, ese miembro, esa invitación, ese hook de TradingView o esa factura para tu workspace.No.
ACCOUNT_NOT_FOUND404No existe esa cuenta para tu tenantNo.
POSITION_NOT_FOUND404No existe esa posición abierta en esa cuenta; normalmente ya está cerradaNo. Lee las posiciones de la cuenta.
ORDER_NOT_FOUND404No existe esa orden para tu tenantNo.
WAVE_NOT_FOUND404No existe esa orden multicuenta para tu tenantNo.
RATE_LIMITED429Demasiadas solicitudes de una clase. El encabezado retry-after dice cuántos segundos esperar, y x-ratelimit-class nombra la clase alcanzada. Consulta Límites de frecuencia.Sí, después de retry-after.

ACCOUNT_NOT_FOUND también es lo que recibes para una cuenta que existe pero pertenece a otra persona. Responder 403 confirmaría que un id adivinado es real. POST /v1/accounts/{id}/password, POST /v1/accounts/{id}/server y DELETE /v1/accounts/{id} responden a una cuenta inexistente con NOT_FOUND en lugar de ACCOUNT_NOT_FOUND; trata ambos igual.

Límites de frecuencia

Los límites son por workspace y por clase de trabajo, así que las consultas repetidas nunca gastan el margen que necesitan tus órdenes. Cada uno es una tasa constante por minuto más una ráfaga corta.

ClaseQué cubreLímite
TradingÓrdenes, cierres, cambios de stops, cancelacionesEl mayor entre 60 por minuto y el doble del cupo de cuentas del plan, con una ráfaga del mayor entre 10 y el cupo de cuentas: por ejemplo, Production 500 por minuto + 250, Business 2,000 + 1,000
Órdenes multicuentaCrear y cancelar órdenes multicuenta10 por minuto + 2
LecturasCada GET600 por minuto + 100
Lecturas en vivoGET …/quotes y GET …/figures?fresh=true, que solo se cobran cuando realmente se consulta a la terminal de la cuenta (las respuestas compartidas y en caché son gratis). Por cuenta, sumando todos los llamadores y claves, además de contar como lecturas. Un rechazo lleva x-ratelimit-class: live.300 por minuto + 50
Otras escriturasTodo lo demás120 por minuto + 20

Cada respuesta nombra su clase en x-ratelimit-class y el tope en x-ratelimit-limit. Las sesiones de la consola tienen sus propios límites.

Cuentas

CódigoEstadoCausa¿Reintentar?
ACCOUNT_EXISTS409Ese login + server ya está conectado en tu workspaceNo. Usa la cuenta existente: su id está en details. Para cambiar su contraseña, POST /v1/accounts/{id}/password.
SECRET_STORE_UNAVAILABLE503No se pudo guardar la credencial, así que la cuenta no se creóSí, con backoff.
ACCOUNT_EXECUTING409En POST /v1/accounts/{id}/password o DELETE /v1/accounts/{id}: hay una orden en curso, así que no se cambió nadaSí, cuando la orden se resuelva.
ACCOUNT_HAS_POSITIONS409En DELETE /v1/accounts/{id}: nuestra última revisión encontró posiciones abiertas. details dice cuántas.No. Ciérralas primero, o elimina con force=true: siguen abiertas en el broker, pero ya no se pueden mostrar ni cerrar aquí.
NO_PASSWORD409En POST /v1/accounts/{id}/server: no hay contraseña guardada para esta cuenta (se desconectó)No. Envía la contraseña con el servidor a /password.
DEMO_ONLY402En una prueba: no se conecta una cuenta real; la prueba, de cualquier plan, es para cuentas demoNo. Paga el plan para conectar cuentas reales.
TRIAL_ACCOUNT_USED402En una prueba: ese login demo ya se usó en otra pruebaNo. Usa otra cuenta demo, o elige un plan.
ACCOUNT_CHANGED409En POST /v1/accounts/{id}/password: la cuenta se desconectó, o su contraseña se reemplazó, mientras corría la solicitud. No se cambió nada.Sí: lee la cuenta y luego vuelve a conectar o a reemplazar.
ACCOUNT_IN_WAVE409En DELETE /v1/accounts/{id}: una orden multicuenta que incluye esta cuenta no ha terminado. details tiene su id.Sí, cuando se liquide, o cancélala.

Trading

CódigoEstadoCausa¿Reintentar?
SEND_FAILED503Demostrado que nunca llegó al brokerSí. El único reenvío seguro.
ORDER_REJECTED422El broker la rechazó, con un motivo y su propio retcodeSolo si retryable es true
NO_PRICE422El broker de la cuenta no tenía un precio actual para el símbolo: el mercado está cerrado, o este broker no lo ofrece. No se envió nada.Cuando el símbolo esté cotizando. Revisa su horario en /instruments. Se puede reutilizar el mismo Idempotency-Key.
ORDER_UNRESOLVED503No sabemos si se ejecutóNunca. Consulta la orden.
IDEMPOTENCY_KEY_REUSED409Esa clave se usó para una orden distintaNo. Usa una clave nueva.
IDEMPOTENCY_IN_FLIGHT409La primera solicitud con esa clave sigue en cursoSí, en breve.
TRADING_DISABLED409El trading está desactivado para la cuenta, o para todo el workspace por su interruptor de emergencia, cierres incluidosNo.
ACCOUNT_NOT_READY409La cuenta no está ready: fuera de línea en modo cold, todavía conectándose, en un estado que requiere atención o poniéndose en línea por otra solicitud; y, en /quotes y /candles, no está en línea (ready, executing o degraded); en /figures?fresh=true, no está readyConsulta su estado; reintenta cuando esté ready. No si requiere atención.
NO_RUNTIME409La cuenta figuraba en línea pero no se puede alcanzar; o, en /calculate, está fuera de línea, o falló ponerla en línea para una ordenReinicia la cuenta, o ponla en línea.
MT5_UNAVAILABLE503En /calculate, /quotes, /candles o /figures?fresh=true: la terminal de la cuenta no respondió (en /candles, también mientras todavía no se ha medido el reloj del broker)Sí, en breve.
CAPABILITY_UNAVAILABLE501En /quotes, /candles o /figures?fresh=true: la terminal de la cuenta es anterior a esa función. La obtiene en su próxima actualización. El historial de precios (/candles) está disponible después del próximo mantenimiento programado.Ahora no. Mientras tanto, usa el currentPrice de las posiciones, o /figures sin fresh.

422 en lugar de 400 para un rechazo: la solicitud estaba bien formada y la entendimos. El broker la rechazó, que es un problema distinto con una solución distinta.

ORDER_UNRESOLVED es el que hay que manejar con cuidado. Consulta Trading e historial.

Planes

CódigoEstadoCausa¿Reintentar?
QUOTA_EXCEEDED402Abrir esto superaría el límite del plan. En los planes de pago, las órdenes por encima del cupo se cobran por orden hasta el doble del cupo, y después se rechazan las nuevas órdenes de apertura; en una prueba se rechazan al llegar al cupo, y un workspace sin plan no puede abrir nada. En los planes sin excedente (una prueba, Personal) las ejecuciones de apertura se detienen al llegar al cupo hasta el día 1 del mes (UTC). En Personal, una segunda cuenta real también se rechaza aquí. En la prueba de un plan, las cuentas demo tienen un tope de 5 aunque el plan en sí permita más; pagar el plan desbloquea su cupo completo. En un plan con límite de miembros, también las invitaciones. También: las órdenes multicuenta de este mes, las cuentas en una orden multicuenta o las cuentas conectadas a la vez. Cerrar nunca se rechaza por facturación, y tampoco cancelar ni mover stops.No. Cambia de plan, o espera al mes siguiente.
PERSONAL_PLAN_USED409Ya tienes un workspace Personal: uno por persona, comprobado por el correo del owner (sin distinguir mayúsculas, +tag ni los puntos de Gmail) y por el login del broker. Se responde al iniciar el plan o al conectar una cuenta en uno.No. Usa ese workspace, o elige Production.
FEATURE_NOT_IN_PLAN402El plan no incluye esto: waves, órdenes pendientes, cuentas always-on. Nombra los planes que sí lo incluyen. Reducir lo que ya tienes nunca se rechaza.No. Cambia de plan.
CREDIT_LIMIT402Conectar una cuenta, reconectar una, cambiar una a always_on, o suscribir, reanudar o restablecer un seguidor de copy trading llevaría el uso de un plan por cuenta más allá de su precio —cuentas por encima de las incluidas, cuentas always-on, seguidores por encima de los incluidos, contados por un mes completo— por encima de lo que el workspace puede tener ahora: el precio mensual del plan (Production: $99), más lo que pagó en renovaciones y cargos por uso en los últimos 90 días. El mensaje dice el límite y dónde estás. No se cambia nada de lo que ya está corriendo, y bajar un modo nunca se rechaza. Los acuerdos Enterprise definen el suyo.No. Crece a medida que se procesan los pagos; o quita una cuenta de always-on o desconecta una, o contáctanos para ampliarlo.
WORKSPACE_BUSY503Otro cambio en las cuentas de este workspace seguía en curso después de 10 segundos, así que este no se inicióSí, en breve.
PAYMENT_OVERDUE402No se pudo cobrar un cargo por uso (rechazado durante una semana, o no confirmado con tu banco en un mes), así que la apertura está en pausa: órdenes de apertura, órdenes multicuenta, conexión de cuentas nuevas y cambio a always_on. Cerrar posiciones, cancelar órdenes y mover stops nunca se rechaza, y una cuenta desconectada se puede volver a conectar (no como always-on) para cerrar lo que tiene.No. Págalo en Billing (vuelve a intentar con la tarjeta, o confírmalo con tu banco); la apertura se reanuda en cuanto se paga.

Facturación

CódigoEstadoCausa¿Reintentar?
BILLING_NEEDS_THE_OWNER403El plan lo cambia el owner del workspace, con sesión iniciada; nunca con una API keyNo.
PLAN_NOT_PURCHASABLE400Free, la prueba, Enterprise, un plan que ya no se vende (Starter, Scale) o un plan desconocido no se pueden comprar por checkout, ya sea como primera compra, como cambio de plan o como nuevo pago del plan en el que estásNo. Elige un plan de GET /v1/plans.
CONTRACT_PLAN409El workspace está en un plan por contrato, que se cambia hablando con nosotrosNo.
ALREADY_ON_PLAN409Ya pagas ese plan con tarjetaNo.
REDUCE_USAGE_FIRST409Cambiar a un plan cuyo cupo de uso es menor de lo que el workspace usa ahora (cuentas always-on, cuentas por encima de las que incluye el nuevo plan). El mensaje dice qué reducir. No se inició nada.Después de reducirlo: cambia cuentas a warm-on-demand o desconecta algunas.
CARD_SUBSCRIPTION_ACTIVE409Pagas con tarjeta; cancélalo antes de pagar con criptoNo.
CRYPTO_PERIOD_RUNNING409Hay un mes pagado con cripto en curso; cambia a tarjeta cuando termineCuando termine.
DOWNGRADE_AT_PERIOD_END409Un plan más barato con cripto se compra cuando termina el mes en cursoCuando termine.
NOTHING_TO_CANCEL409No hay plan de pagoNo.
COIN_NOT_ACCEPTED400Esa moneda no se ofrece; consulta GET /v1/billing/crypto/coinsNo. Elige otra.
BELOW_COIN_MINIMUM409El precio está por debajo del mínimo de NOWPayments para esa moneda, así que llegaría incompletoNo. Elige otra moneda.
CARD_UNAVAILABLE / CRYPTO_UNAVAILABLE503Ese método de pago no está abierto en este servidor: no está configurado o, en el caso de cripto, está desactivado (paga con tarjeta).No.
NO_ANNUAL_PRICE400Ese plan solo se factura mensualmenteNo. Elige mensual.
NO_AGREEMENT404Pagar un acuerdo: este workspace no tiene ningunoNo.
PAID_BY_TRANSFER409El acuerdo se factura y se paga por transferencia, no con tarjetaNo.
ALREADY_PAYING409El acuerdo ya se paga con tarjetaNo.
NOT_CANCELLING409Deshacer una cancelación cuando no hay ninguna programadaNo.
PROVIDER_REFUSED409El proveedor de la tarjeta no aceptó deshacer una cancelaciónNo. Contáctanos.
SUBSCRIPTION_LIVE409Canjear un cupón mientras pagas un plan: cancela primero esa suscripciónNo.
PLAN_ARRANGED409Canjear un cupón en un workspace con un plan acordado con nosotrosNo. Escríbenos.
CHECKOUT_PENDING409Canjear un cupón mientras se está configurando un pago con tarjeta de un plan para este workspaceDespués de terminar ese pago, o cuando venza (un día).
CHECKOUT_LIMIT429Demasiados checkouts iniciados en las últimas 24 horas: 5 por workspace, 10 por correo del owner del workspaceDespués de 24 horas, o contáctanos.
PROVIDER_ERROR503El proveedor de pagos rechazó o falló; no se cobró nada aquíSí, en breve.
COUPON_INVALID400Ese código no existe, venció o ya se agotóNo.
TOO_MANY_ATTEMPTS429Demasiados códigos incorrectos en la última hora, o se volvió a intentar la tarjeta para un cargo por uso 3 veces en la última horaDespués de una hora.

Instrumentos

CódigoEstadoCausa¿Reintentar?
UNKNOWN_INSTRUMENT400Una orden nombró un instrument que no está en GET /v1/instrumentsNo. Nombra un instrumento de la lista, o envía el symbol del broker.
INSTRUMENT_NOT_OFFERED422El broker de esta cuenta no ofrece el instrumento. No se envió nada.No.
INSTRUMENT_AMBIGUOUS422El broker tiene más de un símbolo plausible para él; details los lista. No se envió nada.No. Envía el que quieras como symbol.
SYMBOLS_NOT_SYNCED409La cuenta nunca ha estado en línea, así que todavía no se conocen los símbolos de su brokerSí, cuando la cuenta haya estado en línea.
SESSIONS_NOT_SYNCED409En GET /v1/accounts/{id}/sessions: todavía no se ha leído el horario de mercado de la cuenta. Se lee más o menos un minuto después de que se pone en línea por primera vez.Sí, en breve.
SYMBOL_NOT_FOUND404En GET /v1/accounts/{id}/sessions o /candles: el broker de la cuenta no tiene ese símboloNo. Revisa GET /v1/accounts/{id}/symbols.
SYMBOLS_UNAVAILABLE503En POST /v1/accounts/{id}/symbols/sync: la terminal no listó sus símbolos. La lista anterior no cambia.Sí, en breve.

Órdenes multicuenta

CódigoEstadoCausa¿Reintentar?
WAVE_ALREADY_RELEASING409Cancelar una orden multicuenta cuyas órdenes ya empezaron a salirNo. Cierra las posiciones resultantes en su lugar.
INSTRUMENT_UNAVAILABLE422Una orden multicuenta nombró un instrument que una o más de sus cuentas no pueden operar. details lista cada cuenta con code (INSTRUMENT_NOT_OFFERED, INSTRUMENT_AMBIGUOUS con candidates, o SYMBOLS_NOT_SYNCED) y message. No se colocó nada.No. Deja fuera esas cuentas, pon en línea una vez una cuenta nunca sincronizada, o envía symbol.

Copy trading

CódigoEstadoCausa¿Reintentar?
COPY_STRATEGY_NOT_FOUND404No existe esa estrategia en este workspace.No.
COPY_SUBSCRIPTION_NOT_FOUND404No existe esa suscripción en este workspace.No.
MASTER_NOT_ALWAYS_ON409Crear una estrategia a partir de una cuenta que no es always_on. Una cuenta maestra operada a mano nunca envía una orden a fxapis, así que el desconectador por inactividad la detendría.No. Cambia primero su modo con POST /v1/accounts/{id}/mode.
NETTING_NOT_SUPPORTED409La cuenta maestra o la seguidora es una cuenta netting. El copy trading copia solo entre cuentas hedging.No.
STRATEGY_EXISTS409Esta cuenta ya es una estrategia.No.
ACCOUNT_IS_FOLLOWER409Crear una estrategia a partir de una cuenta que ya sigue a otra. Una cuenta no puede copiar y ser copiada.No. Elimina primero esa suscripción.
ACCOUNT_IS_MASTER409Suscribir, o reanudar una suscripción en, una cuenta que es la maestra de una estrategia; o sacar de always_on a la maestra de una estrategia (POST /v1/accounts/{id}/mode) antes de archivar la estrategia.No.
MODE_CHANGE_CONFLICT409POST /v1/accounts/{id}/mode mientras otros cambios a la misma cuenta seguían llegando primero. Muy raro.Sí, después de leer la cuenta.
FOLLOWER_IS_MASTER409Suscribir una cuenta a su propia estrategia.No.
SUBSCRIPTION_EXISTS409Esta cuenta ya sigue esta estrategia.No.
SUBSCRIPTIONS_ACTIVE409Archivar una estrategia que una o más suscripciones todavía copian.No. Pausa o elimina primero esas suscripciones.
STRATEGY_ARCHIVED409Suscribirse a una estrategia archivada, o reanudarla.No.
SUBSCRIPTION_STOPPED409Cambiar la configuración o el estado de una suscripción que un límite de riesgo detuvo.No. Restablécela primero con POST /v1/copy/subscriptions/{id}/reset.
COPY_TRADING_PAUSED503Crear una estrategia, suscribir, reanudar una estrategia o una suscripción, o restablecer una mientras el copy trading está en pausa en este servidor (antes de un mantenimiento programado). Leer, cambiar la configuración, pausar y eliminar siguen funcionando; GET /v1/copy/status dice si está en pausa.Sí, cuando GET /v1/copy/status responda paused: false.
SUBSCRIPTION_DELETING409Cambiar o restablecer una suscripción que se está eliminando (todavía se están cerrando sus posiciones).No. Vuelve a eliminarla para reintentar los cierres que fallaron; se quita cuando terminan.
NOT_STOPPED409Restablecer una suscripción que no está stopped.No.
SUBSCRIPTION_CHANGED409La configuración de un PATCH se combinó con una versión de la suscripción que cambió mientras tanto.Sí: consúltala e inténtalo de nuevo.

Ninguno de estos se puede reintentar tal como se envió: cada uno nombra algo de la estrategia, la suscripción o la cuenta que la propia solicitud debe cambiar primero.

Hooks de alertas de TradingView

La URL del hook los devuelve a TradingView, y quedan registrados en el log del hook.

CódigoEstadoCausa¿Reintentar?
HOOK_LIMIT409Crear un hook cuando el workspace ya tiene 25No. Elimina uno que ya no uses.
HOOK_DISABLED409El hook está en pausa, o la API key que lo creó fue revocada y el hook se detuvo con ellaNo. Reanúdalo; para el hook de una clave revocada, crea un hook nuevo.
INVALID_ALERT400El mensaje de la alerta no se pudo leer como una ordenNo. Corrige el mensaje de la alerta.
SENDER_NOT_ALLOWED403El hook solo acepta las direcciones de webhook de TradingView, y esto vino de otro lugarNo.
RATE_LIMITED429Más de 30 alertas a un hook en un minutoNo: TradingView no reintenta.

Webhooks y eventos

CódigoEstadoCausa¿Reintentar?
EVENT_NOT_IN_HISTORY400El id de evento de after es más antiguo de lo que guarda el historial de eventos de tu plan, o no es de este workspace.No. Reanuda con since, y concilia el estado más antiguo desde la API REST.
EVENT_NOT_FOUND404No existe ese evento en tu historial de eventos; o, para reenviar, ninguno que se haya enviado a este endpoint o que este endpoint reciba.No.
DELIVERY_NOT_FOUND404No existe ese intento de entrega a este endpoint en los últimos 30 días.No.
WEBHOOK_LIMIT409El workspace ya tiene 10 endpoints de webhooks.No. Elimina uno que ya no uses.
WEBHOOK_DISABLED409El endpoint está desactivado o en pausa, así que no se puede probar ni reenviarle eventos.No. Actívalo primero.

Consola, claves y miembros

CódigoEstadoCausa¿Reintentar?
UNTRUSTED_ORIGIN403Una solicitud que cambia el estado llevó la sesión de un miembro desde un sitio que no es la consolaNo.
KEY_LIMIT409El workspace ya tiene 50 claves sin revocar (las vencidas cuentan hasta que se revocan). No confundir con KEY_LIMIT_EXCEEDED (403), los límites de trading propios de una clave.No. Revoca una.
KEY_REVOKED409Una clave revocada no se puede renombrar ni cambiar de alcanceNo. Crea una nueva.
MEMBERS_NEED_A_PERSON403A los miembros los gestiona un owner o admin con sesión iniciada, nunca una API keyNo.
NOT_ALLOWED403Tu rol no puede hacerle eso a ese miembroNo.
ALREADY_MEMBER409Esa dirección ya está en este workspaceNo.
EMAIL_IN_USE409Esa dirección tiene una cuenta de fxapis, así que no se puede invitarNo.
ALREADY_ACCEPTED409La invitación ya se usó; quita al miembro en su lugarNo.
INVITATION_INVALID404Cualquier enlace de invitación que no sea válido: falsificado, usado, retirado, vencidoNo. Pide uno nuevo.
INVITATION_CLOSED409Volver a enviar una invitación que se usó, se retiró o vencióNo. Invita de nuevo.
PASSWORD_BREACHED400Registrarse o aceptar una invitación con una contraseña encontrada en filtraciones de datos conocidasNo. Elige otra contraseña.
EMAIL_UNAVAILABLE / INVITATIONS_UNAVAILABLE503El correo o las invitaciones no están configurados en este servidor; copia el enlace de invitación en su lugarNo.
TOO_SOON429La invitación se envió hace menos de un minutoSí, después de un minuto.
STEP_UP_REQUIRED403Un cambio sensible desde una sesión de la consola que no confirmó que es su dueño en las últimas dos horas (diez minutos en la consola del staff). details[0].method es totp o password. Nunca se responde a una API key.Sí, después de POST /v1/session/step-up (la consola lo hace por ti).
STEP_UP_INVALID400El código (un código de la app de autenticación, o un código de respaldo, cada uno de un solo uso) o la contraseña dados para confirmar eran incorrectos, o faltabanSí, con el correcto.
STEP_UP_LOCKED429Demasiadas confirmaciones incorrectas: la pausa de inicio de sesión de la cuenta para una contraseña, la pausa propia del código para un código o, al volver a entrar a la consola del staff, más de cinco intentos por minuto desde una sesiónSí, después de retry-after.
STEP_UP_UNAVAILABLE503No se pudo contabilizar el reingreso a la consola del staff, así que no se comprobóSí, en un minuto.
MEMBER_INACTIVE403No se puede crear una clave a nombre de un miembro al que se quitó, se suspendió o se hizo member mientras se creabaNo.
SESSION_ONLY403Las sesiones y las confirmaciones pertenecen a una persona con sesión iniciada; una API key no tieneNo.
SESSION_NOT_FOUND404No existe esa sesión tuyaNo.
CANNOT_REVOKE_CURRENT409Terminar la sesión que estás usando es cerrar sesiónNo. Cierra sesión en su lugar.
ADMIN_KEY_REQUIRED403Una API key normal llamó a /v1/api-keys. Gestionar claves requiere una clave de administrador (fx_admin_…) o la consola.No.
ADMIN_KEY_NOT_ALLOWED403Una clave de administrador llamó a una ruta de /v1 distinta de /v1/api-keys. Gestiona claves y nada más; fuera de /v1 (incluido /mcp) recibe 401 UNAUTHENTICATED.No. Usa una clave normal.
ADMIN_KEY_IP_NOT_ALLOWED403La clave de administrador no acepta solicitudes desde la dirección de la que vino esta.No. Llama desde una dirección permitida, o pide al owner una clave que la permita.
ADMIN_KEY_EXPIRED401La clave de administrador pasó su fecha de vencimiento.No. El owner crea una nueva.
ADMIN_KEY_LIMIT409El workspace ya tiene cinco claves de administrador activas.No. Revoca una.
OWNER_ONLY403Solo el owner del workspace, con sesión iniciada en la consola, crea o revoca claves de administrador.No.

El inicio de sesión en sí (/auth, que usa la consola) responde con su propia forma, { code, message }:

CódigoEstadoCausa
SIGN_IN_LOCKED429Diez contraseñas incorrectas para esta cuenta en 15 minutos; en pausa 15 minutos (retry-after). Restablecer la contraseña la quita.
CHALLENGE_REQUIRED / CHALLENGE_FAILED403Pasa la verificación humana (siteKey la nombra) y envía su token en x-turnstile-token.
TWO_FACTOR_CODE_REQUIRED400Desactivar la verificación en dos pasos, o generar nuevos códigos de respaldo, necesita el código actual (o un código de respaldo) además de la contraseña.
TOTP_ALREADY_ENABLED400La verificación en dos pasos ya está activada; desactívala antes de configurar una app nueva.
TOO_MANY_ATTEMPTS429Más de cinco comprobaciones de contraseña por minuto para una persona (cambiar la contraseña, activar o desactivar la verificación en dos pasos, nuevos códigos de respaldo). No pausa el inicio de sesión.
TOTP_URI_NOT_OFFERED / CODE_CHECK_NOT_OFFERED403La clave de configuración se muestra una vez, al configurar; los códigos se comprueban al iniciar sesión o cuando la consola te pide confirmar.
TRUST_DEVICE_NOT_OFFERED400fxapis pide un código en cada inicio de sesión.

Ciclo de vida

CódigoEstadoCausa¿Reintentar?
NEEDS_OPERATOR409La cuenta está en un estado que una persona debe corregir: contraseña incorrecta, 2FA, certificado, trading desactivadoNo. Consulta abajo.
NO_SECRET409No hay credencial guardada. La cuenta se desconectó, o la creación falló a medias.No. Vuelve a conectarla.
ACCOUNT_EXECUTING409Hay una orden en curso, y desconectar la cuenta ahora dejaría su resultado inciertoSí, cuando la orden se resuelva.
ACCOUNT_LEASED_ELSEWHERE409Otra solicitud ya está poniendo en línea o desconectando la cuenta. El trading no se ve afectado.Sí, en un momento.
SCHEDULER_FAILED503No pudimos poner la cuenta en línea. Es nuestro, no tuyo.Sí, con backoff.
RESTART_FAILED503La cuenta se desconectó pero no volvió a ponerse en líneaSí, con backoff.
INTERNAL_ERROR500Inesperado. Ya está registrado de nuestro lado con tu requestId.Sí, con backoff.

NEEDS_OPERATOR merece énfasis. No lo reintentes, y no lo metas en un bucle con backoff. Los inicios de sesión fallidos repetidos son la forma en que un broker bloquea una cuenta, y en ese punto corregir la contraseña ya no basta. Muéstraselo a quien sea dueño de las credenciales.

Reintentar

Decide por code, no por estado. Reintenta 500, y un 503 cuyo code no sea ORDER_UNRESOLVED, con backoff exponencial y jitter. Nunca reintentes ORDER_UNRESOLVED: consulta la orden. No reintentes 4xx, salvo 429 después de su retry-after; nada más de la solicitud habrá mejorado. Tampoco reintentes 501 CAPABILITY_UNAVAILABLE: la respuesta solo cambia cuando se actualiza la terminal de la cuenta.

Por qué 503 y no 502. Cada fallo que es nuestro y no tuyo —SEND_FAILED, ORDER_UNRESOLVED, SCHEDULER_FAILED, RESTART_FAILED, PROVIDER_ERROR— responde 503 con el cuerpo JSON. Hasta el 3 de octubre de 2026 eran 502, y la capa de red frente a la API reemplazaba el cuerpo de cada 502 con su propio texto, así que un cliente no podía distinguir un reenvío seguro de uno que nunca debe ocurrir. Si ramificabas según 502, ramifica según code.

import random, time

def retryable(response):
    if response.status_code == 500:
        return True
    if response.status_code == 503:
        # SEND_FAILED is proven never to have reached the broker. ORDER_UNRESOLVED
        # may have executed: poll the order, never resend.
        return response.json().get("error", {}).get("code") != "ORDER_UNRESOLVED"
    return False

def call_with_retry(send, attempts=5):
    # For an order, `send` must carry the same Idempotency-Key on every attempt.
    for attempt in range(attempts):
        response = send()
        if not retryable(response):
            return response
        if attempt == attempts - 1:
            return response
        # Jitter, not a fixed schedule: every client backing off in lockstep
        # arrives together and reproduces the load that caused the failure.
        time.sleep(min(2 ** attempt, 30) * (0.5 + random.random()))
    raise AssertionError("unreachable")

En una orden, send debe llevar el mismo Idempotency-Key en cada intento; y el jitter evita que todos los clientes que esperan al mismo ritmo vuelvan juntos y reproduzcan la carga que causó el fallo.

Incluso un ORDER_UNRESOLVED reintentado es inofensivo cuando lleva el mismo Idempotency-Key: la clave sigue reclamada y vuelve la misma respuesta. Lo que nunca debe ocurrir es un reenvío con una clave nueva.

Los 503 del ciclo de vida —SCHEDULER_FAILED, RESTART_FAILED— no involucran ninguna orden y también se pueden reintentar con backoff sin riesgo.

warm (poner en línea) se puede reintentar tal cual sin riesgo: una segunda llamada a una cuenta que ya está en línea devuelve alreadyRunning: true.

Enviar órdenes no es seguro de reintentar a ciegas. Envía un Idempotency-Key con cada orden: un reintento con la misma clave devuelve el primer resultado en lugar de abrir una segunda operación. Reintentar sin una es el único lugar de esta API donde un reintento descuidado cuesta dinero.

Cuando el error es el estado, no el código HTTP

Un 202 de warm significa que aceptamos el trabajo, no que tuvo éxito. El inicio de sesión todavía puede fallar después, y lo informa a través del estado de la cuenta, no de un código HTTP que ya nadie está escuchando.

Consulta GET /v1/accounts/{id}/status y trata invalid_credentials, needs_2fa, needs_certificate y trading_disabled como fallos. Cuentas y ciclo de vida tiene un bucle de consulta que maneja esto correctamente.

En esta página