Skip to content

ID verification flow integration

An example of how ID collection and verification can be integrated into your onboarding workflow.

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.

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

Before starting the integration, ensure you have:

  1. Completed the Authentication guide and obtained your OAuth2 credentials
  2. A Xama account created at https://platform.xamatech.com
  3. Your Client ID from the Xama platform
  4. Email connection configured in Xama (if sending onboarding emails): https://platform.xamatech.com/portal/hub/settings/email-settings
  5. Familiarity with the Xama training materials (available in the platform’s training center)

Before working with the API, it’s important to understand how Xama uses certain terms:

Xama UI TermAPI TermDescription
ClientAccountA client record as shown in the Xama interface (company, individual, trust, etc.)
N/AClientYour Xama customer account - used as {clientId} in all API calls
ContactContactAn individual person associated with an account

The typical onboarding flow follows this sequence:

  1. Create client and contacts in Xama
  2. Trigger onboarding request to collect documents
  3. Contact completes verification via email link or embedded portal
  4. Receive webhook notification when verification is complete
  5. Analyze results and check document/face match decisions
  6. Copy verified data to contact record
  7. Trigger AML check for identity verification and screening
  8. Review screening results for PEP/Sanctions matches
  9. Complete compliance workflow based on results

The verification journey follows this high-level flow:

Before triggering onboarding requests, you must create the client (account) and associated contacts in Xama.

Endpoint

POST /clients/{clientId}/accounts

Request Example

Terminal window
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

ValueUse CaseDescription
INDIVIDUALB2C relationshipsSingle-person entities (e.g., personal tax returns, sole traders)
COMPANYB2B relationshipsMulti-contact entities (companies, partnerships, trusts, charities)

Request Parameters

FieldTypeRequiredDescription
namestringYesClient/company name
typestringYesCOMPANY or INDIVIDUAL
reg_numberstringNoCompany registration number
primary_contactobjectYesPrimary contact details

Primary Contact Fields

FieldTypeRequiredDescription
first_namestringYesContact’s first name
middle_namestringNoContact’s middle name
last_namestringYesContact’s last name
emailstringYesContact’s email (required for onboarding emails)
phonestringNoContact phone number
date_of_birthstringNoFormat: YYYY-MM-DD
driving_license_numberstringNoDriving license number
driving_license_expiry_datestringNoFormat: YYYY-MM-DD
passport_numberstringNoPassport number
passport_expiry_datestringNoFormat: YYYY-MM-DD
primary_addressobjectNoPrimary residential address

Add additional contacts (beneficial owners, directors, etc.) to an account.

Endpoint

POST /clients/{clientId}/accounts/{accountId}/contacts

Request Example

Terminal window
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.

Onboarding requests collect ID documents, selfies, personal details, and proof of address from contacts.

  1. Email connection configured (if sending emails): Configure at https://platform.xamatech.com/portal/hub/settings/email-settings
  2. 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

Terminal window
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

ParameterTypeDescription
suppress_invitation_mailbooleanfalse = Send email; true = Don’t send email (retrieve link manually)
frontend_redirect_urlstringURL to redirect user after completion (optional)
personal_detailsbooleanRequest home address from user
idscanbooleanRequest ID document (passport/license) - use when face_match is false
face_matchbooleanRequest ID document + selfie + perform biometric verification
face_match_mobilebooleanRequest ID document + selfie + perform biometric verification over Xama Verify app
unique_emailbooleanCollect preferred email address
legal_names_historybooleanCollect legal names history
home_address_historybooleanCollect address history of 12 months
selfiebooleanRequest selfie without biometric check (use when face_match is false) - not recommended
proof_of_identitybooleanRequest additional proof of identity document
proof_of_addressbooleanRequest proof of address document
ttl_in_daysnumberHow long the verification remains valid (e.g., 365)
is_automatic_refresh_enabledbooleanAutomatically 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

You have two options for delivering the onboarding link to contacts:

Set suppress_invitation_mail: "false" and Xama will email the link to the contact’s email address.

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

Terminal window
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

Use webhooks to receive real-time notifications when contacts complete onboarding requests, eliminating the need for polling.

Endpoint

POST /clients/{clientId}/subscriptions

Request Example

Terminal window
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

FieldTypeDescription
callback_urlstringYour webhook endpoint URL
typestringMust be WEBHOOK
api_secretstringSecret for webhook signature verification
entities[].entitystringCONTACT for onboarding reports
entities[].report_typesarray["ONBOARDING"] to monitor onboarding requests
entities[].eventsarrayEvents to monitor (see below)

