Skip to main content

KYC (Know Your Customer) Guide

KYC is a process to verify user identity, ensuring compliance with regulations and preventing fraud or illegal activities. It involves validating personal information and documents.

info

Remember that to perform KYC for a Subaccount, simply pass the subAccountId field as a request parameter.

KYC Level 1 - API

This guide outlines the multi-step process for completing KYC Level 1 by uploading identity documents and a selfie. This flow is ideal for handling user documents securely.

The process consists of three main steps:

  1. Requesting secure URLs to upload the documents.
  2. Uploading the document files.
  3. Submitting the KYC request with the uploaded document information.

Step 1: Request Document Upload URL - Selfie and Document

First, you need to request a secure pre-signed URL to upload your document. This endpoint will generate a link for you to send the file.

HTTP POST Request:

https://api.sandbox.avenia.io:10952/v2/documents/

Fields

FieldTypeRequiredDescription
documentTypestringYesThe type of document to be uploaded. Supported values: ID, DRIVERS-LICENSE, PASSPORT, SELFIE, SELFIE-FROM-LIVENESS.
isDoubleSidedbooleanNoIf true, the API will return two URLs for uploading the front and back of the document. Defaults to false.

Sample JSON Body:

{
"documentType": "DRIVERS-LICENSE",
"isDoubleSided": true
}

JSON Response

If isDoubleSided is false or not provided:

{
"id": "46225dda-6371-4b1c-a777-eac36ec402af",
"uploadURLFront": "https://s3.amazonaws.com/kyc-uploads/46225dda-6371-4b1c-a777-eac36ec402af-front?AWSAccessKeyId=..."
}

If isDoubleSided is true:

{
"id": "46225dda-6371-4b1c-a777-eac36ec402af",
"uploadURLFront": "https://s3.amazonaws.com/kyc-uploads/46225dda-6371-4b1c-a777-eac36ec402af-front?AWSAccessKeyId=...",
"uploadURLBack": "https://s3.amazonaws.com/kyc-uploads/46225dda-6371-4b1c-a777-eac36ec402af-back?AWSAccessKeyId=..."
}

if documentType is SELFIE-FROM-LIVENESS:

{
"id": "c03b56e9-5c7d-444f-b90d-5aa2b28b8d9d",
"sessionId": "41909959-4796-4619-9bad-e96415fd72ce",
"livenessUrl": "https://app.avenia.io/liveness/41909959-4796-4619-9bad-e96415fd72ce?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTY1MDU1MTEsImlhdCI6MTc1NjUwNTIxMSwic2Vzc2lvbklkIjoiNDE5MDk5NTktNDc5Ni00NjE5LTliYWQtZTk2NDE1ZmQ3MmNlIiwic3ViIjoiYzAzYjU2ZTktNWM3ZC00NDRmLWI5MGQtNWFhMmIyOGI4ZDlkIn0.DRudCz4dyk5gf4bdA-g5z7wkjSf8A64B8KkiclHM1p4",
"validateLivenessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTY1MDU1MTEsImlhdCI6MTc1NjUwNTIxMSwic2Vzc2lvbklkIjoiNDE5MDk5NTktNDc5Ni00NjE5LTliYWQtZTk2NDE1ZmQ3MmNlIiwic3ViIjoiYzAzYjU2ZTktNWM3ZC00NDRmLWI5MGQtNWFhMmIyOGI4ZDlkIn0.DRudCz4dyk5gf4bdA-g5z7wkjSf8A64B8KkiclHM1p4"
}

Now you must perform the liveness check via the livenessUrl link.

cURL Example:

curl -X POST "https://api.sandbox.avenia.io:10952/v2/documents/" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "documentType": "DRIVERS-LICENSE", "isDoubleSided": true }'
info

