> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brale.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ach_debit to end user wallet 

> Create an ach_debit funded transaction to a custodial, or self custody wallet.

## Introduction

This document is a guide to help your team evaluate and implement the ach\_debit transfer type. It covers what the ach\_debit functionalities are, how to get set up, and the key steps to go from initial testing to production. Use it as a reference while you integrate.

When making `POST` requests Brale requires an Idempotency-Key header to be included and used on retries. Read more about [idempotency keys in Brale](https://brale.mintlify.app/key-concepts/idempotency#what-is-an-idempotency-key). Using ach-debits required your business to be fully onboarded, and branded ach\_debits are a premium feature.

* **Testnet Environment**
  * If users wants to first test the below endpoints on testnet, they will need to create API credentials that are scoped to testnet - please follow the below link for more information:
    * [Sandbox and Testnet walkthrough](https://brale.mintlify.app/overview/sandbox-and-testnet)
* **Production Environment**
  * Partners can leverage mainnet APIs by using their mainnet API keys generated in the Brale Portal.

## End Customer Account Creation

* [`Here is an example of how to get your account_id`](https://brale.mintlify.app/guides/how-to/get-your-account-id)

  ```tsx theme={null}
  curl --request GET \
    --url https://api.brale.xyz/accounts \
    --header "Authorization: Bearer ${ACCESS_TOKEN}"
  ```
* Managed account model: where Partner’s end users can create an account under Partner account, where Partner will have access to those accounts. This will allow end users to view their account and transaction history for all onramp operations executed. The Partner will be able to execute onramp operations on behalf of the end users as well.

## **Create Plaid link token**

* The following request is an example of how to create a Plaid Token that you will need to use next section when setting up addresses for funding your transactions. Specifically, you will want to store the `link_token` as this is the plaid token you will need to use in subsequent requests.
* **Native mobile app considerations (Plaid Link):**

  Because Brale manages the Plaid client configuration, mobile Plaid OAuth is **not fully self-serve**. You must submit your platform-specific values to Brale so they can be whitelisted before mobile Plaid OAuth will work.

  Your backend should create the `link_token`. Your mobile app uses the `link_token` to initialize Plaid Link.

  **iOS:**

  * Provide Brale with your iOS **redirect URI**. This must be an HTTPS universal link (e.g., `https://example.com/plaid-redirect`). Custom URL schemes are not supported for Plaid OAuth on iOS.
  * Your app must be configured for [Universal Links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content) so the redirect returns the user to your app after they complete the bank login.

  **Android:**

  * Provide Brale with your **Android package name** (`android_package_name`, i.e., the `applicationId` from your app's build configuration).
  * The package name you submit must exactly match your app's configuration. A mismatch will prevent Plaid from redirecting back to your app.

  <Warning>
    Brale must whitelist your iOS redirect URI and/or Android package name before mobile Plaid OAuth will function. Contact Brale to submit these values.
  </Warning>

  **Troubleshooting: user completes bank login but is not returned to the app**

  If the user finishes the Plaid/bank login flow but lands in Safari (iOS) or is not redirected back to your app (Android), check the following:

  * **Brale whitelist not completed** — confirm Brale has approved your redirect URI or package name.
  * **iOS Universal Link misconfigured** — verify your app's Associated Domains entitlement and `apple-app-site-association` file are set up correctly.
  * **Android package name mismatch** — ensure the `android_package_name` submitted to Brale matches your app's `applicationId`.
  * **App configuration does not match the submitted value** — double-check that the value registered with Brale exactly matches what your app is using at runtime.

```bash theme={null}
curl --request POST \
  --url https://api.brale.xyz/accounts/{account_id}/plaid/link_token \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "legal_name": "John Doe",
  "email_address": "user@example.com",
  "phone_number": "+1234567890",
  "date_of_birth": "1990-01-01"
}
'
```

Response Body Example:

```json theme={null}
{
  "link_token": "link-sandbox-123456789",
  "expiration": "2024-01-01T12:00:00Z",
  "callback_url": "https://customer.com/webhooks/plaid-updates"
}
```

* Your backend should call the endpoint indicated by `callback_url` (which is the Brale “register account” step) and pass the `public_token` (and your webhook URL, if applicable). This registers the bank account inside Brale and returns an `address_id` for subsequent transfers.

## Setup addresses (Funding)

* If the user wants to connect a financial institution to fund their stablecoin with, they will need to create an external address for it. The same goes for funding stablecoins with existing digital assets from an external wallet. When transferring to an external address (on-chain wallet or off-chain bank account), use:
* **`POST /accounts/{account_id}/addresses/external`**
* Include an **`Idempotency-Key`** header and a JSON body. Examples: **On-chain wallet (e.g., Solana) request body example:**

  ```json theme={null}
  {
    "name": "User Solana Wallet",
    "address": "7xKXtg...",
    "transfer_types": ["solana"]
  }
  ```

  **Off-chain bank account request example:**

  * Partner will need to create a form that requests this information from end users to provide the below data
  * Once the below data has been recorded, Brale will generate a “Address ID” that corresponds to the financial institution OR the external wallet, and for any future debit operations we will reference the “Address ID”. [Create off-chain external address](https://brale.mintlify.app/api-reference/brale/create-address):

  ```bash theme={null}
  curl --request POST \
    --url https://api.brale.xyz/accounts/{account_id}/addresses/external \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Idempotency-Key: <idempotency-key>' \
    --data '
  {
    "name": "Operating Account (ACH Debit)",
    "transfer_types": [
      "ach_debit"
    ],
    "plaid_token": "PUBLIC_TOKEN_EXCHANGED_WITH_BRALE"
  }
  '
  ```

## Requesting Mint/On-ramping

* At this stage your end users’ accounts should already be connected, where Brale will execute debits and mint to desired stablecoins from the process below:
* You will need to call the following below endpoints with the relevant data to be able to execute a `swap` or a `transfer`.

  * Transfer - Fiat to Stablecoin Transfer scenarios:
  * [`Transfer scenarios: understanding value_type and transfer_type`](https://brale.mintlify.app/key-concepts/transfers#transfer-scenarios-understanding-value_type-and-transfer_type)

  **POST** **`https://api.brale.xyz/accounts/account_id/transfers`**

  * `USDC` to `SBC` request body example:

  ```json theme={null}
  {
    "amount": {
      "value": "100",
      "currency": "USD"
    },
    "source": {
      "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
      "value_type": "USDC",
      "transfer_type": "Solana"
    },
    "destination": {
      "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
      "value_type": "SBC",
      "transfer_type": "Solana"
    }
  }
  ```

  * [`USD to Stablecoin request body example`](https://brale.mintlify.app/key-concepts/transfers#usd-to-stablecoin-ach-debit):

  ```json theme={null}
  {
    "amount": {
      "value": "1",
      "currency": "USD"
    },
    "source": {
      "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4", // address_id is the primitive, even for onchain sources
      "value_type": "USD",
      "transfer_type": "ach_debit"
    },
    "destination": {
      "address_id": "34yGFQf7tP1HJCPAWNGaN4rh4nX",
      "value_type": "SBC",
      "transfer_type": "polygon"
    },
    "brand": { "account_id": "34lCJZ2bxbPAzB3ou67Md01veUo" }
  }
  ```
