Formato de error#
Todos los errores de /api/dex/v1 tienen la misma forma JSON y un código HTTP acorde:
{
"success": false,
"error": {
"schema_version": "botradix-dex-error-v1",
"code": "SCOPE_NOT_ALLOWED",
"message": "…",
"retryable": false,
"details": {},
"request_id": "dxr_…"
},
"request_id": "dxr_…",
"api_version": "v1",
"api_schema_revision": "botradix-dex-api-v1.1"
}Usa error.code en tu lógica (los mensajes pueden cambiar) y guarda request_id si contactas con soporte. retryable: true indica que la misma petición puede funcionar más tarde.
Errores habituales#
| HTTP | Código | Significado |
|---|---|---|
| 400 | (códigos de validación) | Falta un campo, tiene un formato incorrecto o está fuera de rango. prepare valida el cuerpo antes que la clave |
| 400 | IDEMPOTENCY_KEY_REQUIRED | /orders/prepare necesita una clave de idempotencia válida |
| 401 | API_KEY_REQUIRED | No se envió clave de API |
| 401 | API_KEY_INVALID | La clave tiene un formato incorrecto o no es válida |
| 401 | API_KEY_INACTIVE | La clave está revocada o caducada |
| 403 | SCOPE_NOT_ALLOWED | La clave no tiene el scope que exige el endpoint o la acción |
| 403 | IP_NOT_ALLOWED | La IP de la petición no está en la lista permitida de la clave |
| 403 | delegated_executor_binding_required | La ejecución delegada necesita un ejecutor vinculado a la clave |
| 409 | IDEMPOTENCY_KEY_CONFLICT | La clave de idempotencia se usó con otros datos en las últimas 24 horas |
| 409 | DUPLICATE_CLIENT_ORDER_ID | El client_order_id se usó con otros datos |
| 409 | active_api_key_limit_reached | La wallet ya tiene 10 claves activas |
| 429 | RATE_LIMITED | Se superó un límite de la clave |
| 503 | REALTIME_STREAM_ASYNC_WORKER_REQUIRED | El stream SSE no está activado en este servicio |
Códigos de la versión 2.2#
| Código | Significado | Qué hacer |
|---|---|---|
COMMITTED_EXECUTOR_REQUIRED | En un mercado con reglas de riesgo V2, abrir, ampliar o invertir por la ruta delegada se ejecuta comprometido con un precio observado después de tu orden, y solo un ejecutor del protocolo puede hacerlo. Tu ejecutor no lo es | Usa el ejecutor de BotRadix vinculado a tu clave |
INVERT_NEEDS_AGENT | En un mercado con reglas de riesgo V2, la inversión no puede enviarse como transacción directa de la wallet | Actívala con tu clave de trading (o por la ruta delegada con un ejecutor del protocolo) |
INTENT_CREATED_AT_BEFORE_RECEPTION | La hora de compromiso de la orden es anterior a su recepción en el servicio (margen de 2 s); no se envía nada | Prepárala de nuevo |
WALLET_MARGIN_NEEDS_AGENT | Un mercado de tu cuenta cruzada tiene la sesión cerrada: el margen aislado sale de tu wallet, firmado por tu wallet o cofirmado por tu wallet junto a tu clave de trading. "Margen +" necesita la clave de trading | Activa la clave de trading y repite |
WALLET_MARGIN_NEEDS_WALLET_SIGNATURE | El margen desde tu wallet necesita la firma de tu wallet para esta operación; una sesión de trading no puede traerlo | Repite la operación y fírmala con tu wallet (o usa tu clave de trading, con la cofirma de tu wallet) |
WALLET_COSIGN_REQUIRED | Falta la cofirma de tu wallet para el margen desde tu wallet | Confirma de nuevo y firma con tu wallet |
WALLET_COSIGN_SIGNATURE_INVALID | La cofirma no corresponde a esta wallet o a esta operación; no se ha movido nada | Prepárala de nuevo; si se repite, escribe a support@botradix.com |
WALLET_COSIGN_INVALID | La cofirma preparada no coincide con la operación; no se ha movido nada | Prepárala de nuevo |
WALLET_MARGIN_BALANCE_REQUIRED | Con esa sesión cerrada, tu wallet no tiene USDC suficiente para el margen (y, en una apertura, las comisiones máximas y, en una orden limitada o stop, la fianza). details.wallet_margin_usdc indica el importe | Añade USDC a tu wallet o espera a que reabra la sesión |
LIQUIDITY_CAPACITY (también en /orders/execute) | El vault rechaza el riesgo: su cupo para este mercado y dirección está lleno, o una orden que se suma a una posición con take profit respaldado lo superaría (la vista previa no siempre lo anticipa). Desde la v2.2 la vía delegada lo responde con HTTP 400 en lugar de un 503 con VAULT_CAPACITY; details.max_open_usdc da el cupo cuando se puede estimar | Prueba el lado contrario, un importe menor o más tarde |
Al invertir junto a una posición neta del lado contrario con la misma clave, la respuesta puede devolver el id de esa neta: no hay DexPositionOpened, sino DexPositionChanged de la neta.
Por qué una acción preparada no se puede ejecutar#
Cuando prepare funciona pero execution.ready es false, execution.reason lo explica:
| Motivo | Significado |
|---|---|
withdraw_margin_insufficient | El retiro dejaría muy poco margen libre. Retira menos o cierra posiciones |
oracle_unavailable | Ahora mismo no hay un precio de mercado actual en cadena; inténtalo de nuevo en unos instantes |
funding_unavailable / funding_stale | Hay que actualizar el funding del mercado antes de abrir posiciones nuevas |
market_session_closed | El mercado está fuera de su sesión de negociación |
price_out_of_bounds | El precio se movió más allá de tu deslizamiento permitido; vuelve a preparar |
price_tick_rejected | El precio no coincide con el tick size del mercado |
contract_limits_rejected | La orden supera un límite del contrato (tamaño, apalancamiento) o ha caducado |
vault_capacity_unavailable | Ahora mismo no hay capacidad de liquidez suficiente para esta posición |
market_risk_paused | Las posiciones nuevas están pausadas en este mercado |
market_not_bound / dex_not_operational | El mercado aún no está habilitado para operar |
invalid_take_profit / invalid_stop_loss | El TP o el SL están en el lado equivocado del precio actual |
intent_expired | La preparación caducó; vuelve a preparar |
simulation_unavailable | La simulación previa no pudo ejecutarse; vuelve a preparar en un momento |
contract_preflight_failed | El contrato rechazaría la acción en las condiciones actuales |
Límites de uso#
Cada clave de API tiene sus propios límites, contados en ventanas de 60 segundos:
| Límite | Por defecto |
|---|---|
| Todas las peticiones | 3.600 por minuto |
/orders/prepare | 900 por minuto y 40 por segundo |
Lecturas de cuenta (/account, /positions…, /orders…, /collateral, /transactions, /trades, /orders/execute) | 3.000 por minuto |
/candles | 900 por minuto |
Las quotas propias de una clave se pueden fijar al crearla o rotarla, hasta estos máximos por minuto: peticiones 30.000, órdenes 12.000, ráfaga 1.000, lecturas de cuenta 20.000 y lecturas históricas 12.000.
Además de los límites por clave, el borde de red admite hasta 100 peticiones por segundo por IP (ráfagas de 200) y 60 por segundo por clave de API (ráfagas de 120). Esos rechazos son respuestas 429 simples, sin el cuerpo JSON.
Las respuestas incluyen X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (hora Unix en segundos en la que se reinicia la ventana) para el límite general de la clave. Las respuestas 429 no llevan Retry-After: espera de forma exponencial con algo de aleatoriedad (por ejemplo 1, 2, 4, 8 segundos).
Reintentos#
- Reintenta ante
429, ante5xxy cuandoerror.retryableseatrue, con espera exponencial. - Reutiliza la misma clave de idempotencia, con los mismos datos, al reintentar un
prepareo unexecute, para que una respuesta perdida no cree una segunda preparación ni una segunda orden. - Nunca reintentes a ciegas una transacción ya enviada: consulta antes
/transactionso/native/executions/{tx_hash}.
Cabeceras de respuesta#
| Cabecera | Valor |
|---|---|
X-BotRadix-API-Version | v1 |
X-BotRadix-API-Schema | botradix-dex-api-v1.1 |
X-Request-ID | Tu ID de petición, o uno generado por el servidor (dxr_…) |
Cache-Control | no-store |
Política de versionado#
/api/dex/v1es el contrato estable de integración. En v1 se pueden añadir campos y endpoints nuevos sin aviso; tu cliente debe ignorar los campos que no conozca.- Los cambios que romperían integraciones existentes se publican en una versión nueva.
GET /metadevuelve la revisión de esquema y las capacidades actuales.- Los endpoints sin versión que usa el terminal web (
/api/dex/…sinv1) pueden cambiar en cualquier momento.