Skip to main content
ShieldID

Webhooks & integrations

Identity verification webhooks, a hosted page and a widget.

Send an applicant to a hosted verification page or drop the widget into your own flow, get a signed webhook the moment a result is in, and let anyone with the link confirm it on a public credential-check page. A KYC API integration built to go live in an afternoon.

  • HMAC-SHA256 signed callbacks
  • QR hand-off from desktop to phone
  • Sandbox sessions are never billed

Hosted verification page

One link does the whole flow.

Create a session through the API and you get back a verification URL. Send it by email, text or in your own app — the page handles the rest.

Desktop

The applicant opens the link at their desk.

QR hand-off

The page shows a QR code and a short instruction card.

Phone capture

Scanning it switches the same session to document and selfie capture.

Verified

The session reaches VERIFIED, still on the phone.

Back to you

A redirect to your return URL, plus a signed webhook, either way.

Works like a payment redirect

The applicant lands on a page at your session's own URL. No account, no app to install.

QR hand-off, desktop to phone

Opened on a desktop, the page shows a QR code and a short instruction card instead of asking for camera access. Scanning it opens the same link on the phone, which switches straight to document and selfie capture.

Returns to you, with the answer

Once the session reaches VERIFIED, the page redirects to your return URL with the session ID and status appended, so your app knows what happened without waiting on anything else.

Branded, on qualifying plans

Your company name, logo, accent colour and terms and privacy links, applied to the hosted page and the credential-check page.

Webhooks

A signed callback, the moment a result is in.

Give us a webhook URL when you create a session and we post the result to it as soon as the session finishes, no polling required.

Signed, not just sent

Every delivery carries an X-Bio-Signature header: an HMAC-SHA256 of the request body, so you can prove it came from us before you trust it.

Retried, not fire-and-forget

A delivery that fails is retried three times, with a longer wait before each attempt.

Every attempt is recorded

Success or failure, we keep a record of the attempt on our side.

Coming soon A delivery log inside the portal, so you can see every attempt yourself, is coming soon.

Treat the latest VERIFIED as the truth

Retries mean a delivery can, in rare cases, arrive out of order. Don't key your logic off receiving a webhook at all — key it off the session ID, and let a later VERIFIED overwrite an earlier one. If you keep your own state, de-duplicate by session ID rather than by webhook receipt.

Verify the signature

Trust the payload before you act on it.

Recompute the HMAC-SHA256 over the raw request body and compare it with X-Bio-Signature before you parse anything.

javascript
const crypto = require("crypto");

function verifySignature(rawBody, signatureHeader, secret) {
  const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signatureHeader || "", "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Read the raw body — don't let a JSON body-parser touch it first.
app.post("/hooks/shieldid", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.header("X-Bio-Signature") || "";
  if (!verifySignature(req.body, signature, process.env.SHIELDID_WEBHOOK_SECRET)) {
    return res.status(401).send("invalid signature");
  }
  const event = JSON.parse(req.body);
  // Treat the latest VERIFIED status as authoritative; de-duplicate by session_id.
  res.status(200).send("ok");
});

JS widget

The hosted flow, dropped into your own page.

The widget creates a session and renders the same hosted flow inline, in an iframe, so applicants never leave your site.

  • Renders in an iframe with camera and microphone access, sized to its container.
  • Reads the session status the same way the hosted page does: through your return URL and your webhook, once the session finishes.

Coming soon In-page completion callbacks (onComplete, onCancel, onStep, automatic resize) are coming soon. Until then, use return_url and webhooks to learn when a session finishes — they work today.

Before you ship this to production

The widget currently accepts an API key directly in the browser. Treat that as a sandbox convenience, not a production pattern: create the session from your own backend with your key kept server-side, and hand the widget only the resulting session, never a live key a visitor's browser can read.

html
<script src="https://cdn.shieldid.ca/sdk/v1/widget.js"></script>
<div id="shieldid-verify"></div>
<script>
  TLVerify.init({
    apiKey: "vk_sand_your_key", // sandbox only — see the note above for production
    containerId: "shieldid-verify",
    returnUrl: "https://yourapp.example/verified",
    webhookUrl: "https://yourapp.example/hooks/shieldid",
    locale: "en",
  });
</script>

Credential-check page

A public page for a verified session.

Once a session reaches VERIFIED, its own credential-check link shows a plain-language confirmation: the applicant's name, the document type and the status. Anyone holding the link — a co-signer, a front-desk clerk, a counterparty — can confirm the result without signing in to your dashboard.

Jordan Reyes

Sample data

Ontario driver’s licence

Verified

  • No sign-in required to view it.
  • No raw ID image and no confidence score ever appears on it — a status and the identity, nothing more.
  • Branded the same way as the hosted page, on qualifying plans.

Integration patterns

How six kinds of businesses wire this up.

The building blocks are the same everywhere: a session, a link or a widget, a webhook. The pattern that fits changes by how and when you need the answer.

Rental & property management

Send the hosted link in the same email as the rental application. The webhook flips the applicant to verified in your system before you review the file.

Legal & law firms

Send the link during client intake and store the webhook receipt with the file, so client identification is on the record before the retainer starts.

Condo corporations

Link out from the owner or tenant registration form the board already uses; the result lands before the unit is added to the roll.

Fintech & lending

The webhook triggers your own underwriting step automatically, so an applicant never waits on a person to notice a result came in.

Marketplaces & gig platforms

Embed the widget in seller or driver onboarding for a flow that never leaves your app; create the session from your backend, as recommended above.

E-signature

Run the hosted flow before the signing ceremony starts, and gate document release on the webhook, not on the applicant's own say-so.

Questions

Straight answers about integrating.

Get started

Wire up a webhook. Watch it fire.

Create a sandbox session with a webhook URL, run a verification on your own phone, and read the signed callback it sends.