Channels
Overview
Channels represent a payment route with specific characteristics for processing transactions.
A Channel can be seen as a type of contract where the details are fixed, including fees and transaction limits.
Each Channel is defined by:
- Country
- Fiat Currency
- Payment Method Type
Important note: the Country code XX is used for Channels with multiple compatible countries, these Channels are available internationally.
Using Channels
Get Available Countries
To retrieve the list of supported countries and their available fiat currencies, use the GET /channels/sell/countries endpoint in the Business API.
curl -L 'https://api.sandbox.noah.com/v1/channels/sell/countries' \
-H 'Accept: application/json' \
-H 'X-Api-Key: <X-Api-Key>'
Get Available Channels
Query available channels for a specific country or currency:
To retrieve the list of available channels for a specific country or currency, use the GET /channels/sell endpoint in the Business API.
curl -L 'https://api.sandbox.noah.com/v1/channels/sell
?Country=GB // Provide country (optional if currency is specified)
&CryptoCurrency=USDC_TEST
&FiatCurrency=EUR // Provide currency (optional if country is specified)
&FiatAmount=1000' // Optional - includes price calculation \
-H 'Accept: application/json' \
-H 'X-Api-Key: <X-Api-Key>'
For details on the USDC_TEST token, used above, see Sandbox Testnet Currencies.
For each channel returned by the call above, the response body is as follows.
{
"Calculated": {
"TotalFee": "2"
},
"Country": "DE",
"FiatCurrency": "EUR",
"FormSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"BankDetails": {
"properties": {
"AccountType": {
"enum": [
"Checking",
"Savings"
],
"title": "Account Type",
"type": "string"
},
"AccountNumber": {
"maxLength": 22,
"minLength": 22,
"pattern": "^DE[0-9]{2}[A-Z0-9]{18}$",
"title": "IBAN",
"type": "string"
}
},
"required": [
"AccountType",
"AccountNumber"
],
"title": "Bank Details",
"type": "object"
}
},
"required": [
"BankDetails"
]
},
"ID": "ebb9736b-08b3-599d-886b-10ee8aea82b5",
"Limits": {
"MinLimit": "1"
},
"PaymentMethodCategory": "Bank",
"PaymentMethodType": "BankSepa",
"ProcessingSeconds": 60,
"Rate": "0.86"
}
Looking at the above payload, consider the following when you select a channel.
- Transaction limits (
Limitsobject). - Processing time (
ProcessingSeconds). - Payment method requirements, some channels may require a Dynamic Form to submit a transaction.
Get Dynamic Forms
You can retrieve the required form fields for a given channel through two means:
-
Directly from the Supported Channels Endpoint. When you query available channels using the
GET /channels/sellendpoint, the response includes the form schema needed for the selected payment method, as shown above. This method simplifies the process by reducing the number of API calls. -
Using the Dynamic Form Endpoint. After selecting a channel, you can retrieve the required form fields by calling the
GET /channels/:ChannelID/formendpoint. This endpoint provides a JSON Form schema specifying the required fields for the selected payment method.
Code Example
Basic channel retrieval and selection:
// 1. Get available countries
const countries = await api.get('/v1/channels/sell/countries');
// 2. Get channels for selected country
const channels = await api.get('/v1/channels/sell', {
params: {
Country: 'GB',
CryptoCurrency: 'BTC',
FiatCurrency: 'GBP',
FiatAmount: '1000',
PageSize: 20,
},
});
// 3. Get form schema for selected channel
const formSchema = await api.get(`/channels/${channelId}/form`);
Best Practice 1: Regular Updates
- Query the available payment channels immediately before displaying them to end users.
- Avoid relying on stale or cached data for prolonged periods — channels and their limits (e.g., max/min transaction amounts) can change frequently.
- Always obtain channel IDs from the Channels API at runtime — they are not suitable for caching or hardcoding.
Best Practice 2: Error Handling
- Handle channel disablement gracefully, by attempting to retrieve an equivalent channel.
- Validate transaction amounts against channel limits, before allowing a customer to select a channel.
- Verify all required form fields are available, before allowing a customer to select a channel.
Best Practice 3: Performance
- Implement pagination or filtering when listing multiple channels to reduce payload size and improve response times.
- If pricing calculations are required, pass any needed parameters (like
FiatAmount) in the API request.
Payin Channels
For payins (fiat → crypto), the channel is determined implicitly by the currency you specify when calling the POST workflows/bank-deposit-to-onchain-address endpoint. Unlike payouts where you query and select from available channels, payins use an orchestrated workflow where Noah assigns the appropriate Virtual Account and payment method based on the customer's eligibility and the requested currency.
| Fiat Currency | Virtual Account Type | Payment Method Type | How It Works |
|---|---|---|---|
| EUR | IBAN | BankSepa | Customer receives a dedicated IBAN for SEPA deposits |
| USD | ACH Routing Number | BankAch | Customer receives a dedicated ACH routing/account number. Wire transfers (BankFedwire) and international wires (BankSwift) are also accepted to the same account. |
To set up a payin channel, call the workflow endpoint with the desired FiatCurrency, CryptoCurrency, Network, and DestinationAddress. Noah returns the assigned Virtual Account details (account number, bank code, payment method ID) which you display to your customer.
For step-by-step integration guides, see:
Payin vs. Payout Channel Selection
| Aspect | Payin | Payout |
|---|---|---|
| Channel selection | Implicit - determined by currency and customer eligibility | Explicit - query available channels and select one |
| API pattern | Single call to workflow endpoint | Query channels → select → get form → prepare → execute |
| Payment method | Assigned by Noah (Virtual Account) | Customer supplies details via Dynamic Form |
| Endpoint | POST workflows/bank-deposit-to-onchain-address | GET channels/sell + POST transactions/sell |
Payment Method Types
The API uses PaymentMethodType values to identify specific payment rails. These appear in channel responses, webhook payloads, and payment method objects throughout the API.
| PaymentMethodType | Description | Currencies | Typical Settlement |
|---|---|---|---|
BankSepa | SEPA Credit Transfer | EUR | 1-3 business days |
BankSepaInstant | SEPA Instant Credit Transfer | EUR | Seconds |
BankAch | ACH transfer (US) | USD | 1-3 business days |
BankFedwire | Fedwire (US domestic wire) | USD | Same day |
BankSwift | SWIFT / International Wire | USD, EUR | 1-5 business days |
Additional payment method types are available across regions, including local bank transfers, mobile money, digital wallets, and card-based methods. The set of available methods is large and changes as new rails are added. Always query the Channels API for the current list.
The Channels API is the authoritative source for available payment methods. The table above covers the core banking rails for Virtual Account flows. For the full set of payout methods available in any given country, query the GET /channels/sell endpoint at runtime.
Each payment method type belongs to a PaymentMethodCategory:
| Category | Description | Form Data |
|---|---|---|
| Bank | Bank transfer methods (SEPA, ACH, Fedwire, SWIFT, and local equivalents) | Bank account details (IBAN, routing number, account number) |
| Card | Card-based payment methods | Card details (via hosted interface) |
| Identifier | Identifier-based methods (e.g. tax ID, phone number, email) | Local identifier as required by the payment rail |
The FormSchema returned by a channel tells you exactly which fields to collect for that specific payment method and provider. See Form Schemas for details on rendering and submitting form data.
Related Developer Journeys
- Form Schemas — Understanding and using form schemas for automation
- Dynamic User Interface — Building UIs with dynamic forms
- Global Payout Journey
- Automated Payout