Transfer Internal Fiat Funds

Internal fund transfers move money between Wallets and Cards within your Program — no external rails, no clearing delay, no bank credentials required. This guide covers the single transfer endpoint, valid transfer directions, response handling, and how to verify the outcome.

Transfer directions

flowchart LR
    WAL1["Wallet A"] -->|"destinationType = 0"| WAL2["Wallet B"]
    WAL1 -->|"destinationType = 1"| CARD["Card"]
    CARD -. "❌ not supported" .-> WAL1
SourceDestinationdestinationTypeSupported?
WalletAnother Wallet0
WalletCard Account1
Card AccountWalletn/a❌ — not supported
Card AccountCard Accountn/a❌ — not supported
❗️

Transfers can only originate from a Wallet. There is no card-to-wallet or card-to-card transfer endpoint. If your use case requires moving funds out of a Card Account and into a Wallet (e.g., to redistribute unspent balances), this is not currently possible via the API — raise a support ticket. Design your fund-flow architecture with this constraint in mind: funds go Wallet → Card, not the other way.


The transfer endpoint

POST /wallets/transfer
FieldRequiredTypeDescription
sourceWalletIdYesintegerThe walletId from which funds are drawn
destinationTypeYesinteger enum0 = destination is a Wallet · 1 = destination is a Card
destinationIdYesintegerThe walletId or cardId receiving the funds (per destinationType)
amountYesintegerDecimal-implied amount (e.g., 25000 = $250.00 in USD)
descriptionNostringFree-text transfer note, useful for reconciliation

Example: Wallet → Card

{
  "sourceWalletId": 3301,
  "destinationType": 1,
  "destinationId": 8821,
  "amount": 25000,
  "description": "Q3 expense allocation — Jordan Reyes"
}

Example: Wallet → Wallet

{
  "sourceWalletId": 3301,
  "destinationType": 0,
  "destinationId": 3405,
  "amount": 100000,
  "description": "EMEA → APAC rebalance"
}

Response and status

{
  "transId": 91234,
  "transStatus": 1
}
🚧

The transfer transStatus enum is different from the transaction list transStatus enum. Both use the same field name but with completely different value sets:

transStatusTransfer meaningTransaction-list meaning
0Pending
1ApprovedPending
2DeclinedCleared
3PartialCompletion
4ErrorDeclined
5Error

Always check which context a transStatus value comes from before acting on it.

Handling each response status

transStatusMeaningWhat to do
0 PendingTransfer submitted, processingPoll GET /wallets/{walletId} to confirm funds moved
1 ApprovedTransfer completed successfullyVerify via balance / transaction history
2 DeclinedTransfer rejectedCheck source wallet balance, destination validity, and that amount is ≤ available funds
3 PartialTransfer partially completedInvestigate — may indicate a partial-funds scenario; verify both source and destination balances
4 ErrorProcessing errorRetry with the same parameters; if persistent, raise a support ticket with the attempted transId

Verifying the transfer

After a successful (transStatus = 1) transfer, verify the outcome at both ends:

Check the source wallet balance

GET /wallets/{sourceWalletId}

Then query the wallet's transaction history to confirm the outgoing entry (see Reconcile Transactions & Fees).

Check the destination card balance

GET /cards/{cardId}/balance
{
  "ledgerBalance": 125000,
  "availableBalance": 125000,
  "currency": 0
}

Internal transfers move directly into availableBalance — there's no clearing delay because no external correspondent banking is involved.

Check the destination wallet

GET /wallets/{destinationWalletId}

Idempotency and safe retries

🚧

No idempotency-key mechanism is currently published for this endpoint. If a transfer request times out or returns a 5xx, do not blindly retry — first verify whether the transfer actually succeeded by checking GET /cards/{cardId}/balance or the wallet's transaction history. A duplicate retry on a successful transfer will move funds twice. See Errors & Status Codes.


Common patterns

Regular top-up schedule (e.g., monthly expense allocation)

  1. At the start of each period, transfer a fixed amount from the corporate Wallet to each Card
  2. Use description to include the period reference (e.g., "June 2024 allocation") for reconciliation
  3. At period end, any unspent balance remains on the Card for the next period (or request card closure via support ticket if returning funds is required)

On-demand top-up (cardholder requests additional funds)

  1. Cardholder requests additional funds through your application
  2. Your application calls POST /wallets/transfer from the corporate Wallet to the Card
  3. Funds are available immediately in availableBalance — no waiting period

Rebalancing between wallets (e.g., consolidating department budgets)

  1. POST /wallets/transfer with destinationType = 0 from the source Wallet to a consolidated Wallet
  2. Repeat for each wallet being consolidated
  3. The consolidated Wallet can then be used as the source for subsequent Card top-ups

What's next