Update a beneficiary (alias)
const url = 'https://api.payhero.africa/api/global/beneficiaries/a2e0434e-17ae-41b1-a1cf-1694ad63ee99';const options = { method: 'PUT', headers: {Authorization: 'Basic <credentials>', 'Content-Type': 'application/json'}, body: '{"name":"John Doe","first_name":"John","last_name":"Doe","surname":"example","email":"john.doe@example.com","country":"KE","phone":"+254712345678","address":"Moi Drive, Umoja","date_of_birth":"10/03/1997","id_number":"32460968","id_type":"national_id","additional_id_type":"BVN","additional_id_number":"0123456789","gender":"example","marital_status":"example","account_name":"John Doe","account_number":"+254712345678","account_type":"momo","external_reference":"customer-8821","customer_type":"retail","is_active":false}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.payhero.africa/api/global/beneficiaries/a2e0434e-17ae-41b1-a1cf-1694ad63ee99 \ --header 'Authorization: Basic <credentials>' \ --header 'Content-Type: application/json' \ --data '{ "name": "John Doe", "first_name": "John", "last_name": "Doe", "surname": "example", "email": "john.doe@example.com", "country": "KE", "phone": "+254712345678", "address": "Moi Drive, Umoja", "date_of_birth": "10/03/1997", "id_number": "32460968", "id_type": "national_id", "additional_id_type": "BVN", "additional_id_number": "0123456789", "gender": "example", "marital_status": "example", "account_name": "John Doe", "account_number": "+254712345678", "account_type": "momo", "external_reference": "customer-8821", "customer_type": "retail", "is_active": false }'Identical to PATCH /api/global/beneficiaries/{uuid} — despite the verb, PUT also
merges rather than replacing. Use whichever your HTTP client prefers.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The beneficiary’s uuid, as returned on create.
Example
a2e0434e-17ae-41b1-a1cf-1694ad63ee99Request Bodyrequired
Section titled “Request Bodyrequired”object
Full name, split on the first space. Required on create unless you send
first_name + last_name instead, which win if both are present.
Example
John DoeExample
JohnExample
DoeRequired for tier_0, and therefore for every beneficiary.
Example
john.doe@example.comRequired for tier_0. ISO 3166-1 alpha-2 code (or country name).
Example
KERequired for full. Returned as phone_number.
Example
+254712345678Required for full.
Example
Moi Drive, UmojaRequired for full. Accepts mm/dd/yyyy (what the cross-border providers document), yyyy-mm-dd or RFC 3339. Returned as RFC 3339.
Example
10/03/1997Required for full. Stored and returned as national_id. Unique per account — the same person can be a beneficiary of several merchants.
Example
32460968Required for full. Must be NIN in Nigeria.
Example
national_idRequired for full in Nigeria, where it must be BVN.
Example
BVNRequired for full in Nigeria.
Example
0123456789Destination account holder name.
Example
John DoeDestination account. Backfills payment_config.account_number on payments that reference this beneficiary.
Example
+254712345678Destination account type, e.g. momo or bank.
Example
momoYour own identifier for this counterparty. Unique per account, and makes POST idempotent.
Example
customer-8821Example
retailUpdate only. Set false to stop the beneficiary transacting without deleting it.
Example
falseResponses
Section titled “Responses”The updated beneficiary, with kyc_level and kyc recomputed.
A stored counterparty. Note that a few fields are named differently on the way out than
on the way in: phone is returned as phone_number, and id_number as national_id.
object
Send this as customer.customer_uuid on payments.
The id_number you sent.
The phone you sent.
The PayHero account that owns this beneficiary, derived from your API key.
Recomputed on every write from the metadata actually present. Never settable.
The beneficiary’s KYC standing, recomputed on every write. Read-only.
object
Fields still needed to reach full. Send these to the update endpoint.
Fields still needed to reach tier_0. Non-empty only on a rejected create.
Lifetime USD total this beneficiary has transacted while at tier_0.
Headroom left before full KYC becomes mandatory.
Per-transaction ceiling while at tier_0.
Currencies a tier_0 beneficiary can never transact in.
True when the country needs a second ID (Nigeria) and it has not been supplied.
Example
{ "id": 94, "uuid": "a2e0434e-17ae-41b1-a1cf-1694ad63ee99", "first_name": "John", "last_name": "Doe", "national_id": "32460968", "date_of_birth": "1997-10-03T00:00:00Z", "phone_number": "+254712345678", "email": "john.doe@example.com", "address": "Moi Drive, Umoja", "country": "KE", "account_id": 63, "account_name": "John Doe", "account_number": "+254712345678", "account_type": "momo", "customer_type": "retail", "kyc_level": "tier_0", "tier_0_lifetime_usd": 0, "is_active": true, "kyc": { "level": "tier_0", "full_kyc": false, "missing_full_kyc_fields": [ "address", "date_of_birth", "id_number", "id_type", "phone" ], "missing_reduced_kyc_fields": [], "tier_0_lifetime_usd": 0, "tier_0_remaining_usd": 200, "tier_0_limit_reached": false, "tier_0_max_transaction_usd": 20, "tier_0_excluded_currencies": [ "BWP", "NGN", "ZAR" ], "requires_additional_id": false }}The request was rejected (validation or business-rule failure).
object
Examples
{ "error_code": "invalid_argument", "error_message": "the transaction amount is insufficient as it wont cater for cost: (4.62)", "status_code": 400}{ "error_code": "invalid_argument", "error_message": "The passed channel is not active", "status_code": 400}Missing or invalid Basic auth credentials.
object
Example
{ "error_code": "invalid_argument", "error_message": "the transaction amount is insufficient as it wont cater for cost: (4.62)", "status_code": 400}No beneficiary with that UUID exists on the account behind your API key. A UUID that belongs to another merchant also returns 404 — never 403.
object
Examples
{ "error_code": "not_found", "error_message": "beneficiary \"a2e0434e-17ae-41b1-a1cf-1694ad63ee99\" does not exist", "status_code": 404}
