Identity & business checks
These checks answer “is this identifier real, and whose is it?” — for a
person (KYC) or for a registered business (KYB). They all run through
POST /api/v1/kyc/verify/{check} and return the
standard envelope.
Person (KYC)
Section titled “Person (KYC)”check |
Country | Required fields |
|---|---|---|
national_id_ke |
Kenya | number — e.g. 28200002 |
passport_ke |
Kenya | number — e.g. AK0000000 |
nin |
Nigeria | number_nin — 11 digits |
bvn_basic |
Nigeria | number — 11 digits |
bvn |
Nigeria | number — 11 digits |
national_id_gh |
Ghana | id_number — e.g. GHA-000000000-0 |
national_id_ug |
Uganda | national_id, surname, dob, document_id |
national_id_ci |
Côte d’Ivoire | id_number, card_type (new or old) |
national_id_sl |
Sierra Leone | id_number |
national_id_zm |
Zambia | number — e.g. 1000001/00/1 |
national_id_za |
South Africa | id_number — 13 digits |
voter_id_tz |
Tanzania | id_number, issue_date (YYYY-MM-DD) |
resident_card_ci |
Côte d’Ivoire | id_number, card_type (new or old) |
passport_gh |
Ghana | number — e.g. G0000000 |
passport_ng |
Nigeria | number, nin, dob (YYYY-MM-DD) |
bvn_basic returns the holder’s name, date of birth and phone. bvn adds the
enrolment bank and branch, e-mail, gender and watch-list status.
Verify a Kenyan national ID
Section titled “Verify a Kenyan national ID”curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/national_id_ke" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "number": "28200002" }'const res = await fetch(`${process.env.PH_CONNECT_URL}/api/v1/kyc/verify/national_id_ke`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Basic ' + Buffer.from( `${process.env.PH_API_USERNAME}:${process.env.PH_API_PASSWORD}`, ).toString('base64'), }, body: JSON.stringify({ number: '28200002' }),})
const check = await res.json()
if (check.status !== 'verified') { throw new Error(`ID not verified: ${check.detail}`)}
// Keep this — it is the token you attach to a KYC submission.const nationalIdToken = check.lookup_idimport os, requests
res = requests.post( f"{os.environ['PH_CONNECT_URL']}/api/v1/kyc/verify/national_id_ke", auth=(os.environ["PH_API_USERNAME"], os.environ["PH_API_PASSWORD"]), json={"number": "28200002"},)check = res.json()
if check["status"] != "verified": raise RuntimeError(f"ID not verified: {check['detail']}")
national_id_token = check["lookup_id"]{ "lookup_id": "9f2c61ab4d7e4a0c8b115d3e", "check": "national_id_ke", "category": "national_id", "country": "KE", "actor_type": "I", "subject_name": "JANE WANJIRU DOE", "status": "verified", "verification_status": "VERIFIED", "source": "prembly", "cached": false, "charged_amount": 40, "charge_currency": "KES", "charge_status": "charged"}A national ID always reports actor_type: "I" — an ID card belongs to a person
by definition.
Business (KYB)
Section titled “Business (KYB)”check |
Country | Required fields |
|---|---|---|
kra_pin |
Kenya | number — the KRA PIN, e.g. P000000000X |
tin_global |
Global | tin, country — ISO code, e.g. MW |
company_global |
Global | company_number, country_code — ISO code |
kra_pin_from_id_ke |
Kenya | number — a national ID; returns that person’s KRA PIN |
tin_ng |
Nigeria | number, channel (TIN, CAC or PHONE) |
tin_from_nin_ng |
Nigeria | number — a NIN; returns the registered TIN |
scuml_ng |
Nigeria | company_number — SCUML anti-money-laundering registration |
Verify a KRA PIN
Section titled “Verify a KRA PIN”The single most useful KYB check in Kenya: it confirms the PIN is registered and active, returns the taxpayer name, and tells you whether the PIN belongs to a company or an individual.
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/kra_pin" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "number": "P000000000X" }'{ "lookup_id": "a1b2c3d4e5f6a7b8c9d0e1f2", "check": "kra_pin", "category": "tax_id", "country": "KE", "actor_type": "C", "subject_name": "ACME TRADING LIMITED", "status": "verified", "verification_status": "VERIFIED", "detail": "KRA PIN Checker (Kenya) verification successful", "response_code": "00", "data": { "PINNo": "P000000000X", "TaxpayerName": "ACME TRADING LIMITED", "Trading_Business_Name": "Acme Trading Limited", "Business_Certificate_Id": "PVT-ABCDEFG", "Partnership": "N", "Paye": "N", "Tot": "N", "Vat": "Y" }, "charged_amount": 50, "charge_currency": "KES", "charge_status": "charged"}Verify a tax ID outside Kenya
Section titled “Verify a tax ID outside Kenya”tin_global covers 120+ countries. Pass the ISO country code alongside the
number:
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/tin_global" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "tin": "MWI789456123", "country": "MW" }'The response’s country echoes the country the check ran against (MW), not
GLOBAL.
Where the provider states a taxpayer class, actor_type reflects it — a
“Non-Individual” taxpayer is C, a “Sole Proprietor” is I. Where it states
nothing, actor_type is absent rather than guessed.
Look up a registered company
Section titled “Look up a registered company”curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/company_global" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "company_number": "PVT-ABCDEFG", "country_code": "KE" }'company_global always reports actor_type: "C".
Tanzania
Section titled “Tanzania”Tanzanian voter IDs need the date the card was issued alongside the number:
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/voter_id_tz" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "id_number": "T100497937714", "issue_date": "2019-01-01" }'Handling a non-match
Section titled “Handling a non-match”A check that ran but found nothing is still an HTTP 200:
{ "lookup_id": "3ab90f1c77e54d2bb0c4e881", "check": "national_id_ke", "category": "national_id", "country": "KE", "status": "not_verified", "verification_status": "NOT_VERIFIED", "detail": "no record found", "source": "prembly", "charged_amount": 40, "charge_status": "charged"}The token is still issued and still resolvable — it is the durable record that
you ran the check and it came back negative. A not_verified token contributes
nothing to a Team’s KYC tier.

