---
title: "Crear una transferencia"
method: POST
path: "/transfers"
tags: ["transfers"]
---

# Crear una transferencia

`POST /transfers`

Mueve dinero desde tu balance al `destination` que indiques. En la mayoría de los casos basta pasar **el identificador como string** — el formato indica a dónde va el dinero:

| `destination` | A dónde va | Registro creado |
|---|---|---|
| `"ba_..."` | Retiro a tu cuenta bancaria | `wi_` (asíncrono) |
| `"ac_..."` | Transferencia instantánea a esa cuenta de Recurrente | `tr_` |
| `"@handle"` | Transferencia a la cuenta con ese handle | `tr_` |
| `"co_..."` | Transferencia al teléfono de ese contacto guardado | `tr_` |
| `"+50255667788"` | Envío a un teléfono; queda `unclaimed` hasta que lo reclamen con KYC | `tr_` |

Para stablecoin (requiere verificación de stablecoin) o para ser explícito, usa la forma de objeto: `destination: {type: "crypto_address", address: "0x…", chain: "base", currency: "USDC"}` crea un envío `sw_`.

Requiere una llave con movimiento de dinero habilitado y la cuenta verificada. Usa `X-ACCOUNT-ID` para operar sobre una cuenta conectada (hija) verificada — admite destinos `bank_account`, y destinos `account` dentro de su misma plataforma (la cuenta madre o cuentas hermanas), para comisiones y liquidaciones.

En Sandbox, `POST /transfers` está bloqueado para todos los destinos porque el balance simulado no es transferible ni retirable.

## Headers

- `X-SECRET-KEY` string, required
- `Idempotency-Key` string

## Request body

- object
  - `amount_in_cents` integer, required — Monto en centavos que se debita del balance en `currency`
  - `currency` 'GTQ' | 'USD' — Moneda del balance de origen. Para destinos `bank_account` es opcional (por defecto, la moneda de la cuenta bancaria); requerida para los demás destinos.
  - `destination` union, required — A dónde va el dinero — el identificador como string (`ba_`/`ac_`/`co_` id, `@handle` o teléfono), o el objeto tipado para stablecoin y casos avanzados
    - string
    - TransferDestinationRequest — Destino tipado del movimiento. Los campos aplicables dependen de `type`.
      - `type` 'bank_account' | 'account' | 'phone_number' | 'crypto_address', required
      - `id` string — bank_account: ID de tu cuenta bancaria (ba_). account: ID (ac_) o handle (@) de la cuenta destinataria. crypto_address: ID de una dirección guardada (cr_).
      - `number` string — phone_number: teléfono del destinatario
      - `contact_id` string — phone_number: ID de un contacto guardado (co_), alternativo a number
      - `address` string — crypto_address: dirección on-chain, alternativa a id
      - `chain` string — crypto_address: red (base, ethereum, polygon, solana, stellar, tron…)
      - `currency` string — crypto_address: stablecoin a enviar (USDC, USDT…)
      - `blockchain_memo` string — crypto_address: memo on-chain (requerido en stellar)
  - `note` string — (Opcional) Nota o descripción del movimiento
  - `is_instant` boolean — Solo destinos `bank_account` — retiro instantáneo (sujeto a elegibilidad y comisión)
  - `should_perform_currency_conversion` boolean — Solo destinos `bank_account` — convierte el balance a la moneda de la cuenta bancaria destino

## Response `201`

Movimiento creado. Los retiros (`wi_`) y envíos cripto (`sw_`) son asíncronos — la respuesta trae el estado inicial; consulta el estado o suscríbete a los webhooks.

