GuidesRecipesAPI ReferenceChangelog
Guides

Funding Accounts

How do I fund an account with fiat?

Overview

Choosing your funding method

There are three different ways to fund an account with fiat currency:

  1. Via a funding transfer from a customer's Plaid connected bank account to the customer's fiat account;
  2. Via a book transfer from the bank's fiat account to the customer's fiat account; or,
  3. Via an ACH, wire transfer, RTP transfer or FedNow transfer to the customer's deposit_bank_account.

Method 1: Funding from a Plaid-connected account

Creating the quote and transfer

All transfers on the Cybrid Platform require creating a quote via POST /api/quotes before executing a transfer via POST /api/transfers. Example funding quote:

{
  "product_type": "funding",
  "customer_guid": "your-customer-guid",
  "asset": "USD",
  "side": "deposit",
  "receive_amount": 10000
}
⚠️

Base units

The receive_amount is in the base units of the currency. In the example above, 10,000 = 10,000 cents = $100.00 USD. Call GET /api/assets to get the number of base decimals for a currency.

In the example above, the asset is USD with side set to deposit and receive_amount set to the desired amount. Once you have your quote guid, proceed to the transfers API.

You need the customer's external_bank_account_guid for this step. Retrieve it by calling GET /api/external_bank_accounts with the customer's guid.

Next, create a transfer via POST /api/transfers with transfer_type set to funding, the quote guid, and the external_bank_account_guid.

⚠️

Sandbox limit

External Bank Accounts with type=plaid are limited to $100.00 per funding transfer in sandbox. You can perform an unlimited number of $100.00 transfers.

Here is an example funding transfer:

{
  "quote_guid": "your-quote-guid",
  "transfer_type": "funding",
  "external_bank_account_guid": "your-account-string",
  "payment_rail": "ach",
  "expected_error": "pending"
}
ℹ️

Sandbox testing

The expected_error field is only available in sandbox to simulate errors.

Payment rails

The Cybrid Platform will default all USD transfers to use same-day ACH, i.e., "payment_rail":"ach", and EFT for all CAD transfers, i.e., "payment_rail":"eft".

Accounts can be funded using other payment rails — see Method 3: Funding via a customer's deposit bank account.

Monitoring the transfer

Transfers are created asynchronously. Monitor the transfer until it reaches the completed state.

Settlement times depend on the payment_rail selected. For example, an ACH transfer requested at 4pm on a business day may not complete until 4pm the next business day. See Fiat Transfer Settlement for details.

Monitor transfer state by querying GET /api/transfers/{transfer_guid}, or register for webhooks to receive automatic notifications on state changes.

After creation, the transfer state is pending and progresses to completed when the fiat settles.

Cancelling a transfer

Transfers can only be cancelled between posting and bank execution -- a very small time window. No API endpoint is currently available for partner-initiated cancellation.

Contact Cybrid support to request a transfer cancellation.

Handling Plaid errors

Creating a funding transfer using an External Bank Account of "account_kind": "plaid" or "account_kind": "plaid_processor_token" can produce several errors.

The Cybrid Platform informs the caller of errors or required actions when using Plaid-connected bank accounts.

Depending on the error received from Plaid, the associated External Bank Account for a transfer can be:

  1. Put into a refresh_required state. This occurs when the customer must re-authenticate to their bank account via Plaid. When this does occur the partner must put their customer through a flow where Plaid Link is initialized in update mode. See the guide Plaid Link Update Mode. The associated External Bank Account cannot be used until the account is re-authorized.
  2. Put into a deleting and eventually deleted state. This occurs when Plaid has lost access to the customer's account completely or the customer has not granted sufficient permissions to Plaid to access their account. When this does occur the partner must instruct the customer to connect a different bank account via Plaid or to grant the required permissions to Plaid while interacting with Plaid Link.

