> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.vlenseg.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.vlenseg.com/_mcp/server.

# PII inquiry: submit the ID card as one PDF

POST https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf
Content-Type: multipart/form-data

Same PII inquiry as `POST /api/FRAServices/PersonallyIdentifiableInformation`, but the national ID is uploaded as **one PDF file that contains both the front and the back**, instead of two base64 images.

The request is `multipart/form-data`. The file must be a real PDF (not another file renamed to `.pdf`) and at most **5 MB**. The front and back are read from the PDF and saved as the usual ID front and ID back steps, so the response has the same shape as the image variant.

OTP is optional: to prove phone-number ownership, call `POST /api/FRAServices/RequestOtpForPii` first and send `otpRequestId` and `otpCode` together. Send both or neither.

Reference: https://docs.vlenseg.com/api-reference/vlens-api/fra-services/post-fraservices-personallyidentifiableinformation-pdf

## Authentication

- `ApiKey` header (required) — Static API key issued to your tenant. Required on every request.
- `Authorization` header (bearer token, required) — End-user JWT from registration or login. Required for verification, signing, and user-scoped operations.

## Servers

- `https://api.vlenseg.com` (Production, default)
- `https://api.vlens.co` (Staging)

## Request

### Body (multipart/form-data)

This endpoint expects a multipart form containing a file.

- `file` (file, required) — One PDF with the front and the back of the national ID. Real PDF content only, at most 5 MB.
- `phoneNumber` (string, required) — The phone number being validated.
- `otpRequestId` (string, optional) — Optional. The `otpRequestId` returned by `POST /api/FRAServices/RequestOtpForPii`. Send together with `otpCode`.
- `otpCode` (string, optional) — Optional. The OTP the user received. Send together with `otpRequestId`.
- `transactionId` (string, optional) — Optional. An existing transaction ID.
- `bypassSpoofingCheck` (boolean, optional) — Optional. Defaults to `false`. Set it to `true` to skip the spoofing check on the ID pages read from the PDF, so a scanned or printed copy is not rejected as a forged document (`5005`). Every other document check still runs.

## Response

### 200

PII inquiry result.

- `data` (FraPiiInquiryResponseData, optional)
- `error_code` (integer, optional, nullable)
- `error_message` (string, optional, nullable)
- `error_descriptions` (list of string, optional, nullable)

## Errors

### 400 Bad Request Error

The file was rejected, the OTP was not verified, or ID validation failed. Read `error_code` and `error_message` to tell the cases apart.

- `error_code` (integer, required) — `6106` wrong OTP code — re-enter it and retry with the same `otpRequestId` (up to 5 tries per OTP). `6105` OTP expired — request a new OTP and retry. `6101` OTP request not valid (unknown, already used, or no tries left) — request a new OTP and retry. `6125` ID front image failed validation. `6126` ID back image failed validation.
- `data` (ApiFraServicesPersonallyIdentifiableInformationPdfPostResponsesContentApplicationJsonSchemaData, optional, nullable) — Details of the failed check. For `6125` / `6126`, `validation_errors` lists the ID image fields that failed.
- `error_message` (string, optional, nullable)

## Types

### FraPiiInquiryResponseData

- `phoneNumberOwnerOutput` (FraPiiInquiryResponseDataPhoneNumberOwnerOutput, optional, nullable) — Whether the phone number is registered to the ID holder.
- `idFrontOutput` (FraPiiInquiryResponseDataIdFrontOutput, optional, nullable) — Extraction and checks for the front of the national ID.
- `idBackOutput` (FraPiiInquiryResponseDataIdBackOutput, optional, nullable) — Extraction and checks for the back of the national ID.
- `csoOutput` (FraPiiInquiryResponseDataCsoOutput, optional, nullable) — Central Security Organisation (CSO) validation result.
- `criminalRecordValidationOutput` (FraPiiInquiryResponseDataCriminalRecordValidationOutput, optional, nullable) — Criminal-record check result. `null` when the check is not enabled for your tenant.

### ApiFraServicesPersonallyIdentifiableInformationPdfPostResponsesContentApplicationJsonSchemaData