- Transfer — Movimiento unificado de dinero saliendo de un balance. El prefijo del `id` indica el registro subyacente: `wi_` retiro bancario, `tr_` transferencia p2p, `sw_` envío de stablecoin. Los registros p2p (`tr_`) conservan además los campos legados `sender` y `recipient`.
  - `id` string — ID del movimiento (tr_ / wi_ / sw_)
  - `status` 'pending' | 'in_review' | 'processing' | 'sent' | 'unclaimed' | 'completed' | 'failed' | 'cancelled' — Estado canónico del movimiento
  - `status_detail` string — Estado crudo del registro subyacente (p. ej. `approved`, `rejected`, `review_requested`)
  - `amount_in_cents` integer — Monto en centavos debitado del balance
  - `currency` string — Moneda del balance de origen
  - `fee_in_cents` integer — Comisión en centavos (retiros instantáneos / internacionales; 0 para p2p)
  - `net_amount_in_cents` integer — Monto neto que llega al destino después de comisiones
  - `note` string, nullable — Nota del movimiento
  - `account_id` string — Cuenta cuyo balance movió este envío. Siempre presente, para que una lista que abarca varias cuentas de una organización siga siendo atribuible.
  - `sent_at` string, date-time, nullable — Momento en que Recurrente envió el retiro al banco; solo aplica a retiros bancarios (`wi_`).
  - `settled_at` string, date-time, nullable — Momento de liquidación bancaria confirmada. Solo está presente para retiros bancarios confirmados o completados (`wi_`).
  - `bank_reference` string, nullable — Referencia que devolvió el riel de envío, cuando ese riel devuelve una. Solo aplica a movimientos `wi_`; no identifica ni enumera transacciones que conformen el retiro.
  - `bank_reference_status` 'available' | 'pending' | 'unsupported' — Qué esperar de `bank_reference`: `available` si ya existe, `pending` si el retiro aún no sale y podría traerla, y `unsupported` si ya salió por un riel que nunca devuelve una. Con `unsupported`, concilia el depósito por `statement_descriptor`.
  - `statement_descriptor` string, nullable — Lo que le pedimos al banco que imprima en el estado de cuenta del beneficiario. Solo aplica a movimientos `wi_`.
  - `balance_transaction_id` string, nullable — Fila del ledger que registró este movimiento (`GET /api/balance_transactions/{id}`). Vacío mientras el dinero no haya salido del balance.
  - `destination` TransferDestination — Destino del movimiento. Los campos presentes dependen de `type`.
    - `type` 'bank_account' | 'account' | 'phone_number' | 'crypto_address'
    - `id` string, nullable — ID del recurso destino (`ba_` cuenta bancaria, `ac_` cuenta, `cr_` dirección cripto)
    - `bank_name` string — bank_account: banco destino
    - `holder_name` string — bank_account: titular de la cuenta bancaria
    - `currency` string — bank_account: moneda de la cuenta bancaria. crypto_address: stablecoin enviada
    - `name` string — account: nombre de la cuenta destinataria
    - `number` string — phone_number: teléfono del destinatario
    - `address` string — crypto_address: dirección on-chain
    - `chain` string — crypto_address: red del envío
    - `amount` integer — crypto_address: monto en unidades menores de la stablecoin que llega al destino
  - `created_at` string, date-time — Fecha de creación
  - `sender` TransferSender — (Solo registros tr_) Cuenta emisora — campo legado
    - `id` string
    - `name` string
    - `type` string
  - `recipient` TransferRecipient — (Solo registros tr_) Destinatario — campo legado
    - `id` string, nullable
    - `name` string
    - `type` string
  - `reversal_of_id` string — ID del transfer original; solo aparece en reversos por reembolso
  - `refund_id` string — ID del reembolso que originó el reverso

## Other responses

- `400` — Error de validación (fondos insuficientes, destinatario inexistente o cuenta bancaria malformada)
- `403` — Llave sin movimiento de dinero (money_movement_not_enabled), cuenta no activa (account_not_active), verificación pendiente (verification_required), verificación de stablecoin pendiente (stablecoin_verification_required) o cuenta conectada sin verificar (connected_account_unverified)
- `422` — La creación está bloqueada en Sandbox (sandbox_unsupported), o el destino es inválido (invalid_destination), falta moneda (currency_required), falta destinatario (recipient_required), el destino no está soportado para cuentas conectadas (destination_not_supported), o el destinatario es ambiguo (ambiguous_recipient)

---

[API](https://skmtc.dev/recurrente/apis/referencia-api.md) · [All operations](https://skmtc.dev/recurrente/apis/referencia-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/recurrente/referencia-api/revisions/da12dce50f30/schema)