When a funding transfer fails, the transfer state is failed with a failure_code. Failure codes and recommended actions:

  1. cancelled -- The transfer was manually cancelled.
  2. compliance_rejection -- The transfer was rejected for compliance reasons.
  3. internal_error -- An internal error occurred. Retry the transfer.
  4. limit_exceeded -- The customer exceeded their activity limits.
  5. non_sufficient_funds -- The customer does not have enough funds.
  6. party_name_invalid -- The external bank account has an invalid party name.
  7. payment_rail_invalid -- The payment rail is not supported by the external bank account.
  8. plaid_access_not_granted -- The external bank account must be re-added via Plaid with correct permissions. The account is set to deleted. See Plaid documentation.
  9. plaid_institution_not_responding -- Balance could not be retrieved. Retry the transfer. See Plaid documentation.
  10. plaid_internal_server_error -- Balance could not be retrieved. Retry the transfer. See Plaid documentation.
  11. plaid_item_not_found -- The external bank account must be re-added via Plaid. The account is set to deleted. See Plaid documentation.
  12. plaid_item_not_supported -- The account is not supported. Connect a different account. The account is set to deleted. See Plaid documentation.
  13. plaid_multiple_accounts -- Multiple accounts were selected in Plaid Link. Only one account may be selected. The account is set to deleted.
  14. plaid_no_accounts -- No compatible accounts found. The account is set to deleted. See Plaid documentation.
  15. plaid_none_balances_error -- Error retrieving balances from Plaid. Retry the transfer.
  16. plaid_unknown_error -- Balance could not be retrieved. Retry the transfer. See Plaid documentation.
  17. refresh_required -- The external bank account must be reconnected via Plaid.
  18. reversed -- The transfer was reversed (returned).

Withdrawals

To withdraw funds from a customer's fiat account to their external bank account, create a quote with side set to withdrawal:

{
  "product_type": "funding",
  "customer_guid": "your-customer-guid",
  "asset": "USD",
  "side": "withdrawal",
  "receive_amount": 10000
}

Then create a funding transfer via POST /api/transfers:

{
  "quote_guid": "your-quote-guid",
  "transfer_type": "funding",
  "external_bank_account_guid": "your-account-string",
  "payment_rail": "wire",
  "beneficiary_memo": "Invoice #12345 payment"
}

The external_bank_account_guid can reference any type of external bank account — Plaid-connected or raw routing.

Beneficiary memo

The optional beneficiary_memo parameter sets the memo that appears on bank statements and wire confirmations for the beneficiary.

Constraints:

  • Maximum 128 characters
  • Cannot be an empty string — use null or omit the field to skip
  • Only applies to withdrawal-direction funding transfers (not deposits, and not other transfer types such as book, crypto, or lightning)

Method 2: Funding via book transfer

Book transfers are similar to Plaid funding but settle instantly.

Creating the quote and transfer

Create a quote via POST /api/quotes, then execute a transfer via POST /api/transfers.

Example book transfer quote:

{
  "product_type": "book_transfer",
  "customer_guid": "your-customer-guid",
  "asset": "USD",
  "side": "deposit",
  "receive_amount": 10000
}

Set side to deposit and receive_amount to the desired amount. Once you have the quote guid, create the transfer via POST /api/transfers:

{
  "quote_guid": "your-quote-guid",
  "transfer_type": "book",
  "expected_error": "pending"
}
ℹ️

Sandbox testing

The expected_error field is only available in sandbox to simulate errors.

Although book transfers settle almost instantly, all transfers are asynchronous. Monitor the transfer state to confirm it reaches completed before using the funds.

Method 3: Funding via a customer's deposit bank account

Customers can receive funds directly into their fiat account via their deposit bank account. For details on creating a deposit bank account, see Deposit Bank Accounts.

Customers can receive funds via ACH push, wire transfer, RTP, or FedNow. Funds sent to a customer's deposit bank account are automatically reconciled to the linked fiat account.

❗️

Minimum deposit

Deposits less than $0.50 are not accepted by the platform and are not returned to the depositor. Do not send transfers to deposit bank accounts that are less than $0.50.

When a deposit is reconciled, the platform_balance in the fiat account reflects the deposit amount.

