Quote a payout
POST/quotesProbar
La llamada la hace tu navegador, contra el servidor que elijas arriba. Si la documentación no está servida desde el mismo origen que la API, el navegador puede bloquear la respuesta por CORS: en ese caso abre estas páginas desde la propia API (/docs) o usa el curl de arriba.
const url = 'http://localhost:3000/v1/quotes';const options = { method: 'POST', headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'}, body: '{"deliver":{"asset":"BS","amount":5000000}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:3000/v1/quotes \ --header 'Content-Type: application/json' \ --header 'x-api-key: <x-api-key>' \ --data '{ "deliver": { "asset": "BS", "amount": 5000000 } }'Scope quotes:write. Sets the payout amount and our fee, and guarantees the result until expires_at. POST /payouts takes no amount: it takes it from here.
You fix one side and we return both. Send amount on ONE of the two sides —never both, never neither—:
1 · Fix deliver (what the beneficiary RECEIVES). They receive it exactly and the fee is added on top, so spend = deliver + fee. This is the recommended way to pay out bolívares. Today an exact amount is only accepted in BS, paying in the same asset.
2 · Fix spend (what YOU spend) plus deliver.asset. What arrives comes from the rate, minus the fee. The two assets must differ: without conversion, fix deliver.amount.
The response is the SAME in both cases —fixed, spend, deliver, fee and rate, with the same names—: the delivered amount is always read from deliver.amount. fixed says which side you fixed.
rate is null when there is no conversion; when there is, it comes as decimals (value, market, spread_bps).
You can fix deliver.amount while paying in another asset (“deliver exactly Bs 1,500.00 and tell me how many USDT that is”): that is the reverse quote, described below.
Quoting is free: it doesn’t hold balance, doesn’t use limits and isn’t billable. Quote as often as you like and use the last one; the ones you don’t use expire and are deleted on their own.
A quote is SINGLE-USE and its TTL is short (~60 seconds by default): quote right before paying out. Using it twice returns 409 quote_already_consumed; using it expired, 422 quote_expired.
Fixing deliver with an amount and paying in another asset (spend without amount) is the reverse quote: the beneficiary receives exactly deliver.amount and we tell you the minimum spend.amount. Rounding up what you spend goes to fee.
The four rejections, all 400 validation_failed, with a message saying what to send instead:
amounton both sides → fix ONE side.amounton neither → the amount is missing.spendfixed withoutdeliver.asset→ say which asset is delivered.spendfixed with the same asset on both sides → without conversion, fixdeliver.amount.
Authorizations
Sección titulada «Authorizations»Request Bodyrequired
Sección titulada «Request Bodyrequired»object
Lo que recibe el beneficiario. Con amount fijas este lado y lo recibe exacto, con la comisión cobrada encima; sin amount sólo dices en qué activo se entrega (obligatorio si fijas spend).
object
Minor units de lo que RECIBE el beneficiario. 5000000 = 50.000,00 Bs. Va aquí o en spend, nunca en los dos.
Lo que se te cobra a ti. Con amount fijas este lado y el importe entregado sale de la tasa, menos comisión.
object
Minor units de lo que pones tú. 100000 = 1.000,00 USD. Va aquí o en deliver, nunca en los dos.
Opcional, y no hace falta para dispersar. Sólo si ya registraste a ese usuario con nosotros; si no existe en tu cuenta, 404 customer_not_found.
Examples
deliver — entrega exactamente 50.000,00 Bs (recomendado)
{ "deliver": { "asset": "BS", "amount": 5000000 }}spend — pon 1.000,00 USD y dime cuántos Bs llegan
{ "spend": { "asset": "USD", "amount": 100000 }, "deliver": { "asset": "BS" }}Responses
Sección titulada «Responses»Cotización creada
Una sola forma de cotización, fijes el lado que fijes. Los mismos campos con los mismos nombres tanto si fijaste deliver como si fijaste spend: lo que recibe el beneficiario se lee siempre en deliver.amount, y lo que se te cobra en spend.amount.
No hay un tercer importe: el bruto es siempre deliver + fee.
Todos los importes van en minor units y llegan como string.
object
Lo que mandas en quoteId al dispersar
Qué lado fijaste tú; el otro lo calculamos nosotros. En una pantalla con los dos importes editables es lo que te dice cuál de los dos NO repintar, para no moverle el cursor al usuario mientras escribe.
Lo que se te cobra a ti, comisión incluida.
object
Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).
Minor units
Lo que cobra el beneficiario.
object
Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).
Minor units
Nuestra comisión, siempre en el activo que se entrega. Sin conversión se cobra encima (spend = deliver + fee); con conversión se descuenta de lo convertido.
object
Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).
Minor units
La tasa aplicada, ya en decimal: no hay escalas que dividir ni punto fijo que interpretar. null cuando no hubo conversión (mismo activo en los dos lados).
object
La tasa que se te aplicó, con nuestro margen ya dentro
La tasa de referencia, antes del margen
La diferencia entre las dos, en puntos básicos. 50 = 0,50 %
Only if you sell from your own account and this quote used bolivars left from an earlier funding at their earlier rate. One item per tranche, oldest first; the last one at your current selling rate if part of it was sold at that rate. rate.value is still the rate of the whole quote (spend.amount × rate.value = deliver.amount, truncated) and the items add up to spend.amount and deliver.amount. Absent otherwise.
object
Bs per 1 unit in this tranche
Minor units of spend.asset
Minor units of deliver.asset
Examples
fixed: deliver — 50.000,00 Bs entregados, 500,00 Bs de comisión
{ "id": "70ec44b5-c1df-45b1-86fe-8f92c3959689", "fixed": "deliver", "spend": { "asset": "BS", "amount": "5050000" }, "deliver": { "asset": "BS", "amount": "5000000" }, "fee": { "asset": "BS", "amount": "50000" }, "rate": null, "status": "open", "expires_at": "2026-08-31T20:22:36.022Z", "created_at": "2026-08-31T20:21:36.022Z"}fixed: spend — misma forma, con la tasa rellena
{ "id": "9f2c1d84-0a37-4d5e-b6c1-71f0a2e4c9d3", "fixed": "spend", "spend": { "asset": "USD", "amount": "100000" }, "deliver": { "asset": "BS", "amount": "3743190" }, "fee": { "asset": "BS", "amount": "37810" }, "rate": { "value": "37.81", "market": "38", "spread_bps": 50 }, "status": "open", "expires_at": "2026-08-31T20:22:36.022Z", "created_at": "2026-08-31T20:21:36.022Z"}Error con código estable
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}customer_not_found: el customerId no existe en tu cuenta (error.meta.field = customerId).
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}Validación de negocio (code dice cuál). Con prefondeo con tasa por ticket, tenant_prefondeo_usa_payout_bs: cotiza deliver en Bs (payout_bs), una cotización con conversión no sirve.
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}Error con código estable
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}