Webhook Events for Onboarding:

EventDescriptionAction
REPORT_INITIATEDOnboarding request createdOptional: Update UI to show “pending” status
REPORT_READYContact completed verificationPrimary event: Retrieve and analyze results
REPORT_ERRORError during verificationHandle error, potentially retry
REPORT_CREDIT_LIMIT_EXCEEDEDAccount credit limit reachedContact Xama support
REPORT_IN_REVIEWManual review requiredOptional: Notify admin team
REPORT_REVIEW_COMPLETEDManual review finishedRetrieve updated results

Implementation Notes:

  • Focus on REPORT_READY for completed verifications
  • Verify webhook signatures using your api_secret
  • Respond with 2xx status code to acknowledge receipt
  • Implement idempotency to handle duplicate webhooks

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

Terminal window
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 PathDescription
statusOverall status: READY when complete
data.idscan.document_decisionPASSED, REFER, or ALERT
data.idscan.face_match_decisionPASSED or FAILED (if face match enabled)
data.idscan.document_typePassport or Driving License
data.idscan.document_decision_dateWhen document was verified
data.idscan.date_of_birthExtracted from ID document
data.idscan.document_given_namesGiven names from document
data.idscan.document_last_nameLast name from document
data.idscan.passport_numberIf document type is Passport
data.idscan.driving_license_numberIf document type is Driving License
data.idscan.document_expiry_dateDocument expiration date
data.personal_detailsAddress provided by contact
review.decisionManual review decision (if applicable)
review.notesReviewer 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:

  1. **Only accept extracted data if **document_decision: "PASSED" - REFER decisions may indicate OCR extraction errors, so data may be incorrect
  2. Check document type before using ID numbers - Use passport_number only if document_type: "Passport", use driving_license_number only if document_type: "Driving License"
  3. Handle REFER decisions - Implement manual review workflow or request re-submission

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.

  1. Retrieve current contact data via GET request
  2. Merge verified data with existing contact data
  3. Update contact via PUT request with complete merged data

Endpoint

GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}

Request Example

Terminal window
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"

Endpoint

PUT /clients/{clientId}/accounts/{accountId}/contacts/{contactId}

Request Example

Terminal window
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., GB for United Kingdom, US for 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_reference to link to your system’s client ID

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

Terminal window
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

ParameterTypeDescription
ttl_in_daysnumberHow long the AML check remains valid (e.g., 365)
is_automatic_refresh_enabledbooleanAutomatically 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

Monitor AML check completion with webhooks.

Endpoint

POST /clients/{clientId}/subscriptions

Request Example

Terminal window
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.

Retrieve and analyze AML check results after receiving a REPORT_READY webhook.

Endpoint

GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}/reports/aml

Request Example

Terminal window
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

FieldPossible ValuesDescription
statusREADY, INITIAL , CREDIT_BALANCE_EXCEEDED, ERROROverall status of the AML check
data.decisionPASS, REFER, ALERTIdentity verification decision
data.pep_matchesNo Match, Potential MatchPEP screening result
data.sanctions_matchesNo Match, Potential MatchSanctions screening result
data.last_decision_dateDateWhen the check was performed
review.decisionPASS, FAILManual review decision (if reviewed)
review.pep_matchesMATCH_DISMISSED, MATCH_CONFIRMED, NO_MATCHReviewed PEP decision
review.sanctions_matchesMATCH_DISMISSED, MATCH_CONFIRMED, NO_MATCHReviewed Sanctions decision
review.notesStringReviewer notes

Decision Interpretations

Identity Verification Decision (data.decision)

Section titled “Identity Verification Decision (data.decision)”
ValueMeaningRecommended Action
PASSIdentity verified against 2+ authoritative sourcesProceed with onboarding
REFERCould not verify against 2+ sourcesManual review required or request additional documents
ALERTSerious issue detected (rare)Manual review required - may indicate underage, deceased, or other critical issue
ValueMeaningRecommended Action
No MatchNo PEP matches foundNo action required
Potential MatchPossible PEP match requires reviewReview match details in Xama platform - most are false positives

Sanctions Matches (data.sanctions_matches)

Section titled “Sanctions Matches (data.sanctions_matches)”
ValueMeaningRecommended Action
No MatchNo sanctions matches foundNo action required
Potential MatchPossible sanctions match requires reviewReview - may indicate restricted individual