Provero Logo

Identity Verification

KYC Match API

Checks identity information against data associated with a mobile subscriber.

Send mobile_number in international format and at least one qualifying verification field. Each supplied identity field is verified independently and returned as a separate result. The API does not return an overall KYC result or score.

Field availability varies by country, mobile network and the subscriber information available to the verification source. A field being accepted by the API does not guarantee that it can be verified for every subscriber.

mobile_number is always required. The qualifying verification fields are full_name, first_name, last_name, address, street_number, street_name, postcode, town_city, region, country and date_of_birth. Other supported identity fields may be supplied alongside a qualifying field, but do not satisfy the minimum request requirement by themselves.

Only send information that is necessary for your verification process.


Endpoint

POST
https://api.provero.io/api/validate/kyc

Headers

Authorization: Bearer REPLACE_WITH_API_TOKEN
Content-Type: application/json
Accept: application/json


Request Body

mobile_number is always required. You must also include at least one verification field marked with an asterisk (*).

Field Type Required Description
mobile_number string Yes Mobile number in E.164 international format, including the leading +, for example +447700900123
*full_name string No Customer's full name
*first_name string No Customer's first name
*last_name string No Customer's last name or surname
*date_of_birth string No Date of birth in YYYY-MM-DD format
*address string No Customer's complete residential address
*postcode string No Postcode or ZIP code
email string No Email address
*street_number string No Building or property number
*street_name string No Street name
*town_city string No Town or city
*region string No State, county, province or region
*country string No Customer's claimed country of residence as an ISO 3166-1 alpha-2 code, for example GB. This is a field to verify, not a routing parameter
additional_address_information string No Flat, unit, building name or other additional address information
middle_name string No Middle name or names
last_name_at_birth string No Last name at birth
gender string No Customer's gender
identity_document_number string No Identity document number as a JSON string. Send the identifier only; document images and scans are not accepted. Supported document types vary by country and mobile network

At least one field marked * must be supplied alongside mobile_number. Other optional fields cannot satisfy this requirement by themselves.

Most common request
{
    "mobile_number": "+447700900123",
    "full_name": "John Doe",
    "date_of_birth": "1985-06-15"
}
Request using all supported fields
{
    "mobile_number": "+447700900123",
    "full_name": "John Doe",
    "first_name": "John",
    "last_name": "Doe",
    "middle_name": "Michael",
    "last_name_at_birth": "Smith",
    "date_of_birth": "1985-06-15",
    "address": "Flat A, 10 High Street, London, SW1A 1AA",
    "street_number": "10",
    "street_name": "High Street",
    "additional_address_information": "Flat A",
    "town_city": "London",
    "region": "Greater London",
    "postcode": "SW1A 1AA",
    "country": "GB",
    "email": "john.doe@example.com",
    "gender": "male",
    "identity_document_number": "ABC123456"
}

Code Examples

curl --request POST \
  --url https://api.provero.io/api/validate/kyc \
  --header 'Authorization: Bearer REPLACE_WITH_API_TOKEN' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "mobile_number": "+447700900123",
    "full_name": "John Doe",
    "date_of_birth": "1985-06-15"
  }'
import requests

url = "https://api.provero.io/api/validate/kyc"
payload = {
    "mobile_number": "+447700900123",
    "full_name": "John Doe",
    "date_of_birth": "1985-06-15",
}
headers = {
    "Authorization": "Bearer REPLACE_WITH_API_TOKEN",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

response = requests.post(url, headers=headers, json=payload)
print(response.status_code)
print(response.json())
const response = await fetch("https://api.provero.io/api/validate/kyc", {
    method: "POST",
    headers: {
        Authorization: "Bearer REPLACE_WITH_API_TOKEN",
        Accept: "application/json",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        mobile_number: "+447700900123",
        full_name: "John Doe",
        date_of_birth: "1985-06-15"
    })
});

const data = await response.json();
console.log(response.status, data);
<?php
$url = 'https://api.provero.io/api/validate/kyc';
$payload = json_encode([
    'mobile_number' => '+447700900123',
    'full_name' => 'John Doe',
    'date_of_birth' => '1985-06-15',
]);

$curl = curl_init($url);
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer REPLACE_WITH_API_TOKEN',
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => $payload,
]);

$response = curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
echo $statusCode . PHP_EOL;
echo $response . PHP_EOL;
<?php
use Illuminate\Support\Facades\Http;

