Verification page

Embed identity verification in your own app
View as Markdown

Before a company can open payment routes, its director completes identity verification. AlphaX hosts that page for you — unbranded, so you can put it inside your own product and keep the customer in your flow.

Onboarding a company onto swap returns it, and you can re-read it any time:

GET /v1/kyc-link
X-API-Key: <your partner API key>
X-Company-Id: <the company id>
1{
2 "swap": {
3 "kycUrl": "https://public-api.alphax.com/kyc/9f2c1d84e7b6a5309c8f",
4 "kycStatus": "not_started",
5 "tosUrl": "https://public-api.alphax.com/kyc/9f2c1d84e7b6a5309c8f/terms",
6 "tosAccepted": false
7 }
8}

The link does not expire, so you can store it against the company and re-open it whenever the customer returns to finish.

Treat kycUrl as a credential — the token in the path is what authorises access to that company’s verification. Don’t put it anywhere public.

Step 2 — Show it

Either send the customer to the URL directly, or embed it. The page sets frame-ancestors *, so an <iframe> works from any origin:

1<iframe
2 src="https://public-api.alphax.com/kyc/9f2c1d84e7b6a5309c8f"
3 allow="camera;"
4 style="width: 100%; height: 100%; border: 0"
5></iframe>

Keep allow="camera;" — verification includes document and selfie capture, and the flow cannot complete without camera access. Give the iframe real height too; the form is full-page.

Pass redirectUri when you onboard the company to send the customer back to your own page when they finish:

1{
2 "products": ["Swap"],
3 "redirectUri": "https://your-app.example/onboarding/done"
4}

Omit it and we show an AlphaX completion page instead.

Step 2b — Have the terms accepted

Verification is only half of what is asked of the company. It must also accept the terms of service, at tosUrl — a second page you embed exactly the same way:

1<iframe
2 src="https://public-api.alphax.com/kyc/9f2c1d84e7b6a5309c8f/terms"
3 style="width: 100%; height: 100%; border: 0"
4></iframe>

No camera is needed here, so allow="camera;" can be dropped.

A company cannot be endorsed until the terms are accepted, no matter how far verification has got. Surface this alongside verification rather than after it — tosAccepted tells you whether it is still outstanding.

The two are deliberately separate pages so you can deep-link to whichever step is still needed, rather than making the customer walk through both again.

Step 3 — React to the outcome

kycStatus moves through these values:

StatusMeaningWhat to do
not_startedA link exists but the customer has not begunKeep the link available
incompleteBegun but not submittedPrompt the customer to finish
awaiting_questionnaireExtra questions must be answeredAsk the customer to reopen the link
awaiting_uboDetails of the ultimate beneficial owners are still neededAsk the customer to reopen the link
under_reviewSubmitted; a human is looking at itWait — no action needed
approvedVerifiedPayment routes can be opened
rejectedDeclinedContact AlphaX support
pausedTemporarily haltedContact AlphaX support
offboardedThe customer has been removedContact AlphaX support

The two awaiting_* states are the ones to surface in your own UI — verification is blocked until the customer supplies something, and reopening kycUrl takes them straight to it. Everything else is informational.

Rather than polling GET /v1/kyc-link, subscribe to company.kyc_status_changed — it fires on every transition. company.kyc_link.issued fires when the link first becomes available, which is useful if you onboard companies from a background job.

Verification is a manual review, not an instant decision. Expect under_review to last hours rather than seconds, and design your onboarding UI to let the customer leave and come back.