Funding via a deposit bank account involves the following steps:

  1. Create a fiat account for the customer or bank
  2. Create a deposit bank account associated with the fiat account
  3. If the deposit bank account is for a bank-level fiat account, provide the deposit bank account account holder details to the Cybrid team: holder name, holder address, email address and phone number. If the deposit bank account is for a customer-level fiat account then this step is not required.
  4. If the deposit bank account is for a bank-level fiat account, wait for the Cybrid team to configure the deposit bank account with the holder details. If the deposit bank account is for a customer-level fiat account then this step is not required and the deposit bank account can be used right away.
  5. Send funds to the deposit bank account using Wire, ACH Push, RTP or FedNow.
  6. Wait for the funds to settle on the Cybrid Platform.

Create a fiat account

To create a USD fiat account, use POST /api/accounts.

Example request:

{
  "type": "fiat",
  "customer_guid": "your-customer-guid",
  "asset": "USD",
  "name": "your-account-name"
}

Example response:

{
  "type": "string",
  "guid": "string",
  "created_at": "2024-06-07T15:17:37.355Z",
  "updated_at": "2024-06-07T15:17:37.355Z",
  "asset": "string",
  "name": "string",
  "bank_guid": "string",
  "customer_guid": "string",
  "platform_balance": 0,
  "platform_available": 0,
  "state": "string",
  "labels": [
    "string"
  ]
}

You'll use the guid from the response above when creating the deposit bank account.

Create a deposit bank account

To create a routable deposit bank account, use POST /api/deposit_bank_accounts.

Example request:

{
  "type":"main",
  "account_guid": "your-account-guid",
  "customer_guid": "your-customer-guid"
}

Example response:

{
  "guid": "string",
  "type": "string",
  "bank_guid": "string",
  "customer_guid": "string",
  "account_guid": "string",
  "created_at": "2024-06-07T15:17:37.355Z",
  "updated_at": "2024-06-07T15:17:37.355Z",
  "asset": "string",
  "state": "string",
  "unique_memo_id": "string",
  "counterparty_name": "string",
  "counterparty_address": {
    "street": "string",
    "street2": "string",
    "city": "string",
    "subdivision": "string",
    "postal_code": "string",
    "country_code": "string"
  },
  "account_details": [
    {
      "account_number": "string"
    }
  ],
  "routing_details": [
    {
      "routing_number_type": "string",
      "routing_number": "string"
    }
  ],
  "labels": [
    "string"
  ]
}

Provide deposit bank account counterparty details to the Cybrid team (ONLY required for bank-level fiat accounts)

The counterparty_name and counterparty_address returned in the response are placeholder data if the deposit bank account was created from a bank-level fiat account.

When created from a customer-level fiat account, counterparty_name and counterparty_address match the customer's KYC information.

For bank-level accounts, you'll need to provide the guid from the response above, as well as the following deposit bank account counterparty details to the Cybrid team in your partner channel:

  • Counterparty name
  • Counterparty address:
    • Street
    • Street2
    • City
    • Subdivision (i.e. state/province)
    • Postal code/zip code
    • Country code
  • Counterparty email
  • Counterparty phone

Wait for Cybrid team to configure the deposit bank account (bank-level fiat accounts only)

After providing the deposit bank account guid and counterparty details, the Cybrid team will confirm when the configuration is complete.

Once the Cybrid team has confirmed the configuration is complete, you may then initiate transfers to this deposit bank account.

Sending funds to the deposit bank account

Retrieve the routing details for the deposit bank account using GET /api/deposit_bank_accounts/{deposit_bank_account_guid}.

❗️

Minimum deposit

Deposits less than $0.50 are not accepted by the platform and are not returned to the depositor. Do not send wires or ACH transfers to deposit bank accounts for less than $0.50.

When the funds are received by the Cybrid Platform and reconciled, a new funding deposit transfer will be automatically created. This funding deposit transfer will progress through the typical sequence of states (i.e. pending, completed).

Monitor the transfer using GET /api/transfers/{transfer_guid} or register for webhooks.