Skip to main content

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.

Key rules
  • All IDs are KSUIDs (26-char, time-sortable); copy/paste carefully.
  • address_id is the universal source/destination primitive (covers wallets and fiat endpoints).
  • Always send Idempotency-Key on create POSTs; never on GETs. Do not reuse a key with a different payload/URI.
Each transfer requires both a source and a destination, which can be:
  • Fiat sources (e.g., a bank account for ACH or wire)
  • On-chain wallet addresses
Each source and destination includes:
  • value_type: The currency being transferred (USD, USDC, USDT, MXN, etc.)
  • transfer_type: The payment rail used (Wire, ACH, Polygon, Solana, SPEI, etc.)

Required Fields

FieldWhereTypeDescription
account_idPathstringAccount whose funds are being moved
amountBodyobject{ "value": "10", "currency": "USD" }
sourceBodyobjectOrigin of funds (fiat rail or on-chain address)
value_typeIn source / destinationstringCurrency/token (e.g., USD, USDC, SBC)
transfer_typeIn source / destinationstringPayment rail / chain (wire, ach_credit, polygon, solana)
address_idIn source / destinationstringWallet or fiat account sending or receiving value
Idempotency-KeyHeaderstringUUID that guarantees exactly-once execution

Optional Fields

FieldWhereTypeDescription
brandBodyobjectACH only. { "account_id": "<ACCOUNT_ID>" } to control which Account name appears on ACH bank statement line items (ACH debit + ACH credit). Not supported for wire or rtp.
wire_memoIn destinationstringWire only. Memo or payment reference text sent with outbound wire transfers. Only applies when destination.transfer_type is wire.

Response-only fields

source.payment_details

source.payment_details appears when Brale has underlying payment metadata to expose for the source leg of a transfer. This is primarily relevant for inbound fiat-funded transfers (e.g., wire or ACH on-ramps, automation-triggered mints). The object is optional and may not be present on every transfer. Wire transfers typically include the fuller set of fields, while ACH transfers may include only a subset — fields may be null or omitted depending on available rail metadata.
FieldTypeDescription
received_atstring (ISO 8601)When the underlying payment was received or posted
sender_namestring | nullName of the originating sender, when available
sender_bank_namestring | nullOriginating bank name, when available
sender_bank_routing_numberstring | nullOriginating bank routing number, when available
payment_referencestring | nullSender-provided payment reference or memo, when available
imadstring | nullWire IMAD / tracking identifier, when available
trace_numberstring | nullACH trace identifier for the underlying payment, when available. Primarily relevant for inbound ACH-funded transfers.
source.payment_details is a response-only field. It is not accepted as input when creating a transfer. Do not confuse it with destination.wire_memo, which is a request field for outbound wire transfers.

destination.payment_details

destination.payment_details appears when Brale has underlying payment metadata to expose for the destination leg of a transfer. This is primarily relevant for outbound wire transfers (stablecoin-to-fiat offramps and wire payouts). The object is optional and may be absent immediately after a transfer is created. For outbound wires, the IMAD is assigned by the sending bank and may not be available until after the wire has been submitted — Brale populates destination.payment_details later when the underlying bank metadata arrives.
FieldTypeDescription
imadstring | nullWire IMAD / tracking identifier for the outbound wire, when available
destination.payment_details is a response-only field. It is not accepted as input when creating a transfer. Do not confuse it with destination.wire_memo, which remains a request field for outbound wire transfers.

Transfer scenarios: understanding value_type and transfer_type

FlowSourceDestinationDescription
Onramp
(Fiat → Stablecoin)
USD / wireSBC / baseMint SBC on Base funded by wire deposit
Offramp
(Stablecoin → Fiat)
SBC / solanaUSD / ACHRedeem SBC on Solana to USD via ACH
Swap
(Stablecoin ↔ Stablecoin)
USDC / solanaSBC / solana1:1 swap from USDC to SBC with no slippage
On-chain PayoutUSDC / polygonUSDC / polygon (external address)Pay a recipient wallet
USDC off-ramp (wire)USDC / polygonUSD / wireOfframp USDC to wire
SBC branded ACH payout (ACH only)SBC / baseUSD / ach_credit + brand (ACH only)ACH payout with brand on statement
Every request is scoped to an account, so the path always starts with: POST https://api.brale.xyz/accounts/{account_id}/transfers // The ID of your or your customer's account

