curl --request POST \
--url https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"accountType": "mobile_money",
"phoneNumber": "+254712345678",
"shortCode": "247247",
"accountReference": "0670179741746",
"countryCode": "KE",
"network": "MPESA",
"accountName": "Jane Doe"
}
'import requests
url = "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money"
payload = {
"accountType": "mobile_money",
"phoneNumber": "+254712345678",
"shortCode": "247247",
"accountReference": "0670179741746",
"countryCode": "KE",
"network": "MPESA",
"accountName": "Jane Doe"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
accountType: 'mobile_money',
phoneNumber: '+254712345678',
shortCode: '247247',
accountReference: '0670179741746',
countryCode: 'KE',
network: 'MPESA',
accountName: 'Jane Doe'
})
};
fetch('https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'accountType' => 'mobile_money',
'phoneNumber' => '+254712345678',
'shortCode' => '247247',
'accountReference' => '0670179741746',
'countryCode' => 'KE',
'network' => 'MPESA',
'accountName' => 'Jane Doe'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money"
payload := strings.NewReader("{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}")
req, _ := http.NewRequest("POST", 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))
}HttpResponse<String> response = Unirest.post("https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Phone number validated successfully.",
"data": {
"isValid": true,
"isSupported": true,
"accountType": "mobile_money",
"requiresInternationalization": false,
"countryCode": "KE",
"countryName": "Kenya",
"callingCode": "<string>",
"internationalNumber": "+254712345678",
"nationalNumber": "0712345678",
"bankName": "<string>",
"currency": "KES",
"network": "MTN",
"mno": "SAFARICOM KENYA",
"message": "<string>",
"accountName": "JANE MARY DOE",
"nameLookupStatus": "MATCHED",
"nameLookupReason": "Name lookup is not available for this payout corridor.",
"matchScore": 95,
"accountStatus": "ACTIVE",
"nameMatch": {
"provided": "Jane Doe",
"score": 100,
"matched": true,
"threshold": 70,
"masked": false
}
}
}{
"success": false,
"message": "Invalid request",
"data": {}
}{
"success": false,
"message": "Unauthorized",
"data": {}
}Validate Mobile Money Account
Validates a phone number in any format (with or without country code). Returns validation status, country information, formatted number, and whether the country is supported for mobile money.
curl --request POST \
--url https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"accountType": "mobile_money",
"phoneNumber": "+254712345678",
"shortCode": "247247",
"accountReference": "0670179741746",
"countryCode": "KE",
"network": "MPESA",
"accountName": "Jane Doe"
}
'import requests
url = "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money"
payload = {
"accountType": "mobile_money",
"phoneNumber": "+254712345678",
"shortCode": "247247",
"accountReference": "0670179741746",
"countryCode": "KE",
"network": "MPESA",
"accountName": "Jane Doe"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
accountType: 'mobile_money',
phoneNumber: '+254712345678',
shortCode: '247247',
accountReference: '0670179741746',
countryCode: 'KE',
network: 'MPESA',
accountName: 'Jane Doe'
})
};
fetch('https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'accountType' => 'mobile_money',
'phoneNumber' => '+254712345678',
'shortCode' => '247247',
'accountReference' => '0670179741746',
'countryCode' => 'KE',
'network' => 'MPESA',
'accountName' => 'Jane Doe'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money"
payload := strings.NewReader("{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}")
req, _ := http.NewRequest("POST", 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))
}HttpResponse<String> response = Unirest.post("https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox-api.kotanipay.io/api/v3/customer/validate/mobile-money")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"accountType\": \"mobile_money\",\n \"phoneNumber\": \"+254712345678\",\n \"shortCode\": \"247247\",\n \"accountReference\": \"0670179741746\",\n \"countryCode\": \"KE\",\n \"network\": \"MPESA\",\n \"accountName\": \"Jane Doe\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Phone number validated successfully.",
"data": {
"isValid": true,
"isSupported": true,
"accountType": "mobile_money",
"requiresInternationalization": false,
"countryCode": "KE",
"countryName": "Kenya",
"callingCode": "<string>",
"internationalNumber": "+254712345678",
"nationalNumber": "0712345678",
"bankName": "<string>",
"currency": "KES",
"network": "MTN",
"mno": "SAFARICOM KENYA",
"message": "<string>",
"accountName": "JANE MARY DOE",
"nameLookupStatus": "MATCHED",
"nameLookupReason": "Name lookup is not available for this payout corridor.",
"matchScore": 95,
"accountStatus": "ACTIVE",
"nameMatch": {
"provided": "Jane Doe",
"score": 100,
"matched": true,
"threshold": 70,
"masked": false
}
}
}{
"success": false,
"message": "Invalid request",
"data": {}
}{
"success": false,
"message": "Unauthorized",
"data": {}
}accountType to paybill or till and pass shortCode instead of phoneNumber.
phoneNumber is required unless accountType is paybill or till, in which case shortCode is required instead. This can’t be expressed as a flat “required” list — see the field descriptions below.accountName to get back a nameMatch score against the account’s real, resolved name — useful for confirming you have the right recipient before a payout./name-lookup endpoint, which is deprecated.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
phoneNumber is required unless accountType is 'paybill' or 'till'; shortCode is required when accountType is 'paybill' or 'till'.
What to validate. Defaults to mobile_money; paybill and till take shortCode instead of phoneNumber.
mobile_money, paybill, till Required unless accountType is paybill or till. Send in international format, including the country code.
"+254712345678"
Required when accountType is paybill or till. The M-PESA shortcode.
"247247"
Account number on a paybill — what a payer would enter. Paybill only.
"0670179741746"
Country code (ISO-2). Only needed for paybill and till, where it defaults to KE.
"KE"
Mobile network, used to route the name lookup. Optional — resolved from the phone number prefix when omitted.
MTN, AIRTEL, VODAFONE, TIGO, YAS, ORANGE, NOT_SUPPORTED, ZAMTEL, MPESA, CHECKOUT, BKTRX, CRDTRX, MOOV, TMONEY, FREE, EXPRESSO, HALOPESA, VODACOM, WAVE "MPESA"
Name you expect on this account. Returns a nameMatch score against the real one.
"Jane Doe"