Referencia de API

Transferencias

Aquí es donde el dinero sale. Una transferencia puede ser interna (un movimiento contable instantáneo entre cuentas de la plataforma) o externa (un envío on-chain a una dirección de terceros). Todas son idempotentes y quedan registradas asiento por asiento.

Estados de una transferencia

Estados

PENDING_APPROVALstatus

Requiere el visto bueno de un segundo operador según tus políticas de riesgo. Nada se envió on-chain todavía.

PROCESSINGstatus

Firmada y transmitida a la red; esperando confirmaciones.

COMPLETEDstatus

Confirmada en la red (o liquidada contablemente si es interna). Es el estado final feliz.

REJECTED / FAILEDstatus

Rechazada por un operador o fallida en la red. En ambos casos el saldo se reintegra al balance contable.

POST/v1/transfers/estimate-fee

Cotizar gas fee

Devuelve el costo estimado de la comisión de red para un activo y una red antes de ejecutar la transferencia.

Cuándo usarlo

Muéstralo al usuario antes de confirmar un retiro, o úsalo para elegir automáticamente la red más barata entre las que aceptas.

Cuerpo (JSON)

networkstringrequerido

Red sobre la que se enviaría.

assetstringrequerido

Símbolo del activo, por ejemplo USDC.

curl
curl -X POST "https://vaultcore.dev.tulkitpay.com/v1/transfers/estimate-fee" \
  -H "x-api-key: $TULKIT_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "network": "POLYGON", "asset": "USDC" }'

Respuesta de ejemplo

200 OK
{
  "network": "POLYGON",
  "asset": "USDT",
  "estimated_gas_fee": "0.001500",
  "gas_price_gwei": "35.5",
  "unit": "POL"
}

Buenas prácticas

  • La cotización es una estimación: el gas puede variar entre el momento del cálculo y la firma.
POST/v1/transfers

Ejecutar transferencia

Inicia una transferencia interna o externa de forma idempotente. Es el endpoint que usan los comercios integrados para ofrecer retiros a sus usuarios.

Cuándo usarlo

Cuando tu usuario confirma un retiro o cuando liquidas un payout programado desde tu backend.

Cuerpo (JSON)

idempotency_keystring (min 8)requerido

Clave estable por intención de pago. Reintentar con la misma clave nunca duplica el envío.

networkenumrequerido

Red de la operación: ETHEREUM, POLYGON, BSC, BASE, ARBITRUM, OPTIMISM, TRON, SOLANA, ROBINHOOD, WORLDCHAIN, AVALANCHE o LINEA.

assetstringrequerido

Símbolo del activo a enviar. Debe estar habilitado para tu comercio en esa red.

amountstringrequerido

Monto como string decimal para conservar precisión, por ejemplo "250.00".

to_addressstringrequerido

Dirección destino. Valídala en tu UI contra el formato de la red antes de enviar.

end_user_idstring

Usuario final al que se le debita el saldo. Omítelo solo para movimientos de tesorería del propio comercio.

notestring (max 500)

Nota interna para tu operación y auditoría. No viaja a la blockchain.

typeINTERNAL | EXTERNAL

Por defecto EXTERNAL (envío on-chain). Usa INTERNAL para mover saldo entre cuentas sin pagar gas.

source_walletHOT_WALLET | GAS_WALLET

Por defecto HOT_WALLET. GAS_WALLET se reserva para operaciones de tesorería y recarga de comisiones.

curl
curl -X POST "https://vaultcore.dev.tulkitpay.com/v1/transfers" \
  -H "x-api-key: $TULKIT_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "idempotency_key": "wd_2026_08_18_0001",
    "network": "POLYGON",
    "asset": "USDC",
    "amount": "250.00",
    "to_address": "0xA1b2...",
    "end_user_id": "eu_01HZX...",
    "type": "EXTERNAL"
  }'

Respuesta de ejemplo

200 OK
{
  "id": "tr_01J9X0P1Q2R3S4T5U6V7W8X9",
  "merchant_id": "mrc_01HZX89ABCDEF1234567890",
  "idempotency_key": "payout_order_88319",
  "network": "BASE",
  "asset": "USDC",
  "amount": "100.500000",
  "to_address": "0x1234567890abcdef1234567890abcdef12345678",
  "end_user_id": "eu_01HZX89ABCDEF1234567890",
  "note": "Pago de nómina o retiro de usuario",
  "type": "EXTERNAL",
  "status": "PROCESSING",
  "tx_hash": null,
  "gas_fee": null,
  "created_at": "2026-08-20T21:20:00.000Z"
}