USD to Stablecoin (Wire Transfer)

Accept a USD deposit to mint stablecoins. POST https://api.brale.xyz/accounts/account_id/transfers
curl --request POST \
  --url "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers" \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer ${AUTH_TOKEN}" \
  --header "Idempotency-Key: $(uuidgen)" \          # generate a fresh key per logical transfer; reuse on retries of the same transfer
  --data '{
    "amount":    { "value": "10", "currency": "USD" },
    "source":    { "value_type": "usd", "transfer_type": "wire" },
    "destination": {
      "address_id": "'"${ADDRESS_ID}"'",
      "value_type": "sbc",
      "transfer_type": "base"
    }
  }'
When initiating a fiat to stablecoin transfer via wire, we will return a set of wire_instructions so you can provide them to your customer.
Response
{
  "id": "2xNL6PAF0cbcQHyjMQJ2RKRfbD9",
  "status": "pending",
  "source": {
    "value_type": "USD",
    "transfer_type": "wire"
  },
  "destination": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "SBC",
    "transfer_type": "base"
  },
  "updated_at": "2025-05-20T20:36:48.147281Z",
  "created_at": "2025-05-20T20:36:48.147281Z",
  "amount": {
    "value": "10",
    "currency": "USD"
  },
  "note": null,
  "wire_instructions": {
    // Brale Bank instructions
  }
}

USD to Stablecoin (ACH Debit)

Onramp to your stablecoin by debiting a Plaid connected address. POST https://api.brale.xyz/accounts/account_id/transfers
Request
{
  "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" }
}
Optional brand object You can specify which Account’s name appears on the receiver’s bank statement line items for ACH only. It is not supported for wire or RTP.

Stablecoin to USD (Wire Offramp or Payout)

Offramp your stablecoin to USD via wire transfer. POST https://api.brale.xyz/accounts/account_id/transfers
Request
{
  "amount": {
    "value": "1",
    "currency": "USD"
  },
  "source": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "SBC",
    "transfer_type": "Polygon"
  },
  "destination": {
    "address_id": "34yGFQf7tP1HJCPAWNGaN4rh4nX",
    "value_type": "USD",
    "transfer_type": "wire",
    "wire_memo": "Invoice 1048"
  }
}
For outbound wire transfers, you can optionally pass destination.wire_memo to include a memo or payment reference for the receiving bank or recipient.

Stablecoin to USD (ACH)

Offramp your stablecoin to USD via ACH Credit. POST https://api.brale.xyz/accounts/account_id/transfers
Request
{
  "amount": {
    "value": "1",
    "currency": "USD"
  },
  "source": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "SBC",
    "transfer_type": "canton"
  },
  "destination": {
    "address_id": "34yGFQf7tP1HJCPAWNGaN4rh4nX",
    "value_type": "USD",
    "transfer_type": "same_day_ach_credit"
  }
}

Stablecoin Swaps

Swap USDC to your own stablecoin (YSBC). All stablecoin swaps are 1:1 with no slippage. POST https://api.brale.xyz/accounts/account_id/transfers
Request
{
  "amount": {
    "value": "100",
    "currency": "USD"
  },
  "source": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "USDC",
    "transfer_type": "Solana"
  },
  "destination": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "YSBC",
    "transfer_type": "Solana"
  }
}

Stablecoin Payout

Process stablecoin payouts to one or many external addresses (EOAs). POST https://api.brale.xyz/accounts/account_id/transfers
Request
{
  "amount": {
    "value": "500",
    "currency": "USD"
  },
  "source": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "SBC",
    "transfer_type": "Solana"
  },
  "destination": {
    "address_id": "2xNL6PAF0cbcQHyjMQJ2RKRfbD9",
    "value_type": "SBC",
    "transfer_type": "Solana"
  }
}

Retrieving a single transfer

