curl --request GET \
--url https://sandbox-api.sakawave.example/v1/currencies/{code}/routes \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sandbox-api.sakawave.example/v1/currencies/{code}/routes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://sandbox-api.sakawave.example/v1/currencies/{code}/routes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)[
{
"id": "01K2Z3AB4M5N6P7Q8RSTVWXYZA",
"name": "Kenya bank transfer",
"destinationCurrency": "KES",
"destinationCountry": "KE",
"scheme": "pesalink",
"paymentMethod": "bank-transfer",
"provider": "provider-a",
"serviceCode": "KE_BANK_TRANSFER",
"requiredFields": [
"bankCode",
"accountNumber"
],
"fieldDescriptors": [
{
"key": "bankCode",
"label": "Bank",
"type": "select",
"required": true,
"options": [
{
"value": "001",
"label": "Example Bank"
}
]
},
{
"key": "accountNumber",
"label": "Account number",
"type": "text",
"required": true,
"minLength": 6,
"maxLength": 20,
"placeholder": "0123456789"
}
],
"settlementTiming": "same_day",
"minimumAmount": "10000",
"maximumAmount": "100000000",
"institutionDirectoryEnabled": true,
"isDefault": true,
"isActive": true
}
]{
"statusCode": 400,
"message": "Must be a valid identifier.",
"code": "validation_failed",
"errors": [
{
"message": "Must be a valid identifier.",
"field": "accountId",
"code": "custom",
"path": [
"accountId"
]
}
]
}{
"statusCode": 401,
"code": "INVALID_API_KEY",
"message": "Invalid or inactive API credentials."
}{
"statusCode": 429,
"message": "Too many API requests. Try again later.",
"code": "api_key_rate_limit_exceeded",
"retryAfterSeconds": 17
}{
"statusCode": 500,
"code": "internal_server_error",
"message": "An unexpected error occurred."
}List routes for a currency
Active payout routes that can deliver to this destination currency, default first. A route carries the routeId and the exact field descriptors you need to build a payment detail or an external destination.
curl --request GET \
--url https://sandbox-api.sakawave.example/v1/currencies/{code}/routes \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sandbox-api.sakawave.example/v1/currencies/{code}/routes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://sandbox-api.sakawave.example/v1/currencies/{code}/routes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)[
{
"id": "01K2Z3AB4M5N6P7Q8RSTVWXYZA",
"name": "Kenya bank transfer",
"destinationCurrency": "KES",
"destinationCountry": "KE",
"scheme": "pesalink",
"paymentMethod": "bank-transfer",
"provider": "provider-a",
"serviceCode": "KE_BANK_TRANSFER",
"requiredFields": [
"bankCode",
"accountNumber"
],
"fieldDescriptors": [
{
"key": "bankCode",
"label": "Bank",
"type": "select",
"required": true,
"options": [
{
"value": "001",
"label": "Example Bank"
}
]
},
{
"key": "accountNumber",
"label": "Account number",
"type": "text",
"required": true,
"minLength": 6,
"maxLength": 20,
"placeholder": "0123456789"
}
],
"settlementTiming": "same_day",
"minimumAmount": "10000",
"maximumAmount": "100000000",
"institutionDirectoryEnabled": true,
"isDefault": true,
"isActive": true
}
]{
"statusCode": 400,
"message": "Must be a valid identifier.",
"code": "validation_failed",
"errors": [
{
"message": "Must be a valid identifier.",
"field": "accountId",
"code": "custom",
"path": [
"accountId"
]
}
]
}{
"statusCode": 401,
"code": "INVALID_API_KEY",
"message": "Invalid or inactive API credentials."
}{
"statusCode": 429,
"message": "Too many API requests. Try again later.",
"code": "api_key_rate_limit_exceeded",
"retryAfterSeconds": 17
}{
"statusCode": 500,
"code": "internal_server_error",
"message": "An unexpected error occurred."
}An unknown currency is not an error
The code is not checked against the currency list. A currency Sakawave does not serve simply matches no routes and returns[] — so an empty array means “nothing delivers there”, not “you asked wrongly”.
Country filtering
A route can be scoped to one country, or serve many through its scheme —sepa and cemac both cover a set. Passing country keeps only the routes that actually serve it, whichever way they are scoped.
Prefer corridors for building a form
This endpoint returns the route row as stored, including internal routing detail.GET /v1/transfer-corridors answers the same question in a provider-neutral shape, with the currency and its countries resolved alongside each route. Use corridors to drive a UI; use this when you already know the currency and only need its routeId values.
provider and serviceCode are internal routing detail that this endpoint currently returns. They are not part of the supported contract and may be withdrawn — do not branch on them.Error codes
| Status | code | Cause |
|---|---|---|
400 | validation_failed | code is not three characters, or country is not two. |
401 | INVALID_API_KEY | The key is missing, invalid, inactive, expired, from the other environment, or blocked by its IP allowlist. |
429 | api_key_rate_limit_exceeded | The per-minute limit for this key was exceeded. |
Authorizations
A secret API key, sent as Authorization: Bearer sk_test_… in sandbox or Bearer sk_live_… in live.
Path Parameters
Destination currency code. Case-insensitive; uppercased before matching.
3 - 10Query Parameters
ISO 3166-1 alpha-2 destination country. Keeps only routes that serve it.
2Response
Successful response.
The routeId to send when creating a payment detail or an external destination.
26^[0-7][0-9A-HJKMNP-TV-Z]{25}$"01K2Z3AB4C5D6E7F8G9HJKMNPQ"
80Null for a route that is not currency-scoped.
3 - 10ISO 3166-1 alpha-2 when the route serves one country. Null for a scheme that spans several.
16The settlement scheme, such as nip, sepa, or cemac.
40bank-transfer, momo-transfer, or stablecoin-transfer for a route that pays a wallet address; its scheme is the chain.
40Internal routing detail. Not part of the supported contract — do not branch on it.
40Internal routing detail. Not part of the supported contract.
60Keys of fieldDescriptors that must be supplied.
Show child attributes
Show child attributes
80An integer number of the asset’s smallest unit. Use this value for arithmetic.
^-?\d+$"2500000"
An integer number of the asset’s smallest unit. Use this value for arithmetic.
^-?\d+$"2500000"
Whether Sakawave resolves institution codes to names for this route.
The route chosen when you do not name one. Listed first.
Always true in this response: inactive routes are not returned.