openapi: 3.1.0 info: title: ADVANCE.AI Open API version: '1.0' summary: eKYC building blocks — token authentication, global document verification, face comparison and liveness detection. description: | ADVANCE.AI is the digital identity verification, KYC/KYB, AML, compliance and risk-management business unit of Advance Intelligence Group (Singapore). Its public "Open API" surface provides eKYC building blocks used by enterprise customers across banking, fintech, payments, crypto and e-commerce in Southeast Asia and other emerging markets. Every request authenticates with a short-lived access token obtained from `POST /openapi/auth/ticket/v1/generate-token` and passed on all subsequent calls in the `X-ACCESS-TOKEN` header. All responses share one envelope — `code`, `message`, `data`, `extra`, `transactionId`, `pricingStrategy` — and the HTTP status is 200 for both success and business errors; the `code` field carries the real outcome. Billing is per response `code`: each documented status code is tagged `free` or `pay`. PROVENANCE — this document was NOT published by ADVANCE.AI. API Evangelist authored it from the company's public documentation at https://doc.advance.ai (pages `global_document_verification.html`, `liveness_detection.html`, `face_recognition.html`, each fetched 2026-09-07, HTTP 200). ADVANCE.AI publishes no OpenAPI of its own — see `openapi.json`/`swagger.json` probes recorded in `well-known/advanceai-well-known.yml`. Every path, method, parameter, status code and example below is transcribed from those pages; nothing is inferred or invented. Operations the documentation does not describe are absent rather than guessed. contact: name: ADVANCE.AI url: https://advance.ai/contact-us/ termsOfService: https://advance.ai/terms-of-service/ x-generated-from: documentation x-authored-by: API Evangelist x-modeled-from: https://doc.advance.ai/ x-provenance: method: generated generated: '2026-09-07' sources: - url: https://doc.advance.ai/global_document_verification.html status: 200 - url: https://doc.advance.ai/liveness_detection.html status: 200 - url: https://doc.advance.ai/face_recognition.html status: 200 note: Transcribed from published documentation. Not a provider-published contract. servers: - url: https://api.advance.ai description: Production host. ADVANCE.AI notes the service is deployed outside mainland China. security: - AccessToken: [] tags: - name: Authentication description: Exchange an access key and request signature for a short-lived access token. - name: Document Verification description: Global Document Verification — SDK licensing and result query with OCR and forgery detection. - name: Face Comparison description: Compare two face photographs and return a similarity score. - name: Liveness Detection description: Liveness session licensing, result retrieval, video evidence and PII data retention. paths: /openapi/auth/ticket/v1/generate-token: post: tags: [Authentication] operationId: generateAccessToken summary: Generate an access token description: | Exchange your `accessKey` and a request `signature` for a short-lived access token. The signature is the SHA256 hash of `accessKey + secretKey + timestamp`. The `timestamp` inside the signature must match the `timestamp` parameter. The returned token is passed on every other operation in the `X-ACCESS-TOKEN` header. Access keys are found on the Websaas Platform under Account > Account Management. Requesting a new token does not invalidate an existing one, and one token is valid across all APIs. security: [] requestBody: required: true content: application/json: schema: type: object required: [accessKey, signature, timestamp] properties: accessKey: type: string description: The account access key. signature: type: string description: SHA256 of accessKey + secretKey + timestamp. timestamp: type: integer format: int64 description: 13-digit epoch milliseconds; suggested within 300 seconds of now. periodSecond: type: integer description: Token validity in seconds. Default 3600, minimum 60, maximum 86400. default: 3600 minimum: 60 maximum: 86400 examples: documented: summary: Example from the ADVANCE.AI documentation value: accessKey: REDACTED_EXAMPLE_ACCESS_KEY signature: REDACTED_EXAMPLE_SIGNATURE timestamp: 1648785145789 periodSecond: 120 responses: '200': description: | Envelope response. `code` carries the outcome — SUCCESS (free), PARAMETER_ERROR (free, "Parameter should not be empty" / "Timestamp error" / "Signature error"), ACCOUNT_DISABLED (free), CLIENT_ERROR (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/TokenData' examples: success: value: code: SUCCESS message: OK data: token: REDACTED_EXAMPLE_JWT expiredTime: 1642580192430 extra: null transactionId: 6c2c50a3049ce67e pricingStrategy: FREE signatureError: value: code: PARAMETER_ERROR message: Signature error data: null extra: null transactionId: 00b05cb9cf6f0fed pricingStrategy: FREE accountDisabled: value: code: ACCOUNT_DISABLED message: Account Disabled data: null extra: null transactionId: 5e00fded1272490e pricingStrategy: FREE /intl/openapi/face-identity/document-verification/v1/auth-license: post: tags: [Document Verification] operationId: authorizeDocumentVerificationLicense summary: Request a Global Document Verification SDK license description: | Step 1 of the three-step Global Document Verification flow. Returns a time-limited `license` that the Android or iOS SDK presents when it captures the document. Step 2 is the SDK capture, which returns an `IDVID`; step 3 is `queryDocumentVerificationResult`. requestBody: required: true content: application/json: schema: type: object properties: licenseEffectiveSeconds: type: integer description: License validity in seconds. Default 600, maximum 86400. default: 600 maximum: 86400 applicationId: type: string description: Comma-separated list of valid application identifiers. examples: documented: value: licenseEffectiveSeconds: 600 applicationId: appId1,appId2 responses: '200': description: | Envelope response. `code` is SUCCESS (pay), ACCESS_DENIED (free) or SERVICE_DISABLED (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/LicenseData' examples: success: value: code: SUCCESS transactionId: 196eb0c777789e58 pricingStrategy: PAY message: OK data: license: jpgEkQQFKD+EXHBmIFLOycYOMkohFVyJzhfq5M0F95pp3EDcLf8Z31e4xqyeyhNXfW...... expireTimestamp: 1603164618149 extra: null accessDenied: value: code: ACCESS_DENIED message: Access denied transactionId: eb0c771967789e58 data: null extra: null pricingStrategy: FREE /intl/openapi/face-identity/document-verification/v1/query: post: tags: [Document Verification] operationId: queryDocumentVerificationResult summary: Query a Global Document Verification result description: | Step 3 of the Global Document Verification flow. Exchanges the `IDVID` returned by the SDK for the captured document image, the OCR field extraction, and the ID forgery verdict. requestBody: required: true content: application/json: schema: type: object required: [IDVID] properties: IDVID: type: string description: The identifier returned by the document verification SDK. resultType: type: string description: | Preferred image encoding. IMAGE_URL returns a link valid for 24 hours; IMAGE_BASE64 returns the image inline. enum: [IMAGE_URL, IMAGE_BASE64] default: IMAGE_URL examples: documented: value: IDVID: ba959a16-a06c-4b82-ae1f-22452b5bbcf3 resultType: IMAGE_URL responses: '200': description: | Envelope response. `code` is SUCCESS (pay), IDVID_NOT_EXISTS (free) or PARAMETER_ERROR (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/DocumentVerificationResult' examples: idvidNotExists: value: code: IDVID_NOT_EXISTS message: The IDVID not exists data: null extra: null transactionId: c67b620fb3607c83 pricingStrategy: FREE parameterError: value: code: PARAMETER_ERROR message: Parameter should not be empty data: null extra: null transactionId: 6630f8dd48d4df0d pricingStrategy: FREE /openapi/face-recognition/v4/check: post: tags: [Face Comparison] operationId: compareFaces summary: Compare two face photographs description: | Uploads two face photographs and returns a similarity rate between 0 and 100, plus the bounding box and detected gender for each face. If several faces are present the largest is selected. Flip angles of 90, 180 and 270 degrees are supported but reduce accuracy. ADVANCE.AI's published guidance: above 70 pass, 55–70 manual check, below 55 reject or verify by another method. Images must be PNG/JPG/JPEG, under 2 MB, and between 256x256 and 4096x4096. requestBody: required: true content: multipart/form-data: schema: type: object required: [firstImage, secondImage] properties: firstImage: type: string format: binary description: The first picture to be uploaded. secondImage: type: string format: binary description: The second picture to be uploaded. responses: '200': description: | Envelope response. `code` is SUCCESS (pay), IMAGE_INVALID_FORMAT (free), IMAGE_INVALID_SIZE (free), NO_FACE_DETECTED_FROM_FIRST_IMAGE (pay), NO_FACE_DETECTED_FROM_SECOND_IMAGE (pay), FIRST_IMAGE_LOW_QUALITY_FACE (pay) or SECOND_IMAGE_LOW_QUALITY_FACE (pay). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/FaceComparisonResult' examples: success: value: code: SUCCESS transactionId: 196eb0c777789e58 pricingStrategy: PAY message: OK data: similarity: 69.0 firstFace: {id: '1', left: 618.0, top: 227.0, right: 715.0, bottom: 350.0, gender: MALE} secondFace: {id: '2', left: 316.0, top: 552.0, right: 894.0, bottom: 1321.0, gender: MALE} extra: null noFaceFirst: value: code: NO_FACE_DETECTED_FROM_FIRST_IMAGE message: No Face detected from the uploaded first picture data: null extra: null transactionId: 7196eb0c77789e58 pricingStrategy: PAY /liveness/ext/v1/generate-signature-id: post: tags: [Liveness Detection] operationId: generateLivenessSignatureId summary: Generate a liveness signatureId description: | Step 1 of the six-step Liveness Detection flow. Returns a unique, single-use `signatureId` for one liveness capture. Obtain a new one after each completed detection. `productLevel` and `livenessType` apply only to Advanguard Liveness Detection Standard/Pro on SDK versions above 4.0.0. requestBody: required: true content: application/json: schema: type: object properties: productLevel: type: string description: | STANDARD — basic compliance, high pass rate, acceptable accuracy. PRO — strong compliance, enhanced accuracy. enum: [STANDARD, PRO] livenessType: type: string description: How the user goes through the liveness capture. Defaults to DISTANT_NEAR. default: DISTANT_NEAR responses: '200': description: Envelope response carrying the signatureId. `code` SUCCESS (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: type: object properties: signatureId: type: string examples: success: value: code: SUCCESS message: OK data: {signatureId: xxxxxxx} extra: null transactionId: ac66706068e737b5 pricingStrategy: FREE /openapi/liveness/v1/auth-license: post: tags: [Liveness Detection] operationId: authorizeLivenessLicense summary: Request a Liveness Detection SDK license description: | Step 2 of the Liveness Detection flow. Returns a time-limited `license` the mobile SDK presents when it runs the liveness capture. requestBody: required: true content: application/json: schema: type: object properties: licenseEffectiveSeconds: type: integer description: License validity in seconds. Default 600, maximum 86400. default: 600 maximum: 86400 applicationId: type: string description: Comma-separated list of valid application identifiers. examples: documented: value: licenseEffectiveSeconds: 600 applicationId: appId1,appId2 responses: '200': description: Envelope response. `code` is SUCCESS (pay), ACCESS_DENIED (free) or SERVICE_DISABLED (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/LicenseData' examples: serviceDisabled: value: code: SERVICE_DISABLED message: Service disabled transactionId: 789196eb0c777e58 data: null extra: null pricingStrategy: FREE /openapi/liveness/v3/detection-result: post: tags: [Liveness Detection] operationId: getLivenessDetectionResult summary: Retrieve a liveness detection result description: | Step 4 of the Liveness Detection flow. Exchanges the `livenessId` (from the SDK) or the `signatureId` (from step 1) for the liveness score, the captured face image, the far/near stage images and, when the score is zero, the attack classification. `livenessId` and `signatureId` cannot both be empty. ADVANCE.AI's published guidance: a score above 50 is normal and the suggestion is pass; below 50 the suggestion is manual check. requestBody: required: true content: application/json: schema: type: object properties: livenessId: type: string description: Identifier for the user's face photo, from the SDK. signatureId: type: string description: The signatureId from generateLivenessSignatureId. resultType: type: string enum: [IMAGE_URL, IMAGE_BASE64] default: IMAGE_URL description: IMAGE_URL links expire after 24 hours. examples: documented: value: livenessId: ddsd-9e6-dcc9-4ca1-bdfe-9f001c05f1b1 resultType: IMAGE_URL responses: '200': description: | Envelope response. `code` is SUCCESS (pay), LIVENESS_ID_NOT_EXISTED (free), RESULT_NOT_FOUND (free) or PARAMETER_ERROR (free). content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: $ref: '#/components/schemas/LivenessResult' examples: attackDetected: value: code: SUCCESS message: OK data: detectionResult: https:// livenessScore: 0.0 auditImageUrl: null imageFarUrl: https:// imageNearUrl: https:// nearImageTime: null farImageTime: null attackType: 3 attackSubType: null sdkVersion: 3.6.2 platform: iOS extra: null transactionId: 16733ebf2ca75a0b pricingStrategy: PAY resultNotFound: value: code: RESULT_NOT_FOUND message: The requested resource was not found or has been deleted data: null extra: null transactionId: d5bec4f642549caf pricingStrategy: FREE /liveness/ext/v1/get-video: get: tags: [Liveness Detection] operationId: getLivenessVideo summary: Retrieve liveness video evidence description: | Step 5 of the Liveness Detection flow. Returns a link to the recorded liveness video, valid for 24 hours; re-query for a fresh link once it expires. Only available on SDK versions above 4.0.0, and video recording is not enabled by default — ADVANCE.AI must activate it for the account first. `pricingStrategy` is documented as deprecated on this operation and always returns FREE. parameters: - name: livenessId in: query required: false schema: {type: string} description: The livenessId of the liveness detection. - name: signatureId in: query required: false schema: {type: string} description: The signatureId of the liveness detection. responses: '200': description: | Envelope response. `code` is SUCCESS, LIVENESS_ID_NOT_EXISTED (free), SIGNATURE_ID_NOT_EXIST (free), VIDEO_NOT_FOUND (free), PARAMETER_ERROR (free) or ERROR. content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: type: object properties: videoUrl: type: string format: uri description: Link to the video. Expires after 24 hours. examples: success: value: code: SUCCESS message: OK data: {videoUrl: 'https://xxx.xxx.xxx'} extra: null transactionId: ac66706068e737b5 pricingStrategy: FREE videoNotFound: value: code: VIDEO_NOT_FOUND message: The requested resource was not found or has been deleted data: null extra: null transactionId: a2190c8682344303 pricingStrategy: FREE /liveness/ext/v1/clear-data: get: tags: [Liveness Detection] operationId: clearLivenessPiiData summary: Delete the PII held for a liveness detection description: | Step 6 of the Liveness Detection flow — "PII Data Retention". Deletes the personally identifiable data ADVANCE.AI holds for one liveness detection, addressed by `livenessId` or `signatureId`. Provided for customers with compliance requirements. IRREVERSIBLE: the documentation describes no restore, undo or recovery window for cleared data. parameters: - name: livenessId in: query required: false schema: {type: string} description: The livenessId whose data should be cleaned up. - name: signatureId in: query required: false schema: {type: string} description: The signatureId whose data should be cleaned up. responses: '200': description: Envelope response. `code` is SUCCESS, PARAMETER_ERROR (free) or ERROR. content: application/json: schema: $ref: '#/components/schemas/Envelope' examples: success: value: code: SUCCESS message: OK data: null extra: null transactionId: ac66706068e737b5 pricingStrategy: FREE components: securitySchemes: AccessToken: type: apiKey in: header name: X-ACCESS-TOKEN description: | Short-lived access token from POST /openapi/auth/ticket/v1/generate-token. Valid for all ADVANCE.AI Open APIs and reusable until it expires. schemas: Envelope: type: object description: | The common ADVANCE.AI response envelope. The HTTP status is 200 for both success and business errors; `code` carries the real outcome and drives billing. required: [code, message] properties: code: type: string description: The ADVANCE.AI status code. See the Glossary for the shared codes. message: type: string description: | Human-readable explanation of the status code. ADVANCE.AI advises branching on `code`, not `message` — the message text may change without notice. data: description: The response content. Shape differs per operation; null on most errors. extra: type: [string, 'null'] description: Extra response info, typically an exception message. Usually empty. transactionId: type: string maxLength: 64 description: The request id. ADVANCE.AI strongly recommends storing it. pricingStrategy: type: string enum: [FREE, PAY] description: Whether this response is billed. TokenData: type: object properties: token: type: string description: The access token, a JWT. expiredTime: type: integer format: int64 description: Expiry as epoch milliseconds. LicenseData: type: object properties: license: type: string description: Authorization code, valid within its effective period. expireTimestamp: type: integer format: int64 description: Expiry as epoch milliseconds. DocumentVerificationResult: type: object properties: image: type: string description: The captured document image, as a 24-hour URL or a base64 string. OCR: $ref: '#/components/schemas/OcrFields' idForgery: type: object description: | Forgery verdict. `result` is "pass" (not forged) or "fail" (forged); `detail` is null on pass. Documented fail reasons include retake/screenshot, colour photocopy or cut-off corner, black-and-white photocopy, pasted face, and modified NIK. properties: result: type: string enum: [pass, fail] data: type: string detail: type: [string, 'null'] OcrFields: type: object description: | Fields extracted from the identity document. The documented example is an Indonesian KTP; the field set is document-dependent. properties: idNumber: {type: string} fullName: {type: string} fullNameLocal: {type: string} expiryDate: {type: string} state: {type: string} city: {type: string} district: {type: string} subdistrict: {type: string} fullAddress: {type: string} gender: {type: string} bloodType: {type: string} religion: {type: string} nationality: {type: string} others: type: object description: Document-specific additional fields, e.g. rtrw, occupation, birthPlaceBirthday, maritalStatus. additionalProperties: true FaceComparisonResult: type: object properties: similarity: type: number format: float minimum: 0 maximum: 100 description: Similarity between the two faces. Higher is more similar. firstFace: $ref: '#/components/schemas/FacePosition' secondFace: $ref: '#/components/schemas/FacePosition' FacePosition: type: object description: Bounding box and detected gender for one face in a picture. properties: id: {type: string, description: An identifier for the face in the picture.} left: {type: number, format: float, description: Pixels from the left edge.} top: {type: number, format: float, description: Pixels from the top edge.} right: {type: number, format: float, description: Pixels from the right edge.} bottom: {type: number, format: float, description: Pixels from the bottom edge.} gender: {type: string, enum: [MALE, FEMALE]} LivenessResult: type: object properties: detectionResult: type: string description: The face image, as a 24-hour URL or a base64 string. livenessScore: type: number format: double minimum: 0 maximum: 100 description: Anti-spoofing score. Below 50 may indicate an attack. auditImageUrl: type: [string, 'null'] description: Zip of audit images. Must be configured in the SDK, otherwise null. 24-hour link. imageFarUrl: type: string description: Photo taken by the user in the far stage. 24-hour link. farImageTime: type: [integer, 'null'] format: int64 imageNearUrl: type: string description: Photo taken by the user in the near stage. 24-hour link. nearImageTime: type: [integer, 'null'] format: int64 attackType: type: [integer, 'null'] description: Returned when livenessScore is 0. 1 presentation attack, 2 injection attack, 3 unsure attack. enum: [1, 2, 3, null] attackSubType: type: [string, 'null'] description: Currently always null; ADVANCE.AI states more detail will follow. sdkVersion: type: string platform: type: string enum: [Android, iOS]