API
Solicita acceso →
Referencia / Cotizaciones

Cotizaciones

La tasa que lees con GET /v2/rate es la que está publicada en ese momento. Entre que la lees, se la muestras a tu usuario y él confirma, pueden pasar varios minutos — y en ese rato la tasa puede moverse. POST /v2/quotes congela un precio: te devuelve los dos montos ya calculados, en enteros, con una vigencia escrita y un solo uso. Mientras la cotización viva, el riesgo de que el mercado se mueva es nuestro, no tuyo.

i
Piénsalo como el ticket de la casa de cambio. El cartel de la pared dice a cuánto está hoy; el ticket dice a cuánto es lo tuyo, con los dos montos escritos y una hora de vencimiento. Con el ticket en la mano ya no importa que el cartel cambie. Eso es una cotización.

POST /v2/quotes — congelar el precio

POST/v2/quotes

Fijas un lado de la operación y nosotros calculamos el otro. El lado que fijas vuelve exactamente igual: no lo tocamos nunca.

Qué lado fijas: amountType

SOURCE — fijas lo que se debita de tu saldo, en tu moneda. Úsalo cuando tu usuario dice «quiero mandar 50 dólares».

TARGET — fijas lo que le llega al beneficiario, en bolívares. Úsalo cuando tu usuario dice «quiero que le lleguen 2.000 bolívares».

Autenticación e idempotencia

Va firmado, igual que POST /v2/payments, y la cabecera idempotency-key es obligatoria y forma parte del envelope firmado. Repetir la misma clave te devuelve la misma cotización con un 200, no una nueva con un 201. Eso es deliberado: si cada reintento congelara un precio nuevo, una red inestable te dejaría con cinco precios congelados de una sola intención.

cURLCopiar
# Quiero mandar USD 50,00 — fijo el lado de origen
curl -X POST https://api.alibanca.com/v2/quotes \
  -H "x-api-key: sk_test_..." \
  -H "x-nonce: $NONCE" \
  -H "idempotency-key: cot-2026-09-14-0001" \
  -H "x-signature: $FIRMA" \
  -H "content-type: application/json" \
  -d '{"amountType":"SOURCE","amountMinor":"5000"}'
RESPUESTA 201
{
  "status": "ok",
  "traceId": "01J9…",
  "payload": {
    "quoteId": "9134",
    "amountType": "SOURCE",
    "sourceCurrency": "USD",
    "sourceAmountMinor": "5000",
    "targetCurrency": "VES",
    "targetAmountMinor": "175002500",
    "rateId": "184",
    "expiresAt": "2026-09-14T18:47:03.000Z"
  }
}

Los dos montos vienen calculados. No los recalcules.

La respuesta no trae una tasa para que multipliques: trae los dos montos, en unidades menores enteras. Es la diferencia entre que el redondeo lo decidamos una vez, nosotros, y quede escrito, o que cada integración lo aplique como se le ocurra y termine discrepando con nuestro asiento por un céntimo.

Si multiplicas sourceAmountMinor por el rate de GET /v2/rate puede que no te dé exactamente targetAmountMinor. Eso es correcto. El número bueno es el que está en la cotización.

Hacia dónde redondea

El lado que fijas nunca se redondea — vuelve tal cual. El lado calculado se redondea a favor de la casa, y eso quiere decir cosas distintas según el lado:

· Con SOURCE, el monto destino se redondea hacia abajo.

· Con TARGET, el monto de origen se redondea hacia arriba.

En la práctica hablamos de una unidad menor —un céntimo— por operación. Lo decimos explícito porque preferimos que lo sepas al integrar y no que lo descubras cuadrando.

!
Ojo con TARGET y montos minúsculos. Si pides que lleguen 0,01 bolívares, el redondeo hacia arriba del lado de origen convierte eso en un céntimo de dólar — miles de veces más de lo que vale. Por eso hay un mínimo del lado destino y por debajo de él la cotización se rechaza con 400. No es un límite comercial: es la aritmética, que a esa escala deja de tener sentido.

Vence, y se usa una sola vez

expiresAt está en la respuesta, siempre. No tienes que adivinar cuánto dura ni asumir un número: está escrito. Después de esa hora la cotización está muerta y el pago que la cite se rechaza.

Una cotización respalda un solo pago. Si dos operaciones citan la misma, la segunda se rechaza. No es una validación que podamos olvidarnos de correr: lo impone la base de datos.

Si tu usuario se arrepiente y vuelve a empezar, pide otra cotización con otra idempotency-key. No hay penalidad por pedir cotizaciones que no ejecutas — sólo ocupan cupo hasta que vencen (ver abajo).

Cuándo NO te damos una cotización

Igual que la tasa, esto falla cerrado: si no podemos darte un precio bueno, no te damos ninguno. Cada caso tiene su código porque lo que tienes que hacer en cada uno es distinto.

400 — el pedido no se puede cotizar

Falta amountType, o no es SOURCE ni TARGET; o amountMinor no es un entero positivo de unidades menores escrito como texto; o el monto destino queda por debajo del mínimo. Es tuyo y se arregla mandando otra cosa. El mensaje dice cuál de los tres fue.

404 — no hay conversión que cotizar

Tu saldo ya está en la moneda de pago: fondeas en bolívares y pagas en bolívares. No hay nada que convertir, y devolverte una cotización 1:1 sería inventar una conversión que no existe. Es estructural: reintentar no ayuda. Emite el pago directo, sin cotización.

409 — no hay cupo ahora mismo

Hay un techo a cuánto precio congelado puede haber vivo a la vez, por cliente y en total. Mientras tus cotizaciones están vivas y sin usar, ocupan ese cupo. Tu pedido está bien; lo que falta es espacio. Se resuelve esperando: en cuanto tus cotizaciones venzan o las ejecutes, el cupo se libera solo. No hace falta que hagas nada para liberarlo.

Si te pasa seguido, es señal de que estás pidiendo más cotizaciones de las que ejecutas — o de que tu techo se te quedó chico. Escríbenos y lo miramos.

503 — no hay tasa vigente

Existe el par, pero nadie tiene una tasa publicada y en vigencia en este momento. Es nuestro, no tuyo. Reintenta en un rato. Nunca te vamos a dar una tasa vencida para no dejarte sin respuesta.

i
Cómo conviene integrarlo. Lee GET /v2/rate para mostrar el precio mientras tu usuario decide; pide POST /v2/quotes cuando confirma; emite el pago citando la cotización. Si entre el paso 2 y el 3 pasan más minutos de los que dura expiresAt, pide otra — es barato y es honesto con tu usuario, que va a ver el precio que de verdad se le va a aplicar.