Skip to content

How it works

The API has four objects. Everything else is either a lookup (balance, usage, bank catalog) or a block that travels inside a request (the sender).

Quote ───────────┐ POST /v1/quotes → quote.id
(quote) │ 1 use, ~60 s POST /v1/beneficiaries → beneficiary.id
▼ POST /v1/payouts → payment.id
Beneficiary ──► Payout ──────► Event ─► your webhookUrl (consumes the quote)
(beneficiary) (payment) (event) ⋮ asynchronous
│ POST your webhookUrl ← event
└─► history (payment.events[])

The event is payment.settled, payment.failed or payment.reversed. The beneficiary is optional: it can go inline in POST /v1/payouts.


Fixes how much is delivered, how much we charge and how much is debited from you. POST /payouts does not accept any amount. You send amount in deliver (what the beneficiary receives) or in spend (what you are charged), never in both; the response is the same in either case, and GET /quotes/{id} returns it identically.

  • Single use. Consuming it twice returns 409 quote_already_consumed.
  • It expires. TTL ~60 s. After expires_at, 422 quote_expired.
  • Quoting is free: it does not reserve balance, does not consume limits and does not generate billable usage.
Field Type What it is
id uuid What you send as quoteId when paying out
fixed deliver · spend Which side you fixed
spend { asset, amount } What you are charged
deliver { asset, amount } What the beneficiary receives
fee { asset, amount } Our fee, always in the delivered asset
rate object · null { value, market, spread_bps }, or null if there is no conversion
status open · consumed · expired
expires_at · created_at ISO-8601 Past expires_at it is no longer usable

Fixing deliver, the fee is added on top; fixing spend, what arrives comes from the rate minus the fee. See quote in bolívares.


Who gets paid. Registration is idempotent on (national ID, bank, method): resending the same data returns the same beneficiary with created: false.

Field Type What it is
id uuid What you send as beneficiaryId when paying out
full_name string Name exactly as the destination bank has it
national_id string Cédula or RIF: V/E/J/G/P + 6 to 9 digits
bank_code string Destination bank, 4 digits (0102, 0134, 0138…)
account_number string · null 20-digit account starting with bank_code. Required for transferencia
phone string · null Mobile 04XXXXXXXXX. Required for pago móvil; optional for bank transfer
asset · country string BS · VE
status active · blocked A blocked beneficiary returns 422 beneficiary_blocked
payout_count int Payouts that reached them successfully
last_success_at · last_failure_reason ISO-8601 · string Their history
created_at ISO-8601

A payment. It consumes a quote and delivers the amount to the beneficiary.

Field Type What it is
id uuid
status see states submitted is the normal outcome
status_reason string · null Why it is where it is
beneficiary_id uuid · null To whom
customer_id uuid · null Which of your users it belongs to, if you sent it
payout_asset · payout_amount BS · string What the beneficiary receives
source_asset · source_amount string What was debited from you: amount plus fee
fee_amount string Our fee. 0 on a failed payment: the entry was fully reversed
method pago_movil · transferencia The method it went out through
bank_reference string · null The receipt the beneficiary sees at their bank. It exists once the transfer completes; it is the only transfer identifier we publish
compensated bool Whether the accounting entry was reversed
settled_at ISO-8601 · null When the money went out
created_at ISO-8601 When you requested it
events[] array Transition history (only in GET /payments/{id})

Each element of events[]:

Field What it is
from_status · to_status The transition
reason ledger_committed, payout_accepted, payout_accepted_async, resolved_by_reaper, payout_failed, payout_returned, payout_reported_failure…
actor api (your call) · network (the payment network notified us) · reaper (our resolution process) · system
metadata Context for the transition. On a payout, methodRequested and methodUsed
created_at When

Every webhook leaves a queryable event, with the details of each attempt.

Field Type What it is
id string Deduplicate on this. It also travels in x-event-id
event_type string payment.settled · payment.failed · payment.reversed
aggregate_type · aggregate_id string Which object it is about (payment + its id)
payload object The body we sent (only in GET /events/{id})
status pending · published · dead dead = your failed queue
attempts int Attempts used
last_error string · null Why the last one failed
next_attempt_at · published_at · dead_at ISO-8601 · null
deliveries[] array Each attempt with its HTTP code and latency

See webhooks.


sender (who orders the transfer) travels inside POST /payouts: it is not a resource and has no id. See pay out. Your position (GET /treasury/position) and your usage (GET /limits/usage) are live figures: they have no id and no queryable history.