GET /v1/fx/route
Consulta los 9 mercados disponibles (7 P2P + paralela + BCV) en paralelo y devuelve el mejor mercado para el monto pedido, junto con las alternativas ordenadas de mejor a peor.
Es el endpoint diferenciador de Pro. En lugar de que tu aplicación llame /v1/fx/rates y calcule el mejor precio manualmente, /v1/fx/route lo hace por ti con una sola llamada, incluyendo filtrado por frescura y motivos de descarte por mercado.
Disponible únicamente en el plan Pro y superiores. En planes inferiores devuelve 402 feature_not_in_plan.
Request
GET /v1/fx/route?from=USD&to=VES&amount=1000&direction=send HTTP/1.1
Host: api.cotizave.com
X-API-Key: ctz_live_aB3cD8fG2hJ5kL9mN1pQ4rS7tU0vWxYzA6bC3dQuery parameters
| Parámetro | Tipo | Requerido | Default | Descripción |
|---|---|---|---|---|
from | string | Sí | — | Moneda origen: USD o VES |
to | string | Sí | — | Moneda destino: VES o USD |
amount | number | Sí | — | Monto a convertir. Debe ser mayor a 0. |
direction | string | No | send | send: maximizar VES recibidos (el caller envía USD).receive: minimizar VES pagados (el caller compra USD). |
max_staleness | integer | No | 0 | Antigüedad máxima de una cotización en segundos. 0 = sin filtro. |
Ejemplos de request
Mejor mercado para enviar 1.000 USD:
curl "https://api.cotizave.com/v1/fx/route?from=USD&to=VES&amount=1000&direction=send" \ -H "X-API-Key: $COTIZAVE_API_KEY"
Mejor mercado para comprar USD pagando VES (con cotizaciones frescas, max 30 min):
curl "https://api.cotizave.com/v1/fx/route?from=VES&to=USD&amount=500000&direction=receive&max_staleness=1800" \
-H "X-API-Key: $COTIZAVE_API_KEY"Response
200 OK
{
"from": {
"currency": "USD",
"amount": 1000
},
"direction": "send",
"best": {
"market": "mexc",
"type": "p2p",
"rate": 649.02,
"amount": 649020.00,
"updated_at": "2026-04-08T17:28:00Z",
"staleness_sec": 87
},
"alternatives": [
{
"market": "bybit",
"type": "p2p",
"rate": 638.50,
"amount": 638500.00,
"updated_at": "2026-04-08T17:29:00Z",
"staleness_sec": 15
},
{
"market": "binance",
"type": "p2p",
"rate": 637.87,
"amount": 637870.00,
"updated_at": "2026-04-08T17:29:00Z",
"staleness_sec": 15
},
{
"market": "parallel",
"type": "parallel",
"rate": 638.87,
"amount": 638870.00,
"updated_at": "2026-04-08T17:25:00Z",
"staleness_sec": 255
}
],
"skipped": [
{
"market": "reference",
"reason": "no_quote"
}
],
"fetched_at": "2026-04-08T17:29:15Z"
}Schema de respuesta
| Campo | Tipo | Descripción |
|---|---|---|
from.currency | string | Moneda origen |
from.amount | number | Monto de entrada |
direction | string | send o receive (eco del parámetro) |
best | RouteOption | El mercado óptimo para la dirección pedida |
alternatives | RouteOption[] | Otros mercados elegibles, ordenados de mejor a peor |
skipped | SkippedMarket[] | omitido | Mercados descartados y motivo (omitido si vacío) |
fetched_at | string (ISO 8601) | Cuándo Cotizave armó la respuesta |
Schema de RouteOption
| Campo | Tipo | Descripción |
|---|---|---|
market | string | Identificador del mercado |
type | string | reference, parallel o p2p |
rate | number | Tasa mid (VES por USD) aplicada |
amount | number | Monto resultante en moneda destino usando este mercado |
updated_at | string (ISO 8601) | Cuándo se actualizó la cotización del mercado |
staleness_sec | integer | Antigüedad de la cotización en segundos al momento de la llamada |
Schema de SkippedMarket
| Campo | Tipo | Descripción |
|---|---|---|
market | string | Identificador del mercado descartado |
reason | string | no_quote: mid ≤ 0 (fuente sin cotización válida). stale: cotización más vieja que max_staleness. |
Cómo funciona direction
El parámetro direction define la perspectiva del ordenamiento:
send(default): el caller tiene USD y quiere maximizar los VES que recibe. Los mercados se ordenan por mid descendente. El mercado con la tasa más alta (más VES por dólar) es el mejor.receive: el caller tiene VES y quiere comprar USD pagando lo menos posible. Los mercados se ordenan por mid ascendente. El mercado con la tasa más baja (menos VES por dólar) es el mejor.
Casos de uso típicos
"¿Dónde conviene cambiar hoy?"
Muéstrale al usuario el mejor exchange ordenado por tasa con una sola llamada:
const res = await fetch(
'https://api.cotizave.com/v1/fx/route?from=USD&to=VES&amount=1000&direction=send',
{ headers: { 'X-API-Key': process.env.COTIZAVE_API_KEY } }
)
const data = await res.json()
console.log(`Mejor: ${data.best.market} — ${data.best.rate} Bs/USD`)
data.alternatives.slice(0, 3).forEach(alt => {
console.log(` ${alt.market}: ${alt.rate} Bs/USD`)
})Arbitraje automatizado
Identifica la mejor compra y la mejor venta entre mercados para calcular el margen de arbitraje:
const [send, receive] = await Promise.all([
fetch('https://api.cotizave.com/v1/fx/route?from=USD&to=VES&amount=1000&direction=send', {
headers: { 'X-API-Key': process.env.COTIZAVE_API_KEY }
}).then(r => r.json()),
fetch('https://api.cotizave.com/v1/fx/route?from=VES&to=USD&amount=1000&direction=receive', {
headers: { 'X-API-Key': process.env.COTIZAVE_API_KEY }
}).then(r => r.json())
])
console.log(`Mejor para vender USD: ${send.best.market} (${send.best.rate})`)
console.log(`Mejor para comprar USD: ${receive.best.market} (${receive.best.rate})`)Widget de tasa óptima
Muestra el mercado top destacado junto con las alternativas ordenadas:
const res = await fetch(
`https://api.cotizave.com/v1/fx/route?from=USD&to=VES&amount=${amount}&direction=send`,
{ headers: { 'X-API-Key': process.env.COTIZAVE_API_KEY } }
)
const { best, alternatives } = await res.json()
// Renderiza best con badge "Mejor tasa"
// Renderiza alternatives como lista secundariaErrores posibles
| Código | error.code | Causa |
|---|---|---|
400 | missing_field | Falta amount |
400 | invalid_format | amount no es un número, o max_staleness no es un entero |
401 | invalid_api_key | API Key inválida, faltante o revocada |
402 | feature_not_in_plan | Tu plan no incluye /v1/fx/route. Body: {"code":"feature_not_in_plan","message":"...","feature":"route","current_plan":"indie"} |
429 | rate_limit_exceeded | Cuota mensual agotada |
500 | internal_error | Error inesperado del lado de Cotizave |
Shape del error 402
Cuando el plan no incluye este endpoint, el body incluye campos adicionales para facilitar el upgrade:
{
"code": "feature_not_in_plan",
"message": "This endpoint requires a Pro plan or higher.",
"feature": "route",
"current_plan": "indie"
}Notas importantes
Disponibilidad desde Pro
/v1/fx/route es exclusivo de los planes Pro y Enterprise. Los planes Free, Starter e Indie pueden calcular el mejor mercado manualmente usando /v1/fx/rates + cálculo del lado del cliente, pero /route centraliza esa lógica, agrega filtrado por frescura y devuelve el array de alternativas ya ordenado.
Cuota: 1 unidad por llamada
Aunque consulta 9 mercados internamente, /v1/fx/route cuenta como 1 unidad de tu cuota mensual (el snapshot ya está cacheado en Redis).