ID verification flow integration
An example of how ID collection and verification can be integrated into your onboarding workflow.
Overview
This guide describes how to integrate Xama's client onboarding, identity verification, and AML screening capabilities into your application. The integration streamlines the collection of ID documentation, identity verification, and compliance checks as part of your customer onboarding workflow.
Integration Capabilities
This integration enables you to:
-
Create clients and contacts in Xama programmatically
-
Trigger onboarding requests to collect ID documents and personal information
-
Embed verification links in your own onboarding portal or send via email
-
Receive real-time notifications when verification is complete via webhooks
-
Analyze verification results including document checks and face matching
-
Copy verified data back to contact records
-
Initiate AML checks for identity verification and PEP/Sanctions screening
-
Review screening results and make compliance decisions
Prerequisites
Before starting the integration, ensure you have:
-
Completed the authentication guide and obtained your OAuth2 credentials
-
A Xama account created at https://platform.xamatech.com
-
Your Client ID from the Xama platform
-
Email connection configured in Xama (if sending onboarding emails): https://platform.xamatech.com/portal/hub/settings/email-settings
-
Familiarity with the Xama training materials (available in the platform's training center)
Understanding Xama Terminology
Before working with the API, it's important to understand how Xama uses certain terms:
|
Xama UI Term |
API Term |
Description |
|---|---|---|
|
Client |
Account |
A client record as shown in the Xama interface (company, individual, trust, etc.) |
|
N/A |
Client |
Your Xama customer account - used as |
|
Contact |
Contact |
An individual person associated with an account |
Integration Workflow
The typical onboarding flow follows this sequence:
-
Create client and contacts in Xama
-
Trigger onboarding request to collect documents
-
Contact completes verification via email link or embedded portal
-
Receive webhook notification when verification is complete
-
Analyze results and check document/face match decisions
-
Copy verified data to contact record
-
Trigger AML check for identity verification and screening
-
Review screening results for PEP/Sanctions matches
-
Complete compliance workflow based on results
Workflow Diagram
The verification journey follows this high-level flow:
API Endpoints and Implementation
Create Client and Contacts
Before triggering onboarding requests, you must create the client (account) and associated contacts in Xama.
Create Client with Primary Contact
Endpoint
POST /clients/{clientId}/accounts
Request Example
curl -X POST "https://xamahub.xamatech.com/api/clients/{clientId}/accounts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"name": "Acme Corporation",
"type": "COMPANY",
"reg_number": "12345678",
"primary_contact": {
"first_name": "John",
"middle_name": "Robert",
"last_name": "Smith",
"email": "john.smith@acme.com",
"phone": "+44 20 1234 5678",
"date_of_birth": "1985-03-15",
"driving_license_number": "SMITH123456JR9AB",
"driving_license_expiry_date": "2030-03-15",
"passport_number": "123456789<<<<01",
"passport_expiry_date": "2029-06-20",
"primary_address": {
"street": "123 High Street",
"postcode": "SW1A 1AA",
"city": "London",
"country_code": "GB",
"type": "PRIMARY"
}
}
}'
Account Type Parameter
|
Value |
Use Case |
Description |
|---|---|---|
|
|
B2C relationships |
Single-person entities (e.g., personal tax returns, sole traders) |
|
|
B2B relationships |
Multi-contact entities (companies, partnerships, trusts, charities) |
Request Parameters
|
Field |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
Client/company name |
|
|
string |
Yes |
|
|
|
string |
No |
Company registration number |
|
|
object |
Yes |
Primary contact details |
Primary Contact Fields
|
Field |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
Contact's first name |
|
|
string |
No |
Contact's middle name |
|
|
string |
Yes |
Contact's last name |
|
|
string |
Yes |
Contact's email (required for onboarding emails) |
|
|
string |
No |
Contact phone number |
|
|
string |
No |
Format: YYYY-MM-DD |
|
|
string |
No |
Driving license number |
|
|
string |
No |
Format: YYYY-MM-DD |
|
|
string |
No |
Passport number |
|
|
string |
No |
Format: YYYY-MM-DD |
|
|
object |
No |
Primary residential address |
Create Additional Contacts
Add additional contacts (beneficial owners, directors, etc.) to an account.
Endpoint
POST /clients/{clientId}/accounts/{accountId}/contacts
Request Example
curl -X POST "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"first_name": "Jane",
"middle_name": "Marie",
"last_name": "Doe",
"email": "jane.doe@example.com",
"phone": "+44 20 9876 5432",
"primary_address": {
"street": "456 Oxford Street",
"postcode": "W1D 1BS",
"city": "London",
"country_code": "GB",
"type": "PRIMARY"
}
}'
Reference: See the Contacts API documentation for complete specifications.
Trigger Onboarding Request
Onboarding requests collect ID documents, selfies, personal details, and proof of address from contacts.
Prerequisites for Onboarding Requests
-
Email connection configured (if sending emails): Configure at https://platform.xamatech.com/portal/hub/settings/email-settings
-
Contact must have email address (even if suppressing emails, use a placeholder/internal email)
Endpoint
PUT /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding
Request Example
curl -X PUT "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"config": {
"parameters": {
"suppress_invitation_mail": "false",
"frontend_redirect_url": "https://yourapp.com/onboarding/complete",
"idscan": "true",
"personal_details": "true",
"proof_of_identity": "true",
"selfie": "false",
"face_match": "false",
"proof_of_address": "true"
},
"ttl_in_days": 365,
"is_automatic_refresh_enabled": false
}
}'
Configuration Parameters
|
Parameter |
Type |
Description |
|---|---|---|
|
|
boolean |
|
|
|
string |
URL to redirect user after completion (optional) |
|
|
boolean |
Request home address from user |
|
|
boolean |
Request ID document (passport/license) - use when |
|
|
boolean |
Request ID document + selfie + perform biometric verification |
|
|
boolean |
Request ID document + selfie + perform biometric verification over Xama Verify app |
|
|
boolean |
Collect preferred email address |
|
|
boolean |
Collect legal names history |
|
|
boolean |
Collect address history of 12 months |
|
|
boolean |
Request selfie without biometric check (use when |
|
|
boolean |
Request additional proof of identity document |
|
|
boolean |
Request proof of address document |
|
|
number |
How long the verification remains valid (e.g., 365) |
|
|
boolean |
Automatically refresh verification before expiry - not recommended |
Configuration Guidelines:
-
Standard ID verification:
idscan: true,face_match: false,selfie: false -
Biometric verification:
face_match: true,idscan: false,selfie: false -
Biometric verification (NFC enabled):
face_match_mobile: true,idscan: false,selfie: false
Suppressing Emails and Embedding Links
You have two options for delivering the onboarding link to contacts:
Option 1: Email Sent by Xama (Default)
Set suppress_invitation_mail: "false" and Xama will email the link to the contact's email address.
Option 2: Embed Link in Your Application
Set suppress_invitation_mail: "true" and retrieve the link to embed in your customer portal, onboarding wizard, or other interface.
Retrieve the Onboarding Link:
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding
Request Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"
Response Extract
{
"data": {
"onboarding_url": "https://platform.xamatech.com/onboarding/complete/abc123..."
}
}
Use the onboarding_url value to direct users to the verification flow from your application.
Frontend Redirect URL:
Set frontend_redirect_url to redirect users back to your application after they complete verification. Without this, users see a generic "Thank you" screen.
Example Use Cases:
-
https://yourapp.com/onboarding/success- Return to onboarding wizard -
https://yourapp.com/dashboard?verified=true- Return to dashboard with status -
https://yourapp.com/clients/{clientId}/complete- Return to client record
Setting Up Webhook Subscriptions
Use webhooks to receive real-time notifications when contacts complete onboarding requests, eliminating the need for polling.
Endpoint
POST /clients/{clientId}/subscriptions
Request Example
curl -X POST "https://xamahub.xamatech.com/api/clients/{clientId}/subscriptions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"callback_url": "https://yourapp.com/webhooks/xama/onboarding",
"type": "WEBHOOK",
"config": {
"api_secret": "your-webhook-secret",
"entities": [
{
"entity": "CONTACT",
"report_types": ["ONBOARDING"],
"events": [
"REPORT_INITIATED",
"REPORT_READY",
"REPORT_ERROR",
"REPORT_CREDIT_LIMIT_EXCEEDED",
"REPORT_IN_REVIEW",
"REPORT_REVIEW_COMPLETED"
]
}
]
}
}'
Configuration Parameters
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
Your webhook endpoint URL |
|
|
string |
Must be |
|
|
string |
Secret for webhook signature verification |
|
|
string |
|
|
|
array |
|
|
|
array |
Events to monitor (see below) |
Webhook Events for Onboarding:
|
Event |
Description |
Action |
|---|---|---|
|
|
Onboarding request created |
Optional: Update UI to show "pending" status |
|
|
Contact completed verification |
Primary event: Retrieve and analyze results |
|
|
Error during verification |
Handle error, potentially retry |
|
|
Account credit limit reached |
Contact Xama support |
|
|
Manual review required |
Optional: Notify admin team |
|
|
Manual review finished |
Retrieve updated results |
Implementation Notes:
-
Focus on
REPORT_READYfor completed verifications -
Verify webhook signatures using your
api_secret -
Respond with 2xx status code to acknowledge receipt
-
Implement idempotency to handle duplicate webhooks
Analyzing Onboarding Request Results
Once you receive a REPORT_READY webhook notification, retrieve the full onboarding report to analyze verification results.
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding
Request Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/onboarding" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"
Response Example
{
"account_id": "ae9a6650-48cb-11ef-b07f-21e051e087da",
"client_id": "1b62c5a0-03a1-11ee-b515-618e61a59cb4",
"config": {
"parameters": {
"face_match": "true",
"proof_of_address": "true"
},
"ttl_in_days": 365,
"is_automatic_refresh_enabled": false
},
"contact_id": "ae9a6651-48cb-11ef-b07f-21e051e087da",
"data": {
"idscan": {
"date_of_birth": "1970-01-01",
"document_type": "Passport",
"passport_number": "564[..]<<<02",
"document_decision": "PASSED",
"document_last_name": "SMITH",
"face_match_decision": "PASSED",
"document_expiry_date": "2030-01-01",
"document_given_names": "JOHN ROBERT",
"document_decision_date": "2024-07-23T08:22:07.3078793",
"driving_license_number": "56[..]63"
},
"report_link": "https://platform.xamatech.com/...",
"refreshed_at": "2024-07-23",
"request_sent_at": "2024-07-23T08:19:08.290Z",
"personal_details": {
"city": "London",
"street": "123 High Street",
"country": "GB",
"postcode": "SW1A 1AA"
}
},
"id": "ae9a6650-48cb-11ef-b07f-21e051e087da--ae9a6651-48cb-11ef-b07f-21e051e087da",
"review": {
"empty": false,
"notes": "Verified",
"status": "COMPLETE",
"decision": "PASSED"
},
"revision": "1721722746296",
"status": "READY",
"type": "ONBOARDING"
}
Key Response Fields
|
Field Path |
Description |
|---|---|
|
|
Overall status: |
|
|
|
|
|
|
|
|
|
|
|
When document was verified |
|
|
Extracted from ID document |
|
|
Given names from document |
|
|
Last name from document |
|
|
If document type is Passport |
|
|
If document type is Driving License |
|
|
Document expiration date |
|
|
Address provided by contact |
|
|
Manual review decision (if applicable) |
|
|
Reviewer notes |
Decision Logic
Document Decision:
-
PASSED- Document verified successfully, data can be trusted -
REFER- Requires manual review, often due to OCR extraction failures -
ALERT- Serious issue (rare: underage, deceased, etc.)
Face Match Decision (if enabled):
-
PASSED- Biometric match between ID photo and selfie successful -
FAILED- Biometric match failed
Critical Implementation Notes:
-
Only accept extracted data if
document_decision: "PASSED"-REFERdecisions may indicate OCR extraction errors, so data may be incorrect -
Check document type before using ID numbers - Use
passport_numberonly ifdocument_type: "Passport", usedriving_license_numberonly ifdocument_type: "Driving License" -
Handle REFER decisions - Implement manual review workflow or request re-submission
Copying Verified Data to Contact Record
After verifying onboarding results, update the contact record with the verified information.
Important: Xama's PUT requests replace all contact data. You must include existing data you want to preserve along with new verified data.
Best Practice Workflow
-
Retrieve current contact data via GET request
-
Merge verified data with existing contact data
-
Update contact via PUT request with complete merged data
Retrieve Contact Record
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}
Request Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"
Update Contact Record
Endpoint
PUT /clients/{clientId}/accounts/{accountId}/contacts/{contactId}
Request Example
curl -X PUT "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"metadata": {
"external_reference": "YOUR-CLIENT-ID-123"
},
"first_name": "John",
"middle_name": "Robert",
"last_name": "Smith",
"type": "PRIMARY",
"email": "john.smith@acme.com",
"phone": "+44 20 1234 5678",
"date_of_birth": "1970-01-01",
"driving_license_number": "",
"driving_license_expiry_date": "",
"passport_number": "564123456",
"passport_expiry_date": "2030-01-01",
"primary_address": {
"street": "123 High Street",
"postcode": "SW1A 1AA",
"city": "London",
"country_code": "GB"
}
}'
Important Notes:
-
Country codes: Use ISO-2 format (e.g.,
GBfor United Kingdom,USfor United States) -
Blank fields: Set to empty string (
"") if not applicable, don't omit -
Data not included will be cleared: Always retrieve existing data first and include it in the update
-
External reference: Use
metadata.external_referenceto link to your system's client ID
Triggering AML Checks
An AML check performs electronic identity verification and screens for Politically Exposed Persons (PEPs) and Sanctions matches.
Prerequisites:
-
Contact must have sufficient data: full name, date of birth, and address
Endpoint
PUT /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/aml
Request Example
curl -X PUT "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/aml" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"config": {
"ttl_in_days": 365,
"is_automatic_refresh_enabled": false
}
}'
Configuration Parameters
|
Parameter |
Type |
Description |
|---|---|---|
|
|
number |
How long the AML check remains valid (e.g., 365) |
|
|
boolean |
Automatically refresh before expiry |
Processing Notes:
-
AML checks are asynchronous and take a few seconds to complete
-
Use webhooks (recommended) or polling to check for completion
-
Results include identity verification decision + PEP/Sanctions screening
Setting Up AML Check Webhooks
Monitor AML check completion with webhooks.
Endpoint
POST /clients/{clientId}/subscriptions
Request Example
curl -X POST "https://xamahub.xamatech.com/api/clients/{clientId}/subscriptions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"callback_url": "https://yourapp.com/webhooks/xama/aml",
"type": "WEBHOOK",
"config": {
"api_secret": "your-webhook-secret",
"entities": [
{
"entity": "CONTACT",
"report_types": ["AML"],
"events": [
"REPORT_INITIATED",
"REPORT_READY",
"REPORT_ERROR",
"REPORT_CREDIT_LIMIT_EXCEEDED",
"REPORT_IN_REVIEW",
"REPORT_REVIEW_COMPLETED"
]
}
]
}
}'
Focus on the REPORT_READY event to know when AML checks are complete.
Analysing AML Check Results
Retrieve and analyze AML check results after receiving a REPORT_READY webhook.
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/aml
Request Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/aml" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"
Response Example
{
"account_id": "4552c460-91f2-11ef-96be-935da77d5118",
"client_id": "1b62c5a0-03a1-11ee-b515-618e61a59cb4",
"config": {
"ttl_in_days": 365,
"is_automatic_refresh_enabled": false
},
"contact_id": "4552c461-91f2-11ef-96be-935da77d5118",
"data": {
"decision": "PASS",
"pep_matches": "Potential Match",
"report_link": "https://platform.xamatech.com/...",
"refreshed_at": "2024-10-24",
"sanctions_matches": "No Match",
"last_decision_date": "2024-10-24"
},
"id": "4552c460-91f2-11ef-96be-935da77d5118--4552c461-91f2-11ef-96be-935da77d5118",
"review": {
"empty": false,
"notes": "Reviewed potential PEP match - determined to be false positive",
"status": "COMPLETE",
"decision": "PASS",
"pep_matches": "MATCH_DISMISSED",
"sanctions_matches": "NO_MATCH"
},
"revision": "1729766007467",
"status": "READY",
"type": "AML"
}
Key Response Fields
|
Field |
Possible Values |
Description |
|---|---|---|
|
|
|
Overall status of the AML check |
|
|
|
Identity verification decision |
|
|
|
PEP screening result |
|
|
|
Sanctions screening result |
|
|
Date |
When the check was performed |
|
|
|
Manual review decision (if reviewed) |
|
|
|
Reviewed PEP decision |
|
|
|
Reviewed Sanctions decision |
|
|
String |
Reviewer notes |
Decision Interpretations
Identity Verification Decision (data.decision)
|
Value |
Meaning |
Recommended Action |
|---|---|---|
|
|
Identity verified against 2+ authoritative sources |
Proceed with onboarding |
|
|
Could not verify against 2+ sources |
Manual review required or request additional documents |
|
|
Serious issue detected (rare) |
Manual review required - may indicate underage, deceased, or other critical issue |
PEP Matches (data.pep_matches)
|
Value |
Meaning |
Recommended Action |
|---|---|---|
|
|
No PEP matches found |
No action required |
|
|
Possible PEP match requires review |
Review match details in Xama platform - most are false positives |
Sanctions Matches (data.sanctions_matches)
|
Value |
Meaning |
Recommended Action |
|---|---|---|
|
|
No sanctions matches found |
No action required |
|
|
Possible sanctions match requires review |
Review - may indicate restricted individual |