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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
UNAUTHENTICATED | 401 | Clave 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_SCOPE | 403 | Clave válida, alcance equivocado. Nombra el alcance que necesita. | No. Emite una clave con ese alcance. |
KEY_LIMIT_EXCEEDED | 403 | Los 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:
| Respuesta | Significado |
|---|---|
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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
INVALID_REQUEST | 400 | El 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_FOUND | 404 | No 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_FOUND | 404 | No existe esa cuenta para tu tenant | No. |
POSITION_NOT_FOUND | 404 | No existe esa posición abierta en esa cuenta; normalmente ya está cerrada | No. Lee las posiciones de la cuenta. |
ORDER_NOT_FOUND | 404 | No existe esa orden para tu tenant | No. |
WAVE_NOT_FOUND | 404 | No existe esa orden multicuenta para tu tenant | No. |
RATE_LIMITED | 429 | Demasiadas 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.
| Clase | Qué cubre | Límite |
|---|---|---|
| Trading | Órdenes, cierres, cambios de stops, cancelaciones | El 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 multicuenta | Crear y cancelar órdenes multicuenta | 10 por minuto + 2 |
| Lecturas | Cada GET | 600 por minuto + 100 |
| Lecturas en vivo | GET …/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 escrituras | Todo lo demás | 120 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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
ACCOUNT_EXISTS | 409 | Ese login + server ya está conectado en tu workspace | No. Usa la cuenta existente: su id está en details. Para cambiar su contraseña, POST /v1/accounts/{id}/password. |
SECRET_STORE_UNAVAILABLE | 503 | No se pudo guardar la credencial, así que la cuenta no se creó | Sí, con backoff. |
ACCOUNT_EXECUTING | 409 | En POST /v1/accounts/{id}/password o DELETE /v1/accounts/{id}: hay una orden en curso, así que no se cambió nada | Sí, cuando la orden se resuelva. |
ACCOUNT_HAS_POSITIONS | 409 | En 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_PASSWORD | 409 | En 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_ONLY | 402 | En una prueba: no se conecta una cuenta real; la prueba, de cualquier plan, es para cuentas demo | No. Paga el plan para conectar cuentas reales. |
TRIAL_ACCOUNT_USED | 402 | En una prueba: ese login demo ya se usó en otra prueba | No. Usa otra cuenta demo, o elige un plan. |
ACCOUNT_CHANGED | 409 | En 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_WAVE | 409 | En 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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
SEND_FAILED | 503 | Demostrado que nunca llegó al broker | Sí. El único reenvío seguro. |
ORDER_REJECTED | 422 | El broker la rechazó, con un motivo y su propio retcode | Solo si retryable es true |
NO_PRICE | 422 | El 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_UNRESOLVED | 503 | No sabemos si se ejecutó | Nunca. Consulta la orden. |
IDEMPOTENCY_KEY_REUSED | 409 | Esa clave se usó para una orden distinta | No. Usa una clave nueva. |
IDEMPOTENCY_IN_FLIGHT | 409 | La primera solicitud con esa clave sigue en curso | Sí, en breve. |
TRADING_DISABLED | 409 | El trading está desactivado para la cuenta, o para todo el workspace por su interruptor de emergencia, cierres incluidos | No. |
ACCOUNT_NOT_READY | 409 | La 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á ready | Consulta su estado; reintenta cuando esté ready. No si requiere atención. |
NO_RUNTIME | 409 | La 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 orden | Reinicia la cuenta, o ponla en línea. |
MT5_UNAVAILABLE | 503 | En /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_UNAVAILABLE | 501 | En /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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
QUOTA_EXCEEDED | 402 | Abrir 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_USED | 409 | Ya 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_PLAN | 402 | El 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_LIMIT | 402 | Conectar 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_BUSY | 503 | Otro 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_OVERDUE | 402 | No 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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
BILLING_NEEDS_THE_OWNER | 403 | El plan lo cambia el owner del workspace, con sesión iniciada; nunca con una API key | No. |
PLAN_NOT_PURCHASABLE | 400 | Free, 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ás | No. Elige un plan de GET /v1/plans. |
CONTRACT_PLAN | 409 | El workspace está en un plan por contrato, que se cambia hablando con nosotros | No. |
ALREADY_ON_PLAN | 409 | Ya pagas ese plan con tarjeta | No. |
REDUCE_USAGE_FIRST | 409 | Cambiar 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_ACTIVE | 409 | Pagas con tarjeta; cancélalo antes de pagar con cripto | No. |
CRYPTO_PERIOD_RUNNING | 409 | Hay un mes pagado con cripto en curso; cambia a tarjeta cuando termine | Cuando termine. |
DOWNGRADE_AT_PERIOD_END | 409 | Un plan más barato con cripto se compra cuando termina el mes en curso | Cuando termine. |
NOTHING_TO_CANCEL | 409 | No hay plan de pago | No. |
COIN_NOT_ACCEPTED | 400 | Esa moneda no se ofrece; consulta GET /v1/billing/crypto/coins | No. Elige otra. |
BELOW_COIN_MINIMUM | 409 | El precio está por debajo del mínimo de NOWPayments para esa moneda, así que llegaría incompleto | No. Elige otra moneda. |
CARD_UNAVAILABLE / CRYPTO_UNAVAILABLE | 503 | Ese 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_PRICE | 400 | Ese plan solo se factura mensualmente | No. Elige mensual. |
NO_AGREEMENT | 404 | Pagar un acuerdo: este workspace no tiene ninguno | No. |
PAID_BY_TRANSFER | 409 | El acuerdo se factura y se paga por transferencia, no con tarjeta | No. |
ALREADY_PAYING | 409 | El acuerdo ya se paga con tarjeta | No. |
NOT_CANCELLING | 409 | Deshacer una cancelación cuando no hay ninguna programada | No. |
PROVIDER_REFUSED | 409 | El proveedor de la tarjeta no aceptó deshacer una cancelación | No. Contáctanos. |
SUBSCRIPTION_LIVE | 409 | Canjear un cupón mientras pagas un plan: cancela primero esa suscripción | No. |
PLAN_ARRANGED | 409 | Canjear un cupón en un workspace con un plan acordado con nosotros | No. Escríbenos. |
CHECKOUT_PENDING | 409 | Canjear un cupón mientras se está configurando un pago con tarjeta de un plan para este workspace | Después de terminar ese pago, o cuando venza (un día). |
CHECKOUT_LIMIT | 429 | Demasiados checkouts iniciados en las últimas 24 horas: 5 por workspace, 10 por correo del owner del workspace | Después de 24 horas, o contáctanos. |
PROVIDER_ERROR | 503 | El proveedor de pagos rechazó o falló; no se cobró nada aquí | Sí, en breve. |
COUPON_INVALID | 400 | Ese código no existe, venció o ya se agotó | No. |
TOO_MANY_ATTEMPTS | 429 | Demasiados códigos incorrectos en la última hora, o se volvió a intentar la tarjeta para un cargo por uso 3 veces en la última hora | Después de una hora. |
Instrumentos
| Código | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
UNKNOWN_INSTRUMENT | 400 | Una orden nombró un instrument que no está en GET /v1/instruments | No. Nombra un instrumento de la lista, o envía el symbol del broker. |
INSTRUMENT_NOT_OFFERED | 422 | El broker de esta cuenta no ofrece el instrumento. No se envió nada. | No. |
INSTRUMENT_AMBIGUOUS | 422 | El 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_SYNCED | 409 | La cuenta nunca ha estado en línea, así que todavía no se conocen los símbolos de su broker | Sí, cuando la cuenta haya estado en línea. |
SESSIONS_NOT_SYNCED | 409 | En 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_FOUND | 404 | En GET /v1/accounts/{id}/sessions o /candles: el broker de la cuenta no tiene ese símbolo | No. Revisa GET /v1/accounts/{id}/symbols. |
SYMBOLS_UNAVAILABLE | 503 | En POST /v1/accounts/{id}/symbols/sync: la terminal no listó sus símbolos. La lista anterior no cambia. | Sí, en breve. |
Órdenes multicuenta
| Código | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
WAVE_ALREADY_RELEASING | 409 | Cancelar una orden multicuenta cuyas órdenes ya empezaron a salir | No. Cierra las posiciones resultantes en su lugar. |
INSTRUMENT_UNAVAILABLE | 422 | Una 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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
COPY_STRATEGY_NOT_FOUND | 404 | No existe esa estrategia en este workspace. | No. |
COPY_SUBSCRIPTION_NOT_FOUND | 404 | No existe esa suscripción en este workspace. | No. |
MASTER_NOT_ALWAYS_ON | 409 | Crear 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_SUPPORTED | 409 | La cuenta maestra o la seguidora es una cuenta netting. El copy trading copia solo entre cuentas hedging. | No. |
STRATEGY_EXISTS | 409 | Esta cuenta ya es una estrategia. | No. |
ACCOUNT_IS_FOLLOWER | 409 | Crear 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_MASTER | 409 | Suscribir, 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_CONFLICT | 409 | POST /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_MASTER | 409 | Suscribir una cuenta a su propia estrategia. | No. |
SUBSCRIPTION_EXISTS | 409 | Esta cuenta ya sigue esta estrategia. | No. |
SUBSCRIPTIONS_ACTIVE | 409 | Archivar una estrategia que una o más suscripciones todavía copian. | No. Pausa o elimina primero esas suscripciones. |
STRATEGY_ARCHIVED | 409 | Suscribirse a una estrategia archivada, o reanudarla. | No. |
SUBSCRIPTION_STOPPED | 409 | Cambiar 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_PAUSED | 503 | Crear 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_DELETING | 409 | Cambiar 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_STOPPED | 409 | Restablecer una suscripción que no está stopped. | No. |
SUBSCRIPTION_CHANGED | 409 | La 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ódigo | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
HOOK_LIMIT | 409 | Crear un hook cuando el workspace ya tiene 25 | No. Elimina uno que ya no uses. |
HOOK_DISABLED | 409 | El hook está en pausa, o la API key que lo creó fue revocada y el hook se detuvo con ella | No. Reanúdalo; para el hook de una clave revocada, crea un hook nuevo. |
INVALID_ALERT | 400 | El mensaje de la alerta no se pudo leer como una orden | No. Corrige el mensaje de la alerta. |
SENDER_NOT_ALLOWED | 403 | El hook solo acepta las direcciones de webhook de TradingView, y esto vino de otro lugar | No. |
RATE_LIMITED | 429 | Más de 30 alertas a un hook en un minuto | No: TradingView no reintenta. |
Webhooks y eventos
| Código | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
EVENT_NOT_IN_HISTORY | 400 | El 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_FOUND | 404 | No 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_FOUND | 404 | No existe ese intento de entrega a este endpoint en los últimos 30 días. | No. |
WEBHOOK_LIMIT | 409 | El workspace ya tiene 10 endpoints de webhooks. | No. Elimina uno que ya no uses. |
WEBHOOK_DISABLED | 409 | El endpoint está desactivado o en pausa, así que no se puede probar ni reenviarle eventos. | No. Actívalo primero. |
Consola, claves y miembros
| Código | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
UNTRUSTED_ORIGIN | 403 | Una solicitud que cambia el estado llevó la sesión de un miembro desde un sitio que no es la consola | No. |
KEY_LIMIT | 409 | El 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_REVOKED | 409 | Una clave revocada no se puede renombrar ni cambiar de alcance | No. Crea una nueva. |
MEMBERS_NEED_A_PERSON | 403 | A los miembros los gestiona un owner o admin con sesión iniciada, nunca una API key | No. |
NOT_ALLOWED | 403 | Tu rol no puede hacerle eso a ese miembro | No. |
ALREADY_MEMBER | 409 | Esa dirección ya está en este workspace | No. |
EMAIL_IN_USE | 409 | Esa dirección tiene una cuenta de fxapis, así que no se puede invitar | No. |
ALREADY_ACCEPTED | 409 | La invitación ya se usó; quita al miembro en su lugar | No. |
INVITATION_INVALID | 404 | Cualquier enlace de invitación que no sea válido: falsificado, usado, retirado, vencido | No. Pide uno nuevo. |
INVITATION_CLOSED | 409 | Volver a enviar una invitación que se usó, se retiró o venció | No. Invita de nuevo. |
PASSWORD_BREACHED | 400 | Registrarse o aceptar una invitación con una contraseña encontrada en filtraciones de datos conocidas | No. Elige otra contraseña. |
EMAIL_UNAVAILABLE / INVITATIONS_UNAVAILABLE | 503 | El correo o las invitaciones no están configurados en este servidor; copia el enlace de invitación en su lugar | No. |
TOO_SOON | 429 | La invitación se envió hace menos de un minuto | Sí, después de un minuto. |
STEP_UP_REQUIRED | 403 | Un 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_INVALID | 400 | El 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 faltaban | Sí, con el correcto. |
STEP_UP_LOCKED | 429 | Demasiadas 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ón | Sí, después de retry-after. |
STEP_UP_UNAVAILABLE | 503 | No se pudo contabilizar el reingreso a la consola del staff, así que no se comprobó | Sí, en un minuto. |
MEMBER_INACTIVE | 403 | No se puede crear una clave a nombre de un miembro al que se quitó, se suspendió o se hizo member mientras se creaba | No. |
SESSION_ONLY | 403 | Las sesiones y las confirmaciones pertenecen a una persona con sesión iniciada; una API key no tiene | No. |
SESSION_NOT_FOUND | 404 | No existe esa sesión tuya | No. |
CANNOT_REVOKE_CURRENT | 409 | Terminar la sesión que estás usando es cerrar sesión | No. Cierra sesión en su lugar. |
ADMIN_KEY_REQUIRED | 403 | Una API key normal llamó a /v1/api-keys. Gestionar claves requiere una clave de administrador (fx_admin_…) o la consola. | No. |
ADMIN_KEY_NOT_ALLOWED | 403 | Una 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_ALLOWED | 403 | La 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_EXPIRED | 401 | La clave de administrador pasó su fecha de vencimiento. | No. El owner crea una nueva. |
ADMIN_KEY_LIMIT | 409 | El workspace ya tiene cinco claves de administrador activas. | No. Revoca una. |
OWNER_ONLY | 403 | Solo 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ódigo | Estado | Causa |
|---|---|---|
SIGN_IN_LOCKED | 429 | Diez contraseñas incorrectas para esta cuenta en 15 minutos; en pausa 15 minutos (retry-after). Restablecer la contraseña la quita. |
CHALLENGE_REQUIRED / CHALLENGE_FAILED | 403 | Pasa la verificación humana (siteKey la nombra) y envía su token en x-turnstile-token. |
TWO_FACTOR_CODE_REQUIRED | 400 | Desactivar 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_ENABLED | 400 | La verificación en dos pasos ya está activada; desactívala antes de configurar una app nueva. |
TOO_MANY_ATTEMPTS | 429 | Má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_OFFERED | 403 | La 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_OFFERED | 400 | fxapis pide un código en cada inicio de sesión. |
Ciclo de vida
| Código | Estado | Causa | ¿Reintentar? |
|---|---|---|---|
NEEDS_OPERATOR | 409 | La cuenta está en un estado que una persona debe corregir: contraseña incorrecta, 2FA, certificado, trading desactivado | No. Consulta abajo. |
NO_SECRET | 409 | No hay credencial guardada. La cuenta se desconectó, o la creación falló a medias. | No. Vuelve a conectarla. |
ACCOUNT_EXECUTING | 409 | Hay una orden en curso, y desconectar la cuenta ahora dejaría su resultado incierto | Sí, cuando la orden se resuelva. |
ACCOUNT_LEASED_ELSEWHERE | 409 | Otra solicitud ya está poniendo en línea o desconectando la cuenta. El trading no se ve afectado. | Sí, en un momento. |
SCHEDULER_FAILED | 503 | No pudimos poner la cuenta en línea. Es nuestro, no tuyo. | Sí, con backoff. |
RESTART_FAILED | 503 | La cuenta se desconectó pero no volvió a ponerse en línea | Sí, con backoff. |
INTERNAL_ERROR | 500 | Inesperado. 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úncode.
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.
Instrumentos y símbolos
Nombra un mercado una sola vez —XAUUSD, US30, BTCUSD— y opera el símbolo propio del broker de cada cuenta. Lista los símbolos, las especificaciones de contrato y el horario de mercado de cualquier broker conectado.
Seguridad
Cómo protegemos las credenciales de tu broker, tus claves y tus datos.