Most teams that need to check who a customer is end up building the same thing: a page that asks for an ID number, a camera screen for a selfie, a progress bar, a consent notice, retries when a photo is blurry, and a back office to review the results. It is weeks of work, and it is not your product.
There is a shorter way: let a hosted flow do the screens, and keep control of the decision. Here is how that looks with the Verification Suite from IdentifyOrg (disclosure: I work on it). The ideas apply to any provider that offers hosted verification.
The three ways in
- No code. A business sets up a flow in a dashboard (which checks, in what order), then sends each applicant a personal link on WhatsApp.
- An iframe or a script on your own site.
- Your server creates a session through the API for each applicant and reads the result afterwards.
All three end in the same place: a session with a status and a result per step.
Create a session from your server
curl -X POST https://api.identifyorg.com/v1/verification-sessions \
-H "X-IdentifyOrg-Key: io_live_..." \
-H "Content-Type: application/json" \
-d '{
"flow_id": "vf_YOUR_FLOW_ID",
"reference": "order-1042",
"applicant": { "name": "Ada Obi", "phone": "08031234567" }
}'
You get back a url. Send it to the applicant, or give it to your page. Two details worth copying into your own designs:
-
referenceis your id (an order or customer number). Sending the same reference again while that session is open returns the same session, so a retry never creates a second one. - Use a secret key on your server only. The flow id that goes in a public page is not a secret and cannot read anything.
Embed it
<div id="identifyorg-verify" data-flow="vf_YOUR_FLOW_ID"></div>
<script src="https://identifyorg.com/embed/verify.js" async></script>
Or a plain iframe. The one thing people forget is the permissions attribute, without which the browser will not let the frame use the camera:
<iframe
src="https://identifyorg.com/v/vf_YOUR_FLOW_ID?embed=1"
title="Identity verification"
allow="camera; geolocation"
style="width:100%;max-width:480px;height:760px;border:0"></iframe>
The form only renders inside websites you have allowed in the flow settings. Any other site sees a blank frame.
Listen to the frame
The embedded page talks to yours with postMessage. Always check the origin:
window.addEventListener("message", (e) => {
if (e.origin !== "https://identifyorg.com") return;
const d = e.data;
if (!d || d.source !== "identifyorg-verify") return;
if (d.type === "resize") iframe.style.height = d.height + "px";
if (d.type === "completed") showThanks(); // they finished, not "they passed"
});
Events you will see: ready, started, step, received, resize, completed, error.
Do not treat completed as proof of anything. It only means the person reached the end. The result belongs to your server.
Read the result with a webhook
Register an endpoint and you get verification_session.started, .completed, .failed and .awaiting_funds. Verify the signature before you trust a payload. The header looks like t=1760437440,v1=9f2c... and the signature is an HMAC-SHA256 of "{t}.{raw_body}" with your webhook secret:
import hmac, hashlib, time
def verify(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t, sig = parts["t"], parts["v1"]
if abs(time.time() - int(t)) > tolerance:
return False # too old: could be a replay
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
The payload includes the status, each step's outcome, and the ID number masked (last four digits). Pictures are never in the webhook; the business reviews those in the dashboard.
Test it first
A flow in test mode returns sample results, charges nothing and makes no real checks. Build the whole integration against it, then switch the flow to live. A test key does the same for the API.
What to decide yourself
A verification result is evidence, not a verdict. Decide what you require (an ID number check only, or also a selfie and a liveness test), what a "review" outcome means for your business, and who looks at it. The tool gives you the signals; the policy is yours.
Top comments (0)