Documentation Index
Fetch the complete documentation index at: https://docs.vobiz.ai/llms.txt
Use this file to discover all available pages before exploring further.
← Partner API Reference
Trigger and manage the customer KYC flow for any sub-account you’ve provisioned. Vobiz supports two delivery modes — async via emailed link, or real-time via in-app redirect — and runs the underlying verification (PAN + Aadhaar OTP for individuals, PAN + GSTIN for companies — no document uploads). Webhook events fire as the session progresses.
All Partner API requests use X-Auth-ID and X-Auth-Token headers. See Authentication for details.
Overview
| Method | Endpoint | Description |
|---|
| POST | /kyc-sessions | Initiate a KYC session (email or redirect flow) |
| GET | /kyc-sessions | List all KYC sessions (paginated) |
| GET | /kyc-sessions/{session_id} | Get a single KYC session by ID |
| POST | /kyc-sessions/{session_id}/resend | Resend the KYC email (email flow only) |
| DELETE | /kyc-sessions/{session_id} | Revoke an in-flight session |
Flow types
Pick the flow that matches your onboarding UX. The request body, response, and post-verification handoff all differ.
flow_type | When to use | Extra required field | Post-verification handoff |
|---|
"email" (default) | Async onboarding — customer completes KYC later from their inbox. | customer_email | Webhook only. |
"redirect" | Real-time inline KYC during signup or checkout. | redirect_url | Browser redirect to your redirect_url?session_id=…&status=…&auth_id=… plus webhook. |
Both flows end with the same Vobiz-hosted KYC widget. The widget itself is internal to Vobiz — you do not call its endpoints directly; you either email a link to it, or redirect the customer to it.
Initiate KYC Session — Email Flow
Async flow. Vobiz emails the link to customer_email; the session sits in email_sent until the customer opens it.
POST /api/v1/partner/kyc-sessions
curl -X POST \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"account_auth_id": "MA_XXXXXXXX",
"flow_type": "email",
"customer_email": "customer@example.com",
"webhook_url": "https://yourapp.com/kyc-webhook",
"expires_in_days": 14,
"reminder_schedule": [
{ "trigger": "days_before_expiry", "value": 3 },
{ "trigger": "days_before_expiry", "value": 1 }
],
"metadata": {
"customer_ref": "TEST_001",
"plan": "starter"
}
}'
Response (201)
{
"session_id": "a5f8da3c-b47f-40c3-a3e6-d2c9a0f27065",
"account_auth_id": "MA_E31MAU98",
"customer_email": "customer@example.com",
"email_dispatched_to": "c***@example.com",
"kyc_type": null,
"status": "email_sent",
"expires_at": "2026-05-15T19:37:01.316686Z",
"widget_url": null,
"kyc_link": null,
"message": "KYC email dispatched successfully"
}
| Field | Description |
|---|
session_id | Permanent identifier for this KYC session — a UUID. Store it for retrieve / resend / revoke. |
account_auth_id | Echoed from the request. |
customer_email | Echoed from the request. |
email_dispatched_to | Masked email address where the link was sent (c***@example.com). |
kyc_type | null until the customer starts the flow; then individual (PAN 4th char = P) or company (PAN 4th char = C). |
status | email_sent on a fresh email-flow session. See Lifecycle. |
expires_at | UTC ISO timestamp after which the link stops working. |
widget_url | Always null for email flow (used for redirect flow only). |
kyc_link | Reserved. Currently null. |
message | Human-readable status string. Don’t parse it — use status. |
Subsequent GET calls return the session under the field name id (UUID) — not session_id as in the POST response. Same value, different key. Use whichever the API returned on the request you just made.
Initiate KYC Session — Redirect Flow
Real-time flow. The response contains a widget_url; redirect the customer to it immediately. No email is sent. After the customer finishes, their browser is redirected to redirect_url?session_id=…&status=…&auth_id=… and a webhook fires.
POST /api/v1/partner/kyc-sessions
curl -X POST \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"account_auth_id": "MA_XXXXXXXX",
"flow_type": "redirect",
"redirect_url": "https://yourapp.com/kyc-complete",
"webhook_url": "https://yourapp.com/kyc-webhook",
"expires_in_days": 14,
"metadata": {
"customer_ref": "TEST_001",
"plan": "starter"
}
}'
Response (201)
{
"session_id": "1a0f7da5-2abb-47bf-a6c3-eb5cff7feda5",
"account_auth_id": "MA_E31MAU98",
"customer_email": null,
"email_dispatched_to": null,
"kyc_type": null,
"status": "link_ready",
"expires_at": "2026-05-15T19:37:01.841263Z",
"widget_url": "https://kyc.vobiz.ai/verify?token=kst_cb1b3fda15c0df5cf58a283e47e9eee148ce0b2b87d7c6693f77296612f58f07",
"kyc_link": null,
"message": "KYC session created — redirect your customer to widget_url to begin."
}
| Field | Description |
|---|
session_id | UUID. Store for retrieve / revoke. |
status | link_ready on a fresh redirect-flow session — distinct from the email flow’s email_sent. |
widget_url | The hosted KYC widget. Redirect the customer’s browser to this URL. Token portion is kst_<64-hex>. |
customer_email / email_dispatched_to | Always null for redirect flow — no email is sent. |
| All other fields | Same semantics as the email-flow response above. |
Resend is not supported for redirect-flow sessions. A POST /kyc-sessions/{id}/resend against a redirect-flow session returns 400 with message "Resend is not available for redirect-flow sessions — no email is associated with this session."
Only one active session per account_auth_id at a time. Creating a new session (email or redirect) for a sub-account that already has an active session will silently auto-revoke the previous one. The old session’s status flips to revoked at the moment the new one is created.This means: if you call resend / revoke on an “old” session id you stashed earlier, you may get 409 Cannot resend: session is 'revoked' or 409 Session is already in terminal status: 'revoked' because a newer POST replaced it. Always operate on the most recent session_id returned by your most recent POST.
Request body — full field reference
| Field | Type | Email flow | Redirect flow | Notes |
|---|
account_auth_id | string | Required | Required | Sub-account auth_id from POST /accounts. |
flow_type | string | Optional | Required = "redirect" | Omit or set "email" for email flow. Set "redirect" for inline flow. |
customer_email | string | Required | Ignored | Where the link is mailed. |
redirect_url | string | Ignored | Required | URL the browser is sent to after the customer finishes the widget. Receives session_id, status, auth_id as query params. |
webhook_url | string | Optional | Optional | HTTPS endpoint that receives kyc.completed / kyc.failed / kyc.session_revoked events. |
expires_in_days | integer | Optional, default 7 | Optional, default 7 | Days until the link / widget URL expires. |
reminder_schedule | array | Optional | Optional | Auto reminder emails before expiry. Each item: { "trigger": "days_before_expiry", "value": <int> }. |
metadata | object | Optional | Optional | Free-form key/value object echoed back on GET and on webhook payloads. Useful fields: customer_ref, plan. |
List KYC Sessions
Returns a paginated list of every KYC session you’ve initiated.
GET /api/v1/partner/kyc-sessions
Query Parameters
| Parameter | Default | Description |
|---|
page | 1 | Page number (1-indexed). |
size | 20 | Items per page. |
status | - | Filter by status: email_sent, link_ready, opened, in_progress, kyc_completed, revoked. |
account_auth_id | - | Filter to a single sub-account. |
curl -X GET \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions?page=1&size=20" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}"
{
"sessions": [
{
"id": "09f40c53-bd09-4e4f-882b-6ebc922278de",
"account_auth_id": "MA_YLTJEUZY",
"customer_email": null,
"kyc_type": null,
"status": "opened",
"expires_at": "2026-05-20T08:32:48.524909Z",
"first_opened_at": "2026-05-06T08:33:01.101780Z",
"completed_at": null,
"webhook_url": null,
"redirect_url": "https://console.vobiz.ai/kyc-complete",
"reminder_schedule": [],
"metadata": null,
"verified_data": null,
"created_at": "2026-05-06T08:32:48.518048Z",
"updated_at": "2026-05-06T08:33:01.094999Z"
}
],
"total": 18,
"page": 1,
"size": 20
}
Each session in the sessions[] array contains the fields documented in Session object below.
Get KYC Session
Fetch the current state of a single session — useful for polling if your webhook receiver isn’t reachable.
GET /api/v1/partner/kyc-sessions/{session_id}
curl -X GET \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions/96df2f70-f51f-41b4-997d-0de8fdb570e8" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}"
{
"id": "96df2f70-f51f-41b4-997d-0de8fdb570e8",
"account_auth_id": "MA_M3P94TZC",
"customer_email": "customer@example.com",
"kyc_type": "individual",
"status": "revoked",
"expires_at": "2026-06-04T06:00:52.443834Z",
"first_opened_at": "2026-05-05T06:02:17.055612Z",
"completed_at": null,
"webhook_url": null,
"redirect_url": null,
"reminder_schedule": [],
"metadata": null,
"verified_data": {
"pan_type": "individual",
"pan_number": "GTBPDXXXXX",
"pan_name_match": true,
"completed_steps": ["pan"],
"pan_registered_name": "SAURABH DUBEY"
},
"created_at": "2026-05-05T06:00:52.435008Z",
"updated_at": "2026-05-06T07:07:38.048734Z"
}
See Session object for full field reference.
Resend KYC Email
Re-sends the KYC link to the customer’s email. Useful if they lost the email or filtered it as spam. Only valid for email-flow sessions that are still in an active status.
POST /api/v1/partner/kyc-sessions/{session_id}/resend
curl -X POST \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions/{session_id}/resend" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}"
The 30-minute cooldown starts at session creation, not at the first resend. POST /kyc-sessions itself dispatches the first email, so a resend fired immediately after creation returns 429. The 429 response tells you exactly how long to wait:{
"error": "HTTPError",
"message": "Email was sent recently. Please wait 1799 seconds before resending.",
"status_code": 429
}
| Response | Meaning |
|---|
200 | Email re-dispatched (only available 30 min after the previous send). |
400 | Session is a redirect-flow session. Message: "Resend is not available for redirect-flow sessions — no email is associated with this session." |
409 | Session is in a terminal status (revoked or kyc_completed). Message: "Cannot resend: session is '<status>'". |
429 | Rate-limited — at most one email send per 30 minutes per session. Message includes the exact remaining-seconds value. |
Revoke KYC Session
Cancels an in-flight session. The hosted link / widget URL stops working immediately and Vobiz fires a kyc.session_revoked webhook.
DELETE /api/v1/partner/kyc-sessions/{session_id}
Request Body (optional)
| Field | Type | Description |
|---|
reason | string | Free-text reason. Surfaced on the webhook and in the audit log. |
curl -X DELETE \
"https://api.vobiz.ai/api/v1/partner/kyc-sessions/{session_id}" \
-H "X-Auth-ID: {your_partner_id}" \
-H "X-Auth-Token: {your_auth_token}" \
-H "Content-Type: application/json" \
-d '{ "reason": "Wrong email — creating new session" }'
Response (200)
{
"message": "Session revoked",
"session_id": "1a0f7da5-2abb-47bf-a6c3-eb5cff7feda5"
}
If the session is already in a terminal status, returns 409 with "Session is already in terminal status: '<status>'".
Session lifecycle
email flow: email_sent ─┐
├─► opened ─► in_progress ─► kyc_completed
redirect flow: link_ready ─┘ │
└─► revoked
(also: revoked at any time via DELETE
or auto-revoked when a new session
is created for the same account_auth_id)
| Status | Meaning |
|---|
email_sent | Fresh email-flow session; awaiting customer to open the emailed link. |
link_ready | Fresh redirect-flow session; widget_url is live and waiting for the redirect. |
opened | Customer has loaded the widget at least once. |
in_progress | Customer has started verification (PAN submitted). kyc_type is now set. |
kyc_completed | All verification steps succeeded. The sub-account’s kyc_status flips to completed. |
revoked | Terminated — either you called DELETE, or you created a new session for the same account (auto-revoke). |
Session object
The fields returned on GET /kyc-sessions and GET /kyc-sessions/{session_id}.
| Field | Type | Notes |
|---|
id | string | Session identifier. |
account_auth_id | string | Sub-account this session belongs to. |
customer_email | string | null | Set on email-flow sessions. |
kyc_type | string | null | individual, company, or null before PAN is submitted. |
status | string | See Session lifecycle. |
expires_at | string | UTC ISO timestamp. |
first_opened_at | string | null | When the customer first loaded the widget. |
completed_at | string | null | Set when status reaches kyc_completed. |
webhook_url | string | null | Echoed from the create request. |
redirect_url | string | null | For redirect-flow: where the customer is sent after finishing. |
reminder_schedule | array | Echoed from the create request. |
metadata | object | null | Echoed from the create request. |
verified_data | object | null | Populated as steps complete — see Verified data. |
created_at | string | UTC ISO timestamp. |
updated_at | string | UTC ISO timestamp. |
Verified data
verified_data accumulates as the customer completes steps. Sample after a successful individual flow:
{
"pan_type": "individual",
"pan_number": "ABCPE1234F",
"pan_name_match": true,
"pan_registered_name": "John Doe",
"completed_steps": ["pan", "aadhaar"],
"aadhaar_name": "John Doe",
"aadhaar_dob": "1990-01-15",
"masked_aadhaar": "9942",
"gender": "MALE",
"address": "221B Baker Street, Mumbai, Maharashtra, 400001, India"
}
Sample after a successful company flow:
{
"pan_type": "company",
"completed_steps": ["pan", "gst"],
"pan_registered_name": "ACME TECHNOLOGIES PVT LTD"
}
Webhook events
Vobiz POSTs JSON to your webhook_url as the session progresses:
| Event | Fires when |
|---|
kyc.completed | All verification steps succeeded. The sub-account’s kyc_status flips to completed. |
kyc.failed | Document invalid, name mismatch, or OTP failure. The session terminates. |
kyc.session_revoked | You revoked the session via DELETE /kyc-sessions/{session_id}. |
Webhook deliveries are retried with exponential backoff on non-2xx responses. Respond with 200 OK quickly and process the event asynchronously.
Verification methods
The customer’s PAN determines which flow runs — the partner does not pick it.
| 4th character of PAN | Flow | Inputs |
|---|
P | Individual | PAN + DOB → Aadhaar via DigiLocker (Govt OTP) |
C | Company | PAN + entity name → GSTIN |
Neither flow requires the customer to upload documents — Vobiz pulls verification data directly from government APIs.
Errors
All errors share this shape:
{
"error": "HTTPError",
"message": "Cannot resend: session is 'revoked'",
"status_code": 409
}
Validation errors (422) include a details array with loc / msg / type per field, e.g.:
{
"error": "ValidationError",
"message": "Request validation failed",
"details": [
{ "type": "json_invalid", "loc": ["body", 78], "msg": "JSON decode error", "input": {}, "ctx": { "error": "Invalid control character at" } }
],
"status_code": 422
}
| Status | Cause |
|---|
400 | POST /resend on a redirect-flow session. |
401 / 403 | Missing or invalid X-Auth-ID / X-Auth-Token. |
404 | account_auth_id does not exist, or belongs to another partner. |
409 | Operation on a session in a terminal status — Cannot resend: session is 'revoked' or Session is already in terminal status: '<status>'. Common cause: a newer session for the same account auto-revoked this one. |
422 | Validation error — e.g. email flow without customer_email, redirect flow without redirect_url, malformed reminder_schedule, invalid JSON body. |
429 | POST /resend called within the 30-minute cooldown. |