To successfully complete KYC Level 1, you must submit both a selfie and a valid document (ID, Driver's License, or Passport).

Make sure to save the id returned in this step for each uploaded document. You will need it to submit the final KYC request.


Step 2: Upload Document Files

Once you have the pre-signed URL(s) from Step 1, you must upload the corresponding document file(s) to each link.

For each URL (uploadURLFront and uploadURLBack), make a PUT request with the binary data of your image. This request must include the If-None-Match: * header.

HTTP PUT Request

Use the uploadURL... returned in Step 1 as the endpoint for your PUT request.

Headers

HeaderValueRequiredDescription
If-None-Match*YesThis header is required for the upload request.
Content-Typefile mime typeYesThe MIME type of your file. Accepted formats are PNG, JPEG, and PDF.

cURL Example

Here’s how to upload the front side of a document:

curl -X PUT "https://s3.amazonaws.com/kyc-uploads/46225dda-6371-4b1c-a777-eac36ec402af-front?AWSAccessKeyId=..." \
-H "Content-Type: image/jpeg" \
-H "If-None-Match: *" \
--data-binary "@/path/to/your/document-front.jpg"
tip

Remember to perform this upload for each link you received. If you requested a double-sided upload, you must make separate PUT requests for uploadURLFront and uploadURLBack.


Step 3: Submit KYC Level 1 Request

After successfully uploading your selfie and document, the final step is to submit the KYC request with your personal information and the document IDs obtained in Step 1.

HTTP POST Request:

https://api.sandbox.avenia.io:10952/v2/kyc/new-level-1/api

Fields

FieldTypeRequiredDescription
fullNamestringYesThe complete name of the individual.
dateOfBirthstringYesThe date of birth (Format: YYYY-MM-DD).
countryOfTaxIdstringYesThe country where the tax identification number was issued.
taxIdNumberstringYesThe tax identification number.
emailstringYesThe email address.
phonestringNoThe phone number.
countrystringYesThe country of residence.
statestringYesThe state/province of residence.
citystringYesThe city of residence.
zipCodestringYesThe postal code.
streetAddressstringYesThe street address.
uploadedSelfieIdstringYesThe id returned in Step 1 for the selfie upload.
uploadedDocumentIdstringYesThe id returned in Step 1 for the document (ID, Passport, etc.).
sandboxRejectbooleanNoSet to true to simulate a failed KYC attempt in the sandbox environment.
info
  • Country codes must follow the ISO 3166-1 alpha-3 standard (e.g., BRA for Brazil).
  • State codes must follow the state or province code standard (e.g., SP for São Paulo).

Sample JSON Body:

{
"fullName": "John Doe",
"dateOfBirth": "1990-01-15",
"countryOfTaxId": "BRA",
"taxIdNumber": "12345678900",
"email": "john.doe@example.com",
"country": "BRA",
"state": "SP",
"city": "Sample City",
"zipCode": "12345-678",
"streetAddress": "123 Main Street",
"uploadedSelfieId": "46225dda-6371-4b1c-a777-eac36ec402af",
"uploadedDocumentId": "a4b2015b-6ace-4c31-bd58-02fe28251582"
}

cURL Example:

curl -X POST "https://api.sandbox.avenia.io:10952/v2/kyc/new-level-1/api" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ ... }'

JSON Response:

{
"id": "4422b3ae-e2ee-44ed-abdf-ab9f682b30d3"
}
info

If you have webhooks configured, you will receive notifications regarding the status of your KYC Level 1 submission.


KYC Level 1 - Web SDK

This guide outlines how to use the Web SDK flow to complete KYC Level 1 verification. This approach is ideal when you want to offload the verification process to a secure, dedicated web interface managed by our platform.

HTTP POST Request:

https://api.sandbox.avenia.io:10952/v2/kyc/new-level-1/web-sdk
info

To perform KYC for a Subaccount, simply pass the subAccountId field as a request parameter.

Request Body

{
"redirectUrl": "https://example.com/kyc-complete"
}

Fields

FieldTypeRequiredDescription
redirectUrlstringNoURL where users will be redirected after completing or canceling the KYC process. If not provided, users will remain on the verification page.

JSON Response

{
"attemptId": "550e8400-e29b-41d4-a716-446655440000",
"kycUrl": "https://sumsub.com/websdk/..."
}

Response Fields Explained

