VeroID

Hosted verify sessions

Send an SMS link so individuals complete verification on mobile. Every document type can be checked. You choose whether the session includes a biometric check.

Developer accounts only. Configure a webhook first, then create sessions with POST /v1/verify/sessions. To embed a consent-first form in your own app (typed fields only, no SMS), see Embedded document form. See Authentication for API keys.

What your users see

The hosted experience lives on VeroID's verify site (linked from SMS). Screenshots below were captured from the same UI in local mock mode with synthetic sample data, not real ID numbers or photos. Mobile width (390×844) is shown; the layout is the same on larger screens with more horizontal space.

  • Choose document type

    When you do not preset documentType on the session, the person picks the ID they will enter. Biometric sessions only list documents with a portrait.

    Choose document type
  • Consent (document + biometric)

    They confirm consent to check details with the document issuer or official record holder. When the session includes biometrics, a separate statement covers the ID photo and live selfie.

    Consent (document + biometric)
  • Consent (document only)

    Sessions without biometrics (for example Medicare) show the document consent statement only.

    Consent (document only)
  • Photograph the ID (front)

    The camera opens in the browser with a card-shaped guide frame, live hints while they align the document, and automatic capture when the image is clear and steady. Saved uploads are not accepted. Driver licences require a back photo in a later step.

    Hosted verify mobile screen for photographing the front of a driver licence: dashed card guide frame in the camera view, live hint to fit the card inside the frame, and auto capture (synthetic mock UI only, no real identity data).
  • Photograph the ID: back (licence)

    Australian driver licences need the rear of the card so the card number is visible.

    Photograph the ID: back (licence)
  • Enter document details

    They type the details printed on the ID. For biometric sessions, these values are compared with the photos before the issuer check runs.

    Enter document details
  • Correctable errors

    If something cannot be saved or validated, they stay on the form with a short message and can try again.

    Correctable errors
  • Live selfie (biometric sessions)

    They follow on-screen prompts for a short video selfie so VeroID can confirm they are physically present.

    Live selfie (biometric sessions)
  • Document-only example (Medicare)

    Without biometrics, the flow goes from consent straight to typed fields, then submit. There are no camera steps.

    Document-only example (Medicare)
  • Submitted

    After they submit, the page says they can close it. It does not show whether the issuer matched. That result is on your webhook and on GET /v1/verify/sessions/:id.

    Submitted
  • Invalid link

    Unknown or malformed links show a generic error.

    Invalid link
  • Expired link

    After expiresAt, the link no longer opens the form.

    Expired link

Setup

PUT /v1/settings/verify-session-webhook
{ "webhookUrl": "https://your.app/webhooks/veroid" }
→ { "webhookSigningSecret": "whsec_..." }

Create session

POST /v1/verify/sessions
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{
  "phone": "+61412345678",
  "consentVersion": "2.0-biometric",
  "documentType": "drivers_licence",
  "biometrics": true,
  "reference": "optional-crm-id",
  "businessName": "Acme Pty Ltd"
}
→ 201 { "id": "<uuid>", "status": "sms_sent", "expiresAt": "<ISO-8601>", ... }

Send an Idempotency-Key header (recommended) so retries do not send duplicate SMS messages or create duplicate sessions. Use a unique value per attempted check (for example a UUID, up to 255 characters). Keys are scoped to your account, test or live, and this create endpoint, and are retained for 24 hours. The same key with the same JSON body returns the original 201 response and Idempotent-Replayed: true. The same key with a different body returns 422 IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PARAMS. If a webhook is slow, call GET /v1/verify/sessions/:id before retrying create, and reuse the same key for that check.

businessName is optional. When set, it is the name in the SMS. Otherwise the SMS uses the account company name. The message reads: Acme Pty Ltd has requested you complete your identity verification securely with VeroID. Click the link to complete this request: followed by the hosted link.

Link expiry

The hosted link works for 8 hours. expiresAt on the create response is that time, in UTC, and is fixed when the session is created.

After expiresAt, the hosted page says the verification link has expired. The session status becomes expired, and VeroID sends verify_session.expired once.

After they submit, the hosted page says they can close it. It does not show the issuer result. Opening the link again says the verification has already been submitted. The result is on the webhook and on GET /v1/verify/sessions/:id.

What you send

You send the phone number, the consent version, and whether the session includes a biometric check. You do not send the person's name, date of birth, document number, or photos. They enter those on the hosted page. Save the webhook URL before the first session, and keep the signing secret. Use reference if you want your own id echoed back on every event.

What VeroID does

VeroID texts the link. On the phone, the person agrees to the check, photographs the document, and enters the details printed on it. When the session includes a biometric check, they also take a live selfie. VeroID then scores that selfie, compares it with the portrait on the document, and checks the entered details with the document issuer. The person can close the page once the selfie is captured. The scores and the issuer result are finished on the server.

What you get back