GET https://api.brale.xyz/accounts/{account_id}/transfers/{transfer_id}

On-chain transfer response

Response
{
  "id": "30NoY6R1Ns2tRBcx1Kb16SnuXOW",
  "status": "complete",
  "amount": {
    "value": "100.00",
    "currency": "USD"
  },
  "created_at": "2025-07-25T21:03:55.364134Z",
  "updated_at": "2025-07-25T21:05:07.779018Z",
  "source": {
    "address_id": "2MhCCIHuK4TGVgT9a4loQzJx1rj",
    "value_type": "USDC",
    "transfer_type": "polygon",
    "transaction_id": "0xdd5646ea…"
  },
  "destination": {
    "address_id": "2O6asmNK4TGVgT9a4loQzJx1rj",
    "value_type": "USDC",
    "transfer_type": "polygon",
    "transaction_id": "0xdd5646ea…"
  },
  "note": null
}

Wire-funded transfer response (with payment_details)

For inbound wire-funded transfers, the response includes source.payment_details with metadata about the underlying payment. This helps you identify the sender and reconcile inbound fiat payments.
Response
{
  "id": "3C0QcbwVywOGyU2HBSenljm5dhU",
  "status": "complete",
  "failure": null,
  "source": {
    "transfer_type": "wire",
    "financial_institution_id": "3AjRnbvj9Mq6crkviJv08d0KLB2",
    "value_type": "USD",
    "payment_details": {
      "received_at": "2026-04-07T00:01:24.514000Z",
      "sender_name": "Originator Name",
      "sender_bank_name": "JPMorgan Chase Bank",
      "sender_bank_routing_number": "000000123",
      "payment_reference": "Simulated Wire",
      "imad": "20260406XOIZJDPP953495"
    }
  },
  "destination": {
    "transaction_id": "0x41c66f1d059dad7a55a854e157a1b5b938780c77ba5296e434a02dfb1727fe5e",
    "transfer_type": "base",
    "address_id": "3ARaM0I93ObWOIFDIztsTx4TAsp",
    "value_type": "ARB"
  },
  "updated_at": "2026-04-07T00:01:44.824834Z",
  "created_at": "2026-04-07T00:01:27.756775Z",
  "note": null,
  "amount": {
    "value": "102.0",
    "currency": "USD"
  },
  "automation_id": "3AjRnDClEzwuCKlRioG3OXMS4pH"
}

Outbound wire transfer response (with destination.payment_details)

For outbound wire transfers (e.g., stablecoin-to-fiat offramps via wire), the response may include destination.payment_details with the wire IMAD once Brale has received the underlying bank metadata. The object may be absent immediately after the transfer is created and appear later when the wire is submitted.
Response
{
  "id": "3D1RcbwVywOGyU2HBSenljm5dhV",
  "status": "complete",
  "source": {
    "address_id": "2VcUIonJeVQzFoBuC7LdFT0dRe4",
    "value_type": "SBC",
    "transfer_type": "solana",
    "transaction_id": "5K8…"
  },
  "destination": {
    "address_id": "34yGFQf7tP1HJCPAWNGaN4rh4nX",
    "value_type": "USD",
    "transfer_type": "wire",
    "wire_memo": "Invoice 1048",
    "payment_details": {
      "imad": "20260406XOIZJDPP953495"
    }
  },
  "updated_at": "2026-04-07T00:05:12.102000Z",
  "created_at": "2026-04-07T00:01:27.756775Z",
  "amount": {
    "value": "100.00",
    "currency": "USD"
  },
  "note": null
}

ACH-funded transfer response (with payment_details)

ACH transfers may include only a subset of payment_details fields. Fields may be null or omitted depending on available rail metadata.
Response (source excerpt)
{
  "source": {
    "transfer_type": "ach_debit",
    "value_type": "USD",
    "payment_details": {
      "received_at": "2026-04-07T02:10:06.921000Z",
      "sender_name": "Test ACH Sender",
      "sender_bank_name": null,
      "sender_bank_routing_number": "721160232",
      "payment_reference": null,
      "imad": null,
      "trace_number": "021000029876543"
    }
  }
}
transaction_id is a response-only field on source and destination. It contains the on-chain transaction hash or off-chain payment reference once the leg has been submitted to the network. It is not present in create requests. You can use transaction_id as a query-parameter filter on the list transfers endpoint.