FieldTypeDescription
attemptIdstringUnique identifier for this KYC attempt.
kycUrlstringURL to redirect the user to complete KYC verification.

cURL Example

curl -X POST "https://api.sandbox.avenia.io:10952/v2/kyc/new-level-1/web-sdk" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"redirectUrl": "https://yourapp.com/kyc-complete"
}'

Usage Flow

  1. Generate Link: Call the endpoint with optional redirectUrl
  2. Redirect User: Direct the user to the returned kycUrl
  3. User Completes Verification: User completes the verification process in the web interface
  4. Redirect Handling: If redirectUrl was provided, user is redirected back after completion
info

Once the user completes the process through the provided URL, you will receive status updates via webhooks if they are configured for your account with the KYC events. You can also poll for the status using the attemptId.


List All Document Statuses

You can retrieve a paginated list of all document uploads. The list can be filtered by creation date and document type.

info

To perform this operation on behalf of a subaccount, provide the subAccountId in the request.

HTTP GET Request:

https://api.sandbox.avenia.io:10952/v2/documents/

Query Parameters

ParameterTypeDescription
createdAtAfterstring(Optional) Filters for documents created after this timestamp (ISO 8601).
createdAtBeforestring(Optional) Filters for documents created before this timestamp (ISO 8601).
documentTypestring(Optional) Filters by a specific document type (e.g., PASSPORT).
cursorstring(Optional) A cursor for navigating to the next page of results.

Sample JSON Response

The response includes an array of documents and a cursor string for pagination.

"documents": [
{
"id": "46225dda-6371-4b1c-a777-eac36ec402af",
"documentType": "SELFIE",
"uploadURLFront": "https://s3.amazonaws.com/kyc-uploads/46225dda-6371-4b1c-a777-eac36ec402af-Front?...",
"uploadStatusFront": "COMPLETED",
"uploadErrorFront": "",
"uploadURLBack": "",
"uploadStatusBack": "",
"uploadErrorBack": "",
"ready": true,
"createdAt": "2025-07-22T17:07:31.367323Z",
"updatedAt": "2025-07-22T17:07:41.473617Z"
},
{
"id": "a4b2015b-6ace-4c31-bd58-02fe28251582",
"documentType": "PASSPORT",
"uploadURLFront": "https://s3.amazonaws.com/kyc-uploads/a4b2015b-6ace-4c31-bd58-02fe28251582-Front?...",
"uploadStatusFront": "COMPLETED",
"uploadErrorFront": "",
"uploadURLBack": "",
"uploadStatusBack": "",
"uploadErrorBack": "",
"ready": true,
"createdAt": "2025-07-22T17:05:45.9915Z",
"updatedAt": "2025-07-22T17:05:56.090998Z"
}
],
"cursor": "NjEtMTc1MzIwMzc4NzE3MQ=="
}

Get Document Status by ID

You can check the status of a single document by providing its ID.

HTTP GET Request:

https://api.sandbox.avenia.io:10952/v2/documents/{documentId}

Path Parameters

ParameterTypeDescription
documentIdstringThe ID of the document, obtained from Step 1.

Response Fields

The response contains the current state of the document.

FieldTypeDescription
idstringThe unique identifier of the document.
documentTypestringThe type of document (e.g., PASSPORT, SELFIE).
uploadURLFrontstringThe pre-signed URL for uploading the front of the document.
uploadStatusFrontstringThe status of the front upload. Possible values: PENDING, PROCESSING, COMPLETED, EXPIRED.
uploadErrorFrontstringAn error message if the front upload failed.
uploadURLBackstringThe pre-signed URL for the back of the document. Only present for double-sided documents.
uploadStatusBackstringThe status of the back upload. Possible values: PENDING, PROCESSING, COMPLETED, EXPIRED.
uploadErrorBackstringAn error message if the back upload failed.
readybooleanIf true, the document's id can be used in the POST /v2/kyc/new-level-1/api request.
createdAtstringThe timestamp when the document request was created.
updatedAtstringThe timestamp of the last update.

Sample JSON Response