$response = Http::withToken('REPLACE_WITH_API_TOKEN')
    ->acceptJson()
    ->post('https://api.provero.io/api/validate/kyc', [
        'mobile_number' => '+447700900123',
        'full_name' => 'John Doe',
        'date_of_birth' => '1985-06-15',
    ]);

dump($response->status(), $response->json());

Response Examples

Exact Match - Score 100
{
    "status": "success",
    "verification_id": "kyc_example_exact",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "match"
        }
    }
}
Partial Match - Strong Similarity (85-99)
{
    "status": "success",
    "verification_id": "kyc_example_strong",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "partial_match",
            "similarity_score": 91,
            "similarity": "strong"
        }
    }
}
Partial Match - Moderate Similarity (80-84)
{
    "status": "success",
    "verification_id": "kyc_example_moderate",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "partial_match",
            "similarity_score": 82,
            "similarity": "moderate"
        }
    }
}
Partial Match - Possible Similarity (75-79)
{
    "status": "success",
    "verification_id": "kyc_example_possible",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "partial_match",
            "similarity_score": 77,
            "similarity": "possible"
        }
    }
}
No Match - Low Similarity (1-74)
{
    "status": "success",
    "verification_id": "kyc_example_low",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "no_match",
            "similarity_score": 40,
            "similarity": "low"
        }
    }
}
No Match - No Similarity (0)
{
    "status": "success",
    "verification_id": "kyc_example_no_match",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "no_match",
            "similarity_score": 0,
            "similarity": "none"
        }
    }
}
Additional response examples 7
Unable to Verify
{
    "status": "success",
    "verification_id": "kyc_example_unable",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "unable_to_verify"
        }
    }
}
Mixed Result
{
    "status": "success",
    "verification_id": "kyc_123e4567-e89b-12d3-a456-426614174000",
    "mobile_number": "+447700900123",
    "mobile_network_code": "23410",
    "results": {
        "full_name": {
            "result": "match"
        },
        "last_name": {
            "result": "partial_match",
            "similarity_score": 91,
            "similarity": "strong"
        },
        "date_of_birth": {
            "result": "unable_to_verify"
        }
    }
}
Missing Identity Field - HTTP 422
{
    "status": "error",
    "error": {
        "code": "missing_verification_data",
        "message": "Supply at least one qualifying verification field: full_name, first_name, last_name, address, street_number, street_name, postcode, town_city, region, country or date_of_birth."
    }
}
Subscriber Not Found - HTTP 404
{
    "status": "error",
    "error": {
        "code": "subscriber_not_found",
        "message": "We couldn't find information for this mobile number."
    }
}
Data Not Available - HTTP 422
{
    "status": "error",
    "error": {
        "code": "data_not_available",
        "message": "The requested information isn't available for this mobile number."
    }
}
Insufficient Balance - HTTP 402
{
    "status": "error",
    "error": {
        "code": "insufficient_balance",
        "message": "Insufficient balance for validation request."
    }
}
Temporarily Unavailable - HTTP 503
{
    "status": "error",
    "error": {
        "code": "service_temporarily_unavailable",
        "message": "KYC verification is temporarily unavailable. Please try again later."
    }
}

Response Body

Success structure

Field Name Type Example Always Present Description
status string success Yes Request status. Returns success when the verification request completed
verification_id string kyc_123e4567-e89b-12d3-a456-426614174000 Yes Unique identifier for the verification request. Retain this when contacting support
mobile_number string +447700900123 Yes Mobile number that was checked
mobile_network_code string|null 23410 No Public Land Mobile Network identifier formed from the Mobile Country Code and Mobile Network Code (MCC+MNC), when returned by the verification source. For example, 23410 identifies the UK (234) and O2 (10). This field does not describe the subscriber porting history
results object {...} Yes Field-level verification results. Contains an entry for each submitted identity field
results.<submitted_field>.result string partial_match Yes Field-level outcome: match, partial_match, no_match or unable_to_verify
results.<submitted_field>.similarity_score number 91 No Similarity value from 0 to 99, returned only for supported fields when the value is not an exact match and a score is available
results.<submitted_field>.similarity string strong No Descriptive similarity: strong, moderate, possible, low or none. Returned only for supported fields when available

Error structure

Field Name Type Example Always Present Description
status string error Yes Request status. Returns error
error.code string missing_verification_data Yes Stable, machine-readable code identifying the error. Use this value in application logic
error.message string Supply at least one qualifying verification field... Yes Human-readable description of the error. Do not rely on this text for application logic

Service Specific Error Codes

