One Time Passcode (OTP) Phone Verification
This section describes how to use the ID&V API for verifying that a user is in control of a claimed phone number using a One Time Passcode (OTP) delivered through their mobile operator's Short Message Service (SMS).
Requirements
To enable phone number verification as part of an ID proofing process, a client application needs an API key and a URL to access the ID proofing service.
This feature is by default not available in Trial accounts. If you need to activate this service for application integration or testing, contact ID&V support to request activation.
Before sending the user phone number for verification to the ID&V service, the client application must notify that it has obtained the consent from the individual whose phone number is going to be verified.
Scenarios
Below are two different scenarios involving users during the phone number verification:
Scenario | User Requirements |
---|---|
SMS OTP verification | User provides their contact details including a phone number |
SMS OTP verification following an Identity Claim verification | User provides an Identity claim containing a phone number |
SMS OTP verification
Steps overview
- Create the identity.
- Submit the consent.
- Submit the user's contact details with a mobile phone number.
- Submit the OTP for verification
- Retrieve the identity claim verification and identity proof results.
Steps
Step 1: Create the identity.
Create an identity on the identity proofing server that will receive all of the data and gather the related verification results.
Step 2: Submit the consent.
Notify the identity proofing service of the different verifications the user has consented to, including SMS OTP verification.
Step 3: Submit the user's Mobile contact details
Submit to the ID&V service the User's contact details, containing their phone number. This request triggers issuance of a One Time Passcode delivered to this phone number.
Step 4: Submit the OTP for verification
The user submit the OTP received for verification.
Step 5: Get the identity status and retrieve proof.
The client application can check the status of the identity and check the verification result.
The user can submit additional pieces of evidence to increase the level of assurance in the identity. Once the client application has reached the end of the process, it can close the transaction by retrieving the proof file that contains all of the identity verification details.
SMS OTP verification following an Identity Claim verification
Steps overview
- Create the identity.
- Submit the consent.
- Submit the user's identity claim with the mobile contact details.
- Submit the received OTP for verification
- Retrieve the identity claim verification and identity proof results.
Steps
Step 1: Create the identity.
Create an identity on the identity proofing server that will receive all of the data and gather the related verification results.
Step 2: Submit the consent.
Notify the identity proofing service of the different verifications the user has consented to, including Identity Claim and SMS OTP verifications.
Step 3: Submit the user's identity claim with Mobile contact details.
Submit to the ID&V service the User's Identity Claim, containing their phone number. This request triggers verification of the Identity Claim, and issuance of a One Time Passcode delivered to this phone number.
Step 4: Submit the OTP for verification
The user submit the OTP received for verification.
Step 5: Get the identity status and retrieve proof.
The client application can check the status of the identity and check the verification result.
The user can submit additional pieces of evidence to increase the level of assurance in the identity. Once the client application has reached the end of the process, it can close the transaction by retrieving the proof file that contains all of the identity verification details.
Web service calls
There are many ways to implement the appropriate Web Service requests depending on your programming language.
For the sake of clarity, the request examples use the cURL tool syntax.
The variables used in the request URLs are:
Variable | Meaning |
---|---|
URL_MAIN_PART | The ID&V domain. |
APIKEY_VALUE | Client application API key as provided by portal administrator. |
IDENTITY_ID | The value obtained after performing step 1 below. This should be the id value from the Create Identity response message. |
Create an identity
This request initiates the verification process with ID&V.
The request looks like this:
Shell1curl -X POST https://[URL_MAIN_PART]/gips/v1/identities \2-H 'Content-Type: multipart/form-data' \3-H 'apikey: [APIKEY_VALUE]'
When this request is sent, the ID&V response contains an id
field.
The value of that field replaces IDENTITY_ID
in subsequent requests.
Sample response:
JSON1{2 "id": "gips-cd46a451-60d2-4c25-a466-7af6518aad0b",3 "status": "EXPECTING_INPUT",4 "levelOfAssurance": "LOA0",5 "creationDateTime": "2023-04-07T21:28:47.991249",6 "evaluationDateTime": "2023-04-07T21:28:50.3901804",7 "upgradePaths": {}8}
Variable | Description |
---|---|
id | The identity identifier that will be used to identify the current transaction in subsequent requests. |
status | Status of the transaction |
levelOfAssurance (LOA) | The current level of assurance for that identity |
creationDateTime | Identity creation date |
evaluationDateTime | The date at which the identity was last evaluated |
upgradePaths | List of possible submissions that would increase LOA |
Submit consent
Consent is a notification from the client application to ID&V that the user consents to their personal information (in this case, their identity attributes) being processed by ID&V for a given period.
With this request, the client application notifies ID&V that the user has consented to the Phone OTP verification.
The request looks like this:
Shell1curl -X POST \2 https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/consents \3 -H 'Content-Type: application/json' \4 -H 'apikey: [APIKEY_VALUE]' \5 -d '[{6 "approved": true,7 "type": "MOBILE_OTP"8 }]'
Sample response:
JSON1[2 {3 "consentId": "6fb21d2b-d97e-487e-8a96-d4d22af1ad2e",4 "approved": true,5 "type": "MOBILE_OTP",6 "validityPeriod": {7 "from": "2022-01-01",8 "to": "2024-01-01"9 }10 }11]
Variable | Description |
---|---|
consentId | The consent identifier that might be used to identify the submitted consent. |
approved | Boolean indicating status of the consent: true or false . |
type | Type of consent submitted (possible values may be: PORTRAIT , GIV , ID_CLAIM , MOBILE_OTP ) |
validityPeriod | The period for which the consent is considered valid. |
to | The date at which the consent will expire and will not be considered valid anymore. |
Submit a mobile contact
With this request, the client application can submit the user's mobile contact.
The request looks like this:
Shell1curl -X POST https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/contact-details/mobile \2 -H 'apikey: [APIKEY_VALUE]' \3 -H 'Content-Type: application/json' \4 -d ' {5 "value": "+33610101010"6 }'
Description of JSON fields in the payload:
Variable | Description |
---|---|
value | The phone number to verify in E.164 format : (+|country calling code|local area number within the country). |
Sample response:
JSON1{2 "status": "PROCESSING",3 "type": "MOBILE_OTP"4}
Variable | Description |
---|---|
status | Evidence status |
type | The evidence type |
Submit a phone OTP code
With this request, the client application can submit the OTP they received for verification.
The request looks like this:
Shell1curl -X POST https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/contact-details/mobile/otp \2 -H 'apikey: [APIKEY_VALUE]' \3 -H 'Content-Type: application/json' \4 -d ' {5 "value": "123456"6 }'
Description of JSON fields in the payload:
Variable | Description |
---|---|
value | OTP value (min size = 4 and max size = 12) |
Note: Phone enrollment code is configurable in ID&V. Clients requiring to be compliant NIST IAL2 proofing shall configure minimal 10 digits.
Sample response:
HTTP status shall be: 204 No Content
Check the status of the user's mobile contact
With this request, the client application can check the processing status of the user's mobile contact.
The request looks like this:
Shell1curl -X GET https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/contact-details/mobile \2 -H 'apikey: [APIKEY_VALUE]' \3 -H 'Content-Type: application/json' \
_Sample response
JSON1{2 "globalStatus": {3 "id": "gips-b6112771-549f-4436-b9d5-666c68681568",4 "status": "EXPECTING_INPUT",5 "levelOfAssurance": "LOA0",6 "creationDateTime": "2023-04-07T17:08:11.9121314",7 "evaluationDateTime": "2023-04-07T17:14:55.1508505",8 "upgradePaths": {}9 },10 "contactDetails": {11 "mobile": {12 "value": "+33610101010",13 "verified": false,14 "otp": {15 "status": "ERROR",16 "creationTime": "2023-04-17T08:33:51.292801",17 "timeout": 60000018 },19 "errors": [20 {21 "code": "1117",22 "message": "Max attempts reached"23 }24 ]25 }26 }27}
Description of JSON fields of the evidence contactDetails
in the payload:
Variable | Description |
---|---|
value | The phone number to verify. Phone number must be in E.164 format. |
verified | Possible values: true only if the phone number has already been verified to be associated to the identity of the user by checking against the operator's users database Otherwise false . |
otp | OTP object |
status | The OTP status. Possible values are PROCESSING DONE PENDING TIMEOUT ERROR (see below) |
creationTime | time at which the otp has been created |
timeout | Time in ms after which the otp will expire after its creation |
Values for status
of the evidence contactDetails
can be:
PROCESSING
- ID&V is in the process of sending of the OTP to the userPENDING
- OTP has been sent to the user and ID&V is waiting for the OTP to be submitted for verification. In case the OTP code does not match, the status remainsPENDING
DONE
- OTP been has been successfully verifiedTIMEOUT
- OTP has expired without being validatedERROR
- Technical error while processing the phone OTP verification
In case of error, it is possible for the user to retry and provide the otp again, without having to generate and receive a new OTP.
Verification of the user's identity claim
With this request, the client application can verify the user's identity claim.
The request looks like this:
Shell1curl -X POST \2 https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/claim \3 -H 'Content-Type: application/json' \4 -H 'apikey: [APIKEY_VALUE]' \5 -d '{6 "attributesData": {7 "givenNames": [{8 "value": "CHRISTOPHE"9 }, {10 "value": "JEAN"11 }12 ],13 "surname": {14 "value": "ULYSSE"15 },16 "dateOfBirth": {17 "value": "1968-10-18"18 },19 "personalNumber": {20 "value": "666436878",21 "issuingCountry": "USA"2223 }24 },25 "addressesData": {26 "streetDetails": {27 "streetLines": [28 "1 MAIN STREET"29 ]30 },31 "postcode": "111110000",32 "city": "ANYTOWN",33 "state": "MA",34 "country": "USA"35 },36 "contactDetails": {37 "mobile": {38 "value": "+33610101010"39 }40 },41 "creditCardDetails": {42 "cardNumber": "1654A354C",43 "cardType": "CREDIT",44 "expiryDate": "2022-02-18"45 }46 }'
Description of JSON fields in the payload:
Variable | Description |
---|---|
attributesData | Contains all identity attributes claimed by the user |
givenNames | Contains a list of the user's given names |
surname | Contains the surname of the user |
dateOfBirth | Contains the date of birth of the user |
gender | Contains the gender of the user |
nationality | Contains the nationality of the user |
personalNumber | Unique number by which the person could be identified within a country. |
issuingCountry | Country where the personal number (SSN) is issued. This field is required if the personalNumber is provided. The issuingCountry contains the ISO 3166-1 alpha-3 code referring of the SSN issuing country |
addressesData | Contains all address related data |
streetDetails | Contains address details at street level |
streetLines | Contains the different lines of the address |
houseNumber | House number relative to the street |
flatNumber | Flat, apartment, or suite identifier in the building |
houseName | House name relative to the street |
district | Name of the district of the address |
locality | Locality information of the address |
postcode | Postcode or ZIP code of the address |
city | City name of the address |
state | If country is USA the state uses USPS two letter abbreviations. Otherwise, contains the state name in full |
county | County name of the address |
country | Contains the ISO 3166-1 alpha-3 code referring to the country of the address |
fullAddress | Contains full unstructured address if captured as such |
contactDetails | Contains contact information associated to that identity |
mobile | Mobile phone number that is registered in the name of the user. Phone number must be in E.164 format. |
creditCardDetails | Contains the credit card details in the name of the user |
cardNumber | Contains the credit card number |
cardType | Contains the model/type of the card (optional) |
expiryDate | Contains the card expiry date (optional) |
Sample response:
JSON1{2 "status": "PROCESSING",3 "type": "ID_CLAIM",4 "id": "440d8c98-f1f4-4c05-a3d8-6025faa3b967"5}
Variable | Description |
---|---|
id | The evidence identifier |
status | Evidence status |
type | The evidence type |
Check the status of the user's identity claim
With this request, the client application can check the processing status of the user's claim identity and see what level of assurance (LOA) has been reached.
The request looks like this:
Shell1curl -X GET \2 https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/claim \3 -H 'Content-Type: application/json' \4 -H 'apikey: [APIKEY_VALUE]'
Sample response: When claim data are not hidden
JSON1{2 "globalStatus": {3 "id": "gips-cd46a451-60d2-4c25-a466-7af6518aad0b",4 "status": "EXPECTING_INPUT",5 "levelOfAssurance": "LOA2",6 "creationDateTime": "2023-04-10T21:28:47.991249",7 "evaluationDateTime": "2023-04-10T21:38:54.7148765",8 "nameReferenceEvidenceId": "440d8c98-f1f4-4c05-a3d8-6025faa3b967",9 "upgradePaths": {},10 "Claim": {11 "evidenceId": "440d8c98-f1f4-4c05-a3d8-6025faa3b967",12 "submitDateTime": "2023-04-10T21:38:51.8796052",13 "type": "ID_CLAIM",14 "evidenceStatus": {15 "evaluationDateTime": "2023-04-10T21:38:54.7148765",16 "status": "VERIFIED",17 "strength": "LEVEL3",18 "score": "LEVEL3",19 "isAdjudicable": false20 },21 "claimData": {22 "attributesData": {23 "givenNames": [24 {25 "value": "CHRISTOPHE",26 "verified": true27 },28 {29 "value": "JEAN",30 "verified": true31 }32 ],33 "surname": {34 "value": "ULYSSE",35 "verified": true36 },37 "dateOfBirth": {38 "value": "1968-10-18",39 "verified": true40 },41 "personalNumber": {42 "value": "666436878",43 "verified": true,44 "issuingCountry": "USA"45 }46 },47 "addressesData": {48 "streetDetails": {49 "streetLines": [50 "1 MAIN STREET"51 ],52 "verified": true53 },54 "postcode": "111110000",55 "city": "ANYTOWN",56 "state": "MA",57 "country": "USA",58 "verified": true59 },60 "contactDetails": {61 "mobile": {62 "value": "+33610101010",63 "verified": true,64 "otp": {65 "status": "DONE",66 "creationTime": "2023-04-10T17:08:20.5701956",67 "timeout": 60000068 }69 }70 },71 "creditCardDetails": {72 "verified": true73 }74 }75 }76 }77}
Sample response
configJSON1{2 "globalStatus": {3 "id": "gips-cd46a451-60d2-4c25-a466-7af6518aad0b",4 "status": "EXPECTING_INPUT",5 "levelOfAssurance": "LOA2",6 "creationDateTime": "2023-11-10T21:28:47.991249",7 "evaluationDateTime": "2023-11-10T21:38:54.7148765",8 "nameReferenceEvidenceId": "440d8c98-f1f4-4c05-a3d8-6025faa3b967",9 "upgradePaths": {},10 "Claim": {11 "evidenceId": "440d8c98-f1f4-4c05-a3d8-6025faa3b967",12 "submitDateTime": "2023-11-10T21:38:51.8796052",13 "type": "ID_CLAIM"14 }15 }16}
Values for status
can be:
-
VERIFIED
- evidence has successfully been verified. When VERIFIED, Identity claim is scored on LEVEL 3. -
INVALID
- evidence is considered invalid after the checks performed. -
NOT_VERIFIED
- evidence was processed, but not enough checks were performed to take a decision. -
PROCESSING
- evidence is currently being processed by the service.
Ending the process and retrieving the proof file
With this request, the client application terminates the proofing process and retrieves all information that the service has gathered and generated.
In response to this request, the client application receives an archive file. The client application may archive this file for audit purpose and use its content as a reference for the user's identity.
Getting the proof terminates the transaction and the service applies the deletion policy to the personal information gathered during the session.
The request looks like this:
Shell1curl -X GET \2https://[URL_MAIN_PART]/gips/v1/identities/[IDENTITY_ID]/proof \3-H 'apikey: [APIKEY_VALUE]' -o proof
Description | |
---|---|
URL_MAIN_PART | The service domain. |
APIKEY_VALUE | Client application API key as provided by your administrator(s). |
IDENTITY_ID | Value obtained after performing Step 1. This value should be the id value from the Create Identity response message. |
API feedback
This section contains error codes and indicators raised when verifying the user's phone number.
Error codes
Error codes in relation to the user's phone verification:
Error Code | Description |
---|---|
1100 | Phone verification service is not available |
1101 | The phone verification session is not longer valid. The session has been deleted because the OTP code has already been validated or the session has expired. |
1105 | OTP SMS service invalid request |
1117 | Max attempt reached on phone verification or OTP request |
1118 | The OTP code is no longer valid. It has already been validated or has expired. |
1151 | Contact details does not match with evidences. This error code is raised if the phone number provided by the user for the OTP verification does not match with the phone number in the user's claimed identity |