{
"document": {
"id": "9e37f9a8-611a-4cad-99fb-dd13268bdf4b",
"documentType": "PASSPORT",
"uploadURLFront": "https://s3.amazonaws.com/kyc-uploads/9e37f9a8-611a-4cad-99fb-dd13268bdf4b-Front?...",
"uploadStatusFront": "COMPLETED",
"uploadErrorFront": "",
"uploadURLBack": "",
"uploadStatusBack": "",
"uploadErrorBack": "",
"ready": true,
"createdAt": "2025-07-22T17:03:07.17181Z",
"updatedAt": "2025-07-22T17:03:27.445025Z"
}
}

cURL Example

curl -X GET "https://api.sandbox.avenia.io:10952/v2/documents/9e37f9a8-611a-4cad-99fb-dd13268bdf4b" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

List All KYC Attempts

You can retrieve a paginated history of all KYC attempts for your account or subaccount. The list can be filtered by date, level, status, and result.

HTTP GET Request:

https://api.sandbox.avenia.io:10952/v2/kyc/attempts/

Query Parameters

ParameterTypeDescription
createdAtAfterstring(Optional) Filters for attempts created after this timestamp (ISO 8601).
createdAtBeforestring(Optional) Filters for attempts created before this timestamp (ISO 8601).
levelNamestring(Optional) Filters by a specific KYC level (e.g., level-1).
statusstring(Optional) Filters by status. Values: PENDING, PROCESSING, COMPLETED, EXPIRED.
resultstring(Optional) Filters by result. Values: APPROVED, REJECTED.
cursorstring(Optional) A cursor for navigating to the next page of results.

Sample JSON Response

{
"attempts": [
{
"id": "4422b3ae-e2ee-44ed-abdf-ab9f682b30d3",
"levelName": "level-1",
"submissionData": { "...": "..." },
"status": "COMPLETED",
"result": "APPROVED",
"resultMessage": "",
"retryable": false,
"createdAt": "2025-07-22T17:36:03.630248Z",
"updatedAt": "2025-07-22T17:36:03.630248Z"
},
{
"id": "e36733f7-182b-4828-9b67-d5be4c9d90db",
"levelName": "level-1",
"submissionData": { "...": "..." },
"status": "COMPLETED",
"result": "REJECTED",
"resultMessage": "birthdate does not match",
"retryable": true,
"createdAt": "2025-07-22T17:31:31.348369Z",
"updatedAt": "2025-07-22T17:31:31.348369Z"
}
],
"cursor": "MTQzLTE3NTMyMDQ2ODk0MjE="
}

Get KYC Attempt by ID

Retrieve a specific KYC attempt by its unique ID.

HTTP GET Request:

https://api.sandbox.avenia.io:10952/v2/kyc/attempts/{attemptId}

Path Parameters

ParameterTypeDescription
attemptIdstringThe ID of the KYC attempt to retrieve.

Sample JSON Response

{
"attempt": {
"id": "e36733f7-182b-4828-9b67-d5be4c9d90db",
"levelName": "level-1",
"submissionData": {
"city": "SP",
"email": "johndoe@example.com",
"state": "BR-SP",
"fullName": "John Doe",
"dateOfBirth": "1998-08-16T00:00:00Z",
"taxIdNumber": "12345678900",
"..." : "..."
},
"status": "COMPLETED",
"result": "REJECTED",
"resultMessage": "birthdate does not match",
"retryable": true,
"createdAt": "2025-07-22T17:31:31.348369Z",
"updatedAt": "2025-07-22T17:31:31.348369Z"
}
}

Response Fields Explained

FieldDescription
idThe unique ID of the KYC attempt.
levelNameThe KYC level attempted (e.g., level-1).
submissionDataAn object containing the data submitted by the user.
statusThe processing status: PENDING, PROCESSING, COMPLETED, EXPIRED.
resultThe final outcome: APPROVED or REJECTED.
resultMessageA message providing details on the result, especially for rejections.
retryableA boolean indicating if the user can attempt this KYC level again.
createdAtThe timestamp when the attempt was created.
updatedAtThe timestamp of the last update.