Ir al contenido

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.

POST
/quotes
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:

  • amount on both sides → fix ONE side.
  • amount on neither → the amount is missing.
  • spend fixed without deliver.asset → say which asset is delivered.
  • spend fixed with the same asset on both sides → without conversion, fix deliver.amount.
Media typeapplication/json
object
deliver

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
asset
required
string
Allowed values: BS USD USDT USDC VESC
amount

Minor units de lo que RECIBE el beneficiario. 5000000 = 50.000,00 Bs. Va aquí o en spend, nunca en los dos.

integer
>= 100
spend

Lo que se te cobra a ti. Con amount fijas este lado y el importe entregado sale de la tasa, menos comisión.

object
asset
required
string
Allowed values: BS USD USDT USDC VESC
amount

Minor units de lo que pones tú. 100000 = 1.000,00 USD. Va aquí o en deliver, nunca en los dos.

integer
>= 100
customerId

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.

string format: uuid
Examples

deliver — entrega exactamente 50.000,00 Bs (recomendado)

{
"deliver": {
"asset": "BS",
"amount": 5000000
}
}

Cotización creada

Media typeapplication/json

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
id

Lo que mandas en quoteId al dispersar

string format: uuid
fixed

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.

string
Allowed values: deliver spend
spend

Lo que se te cobra a ti, comisión incluida.

object
asset

Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).

string
Allowed values: BS USD USDT USDC VESC
amount

Minor units

string
deliver

Lo que cobra el beneficiario.

object
asset

Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).

string
Allowed values: BS USD USDT USDC VESC
amount

Minor units

string
fee

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
asset

Decimales: BS y USD 2; USDT y USDC 6 (1000000 = 1 USDT).

string
Allowed values: BS USD USDT USDC VESC
amount

Minor units

string
rate

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
value

La tasa que se te aplicó, con nuestro margen ya dentro

string
market

La tasa de referencia, antes del margen

string
spread_bps

La diferencia entre las dos, en puntos básicos. 50 = 0,50 %

integer
status
string
Allowed values: open consumed expired
expires_at
string format: date-time
created_at
string format: date-time
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"
}

Error con código estable

Media typeapplication/json
object
error
object
meta

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
key
additional properties
any
type
string
Allowed values: invalid_request_error authentication_error rate_limit_error upstream_error api_error
code

Código ESTABLE. Programa contra esto.

string
message
string
request_id
string
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).

Media typeapplication/json
object
error
object
meta

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
key
additional properties
any
type
string
Allowed values: invalid_request_error authentication_error rate_limit_error upstream_error api_error
code

Código ESTABLE. Programa contra esto.

string
message
string
request_id
string
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.

Media typeapplication/json
object
error
object
meta

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
key
additional properties
any
type
string
Allowed values: invalid_request_error authentication_error rate_limit_error upstream_error api_error
code

Código ESTABLE. Programa contra esto.

string
message
string
request_id
string
Example
{
"error": {
"type": "invalid_request_error",
"code": "insufficient_balance",
"request_id": "req_8a0312ba896772bc441134cd"
}
}

Error con código estable

Media typeapplication/json
object
error
object
meta

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
key
additional properties
any
type
string
Allowed values: invalid_request_error authentication_error rate_limit_error upstream_error api_error
code

Código ESTABLE. Programa contra esto.

string
message
string
request_id
string
Example
{
"error": {
"type": "invalid_request_error",
"code": "insufficient_balance",
"request_id": "req_8a0312ba896772bc441134cd"
}
}