Details of the failed check. For `6125` / `6126`, `validation_errors` lists the ID image fields that failed.

- `validation_errors` (list of string, optional, nullable) — The ID image fields that failed validation. Present on `6125` and `6126`.

### FraPiiInquiryResponseDataPhoneNumberOwnerOutput

Whether the phone number is registered to the ID holder.

- `isMatched` (boolean, optional)
- `errorCode` (integer, optional, nullable)
- `errorKey` (string, optional, nullable)
- `errorMessage` (string, optional, nullable)

### FraPiiInquiryResponseDataIdFrontOutput

Extraction and checks for the front of the national ID.

- `services` (FraDocServices, optional) — Per-service check results for one scanned document. Note the capitalised `Validations` key — the OCR API returns the same block as lowercase `validations`.
- `data` (FraPiiInquiryResponseDataIdFrontOutputData, optional)
- `error_code` (integer, optional, nullable)
- `error_message` (string, optional, nullable)
- `error_descriptions` (list of string, optional, nullable)

### FraPiiInquiryResponseDataIdBackOutput

Extraction and checks for the back of the national ID.

- `services` (FraDocServices, optional) — Per-service check results for one scanned document. Note the capitalised `Validations` key — the OCR API returns the same block as lowercase `validations`.
- `data` (FraPiiInquiryResponseDataIdBackOutputData, optional)
- `error_code` (integer, optional, nullable)
- `error_message` (string, optional, nullable)
- `error_descriptions` (list of string, optional, nullable)

### FraPiiInquiryResponseDataCsoOutput

Central Security Organisation (CSO) validation result.

- `isValid` (boolean, optional)
- `errorCode` (integer, optional, nullable)
- `errorMessage` (string, optional, nullable)

### FraPiiInquiryResponseDataCriminalRecordValidationOutput

Criminal-record check result. `null` when the check is not enabled for your tenant.

### FraDocServices

Per-service check results for one scanned document. Note the capitalised `Validations` key — the OCR API returns the same block as lowercase `validations`.

- `Validations` (FraDocServicesValidations, optional, nullable)
- `spoofing` (FraDocServicesSpoofing, optional, nullable)
- `classification` (FraDocServicesClassification, optional, nullable)
- `liveness` (boolean, optional, nullable) — Not run for this flow — always `null`.
- `AML` (FraDocServicesAml, optional, nullable) — Anti-money-laundering screening result. `null` when not run.
- `SRC` (FraDocServicesSrc, optional, nullable)

### FraPiiInquiryResponseDataIdFrontOutputData

- `name` (string, optional, nullable) — Full Arabic name.
- `first_name` (string, optional, nullable) — Arabic first name.
- `last_names` (string, optional, nullable) — Arabic last names.
- `name_english` (string, optional, nullable) — Transliterated full name.
- `first_name_english` (string, optional, nullable) — Transliterated first name.
- `last_names_english` (string, optional, nullable) — Transliterated last names.
- `idNumber` (string, optional, nullable) — National ID number.
- `idKey` (string, optional, nullable) — ID key printed on the card.
- `dateOfBirth` (string, optional, nullable) — Date of birth, ISO 8601.
- `gender` (string, optional, nullable) — Gender in Arabic. May be `null` on the front — the back scan carries it reliably.
- `govern` (string, optional, nullable) — Governorate (Arabic).
- `govern_english` (string, optional, nullable) — Governorate (English).
- `city` (string, optional, nullable) — City (Arabic).
- `district` (string, optional, nullable) — District (Arabic).
- `address` (string, optional, nullable) — Full address (Arabic).
- `address_1` (string, optional, nullable) — Address line 1 (Arabic).
- `address_2` (string, optional, nullable) — Address line 2 (Arabic).
- `address_english` (string, optional, nullable) — Full address (English).
- `address_1_english` (string, optional, nullable) — Address line 1 (English).
- `address_2_english` (string, optional, nullable) — Address line 2 (English).
- `client_transaction_id` (string, optional, nullable) — Your own reference ID, echoed back.
- `request_id` (string, optional, nullable) — Identifier for this individual request.
- `transaction_id` (string, optional, nullable) — The transaction the scan belongs to.

