Beneficiaries API

The Beneficiaries API allows you to create and manage payment recipients. Beneficiaries are required for withdrawals, transfers, and exchanges where funds need to be sent to external accounts.

Create Beneficiary

Create a new beneficiary for receiving payments. The required fields vary depending on the currency and country.

Endpoint

POST /api/v1/client/beneficiaries

Authentication

This endpoint requires HMAC authentication (Business API Key). Include your API key and signature in the request headers:

http
x-api-key: <your-api-key>x-timestamp: <RFC3339-timestamp>x-signature: <HMAC-signature>

Request Body

FieldTypeRequiredDescriptionExample
user_idstringYes (business API)Business API only. Which Transfaar user this beneficiary is created for. Use "self" or a customer UUID — see Business API: user_id."self" or a UUID
first_namestringYesBeneficiary's first name"John"
last_namestringYesBeneficiary's last name"Doe"
emailstringYesBeneficiary's email address"john.doe@example.com"
phonestringYesBeneficiary's phone number"+1234567890"
bank_namestringYesName of the bank"Access Bank"
account_numberstringConditionalBank account number (required for NGN)"0123456789"
bank_codestringNoBank code (from banks API)"044"
country_codestringYesISO 3166-1 alpha-2 country code"NG", "US", "CA"
currency_codestringYesCurrency code for the beneficiary"NGN", "USD", "CAD"
account_namestringNoAccount holder name (auto-generated if not provided)"John Doe"
ibanstringNoIBAN for SEPA transfers"GB82WEST12345698765432"
bic_swift_codestringNoBIC/SWIFT code for international transfers"CHASUS33"
recipient_addressstringNoPhysical address of the recipient"123 Main St, Lagos"
notesstringNoAdditional notes about the beneficiary"Monthly salary payment"
routing_numberstringNoRouting number (US/Canada)"021000021"
account_typestringNoAccount type"Checking", "Savings"
payment_methodstringNoPayment method/rail"ACH", "Wire", "Sepa"
addressobjectNoStructured address objectSee Address Object below
[blocked]

Business API: user_id (on behalf of)

POST /api/v1/client/beneficiaries is authenticated with your business API key. Every beneficiary is stored against a Transfaar user (the “on behalf of” user). That user must be part of your business.

You send user_idBehavior
"self" (recommended)Explicitly create the beneficiary for the business owner (the Transfaar user tied to your API key). Case-insensitive. Safer than omitting the field.
Customer UUIDThe beneficiary is created for that user. They must be the business owner, an active team member, or a registered customer linked to your business. Otherwise 400 with user_id does not belong to this business.
Omitted or emptyNot allowed for the business API — returns 400 asking for "self" or a customer id.

Tip: For a customer, pass their user id from the Customers API. For your business’s own recipients, pass "user_id": "self".

Address Object (Optional)

When provided, address is validated. State is required (when the country has subdivisions) and must be a subdivision code only (e.g. NY, LA, ON)—subdivision names are not accepted for beneficiaries. Use Regions API to list valid codes.

json
{  "street_1": "123 Main Street",  "city": "Lagos",  "state": "LA",  "postal_code": "100001",  "country": "NG"}

Currency-Specific Requirements

NGN (Nigerian Naira)

  • account_number is required
  • bank_code is recommended (use from Banks API)
  • bank_name is required

USD (US Dollar)

  • payment_method is required (ACH, Wire, or Sepa)
  • For ACH: routing_number and account_number are required
  • For Wire: routing_number, account_number, and bic_swift_code are required
  • account_type is recommended (Checking or Savings)

CAD (Canadian Dollar)

  • email is required (used for Interac e-Transfer)
  • No bank account details needed — the payout is delivered via Interac to the recipient's email

TZS, UGX, SLE (Mobile money payout)