Listing transfers

GET https://api.brale.xyz/accounts/{account_id}/transfers Returns a paginated list of transfers for the account. You can narrow results with query-parameter filters.

Filters

All filters are exact match and case-sensitive. When you combine multiple filters they apply with AND semantics.
ParameterFilters byFormatExample
automation_idAutomation that created the transferKSUID2MhCCIHuK4TGVgT9a4loQzJx1rj
value_typeCurrency / token on source or destinationCanonical API idUSDC, SBC, usd
transfer_typePayment rail / chain on source or destinationCanonical API idpolygon, wire, solana
transaction_idOn-chain transaction hash or off-chain payment referenceString (exact match)0xdd5646ea…
value_type and transfer_type use canonical identifiers listed on the Value types and Transfer types coverage pages.
If no transfers match, the API returns 200 with an empty transfers array.

Filtering by transaction_id

transaction_id is an exact-match filter. Pass the full on-chain transaction hash or off-chain payment reference as the value. The filter matches against the transaction_id field on either the source or destination leg of each transfer.
  • The value must match exactly (case-sensitive, no partial matches).
  • If no transfer matches, the API returns 200 with an empty transfers array.
  • You can combine transaction_id with other filters (transfer_type, value_type, automation_id). Multiple filters use AND semantics — only transfers matching every filter are returned.
curl "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers?transaction_id=<onchain_hash>" \
  -H "Authorization: Bearer ${AUTH_TOKEN}"

Example: filter by automation

curl "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers?automation_id=2MhCCIHuK4TGVgT9a4loQzJx1rj" \
  -H "Authorization: Bearer ${AUTH_TOKEN}"

Example: combined filters

curl "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers?value_type=USDC&transfer_type=polygon&page[size]=10" \
  -H "Authorization: Bearer ${AUTH_TOKEN}"

Pagination

ParameterDescriptionDefault
page[size]Results per page (1–100)25
page[after]Cursor for forward pagination
page[prev]Cursor from pagination.prev
Only one of page[after] or page[prev] may be present per request. Filters persist across pages — you do not need to resend them when paging. Use the pagination.next value from the previous response as the page[after] query parameter in the next request.
# First page
curl "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers?page[size]=50" \
  -H "Authorization: Bearer ${AUTH_TOKEN}"

# Next page
curl "https://api.brale.xyz/accounts/${ACCOUNT_ID}/transfers?page[size]=50&page[after]=${cursor}" \
  -H "Authorization: Bearer ${AUTH_TOKEN}"

Reconciliation best practices

  • Store transfer id, Idempotency-Key, timestamps, status, and any provider references.
  • For inbound fiat-funded transfers, check source.payment_details to identify the sender and match payments. Wire transfers typically include sender_name, sender_bank_name, and imad; ACH transfers may include only a subset of these fields.
  • For outbound wire transfers, check destination.payment_details.imad to record the wire’s IMAD for reconciliation and tracing. It may be absent immediately after the transfer is created and populated later once Brale has the underlying bank metadata.
  • Poll with backoff; avoid tight loops. Reuse the same Idempotency-Key when retrying the same logical transfer.
  • On 401, refresh the token and retry idempotently.

Transfer Statuses

ValueDescription
pendingThe transfer has been submitted but is not yet in progress. This may be due to Brale waiting for funds (e.g., fiat-to-stablecoin wire transfer) or an ongoing review.
processingThe transfer is in progress.
completeThe transfer is finalized and funds have arrived at the destination.
canceledThe transfer has been canceled.
failedAn issue prevented Brale from completing the transfer. Manual intervention may be required.

Transfer Flow

A transfer will progress from pendingprocessingcomplete. Transfers include an updated_at field denoting the last time the status updated.

Transfer Limits

  • Inbound ACH transactions are limited to $50,000 per transaction.
  • There are no limits for wire or stablecoin transactions.