Skip to main content

KYC Verification Flow

The verification flow is the core KYC process that validates a user’s identity. This can be started after prefill or directly with user-provided information.

Starting Verification

Request

POST /v1/kyc/start
{
  "userId": "user_123",
  "firstName": "John",
  "middleName": "Michael",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "phoneNumber": "+15551234567",
  "dateOfBirth": "1990-01-15",
  "ssn": "123-45-6789",
  "address": {
    "addressLine1": "123 Main Street",
    "addressLine2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "postalCode": "10001",
    "country": "US"
  },
  "sessionToken": "session_abc",
  "agreementTime": "2024-01-15T10:30:00Z",
  "referralCode": "REF123",
  "ipAddress": "192.168.1.1"
}

Request Fields

FieldTypeRequiredDescription
userIdstringYesYour internal user identifier
firstNamestringYesLegal first name
middleNamestringNoMiddle name
lastNamestringYesLegal last name
emailstringYesEmail address
phoneNumberstringYesPhone number with country code
dateOfBirthstringYesDate of birth (YYYY-MM-DD)
ssnstringYesSocial Security Number
addressobjectYesResidential address
sessionTokenstringYesSession token
agreementTimedatetimeYesWhen user agreed to terms
referralCodestringNoReferral code if applicable
ipAddressstringNoUser’s IP address

Address Object

FieldTypeRequiredDescription
addressLine1stringYesStreet address
addressLine2stringNoApt/Suite/Unit number
citystringYesCity
statestringYesState (2-letter code)
postalCodestringYesZIP/Postal code
countrystringYesCountry code (e.g., “US”)

Response

When document verification is required:
{
  "status": {
    "decision": "REVIEW",
    "status": "ON_HOLD",
    "subStatus": "Document Request Initiated",
    "externalId": "user_123"
  },
  "docv": {
    "sdkKey": "a0a1869f-cf3e-4acb-919a-62b9fef30e3f",
    "docvTransactionToken": "token_xyz",
    "eventId": "event_123",
    "qrCode": "data:image/png;base64,...",
    "url": "https://verify.example.com/session/abc123"
  }
}

Verification Outcomes

Instant Approval

If the identity can be verified immediately:
{
  "status": {
    "decision": "ACCEPT",
    "status": "CLOSED",
    "subStatus": "",
    "externalId": "user_123"
  },
  "participantId": "firms/ISV-Participant-Acme/users/user_123",
  "account": "firms/ISV-Acme/accounts/a1b2c3d4e5f6"
}
Automatic User ProvisioningWhen a user receives decision: "ACCEPT", the system automatically:
  1. Creates an EP3 participant for the user
  2. Provisions a trading account
  3. Returns the participantId and account identifiers in the response
Use these identifiers for subsequent trading API calls. There is no separate account creation step required. The user can proceed directly to funding after KYC approval.

Document Verification Required

If additional documents are needed, the response includes DocV details:
FieldDescription
sdkKeySocure SDK public key for initializing the DocV SDK
docvTransactionTokenSession token passed to the SDK’s launch() method
eventIdEvent tracking identifier
qrCodeBase64-encoded QR code image for mobile scanning
urlDirect URL for web-based document upload

Socure SDK Integration

For native mobile document capture, integrate the Socure DocV SDK:
  1. Initialize the SDK with sdkKey
  2. Launch verification with docvTransactionToken
  3. Poll /v1/kyc/status or use webhooks to get the final decision
Socure SDK Documentation:

Alternative: Web-Based Verification

If not using the SDK, users can complete document verification via:
  1. QR Code - User scans QR code with mobile device to capture documents
  2. Direct URL - User opens URL on any device to upload documents

Checking Status

Poll the status endpoint to track verification progress. Use the user_id you provided in the start request:
GET /v1/kyc/status?externalId=user_123
Response when KYC is pending (documents required):
{
  "status": {
    "decision": "REVIEW",
    "status": "ON_HOLD",
    "subStatus": "Document Request Initiated",
    "externalId": "user_123"
  },
  "participantId": "",
  "account": ""
}
Response when KYC is approved:
{
  "status": {
    "decision": "ACCEPT",
    "status": "CLOSED",
    "subStatus": "",
    "externalId": "user_123"
  },
  "participantId": "firms/ISV-Participant-Acme/users/user_123",
  "account": "firms/ISV-Acme/accounts/a1b2c3d4e5f6"
}
Response when user hasn’t started KYC:
{
  "status": {
    "decision": "",
    "status": "NOT_STARTED",
    "subStatus": "",
    "externalId": "user_123"
  },
  "participantId": "",
  "account": ""
}

Status Values

Decision

ValueDescription
ACCEPTIdentity verified successfully
REJECTVerification failed
REVIEWVerification in progress, may require action
(empty)KYC not started

Status

ValueDescription
NOT_STARTEDUser has not initiated KYC
OPENVerification in progress with Socure
ON_HOLDWaiting for user to upload documents (DocV)
CLOSEDFinal decision reached (check decision field)

SubStatus

ValueDescription
pendingWaiting for Socure decision
Document Request InitiatedUser must complete document verification
(empty)No additional status info

Integration Flow

Best Practices

  1. Validate input before submission - Check all required fields
  2. Use webhooks if available - Don’t rely solely on polling
  3. Handle all decision states - Show appropriate UI for each
  4. Store externalId - You’ll need it to check status later
  5. Implement retry logic - API calls may occasionally fail
  6. Log all responses - For debugging and compliance