Mobile money beneficiaries use the same create endpoint. Payouts use the standard Fiat Payout flow (WITHDRAWAL or EXCHANGE) — no separate mobile-money payout API.

  • bank_code is required — must be a mobile money operator from the Banks API with ?type=momo (not a traditional bank code)
  • phone is required — recipient wallet number in international format without + (e.g. 255712345678 for Tanzania, 256712345678 for Uganda, 23276123456 for Sierra Leone)
  • bank_name is required — operator display name (e.g. Halotel, Vodacom)
  • account_number is optional — if omitted, phone is used for payout delivery
  • country_code: TZ (TZS), UG (UGX), SL (SLE)

Supported operators (current API catalog):

CountryCurrencyOperatorbank_codePhone prefix
TZTZSTIGOTIGTZA255
TZTZSAIRTELAIRTZA255
TZTZSHALOTELHALTZA255
TZTZSVODACOM (M-PESA)VODTZA255
UGUGXMTN MOBILE MONEYMTNUGA256
UGUGXAIRTELAIRUGA256
SLSLEOrange MoneyORASLE232
SLSLEAfricell AfrimoneyAFRISLE232

Full list and updates: GET /banks/{country}?type=momo — see Banks API: mobile money operators.

List operators:

bash
curl -X GET "https://api.transfaar.com/api/v1/client/banks/TZ?type=momo" \  -H "x-api-key: <your-api-key>" \  -H "x-timestamp: <RFC3339-timestamp>" \  -H "x-signature: <HMAC-signature>"

Example: TZS mobile money beneficiary

json
{  "user_id": "self",  "first_name": "Amina",  "last_name": "Hassan",  "email": "amina.hassan@example.com",  "phone": "255712345678",  "bank_name": "HALOTEL",  "bank_code": "HALTZA",  "country_code": "TZ",  "currency_code": "TZS"}

GHS (Ghana)

Ghana supports mobile money and bank (GHIPSS) payouts. Use the Banks API type filter to load the correct list:

Payout typeBanks APIRequired beneficiary fields
Mobile moneyGET /banks/GH?type=momobank_code (operator), phone, bank_name
Bank accountGET /banks/GH?type=banksbank_code, account_number, bank_name

Supported mobile money operators (Ghana):

Operator (API name)bank_codePhone prefix (no +)
MTN MOBILE MONEYMTN233
VODAFONE CASHVOD233
AIRTELTIGO MONEYAIR233

For mobile money, use phone in international format without + (e.g. 233241234567).

Other Currencies

  • Requirements vary by country
  • Check specific country requirements in the Banks API documentation

Success Response (201 Created)

json
{  "id": "550e8400-e29b-41d4-a716-446655440000",  "user_id": "660e8400-e29b-41d4-a716-446655440001",  "first_name": "John",  "last_name": "Doe",  "email": "john.doe@example.com",  "phone": "+1234567890",  "bank_name": "Access Bank",  "account_number": "0123456789",  "bank_code": "044",  "country_code": "NG",  "currency_code": "NGN",  "status": "pending",  "is_verified": false,  "account_name": "John Doe",  "is_internal": false,  "created_at": "2024-01-15T10:30:00Z",  "updated_at": "2024-01-15T10:30:00Z"}

Error Responses

Status CodeDescription
400Bad Request - Missing required fields, invalid data, or validation errors. For the business API, includes user_id is required... when user_id is missing, user_id does not belong to this business for an invalid user, or user_id "self" is only valid for business API requests when a non-business caller sends "self".
401Unauthorized - Invalid or missing API credentials
409Conflict - Beneficiary already exists
500Internal Server Error

Example Request

bash
curl -X POST https://api.transfaar.com/api/v1/client/beneficiaries \  -H "Content-Type: application/json" \  -H "x-api-key: tf_test_biz_your_api_key" \  -H "x-timestamp: 2024-01-15T10:30:00Z" \  -H "x-signature: your_hmac_signature" \  -d '{    "user_id": "self",    "first_name": "John",    "last_name": "Doe",    "email": "john.doe@example.com",    "phone": "+2348012345678",    "bank_name": "Access Bank",    "account_number": "0123456789",    "bank_code": "044",    "country_code": "NG",    "currency_code": "NGN"  }'