### FraPiiInquiryResponseDataIdBackOutputData

- `maritalStatus` (string, optional, nullable) — Marital status (Arabic).
- `marital_status_english` (string, optional, nullable) — Marital status (English).
- `job` (string, optional, nullable) — Job (Arabic).
- `job_english` (string, optional, nullable) — Job (English).
- `jobTitle` (string, optional, nullable) — Job title (Arabic).
- `job_title_english` (string, optional, nullable) — Job title (English).
- `religion` (string, optional, nullable) — Religion (Arabic).
- `religion_english` (string, optional, nullable) — Religion (English).
- `husbandName` (string, optional, nullable) — Husband's name (Arabic), when present on the card.
- `husbandName_english` (string, optional, nullable) — Husband's name (English).
- `releaseDate` (string, optional, nullable) — Card release date, ISO 8601.
- `idExpiry` (string, optional, nullable) — Card expiry date, ISO 8601.
- `idNumber` (string, optional, nullable) — National ID number.
- `gender` (string, optional, nullable) — Gender (Arabic).
- `gender_english` (string, optional, nullable) — Gender (English).
- `client_transaction_id` (string, optional, nullable) — Your own reference ID, echoed back.
- `request_id` (string, optional, nullable) — Identifier for this individual request.
- `transaction_id` (string, optional, nullable) — The transaction the scan belongs to.

### FraDocServicesValidations

- `validation_errors` (list of FraDocServicesValidationsValidationErrorsItems, optional)

### FraDocServicesSpoofing

- `fake` (boolean, optional) — `true` when the document image looks forged.

### FraDocServicesClassification

- `doc_type` (string, optional) — Detected document type, e.g. `id_front`, `id_back`.

### FraDocServicesAml

Anti-money-laundering screening result. `null` when not run.

- `AML_matched` (boolean, optional) — `true` when the holder matched an AML record.
- `data` (list of FraDocServicesAmlDataItems, optional) — Matched AML records, empty when none.

### FraDocServicesSrc

### FraDocServicesValidationsValidationErrorsItems

- `field` (string, optional)
- `value` (string, optional)
- `errors` (list of FraDocServicesValidationsValidationErrorsItemsErrorsItems, optional)

### FraDocServicesAmlDataItems

### FraDocServicesValidationsValidationErrorsItemsErrorsItems

- `code` (integer, optional)
- `message` (string, optional)

## Examples

**Request**

```json
{
  "file": "<file: string>",
  "phoneNumber": "string"
}
```

**Response**