Read GET /v1/verify/sessions/:id, or the data object on the webhook. Both use the same result fields.livenessScore and faceMatchScore are always present. Each is an integer from 0 to 100, or null when that check did not run. There is no pass or fail for either score. dvs.match is the issuer result, and it is separate from the scores.

GET /v1/verify/sessions/:id
{
  "success": true,
  "id": "6f1c0e3a-1b2c-4d5e-8f90-a1b2c3d4e5f6",
  "reference": "optional-crm-id",
  "status": "completed",
  "documentType": "drivers_licence",
  "consentVersion": "2.0-biometric",
  "verificationId": "ver_abc123",
  "result": {
    "verificationId": "ver_abc123",
    "dvs": {
      "match": true,
      "responseCode": "Y",
      "documentType": "drivers_licence"
    },
    "livenessScore": 96,
    "faceMatchScore": 99
  },
  "expiresAt": "2026-10-26T12:00:00.000Z",
  "phoneLastFour": "5678",
  "createdAt": "2026-10-26T04:00:00.000Z",
  "completedAt": "2026-10-26T04:12:00.000Z"
}

A session without a biometric check returns "livenessScore": null and "faceMatchScore": null.status is completed when the issuer matched the details. status is failed when the issuer did not match, or the check could not be finished. On a failed session, error.code and error.message say why. The scores are still returned when the selfie was scored before the failure.

Webhooks

Events include verify_session.completed, verify_session.failed, verify_session.opened, verify_session.expired, verify_session.cancelled, and verify_session.sms_failed. Every event includes the session id and your reference when you set one.verify_session.completed and verify_session.failed also include data with the same result fields as result on the GET. A failed event adds data.error, the same text as error.message on the GET.

{
  "event": "verify_session.completed",
  "id": "6f1c0e3a-1b2c-4d5e-8f90-a1b2c3d4e5f6",
  "reference": "optional-crm-id",
  "status": "completed",
  "timestamp": "2026-10-26T04:12:00.000Z",
  "data": {
    "verificationId": "ver_abc123",
    "dvs": {
      "match": true,
      "responseCode": "Y",
      "documentType": "drivers_licence"
    },
    "livenessScore": 96,
    "faceMatchScore": 99
  }
}

Verify signatures with the same HMAC scheme as billing webhooks (VeroID-Webhook-Signature, v1.<timestamp>.<body>). Each event is delivered with up to three HTTP POST attempts: immediately, then after 2 seconds, then after 5 seconds when the previous attempt failed (non-2xx, network error, or 30 second timeout). Retries run in the same API process and are not resumed after a restart. Delivery outcomes are stored after all attempts complete.

What the numbers mean

livenessScore is how strongly the live selfie looked like a real person in front of the camera. 0 is no confidence and 100 is the strongest. You choose the minimum you will accept. VeroID does not turn this number into a pass or fail.

faceMatchScore is how similar the portrait on the document is to that live selfie. 0 means no usable likeness and 100 means the faces look the same. You choose the minimum you will accept. VeroID does not turn this number into a pass or fail.

dvs.match is the document-issuer result. true means the details the person entered match the issuer's record.dvs.responseCode is Y, N, D, or S. dvs.status may be invalid_input when the request failed validation (not an identity no-match).D means the check could not be completed; S is a system error and may be retried. Store the scores with your own threshold, and store dvs.match as the issuer outcome.

Document type

documentType accepts every supported document. Omit it and the subject chooses the document on the hosted page. They cannot choose whether the session includes a biometric check.

Biometrics

For definitions, independent liveness testing, completion tips, and how scores appear on every integration path, see Face matching and liveness.

biometrics is set on the create request. The person who opens the SMS link cannot turn it on or off.true adds a guided ID photo, a live selfie, and a face comparison before the document check. The result of that check is livenessScore and faceMatchScore, each from 0 to 100. VeroID does not pass or fail those scores. The biometric check is available only for documents that include a photo: passport, Australian driver licence, ImmiCard, and ASIC/MSIC.biometrics: true with a document that has no photo, such as a Medicare card or birth certificate, is rejected. If you omit documentType and set biometrics to true, the hosted page only offers those photo documents.

Omit biometrics and a passport or driver licence session still includes the check. Every other document type does not, including ImmiCard and ASIC/MSIC. Send biometrics: false to run a passport or driver licence check without a photo or selfie. If you omit both documentType and biometrics, the same default applies after the subject picks a document: passport and driver licence include the check, and every other type does not.

A driver licence needs photos of the front and the back. The ID photo is rejected when it looks edited, composited, photographed from a screen, or printed. For passport and driver licence, the name, date of birth, and document number the subject enters are compared with the text visible on that photo. The subject takes the photo in the browser camera. Saved images cannot be uploaded. Images are stored ephemerally in Sydney (typically deleted within 24 hours or immediately after processing).

Consent

Send consentVersion 2.0-biometric when the session includes a biometric check, and 1.0 when it does not. The hosted page shows the document consent statement, and the biometric statement only when the session includes that check. See Consent and veroid.com.au/consent.