Mover dinero

Todo el dinero que sale de tu balance se mueve con un solo endpoint: POST /api/transfers. Indicas a dónde va el dinero con el objeto destination, y Recurrente crea el movimiento correcto — un retiro bancario, una transferencia a otra cuenta de Recurrente, un envío a un teléfono, o un envío de stablecoin on-chain.

1POST /api/transfers
2{
3 "amount_in_cents": 50000,
4 "currency": "GTQ",
5 "destination": "ba_abc123"
6}

Destinos

En la mayoría de los casos, destination es simplemente el identificador del destino como string — pega el que tengas y el formato indica a dónde va el dinero:

destinationA dónde va el dineroRegistro creado
"ba_abc123"Retiro a esa cuenta bancaria tuyawi_
"ac_xyz789"Transferencia instantánea a esa cuenta de Recurrentetr_
"@mitienda"Transferencia a la cuenta con ese handletr_
"co_maria123"Transferencia al teléfono de ese contacto guardadotr_
"+50255667788"Envío a ese teléfonotr_
1{ "amount_in_cents": 50000, "destination": "ba_abc123" }
2{ "amount_in_cents": 10000, "currency": "GTQ", "destination": "@mitienda", "note": "Pago de servicios" }
3{ "amount_in_cents": 5000, "currency": "GTQ", "destination": "+50255667788" }

El único destino que necesita la forma de objeto es stablecoin, porque una dirección cruda no dice qué token ni en qué red enviarlo:

1{
2 "amount_in_cents": 10000,
3 "currency": "USD",
4 "destination": { "type": "crypto_address", "address": "0x1234…", "chain": "base", "currency": "USDC" }
5}

La forma de objeto también existe para los demás tipos si prefieres ser explícito: { "type": "bank_account", "id": "ba_..." }, { "type": "account", "id": "ac_... | @handle" }, { "type": "phone_number", "number": "..." }.

Notas por destino:

  • Retiros (ba_) — acepta además is_instant (retiro instantáneo, sujeto a elegibilidad y comisión) y should_perform_currency_conversion (convierte el balance a la moneda de la cuenta destino). Si omites currency, se usa la moneda de la cuenta bancaria.
  • Cuentas (ac_ / @handle) — la transferencia es instantánea y sin comisión.
  • Teléfonos y contactos — el movimiento queda unclaimed hasta que el destinatario se registre y complete KYC. Puedes cancelarlo mientras no haya sido reclamado.
  • Stablecoin — requiere completar la verificación de stablecoin en la app. Indica la stablecoin en destination.currency y la red en destination.chain.

Estados

Cada movimiento tiene un status canónico — el mismo vocabulario sin importar el destino — y un status_detail con el estado crudo del registro subyacente.

statusSignificado
pendingCreado, esperando procesamiento o revisión
in_reviewEn revisión manual o de riesgo
processingAprobado, en preparación para enviarse
sentEl dinero va en camino por el rail bancario o la red
unclaimedEnvío a teléfono esperando que el destinatario lo reclame
completedEl dinero llegó a su destino
failedRechazado o falló; el balance se restaura
cancelledCancelado antes de enviarse; el balance se restaura

Las transferencias entre cuentas de Recurrente pasan a completed inmediatamente. Los retiros y envíos de stablecoin son asíncronos: la respuesta del POST trae el estado inicial, y puedes seguir el avance consultando GET /api/transfers/{id} o con webhooks.

Idempotencia

Envía un header Idempotency-Key en cada POST. Si reintentas con la misma llave y el mismo cuerpo, recibirás la respuesta original sin crear un segundo movimiento.

$curl -X POST https://app.recurrente.com/api/transfers \
> -H "X-SECRET-KEY: sk_live_…" \
> -H "Idempotency-Key: pago-nomina-2026-07" \
> -H "Content-Type: application/json" \
> -d '{"amount_in_cents": 50000, "currency": "GTQ", "destination": "ba_abc123"}'

Listar y filtrar

GET /api/transfers devuelve todos tus movimientos — retiros, p2p y stablecoin — del más reciente al más antiguo. Filtra por tipo de destino con types[]:

GET /api/transfers?types[]=bank_account&types[]=crypto_address

GET /api/transfers/{id} y POST /api/transfers/{id}/cancel aceptan cualquier ID de movimiento (tr_, wi_, sw_).

Cuentas conectadas

Si operas una plataforma con cuentas conectadas, pasa account_id para mover dinero de una cuenta hija verificada. Las cuentas hijas admiten destinos bank_account, y transferencias dentro de su misma plataforma — a la cuenta madre (comisiones) o a cuentas hermanas (liquidaciones de marketplace). Los destinos fuera de la familia, teléfonos y cripto no están disponibles para cuentas hijas:

1POST /api/transfers
2{
3 "account_id": "ac_hija123",
4 "amount_in_cents": 50000,
5 "destination": "ba_delahija"
6}

Webhooks

Cada tipo de movimiento emite webhooks al avanzar: transfer.sent/transfer.received (p2p), withdrawal.create/withdrawal.update (retiros) y swap.create/swap.update (stablecoin). Los eventos de retiros y stablecoin incluyen una llave transfer con la misma forma unificada que devuelve la API, además de su llave histórica (withdrawal/swap). Si integras con el endpoint unificado, lee siempre payload.transfer.

Requisitos

Para mover dinero por API necesitas:

  1. Una llave API con movimiento de dinero habilitado (Configuración → Llaves API).
  2. Tu cuenta verificada (KYC completado).
  3. Para stablecoin: haber completado la verificación de stablecoin en la app.

¿Y los endpoints de retiros?

/api/withdrawals y los retiros anidados de cuentas conectadas siguen funcionando indefinidamente para integraciones existentes, pero están marcados como obsoletos: para integraciones nuevas usa siempre /api/transfers.