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 |
business_ownership_ke |
Kenya | number — a BRS registration number, e.g. PVT-GYU5523P |
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".
Company ownership and directors (Kenya)
Section titled “Company ownership and directors (Kenya)”business_ownership_ke reads the Business Registration Service and returns a
company’s ownership and directors — the deepest KYB check available for Kenya.
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/business_ownership_ke" \ -u "$PH_API_USERNAME:$PH_API_PASSWORD" \ -H "Content-Type: application/json" \ -d '{ "number": "PVT-GYU5523P" }'Starting from a KRA PIN
Section titled “Starting from a KRA PIN”If all you hold is a KRA PIN, chain the two checks — kra_pin returns the
registration number as Business_Certificate_Id, which is what BRS takes:
POST /kyc/verify/kra_pin { "number": "P000000000X" } → data.Business_Certificate_Id = "PVT-ABCDEFG"
POST /kyc/verify/business_ownership_ke { "number": "PVT-ABCDEFG" } → ownership and directorsThe first step costs 55 KES and already confirms the company exists, is active and is a company rather than an individual — so run it first and only pay for the BRS lookup when you actually need the directors.
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.