Buenas prácticas

  • Persiste el idempotency_key antes de llamar. Si el request hace timeout, reintenta con la misma clave en lugar de crear otra.
  • Trata PENDING_APPROVAL como un estado normal, no como un error: tu UI debe informar que el retiro está en revisión.
GET/v1/transfers

Listar transferencias

Devuelve el historial de retiros contables y on-chain del comercio, útil para dashboards y exportaciones.

curl
curl "https://vaultcore.dev.tulkitpay.com/v1/transfers" \
  -H "x-api-key: $TULKIT_API_KEY"

Respuesta de ejemplo

200 OK
[
  {
    "id": "tr_01J9X0P1Q2R3S4T5U6V7W8X9",
    "merchant_id": "mrc_01HZX89ABCDEF1234567890",
    "idempotency_key": "payout_order_88319",
    "network": "BASE",
    "asset": "USDC",
    "amount": "100.500000",
    "to_address": "0x1234567890abcdef1234567890abcdef12345678",
    "type": "EXTERNAL",
    "status": "COMPLETED",
    "tx_hash": "0x8e7d6c5b...8e7d",
    "gas_fee": "0.000150",
    "created_at": "2026-08-20T21:20:00.000Z"
  }
]
GET/v1/transfers/:id

Detalle extendido de transferencia

Incluye nonce, gas_fee real pagado y los asientos contables en LedgerEntry asociados a la operación.

Parámetros

idstringrequerido

Id de la transferencia.

curl
curl "https://vaultcore.dev.tulkitpay.com/v1/transfers/tr_01J9X0P1Q2R3S4T5U6V7W8X9" \
  -H "x-api-key: $TULKIT_API_KEY"
POST/v1/transfers/:id/approve

Aprobar transferencia

Aprueba una transferencia en PENDING_APPROVAL para que sea firmada y transmitida on-chain. Es el segundo par de ojos del doble control.

Parámetros

idstringrequerido

Id de la transferencia.

curl
curl -X POST "https://vaultcore.dev.tulkitpay.com/v1/transfers/tr_01J9X0P1.../approve" \
  -H "x-api-key: $TULKIT_API_KEY"

Respuesta de ejemplo

200 OK
{
  "success": true,
  "message": "Transferencia aprobada e iniciada con éxito on-chain.",
  "transfer": {
    "id": "tr_01J9X0P1Q2R3S4T5U6V7W8X9",
    "network": "BASE",
    "asset": "USDC",
    "amount": "100.500000",
    "type": "EXTERNAL",
    "status": "PROCESSING",
    "tx_hash": null,
    "gas_fee": null,
    "created_at": "2026-08-20T21:20:00.000Z"
  }
}

Buenas prácticas

  • Aprobar una transferencia ya resuelta devuelve 409. Consulta su estado antes de reintentar.
POST/v1/transfers/:id/reject

Rechazar transferencia

Rechaza una transferencia en PENDING_APPROVAL y reembolsa el monto al balance contable del comercio.

Parámetros

idstringrequerido

Id de la transferencia.

curl
curl -X POST "https://vaultcore.dev.tulkitpay.com/v1/transfers/tr_01J9X0P1.../reject" \
  -H "x-api-key: $TULKIT_API_KEY"

Respuesta de ejemplo

200 OK
{
  "success": true,
  "message": "Transferencia rechazada y fondos reembolsados al balance contable del merchant.",
  "transfer": {
    "id": "tr_01J9X0P1Q2R3S4T5U6V7W8X9",
    "network": "BASE",
    "asset": "USDC",
    "amount": "100.500000",
    "type": "EXTERNAL",
    "status": "REJECTED",
    "tx_hash": null,
    "gas_fee": null,
    "created_at": "2026-08-20T21:20:00.000Z"
  }
}
GET/v1/balances

Obtener balances

Devuelve los saldos contables consolidados del comercio por activo y red. Este endpoint se autentica con Bearer <cognito_jwt> desde el Portal Web, no con x-api-key.

Cuándo usarlo

Para paneles de tesorería dentro del portal. Desde tu backend, reconstruye posiciones a partir de depósitos y transferencias.

curl
curl "https://vaultcore.dev.tulkitpay.com/v1/balances" \
  -H "Authorization: Bearer $COGNITO_ID_TOKEN"

Respuesta de ejemplo

200 OK
[
  { "asset": "USDT", "network": "POLYGON", "balance": "5000.750000" },
  { "asset": "USDC", "network": "BASE", "balance": "12000.000000" }
]
Antes de mover fondos reales

Valida en mainnet con un monto mínimo, confirma el tx_hash en el explorador de la red y solo entonces habilita el retiro a todos tus usuarios.