HTTP status Error code Meaning Recommended handling
401 invalid_api_key The API key is missing or invalid. Supply a valid API token.
402 insufficient_balance The account does not have enough credit for the request. Add credit before sending another request.
403 kyc_access_not_enabled KYC is not enabled for the account. Request KYC access in the Playground.
404 subscriber_not_found No subscriber information could be found for the mobile number. Check the number. If it is correct, use an alternative verification route.
408 request_timed_out The verification request did not complete within the allowed time. Retry with backoff. Contact support if timeouts continue.
422 invalid_mobile_number The mobile number is invalid or not in international format. Correct the number and include the leading +.
422 missing_verification_data mobile_number was supplied without a qualifying verification field. Add one of the qualifying fields listed in Request Body.
422 data_not_available The subscriber was identified, but none of the requested verification information was available. Try a different identity field or use manual review.
429 rate_limit_exceeded The account has exceeded the permitted request rate. Wait and retry with backoff.
503 service_temporarily_unavailable The KYC verification service is temporarily unavailable. Retry with backoff. Contact support if the problem continues.

Understand the Response

status: success means the verification request completed successfully. It does not mean that the submitted identity information matched.

Each submitted identity field is verified separately and returned under results using the same field name. Fields that are not supplied are not included in the response.

resultScore where availableMeaningRecommended handling
match100The submitted value exactly matched. Exact matches are returned without similarity fields.Treat the individual field as an exact match.
partial_match75-99The value reached the partial-match threshold but was not exact. This indicates similarity, not a verified identity match.Use similarity_score and your own verification rules.
no_match0-74The value did not reach the partial-match threshold.Check the supplied value or follow your no-match process.
unable_to_verify-The field could not be verified for this subscriber. This is not a match or a no match.Try another identity field or review the customer manually.

Similarity

When returned, similarity_score is a value from 0 to 99 describing how similar the submitted value is to the information held. Use result as the field-level outcome and use the score as supporting evidence when the result is partial_match.

An exact match contains only result: match. Similarity fields are omitted when unavailable or not applicable, and unable_to_verify contains only its result.

Similarity scoreresultsimilarityMeaning
100match-Exact match. Similarity fields are not returned.
85-99partial_matchstrongStrong similarity, but not an exact match.
80-84partial_matchmoderateModerate similarity, but not an exact match.
75-79partial_matchpossiblePossible similarity, but not an exact match.
1-74no_matchlowLow similarity; the partial-match threshold was not reached.
0no_matchnoneNo similarity was identified.
Unavailableunable_to_verify-The field could not be checked.

Fields with Similarity Scoring

Every supported field returns result. Only the fields marked Yes may also return similarity_score and similarity.

Submitted fieldReturns resultMay return similarity fields
full_nameYesYes
first_nameYesYes
last_nameYesYes
date_of_birthYesNo
addressYesYes
postcodeYesNo
emailYesNo
street_numberYesYes
street_nameYesYes
town_cityYesYes
regionYesYes
countryYesNo
additional_address_informationYesNo
middle_nameYesYes
last_name_at_birthYesYes
genderYesNo
identity_document_numberYesNo

Subscriber and Field Availability Outcomes

These outcomes are deliberately distinct.

OutcomeScopeMeaning
subscriber_not_foundEntire requestThe mobile subscriber could not be found. The HTTP 404 response contains no field results.
data_not_availableEntire requestThe subscriber was found, but none of the requested identity information was available. The HTTP 422 response contains no usable field results.
unable_to_verifyIndividual fieldThe request completed and the subscriber was found, but that field could not be checked. Other fields may still return results.

Implementation Summary

  • Send mobile_number plus at least one qualifying verification field.
  • email, middle_name, last_name_at_birth, additional_address_information, gender and identity_document_number do not satisfy the minimum request requirement by themselves.
  • Treat every field in results independently and use result as the verification outcome.
  • Treat scores from 75 to 99 as partial_match; scores below 75 remain no_match.
  • Use similarity_score only as supporting evidence. Exact matches return only result: match.
  • Do not treat unable_to_verify as no_match.
  • Use error.code, not error.message, for application logic.
  • Automatically retry only HTTP 408, 429 and 503 responses, using backoff.

Retry Guidance

Only retry the same request automatically for request_timed_out, rate_limit_exceeded and service_temporarily_unavailable.

Use exponential backoff and limit the number of retries. Do not automatically retry validation, authentication, access, balance or verification-outcome errors without first changing the relevant input or account state.