Age Verification
For the full integration flow, see API Overview.
Endpoint
| Environment | URL |
|---|---|
| Production | POST https://api.id.unico.app/processes/v1 |
| Sandbox | POST https://api.id.uat.unico.app/processes/v1 |
Request
| Header | Value |
|---|---|
Authorization | Bearer <access_token> (see Authentication) |
APIKEY | Provisioned API key — must have Age Verification capabilities enabled. |
Content-Type | application/json |
| Field | Type | Required | Description |
|---|---|---|---|
subject | object | yes | User information container. |
subject.code | string | conditional | CPF (BR) or CURP (MX), without formatting. Required when the flow includes Liveness or Identity Verification (see Age Verification capability); not required for Age Verification-only flows. |
subject.name | string | no | User's full name. |
subject.gender | string | no | M for male or F for female. |
subject.birthDate | string (ISO 8601) | no | Date of birth (YYYY-MM-DD). |
subject.email | string | no | User's email address. |
subject.phone | string | no | Phone number: country code + area code + number, no separators (e.g. 5519725570707). |
useCase | string | no | Operation's scenario identifier. |
subsidiaryId | string | no | Branch ID — required only if multiple branches exist. |
imageBase64 | string | yes | Encrypted SDK output or base64 image (PNG, JPEG, WebP). |
- Minimum resolution: 640 × 480 (HD standard)
- Maximum file size: 800 KB (JPEG92 compression recommended)
- JWT tokens from the SDK expire after 10 minutes and can only be used once
Example
- cURL
- Node.js
curl -X POST https://api.id.unico.app/processes/v1 \
-H "Authorization: Bearer $TOKEN" \
-H "APIKEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": {
"code": "12345678909",
"name": "Luke Skywalker",
"birthDate": "2000-05-20",
"email": "[email protected]",
"phone": "5519725570707"
},
"useCase": "AgeVerification",
"imageBase64": "/9j/4AAQSkZJR..."
}'
import fetch from 'node-fetch';
const res = await fetch('https://api.id.unico.app/processes/v1', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.UNICO_ACCESS_TOKEN}`,
'APIKEY': process.env.UNICO_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
subject: {
code: '12345678909',
name: 'Luke Skywalker',
birthDate: '2000-05-20',
phone: '5519725570707'
},
useCase: 'AgeVerification',
imageBase64: capturedImage
})
});
const result = await res.json();
Responses
The response fields returned depend on which capabilities are enabled for your APIKEY.
Age Verification only (no Liveness, no Identity Verification):
{
"id": "80371b2a-3ac7-432e-866d-57fe37896ac6",
"status": 3,
"idAge": { "result": "yes" }
}
Age Verification + Liveness + Identity Verification:
{
"id": "80371b2a-3ac7-432e-866d-57fe37896ac6",
"status": 3,
"unicoId": { "result": "yes" },
"idAge": { "result": "yes" },
"liveness": 1
}
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Process identifier. Use with Get Process for re-queries. |
status | integer | 3 (finished with success), 5 (error). Only use status = 3 for business decisions. For all possible values, see Get Process. |
idAge.result | string | yes, no, inconclusive — Age Verification result. Present in all responses. |
unicoId.result | string | yes, no, inconclusive — present only when Identity Verification is enabled. |
liveness | integer | 1 (passed), 2 (failed) — present only when Liveness is enabled. |
Error Codes
- 400 Bad Request
- 403 Forbidden
- 409 Conflict
- 429 Too Many Requests
- 500 Internal Server Error
| Code | Message | Description |
|---|---|---|
20900 | O base64 informado não é válido. | Invalid base64 parameter; potential image or injection issue. |
20807 | A imagem precisa estar no padrão HD ou possuir uma resolução superior a 640 x 480. | Image resolution below minimum threshold. |
20509 | The subject.name field is invalid. | subject.name contains invalid characters. |
20508 | The subject.gender field is invalid. | subject.gender must be M or F. |
20507 | O parâmetro subject.code é inválido. | Malformed or non-existent identifier value. Only fires when Liveness or Identity Verification is included in the flow — not required for Age Verification-only flows. |
20506 | O base64 informado é muito grande. O tamanho máximo suportado é até 800kb. | Payload exceeds 800 KB; compress to JPEG92. |
20505 | O base64 informado não é suportado. Os formatos aceitos são png, jpeg e webp. | Unsupported format or invalid base64 prefix. |
20062 | The useCase field is invalid. | Unrecognized value in the useCase field. |
20021 | The subject.phone field is invalid. | subject.phone format is invalid (IDD + area code + number, 13 chars). |
20019 | The subject.birthDate field is invalid. | subject.birthDate is outside ISO 8601 format (YYYY-MM-DD). |
20009 | O parâmetro imagebase64 não foi informado. | Missing selfie image parameter. |
20008 | The subject.email field is invalid. | Invalid email format in subject.email. |
20005 | O parâmetro subject.code não foi informado. | Missing subject.code parameter. Only fires when Liveness or Identity Verification is included in the flow — not required for Age Verification-only flows. |
20004 | O parâmetro subject não foi informado. | Missing subject object. |
20003 | The request body is missing or invalid. | Null or malformed payload. |
20002 | O parâmetro APIKey não foi informado. | Missing APIKEY header. |
20001 | O parâmetro authtoken não foi informado. | Missing authentication token header. |
10508 | The JWT with the captured face has already been used. | JWT can only be consumed once. |
10507 | The JWT with the captured face is expired. | JWT exceeds 10-minute validity window. |
10506 | The imageBase64 field is not a valid JWT from SDK. | The imageBase64 is not a valid JWT generated by the SDK. |
Bearer token or APIKEY missing, expired, or invalid. See Authentication.
| Code | Message | Description |
|---|---|---|
30017 | User does not have permission to perform this action. | Malformed JWT or user without permission to perform this operation. |
30017 | Jwt header is an invalid JSON. | The access-token contains invalid characters. |
10502 | O token informado está expirado. | Expired access-token. |
10501 | O token informado é inválido. | Invalid authentication token. |
10201 | O AppKey informado é inválido. | Missing or nonexistent APIKEY. |
| Code | Message | Description |
|---|---|---|
20073 | The processID already exists. | The processId provided already exists for this tenant. |
Rate limit reached. When your system receives an HTTP 429 error, you must implement mechanisms to prevent cascading failures and avoid worsening the restriction.
Best practices:
- Cool-down period (backoff): Immediately halt or throttle subsequent requests from your system. Do not continuously retry failed requests in a tight loop.
- Queueing & throttling: Buffer or queue outgoing requests on your end to control the traffic flow before re-sending them.
- Exponential backoff with jitter: When retrying, increase the waiting time exponentially between attempts (e.g., 1 s, 2 s, 4 s, 8 s) and add a small random delay ("jitter") to prevent a herd effect where all queued requests retry at the exact same millisecond.
Continuously hitting a rate-limited endpoint without backing off can prolong the restriction period and severely impact your system's operational throughput. Properly throttling requests on your side ensures a smoother, more resilient integration.
For default limits, increase requests and additional details, see Rate Limits.
| Code | Message | Description |
|---|---|---|
99999 | Internal failure! Try again later. | Server-side processing error. |
What's next
- For querying an existing process, see Get Process.