```json
{
  "data": {
    "phoneNumberOwnerOutput": {
      "isMatched": true,
      "errorCode": 0,
      "errorKey": null,
      "errorMessage": null
    },
    "idFrontOutput": {
      "services": {
        "Validations": {
          "validation_errors": []
        },
        "spoofing": {
          "fake": false
        },
        "classification": {
          "doc_type": "id_front"
        },
        "liveness": null,
        "AML": {
          "AML_matched": false,
          "data": []
        },
        "SRC": null
      },
      "data": {
        "name": "محمد على حسن ابراهيم",
        "first_name": "محمد",
        "last_names": "على حسن ابراهيم",
        "name_english": "Mohamed Ali Hassan Ibrahim",
        "first_name_english": "Mohamed",
        "last_names_english": "Ali Hassan Ibrahim",
        "idNumber": "29001011234567",
        "idKey": "AB1234567",
        "dateOfBirth": "1990-01-01T00:00:00",
        "gender": null,
        "govern": "القاهرة",
        "govern_english": "Cairo",
        "city": "القاهرة",
        "district": "المعادي",
        "address": "١٢ شارع النيل-المعادي القاهرة",
        "address_1": "١٢ شارع النيل",
        "address_2": "المعادي القاهرة",
        "address_english": "12 Nile Street-Maadi Cairo",
        "address_1_english": "12 Nile Street",
        "address_2_english": "Maadi Cairo",
        "client_transaction_id": null,
        "request_id": "00000000-0000-0000-0000-000000000000",
        "transaction_id": "9c1f0e2a-7b3d-4f5a-8c6e-1d2b3a4c5d6e"
      },
      "error_code": null,
      "error_message": null,
      "error_descriptions": null
    },
    "idBackOutput": {
      "services": {
        "Validations": {
          "validation_errors": []
        },
        "spoofing": {
          "fake": false
        },
        "classification": {
          "doc_type": "id_back"
        },
        "liveness": null,
        "AML": null,
        "SRC": null
      },
      "data": {
        "maritalStatus": "متزوج",
        "marital_status_english": "married",
        "job": "مهندس",
        "job_english": "Engineer",
        "jobTitle": "",
        "job_title_english": null,
        "religion": "مسلم",
        "religion_english": "muslim",
        "husbandName": "",
        "husbandName_english": null,
        "releaseDate": "2023-04-01T00:00:00",
        "idExpiry": "2030-04-29T00:00:00",
        "idNumber": "29001011234567",
        "gender": "ذكر",
        "gender_english": "male",
        "client_transaction_id": null,
        "request_id": "00000000-0000-0000-0000-000000000000",
        "transaction_id": "9c1f0e2a-7b3d-4f5a-8c6e-1d2b3a4c5d6e"
      },
      "error_code": null,
      "error_message": null,
      "error_descriptions": null
    },
    "csoOutput": {
      "isValid": true,
      "errorCode": 0,
      "errorMessage": null
    },
    "criminalRecordValidationOutput": null
  },
  "error_code": null,
  "error_message": null,
  "error_descriptions": null
}
```

**SDK Code**

```python FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
import requests

url = "https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf"

files = { "file": "open('string', 'rb')" }
payload = {
    "phoneNumber": "string",
    "otpRequestId": ,
    "otpCode": ,
    "transactionId": ,
    "bypassSpoofingCheck": 
}
headers = {"ApiKey": "<apiKey>"}

response = requests.post(url, data=payload, files=files, headers=headers)

print(response.json())
```

```javascript FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
const url = 'https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf';
const form = new FormData();
form.append('file', 'string');
form.append('phoneNumber', 'string');
form.append('otpRequestId', '');
form.append('otpCode', '');
form.append('transactionId', '');
form.append('bypassSpoofingCheck', '');

const options = {method: 'POST', headers: {ApiKey: '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\nstring\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpRequestId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpCode\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transactionId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bypassSpoofingCheck\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("ApiKey", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
require 'uri'
require 'net/http'

url = URI("https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["ApiKey"] = '<apiKey>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\nstring\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpRequestId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpCode\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transactionId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bypassSpoofingCheck\"\r\n\r\n\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf")
  .header("ApiKey", "<apiKey>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\nstring\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpRequestId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpCode\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transactionId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bypassSpoofingCheck\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf', [
  'multipart' => [
    [
        'name' => 'file',
        'filename' => 'string',
        'contents' => null
    ],
    [
        'name' => 'phoneNumber',
        'contents' => 'string'
    ]
  ]
  'headers' => [
    'ApiKey' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
using RestSharp;

var client = new RestClient("https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf");
var request = new RestRequest(Method.POST);
request.AddHeader("ApiKey", "<apiKey>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\nstring\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpRequestId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"otpCode\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transactionId\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bypassSpoofingCheck\"\r\n\r\n\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift FRA Services_postFraservicesPersonallyidentifiableinformationPdf_example
import Foundation

let headers = ["ApiKey": "<apiKey>"]
let parameters = [
  [
    "name": "file",
    "fileName": "string"
  ],
  [
    "name": "phoneNumber",
    "value": "string"
  ],
  [
    "name": "otpRequestId",
    "value": 
  ],
  [
    "name": "otpCode",
    "value": 
  ],
  [
    "name": "transactionId",
    "value": 
  ],
  [
    "name": "bypassSpoofingCheck",
    "value": 
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://api.vlenseg.com/api/FRAServices/PersonallyIdentifiableInformationPdf")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```