curl --request PATCH \
--url https://api.bachs.io/v1/payouts/destinations/{destination_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Treasury NGN Account"
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Treasury NGN Account'})
};
fetch('https://api.bachs.io/v1/payouts/destinations/{destination_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/payouts/destinations/{destination_id}"
payload = { "name": "Treasury NGN Account" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/payouts/destinations/{destination_id}"
payload := strings.NewReader("{\n \"name\": \"Treasury NGN Account\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "pd_7Kq2mNv4XbR9dLc0",
"name": "Treasury NGN Account",
"type": "bank_account",
"currency": "NGN",
"status": "pending_review",
"status_reason": null,
"is_usable": false,
"is_default": false,
"account_number": "0123456789",
"account_name": "JOHN DOE",
"bank_code": "058",
"bank_name": "Guaranty Trust Bank",
"phone_number": null,
"mobile_provider": null,
"wallet_address": null,
"network": null,
"reviewed_at": null,
"created_at": "2026-01-24T14:30:00.000Z",
"updated_at": "2026-02-22T14:30:00.000Z"
}{
"detail": "Invalid request parameters",
"error_code": "VALIDATION_ERROR",
"errors": [
{
"field": "amount",
"message": "Amount must be a positive decimal string",
"type": "value_error"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}{
"detail": "Resource not found",
"error_code": "NOT_FOUND"
}{
"detail": "Rate limit exceeded. Please retry after a few seconds.",
"error_code": "TOO_MANY_REQUESTS"
}{
"detail": "An unexpected error occurred. Please try again later.",
"error_code": "INTERNAL_SERVER_ERROR"
}Update Payout Destination
Update a destination: rename it, (de)promote it as a payout schedule’s default, or restate where money lands.
name and is_default alone are safe: neither touches review status, since the default can only ever be one of your own approved destinations. Sending any routing detail (currency, type, account, wallet or phone) restates the destination in full, the same shape as POST; omitted routing fields fall back to what is already stored. Changing an account number, bank code, wallet, network, or phone number this way sends the destination back for review, because the approval it holds was granted for the details it is being asked to leave behind.
Common errors:
400 VALIDATION_ERROR: neithernamenoris_defaultsent, or an invalid payload for the destination type. Resolution: validate request fields and retry.401 UNAUTHORIZED: API key is missing, invalid, or revoked. Resolution: use a valid API key in theAuthorizationheader.404 NOT_FOUND:destination_idwas not found. Resolution: verify destination ID and retry.
curl --request PATCH \
--url https://api.bachs.io/v1/payouts/destinations/{destination_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Treasury NGN Account"
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Treasury NGN Account'})
};
fetch('https://api.bachs.io/v1/payouts/destinations/{destination_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/payouts/destinations/{destination_id}"
payload = { "name": "Treasury NGN Account" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/payouts/destinations/{destination_id}"
payload := strings.NewReader("{\n \"name\": \"Treasury NGN Account\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "pd_7Kq2mNv4XbR9dLc0",
"name": "Treasury NGN Account",
"type": "bank_account",
"currency": "NGN",
"status": "pending_review",
"status_reason": null,
"is_usable": false,
"is_default": false,
"account_number": "0123456789",
"account_name": "JOHN DOE",
"bank_code": "058",
"bank_name": "Guaranty Trust Bank",
"phone_number": null,
"mobile_provider": null,
"wallet_address": null,
"network": null,
"reviewed_at": null,
"created_at": "2026-01-24T14:30:00.000Z",
"updated_at": "2026-02-22T14:30:00.000Z"
}{
"detail": "Invalid request parameters",
"error_code": "VALIDATION_ERROR",
"errors": [
{
"field": "amount",
"message": "Amount must be a positive decimal string",
"type": "value_error"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}{
"detail": "Resource not found",
"error_code": "NOT_FOUND"
}{
"detail": "Rate limit exceeded. Please retry after a few seconds.",
"error_code": "TOO_MANY_REQUESTS"
}{
"detail": "An unexpected error occurred. Please try again later.",
"error_code": "INTERNAL_SERVER_ERROR"
}Authorizations
Bearer token authentication. Pass your API key as Authorization: Bearer sk_.... See Authentication for keys, scopes, and sandbox vs production.
Path Parameters
Body
The one update a destination allows. name and is_default alone are safe: a rename touches no routing column, and the default can only ever be one of your own approved destinations. Sending any field below restates the destination in full, the same shape as POST; omitted routing fields fall back to what is already stored. Changing an account number, bank code, wallet, network or phone number this way sends the destination back for review, because the approval it holds was granted for the details it is being asked to leave behind.
The new name for this destination.
1 - 255"Treasury NGN Account"
Make this the destination a payout schedule pays out to for its currency. Setting it demotes the previous default; false clears it. Ignored if this request also changes where money lands and that change sends the destination back for review.
true
Currency code this destination accepts (e.g., 'NGN', 'USD', 'USDT_TRC20').
10null
Type of payout destination: bank_account, mobile_money, or crypto_wallet.
null
Alias for type. type wins if both are sent.
null
Account number for bank routes that use one. EUR SEPA uses iban; CAD Interac to email uses interac_email.
50null
Account holder name required for international bank routing. For NGN, the bank resolves the name and ignores a supplied value.
255"Example account holder"
Supported local bank code from List Banks for the destination country. International schemes use their currency-specific routing fields.
20null
Bank name for international bank routing. For NGN, it is resolved from the bank.
255"Example bank"
Phone number for the mobile money account.
20null
Mobile money provider (e.g., 'MTN', 'Vodafone').
50null
Cryptocurrency wallet address.
255null
Blockchain network. Optional when the currency already names its network (e.g. USDT_TRC20).
50null
Additional custom metadata to associate with this destination.
null
GBP sort code, six digits; spaces and dashes are normalized.
12IBAN for a EUR SEPA bank destination.
50Bank BIC, 8 or 11 characters, for EUR SEPA. This does not select SWIFT; SWIFT payouts are not currently offered.
20Nine-digit US ABA routing number for USD ACH, Wire or RTP.
15US bank branch address required for USD bank destinations. This is separate from the account holder address.
Show child attributes
Show child attributes
Three-digit Canadian institution number for EFT or Interac to a bank account.
8Five-digit Canadian transit number for EFT or Interac to a bank account.
10Destination email for CAD Interac using interac_email.
255Choose ach, wire or rtp for USD; eft, interac_account or interac_email for CAD. Leave out for GBP and EUR. SWIFT payouts are not currently offered.
Response
Success
Response containing payout destination details (bank account, mobile money, or crypto wallet).
Unique identifier for this payout destination. Use this ID when creating payouts.
"pd_7Kq2mNv4XbR9dLc0"
User-friendly name for this destination. Helps you identify destinations in your system.
"My GTBank Savings"
Type of payout destination: bank_account, mobile_money, or crypto_wallet. Determines which fields are populated.
bank_account, mobile_money, crypto_wallet "bank_account"
Currency code this destination accepts (e.g., 'NGN', 'USD', 'USDT_TRC20'). Payouts to this destination must use this currency.
"NGN"
Review status. pending_review: awaiting review, not usable yet. approved: cleared for payouts. rejected: permanently unusable, register a new destination instead.
pending_review, approved, rejected "approved"
Free-text reason set by review, populated when the destination is rejected. Null while pending or approved.
null
Whether this destination can be used for a payout right now. True only when status is approved and the destination has not been deactivated.
true
Whether a payout schedule pays out to this destination for its currency. Set it with PATCH /v1/payouts/destinations/{destination_id}.
false
Account number for bank routes that use one. EUR SEPA uses iban; CAD Interac to email uses interac_email.
"0123456789"
Account holder name as resolved from the bank. Only populated for bank_account destinations.
"JOHN DOE"
Supported local bank code from List Banks for the destination country. International schemes use their currency-specific routing fields.
"058"
Full name of the bank. Only populated for bank_account destinations.
"Guaranty Trust Bank"
Phone number associated with the mobile money account. Only populated for mobile_money destinations.
null
Mobile money provider (e.g., 'MTN', 'Vodafone'). Only populated for mobile_money destinations.
null
Cryptocurrency wallet address. Only populated for crypto_wallet destinations.
null
Blockchain network (e.g., 'TRC20', 'ERC20'). Only populated for crypto_wallet destinations. May be included in currency code (e.g., 'USDT_TRC20').
null
ISO 8601 timestamp when this destination was last reviewed by an admin. Null until reviewed.
null
ISO 8601 timestamp when this destination was created.
"2026-01-24T14:30:00.000Z"
ISO 8601 timestamp when this destination was last updated.
"2026-01-24T14:30:00.000Z"
GBP sort code, six digits; spaces and dashes are normalized.
12IBAN for a EUR SEPA bank destination.
50Bank BIC, 8 or 11 characters, for EUR SEPA. This does not select SWIFT; SWIFT payouts are not currently offered.
20Nine-digit US ABA routing number for USD ACH, Wire or RTP.
15US bank branch address required for USD bank destinations. This is separate from the account holder address.
Show child attributes
Show child attributes
Three-digit Canadian institution number for EFT or Interac to a bank account.
8Five-digit Canadian transit number for EFT or Interac to a bank account.
10Destination email for CAD Interac using interac_email.
255Choose ach, wire or rtp for USD; eft, interac_account or interac_email for CAD. Leave out for GBP and EUR. SWIFT payouts are not currently offered.

