KYC (Regulated Countries)
Collect identity details where a country's regulator requires them
KYC (Regulated Countries)
The US provisions numbers instantly. Some other countries regulate who can hold a number and require the registrant's identity details before the number is ordered. When a purchase returns status: "kyc_required", run this flow. That response also carries a kycUrl: a ready-made link to the hosted form for that country, so you can hand the step off instead of building the form yourself with the endpoints below.
1. Check availability and address constraints
Call checkPhoneNumberAvailability (GET /v1/phone-numbers/availability?country=XX) first. It tells you whether there is deliverable inventory and an addressConstraint:
geo- the registrant's address must be in one of the returnedareas(some countries stock numbers tied to a specific city).country- any in-country address works.none- no address is required.
Checking first avoids the worst case: a submission that passes review but can never be assigned a number because the address is in the wrong area.
2. Get the form for the country
getPhoneNumberKycForm (GET /v1/phone-numbers/kyc?country=XX) returns the exact fields that country requires (text fields, an address, and document uploads such as an ID or business registration), plus whether the owner already has a reusable, approved verification for that country.
const { data: form } = await zernio.phonenumbers.getPhoneNumberKycForm({
query: { country: 'GB' }
});
console.log(form.fields);curl "https://zernio.com/api/v1/phone-numbers/kyc?country=GB" \
-H "Authorization: Bearer YOUR_API_KEY"3. Submit the details
Submit the collected values, documents, and address to submitPhoneNumberKyc (POST /v1/phone-numbers/kyc). Each document can be sent inline (base64) or as a documentId from a prior upload (POST /v1/phone-numbers/kyc/upload-document). For an ID-card requirement, carriers usually need BOTH sides: combine front and back into a single file before uploading (a one-sided ID is a common decline reason). The order goes to regulatory review and the number activates within 1-3 business days. To know when: poll GET /v1/phone-numbers/{id} or, better, listen for the whatsapp.number.activated / whatsapp.number.declined webhooks (they fire for every number; the names are legacy).
curl -X POST "https://zernio.com/api/v1/phone-numbers/kyc" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profileId": "YOUR_PROFILE_ID",
"country": "GB",
"values": { "REQUIREMENT_ID": "Acme Ltd | Jane Doe | +44..." },
"documents": [{ "requirementId": "REQUIREMENT_ID", "filename": "id.png", "base64": "..." }],
"address": {
"requirementId": "REQUIREMENT_ID", "country_code": "GB",
"street_address": "10 Downing Street", "locality": "London",
"administrative_area": "London", "postal_code": "SW1A 2AA"
}
}'PII (ID documents, address) streams straight to our number provider in-request; Zernio never stores the document bytes. You can pre-validate an address with validatePhoneNumberKycAddress and pre-check a whole packet with reviewPhoneNumberKycPacket before submitting, to catch problems early.
Hand the form off (white-label)
If you would rather not build the document-collection UI, createPhoneNumberKycLink (POST /v1/phone-numbers/kyc/share) returns a single-use, login-free hosted page that runs the same guided wizard. Pass branding (company name, logo, brand color) so the customer signs up to you with no Zernio login, and redirect_url to send them back to your app afterward. The number provisions under your account once they submit.
Fix a declined number
You do not start over. A declined number stays in your list under a pending status with a decline reason. Fetch just the flagged requirements with getPhoneNumberRemediation (GET /v1/phone-numbers/{id}/remediate), then re-submit the corrected values to remediatePhoneNumber (POST /v1/phone-numbers/{id}/remediate). The number goes back to review on the same record and keeps its place in the queue.