For a registered customer, set "user_id" to that customer’s Transfaar user UUID instead of "self".

Example: JavaScript/Node.js

javascript
const crypto = require('crypto');
async function createBeneficiary(apiKey, secretKey, beneficiaryData) {  const timestamp = new Date().toISOString();  const body = JSON.stringify(beneficiaryData);  const dataToSign = body + '|' + timestamp;    const signature = crypto    .createHmac('sha256', secretKey)    .update(dataToSign)    .digest('hex');
  const response = await fetch('https://api.transfaar.com/api/v1/client/beneficiaries', {    method: 'POST',    headers: {      'Content-Type': 'application/json',      'x-api-key': apiKey,      'x-timestamp': timestamp,      'x-signature': signature    },    body: body  });
  return await response.json();}
// Usageconst beneficiary = await createBeneficiary(  'your-api-key',  'your-secret-key',  {    user_id: 'self',    first_name: 'John',    last_name: 'Doe',    email: 'john.doe@example.com',    phone: '+2348012345678',    bank_name: 'Access Bank',    account_number: '0123456789',    bank_code: '044',    country_code: 'NG',    currency_code: 'NGN'  });

List Beneficiaries

Retrieve a paginated list of beneficiaries for the authenticated business.

Endpoint

GET /api/v1/client/beneficiaries

Query Parameters

ParameterTypeDescriptionExample
page_idintegerPage number (default: 1)1
page_sizeintegerNumber of items per page (default: 10)20
currencystringFilter by currency code"NGN", "USD"
countrystringFilter by country code"NG", "US"
emailstringFilter by beneficiary email"john@example.com"
namestringSearch by beneficiary name"John"
user_idstring (UUID)Business API: Optional filter — only beneficiaries for this user. If provided, must be a user that belongs to your business (owner, team member, or customer); otherwise 400. Omit to list across all users under your business.Customer UUID
use_tagbooleanFilter for internal tag beneficiariestrue, false

Success Response (200 OK)

json
{  "data": [    {      "id": "550e8400-e29b-41d4-a716-446655440000",      "first_name": "John",      "last_name": "Doe",      "email": "john.doe@example.com",      "bank_name": "Access Bank",      "country_code": "NG",      "currency_code": "NGN",      "status": "verified",      "is_verified": true    }  ],  "pagination": {    "page_id": 1,    "page_size": 10,    "total": 25,    "total_pages": 3  }}

Get Beneficiary

Retrieve details of a specific beneficiary by ID.

Endpoint

GET /api/v1/client/beneficiaries/{id}

Path Parameters

ParameterTypeDescription
idUUIDBeneficiary ID

Success Response (200 OK)

Returns the full beneficiary object with all details.


Update Beneficiary

Update an existing beneficiary's information.

Endpoint

PATCH /api/v1/client/beneficiaries/{id}

Request Body

Same structure as create beneficiary, but all fields are optional. Only provided fields will be updated.


Delete Beneficiary

Delete a beneficiary. Beneficiaries that are associated with active transactions cannot be deleted.

Endpoint

DELETE /api/v1/client/beneficiaries/{id}

Success Response (200 OK)

json
{  "message": "Beneficiary deleted successfully"}

Related Endpoints


Best Practices

  1. Use Bank IDs - When creating beneficiaries, use the bank_code from the Banks API for better reliability
  2. Validate Accounts - Use the account lookup endpoint to verify account numbers before creating beneficiaries
  3. Handle Verification - Beneficiaries start with status: "pending" and may require verification depending on currency and amount
  4. Store Beneficiary IDs - Save the beneficiary id returned from create for use in quote/transaction requests