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.
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:
- Requesting secure URLs to upload the documents.
- Uploading the document files.
- 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
| Field | Type | Required | Description |
|---|---|---|---|
| documentType | string | Yes | The type of document to be uploaded. Supported values: ID, DRIVERS-LICENSE, PASSPORT, SELFIE, SELFIE-FROM-LIVENESS. |
| isDoubleSided | boolean | No | If 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 }'
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
| Header | Value | Required | Description |
|---|---|---|---|
| If-None-Match | * | Yes | This header is required for the upload request. |
| Content-Type | file mime type | Yes | The 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"
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
| Field | Type | Required | Description |
|---|---|---|---|
| fullName | string | Yes | The complete name of the individual. |
| dateOfBirth | string | Yes | The date of birth (Format: YYYY-MM-DD). |
| countryOfTaxId | string | Yes | The country where the tax identification number was issued. |
| taxIdNumber | string | Yes | The tax identification number. |
| string | Yes | The email address. | |
| phone | string | No | The phone number. |
| country | string | Yes | The country of residence. |
| state | string | Yes | The state/province of residence. |
| city | string | Yes | The city of residence. |
| zipCode | string | Yes | The postal code. |
| streetAddress | string | Yes | The street address. |
| uploadedSelfieId | string | Yes | The id returned in Step 1 for the selfie upload. |
| uploadedDocumentId | string | Yes | The id returned in Step 1 for the document (ID, Passport, etc.). |
| sandboxReject | boolean | No | Set to true to simulate a failed KYC attempt in the sandbox environment. |
- Country codes must follow the ISO 3166-1 alpha-3 standard (e.g.,
BRAfor Brazil). - State codes must follow the state or province code standard (e.g.,
SPfor 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"
}
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
To perform KYC for a Subaccount, simply pass the subAccountId field as a request parameter.
Request Body
{
"redirectUrl": "https://example.com/kyc-complete"
}
Fields
| Field | Type | Required | Description |
|---|---|---|---|
| redirectUrl | string | No | URL 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
| Field | Type | Description |
|---|---|---|
| attemptId | string | Unique identifier for this KYC attempt. |
| kycUrl | string | URL 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
- Generate Link: Call the endpoint with optional
redirectUrl - Redirect User: Direct the user to the returned
kycUrl - User Completes Verification: User completes the verification process in the web interface
- Redirect Handling: If
redirectUrlwas provided, user is redirected back after completion
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.
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
| Parameter | Type | Description |
|---|---|---|
createdAtAfter | string | (Optional) Filters for documents created after this timestamp (ISO 8601). |
createdAtBefore | string | (Optional) Filters for documents created before this timestamp (ISO 8601). |
documentType | string | (Optional) Filters by a specific document type (e.g., PASSPORT). |
cursor | string | (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
| Parameter | Type | Description |
|---|---|---|
documentId | string | The ID of the document, obtained from Step 1. |
Response Fields
The response contains the current state of the document.
| Field | Type | Description |
|---|---|---|
id | string | The unique identifier of the document. |
documentType | string | The type of document (e.g., PASSPORT, SELFIE). |
uploadURLFront | string | The pre-signed URL for uploading the front of the document. |
uploadStatusFront | string | The status of the front upload. Possible values: PENDING, PROCESSING, COMPLETED, EXPIRED. |
uploadErrorFront | string | An error message if the front upload failed. |
uploadURLBack | string | The pre-signed URL for the back of the document. Only present for double-sided documents. |
uploadStatusBack | string | The status of the back upload. Possible values: PENDING, PROCESSING, COMPLETED, EXPIRED. |
uploadErrorBack | string | An error message if the back upload failed. |
ready | boolean | If true, the document's id can be used in the POST /v2/kyc/new-level-1/api request. |
createdAt | string | The timestamp when the document request was created. |
updatedAt | string | The 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
| Parameter | Type | Description |
|---|---|---|
createdAtAfter | string | (Optional) Filters for attempts created after this timestamp (ISO 8601). |
createdAtBefore | string | (Optional) Filters for attempts created before this timestamp (ISO 8601). |
levelName | string | (Optional) Filters by a specific KYC level (e.g., level-1). |
status | string | (Optional) Filters by status. Values: PENDING, PROCESSING, COMPLETED, EXPIRED. |
result | string | (Optional) Filters by result. Values: APPROVED, REJECTED. |
cursor | string | (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
| Parameter | Type | Description |
|---|---|---|
attemptId | string | The 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
| Field | Description |
|---|---|
id | The unique ID of the KYC attempt. |
levelName | The KYC level attempted (e.g., level-1). |
submissionData | An object containing the data submitted by the user. |
status | The processing status: PENDING, PROCESSING, COMPLETED, EXPIRED. |
result | The final outcome: APPROVED or REJECTED. |
resultMessage | A message providing details on the result, especially for rejections. |
retryable | A boolean indicating if the user can attempt this KYC level again. |
createdAt | The timestamp when the attempt was created. |
updatedAt | The timestamp of the last update. |