Skip to main content
How a parent account starts a hosted KYC for one of its sub-accounts via email link, and registers a webhook to receive status updates.

Flow

1

Create the session

Parent calls Create KYC Session with flow_type: "email", the customer’s email, and a webhook_url.
2

Vobiz emails the link

Vobiz emails the customer a signed link to the Vobiz-hosted KYC widget.
3

Customer completes KYC

Customer completes KYC in the widget.
4

Receive webhook events

Vobiz POSTs webhook events to your webhook_url at each stage (initiated → submitted → completed/failed).

1. Create the KYC session (register the webhook)

POST https://api.vobiz.ai/api/v1/sub-accounts/{sub_auth_id}/kyc-sessions
Auth: parent main account — X-Auth-ID: MA_xxxx + X-Auth-Token: <token> (or Authorization: Bearer <JWT>). The sub_auth_id path param (SA_xxxx) identifies the sub-account being verified.
Body:
{
  "flow_type": "email",
  "customer_email": "customer@example.com",
  "webhook_url": "https://your-app.example.com/kyc/webhook",
  "expires_in_days": 30,
  "reminder_schedule": [
    { "trigger": "days_before_expiry", "value": 3 }
  ],
  "metadata": { "your_ref": "anything you want echoed back" }
}
FieldRequiredNotes
flow_typeyes"email" for this flow (default).
customer_emailyes (email flow)Where the KYC link is sent. Falls back to the sub-account’s email if omitted.
webhook_urlno but needed for callbacksHTTPS endpoint that receives the events below. No webhook_url = no callbacks.
expires_in_daysno1–365, default 30.
reminder_schedulenoReminder emails, e.g. 3 days before expiry.
metadatanoArbitrary JSON, echoed back in every webhook payload.
account_auth_id in the schema is set automatically from the path sub_auth_id for this flow — you don’t need to send it.
Response 201:
{
  "session_id": "b6a1f3c2-7a44-4e2b-9c11-...",
  "account_auth_id": "SA_xxxx",
  "customer_email": "customer@example.com",
  "email_dispatched_to": "c***@example.com",
  "status": "email_sent",
  "expires_at": "2026-07-04T08:51:10Z",
  "widget_url": null,
  "message": "KYC email dispatched successfully"
}
widget_url is only populated for flow_type: "redirect"; kyc_link is returned only in dev for testing without email.

2. Webhook events you’ll receive

Vobiz POSTs JSON to your webhook_url as the session progresses:
EventWhen
kyc.initiatedSession created / email dispatched.
kyc.submittedCustomer submitted their documents.
kyc.completedVerification passed.
kyc.failedVerification failed.
kyc.session_expiredLink expired before completion.
kyc.session_revokedSession manually revoked.
Payload:
{
  "event": "kyc.completed",
  "timestamp": "2026-06-04T08:51:10Z",
  "session_id": "b6a1f3c2-7a44-4e2b-9c11-...",
  "account_auth_id": "SA_xxxx",
  "customer_email": "customer@example.com",
  "kyc_type": "individual",
  "session_status": "kyc_completed",
  "metadata": { "your_ref": "anything you want echoed back" },
  "created_at": "2026-06-04T08:40:00+00:00",
  "updated_at": "2026-06-04T08:51:10+00:00"
}

3. Verify the signature

Every delivery includes an HMAC signature header:
X-Vobiz-Signature: sha256=<hex>
  • Algorithm: HMAC-SHA256 over the raw request body.
  • Secret: your parent account’s auth_token.
Verify (Python):
import hmac, hashlib

def verify(raw_body: bytes, header: str, auth_token: str) -> bool:
    expected = "sha256=" + hmac.new(auth_token.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
Return 2xx to acknowledge. Failed deliveries are retried with exponential backoff.

cURL example

curl -X POST "https://api.vobiz.ai/api/v1/sub-accounts/SA_XXXX/kyc-sessions" \
  -H "X-Auth-ID: MA_XXXX" \
  -H "X-Auth-Token: <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "flow_type": "email",
    "customer_email": "customer@example.com",
    "webhook_url": "https://your-app.example.com/kyc/webhook"
  }'