Identity Validations
Combinations and Strategies per Signer
When generating a signing process, it is essential to understand the different possible combinations of identity validations, as well as the strategies that allow you to apply them globally or individually per signer.
To structure these validations, there are rules you must consider to ensure the process works correctly.
1. Types of Available Validations
The identity validations you can combine in a process include:
| Validation | Type | Required | Description |
|---|---|---|---|
camera | Boolean | Optional | Requests a photo of the signer's face. |
otpCode | Boolean | Optional | Requests a verification code. |
options.camera | String | Conditional | If you want to match the face photo with the signer's ID, you must send 'identification' in this field, or if you want only the participant's photo, send 'photo'. |
options.otpCode | String | Conditional | This field accepts the values 'phone' and 'email' to indicate through which medium the signer will receive the code if otpCode is set to true in the base data. |
options.whatsapp | Boolean | Conditional | Send this field as true only if you want the signing flow of this signer to be carried out through WhatsApp; by default, it is false. |
options.both | Boolean | Conditional | Send this field as true only if you want the signing flow of this signer to be carried out through WhatsApp and email, by default it is false. |
options.identificationCardBack | Boolean | Conditional | Send this field as true only if you want the identity validation to additionally request the back side of the document only available for WhatsApp. |
Here you can see the list of countries and accepted identity documents
both does not exist as a standalone fieldboth is not a top-level parameter: it does not exist at the root of the request nor as signProfile[x].both. It only exists nested as options.both (or signProfile[x].options.both for individual validations).
2. Global and Individual Validations
You can apply validations in two ways:
- Global: at the root of the request. They are automatically applied to all signers.
- Individual: in the signProfile[x] object, to validate each signer in a personalized way.
Individual validations take precedence over global ones when both are declared.
Package creation (POST /document/many) does not support per-signer individual validations: validations are read only from the root of the request and apply to every participant in the package. What this section describes about individual validations does not apply to that endpoint.
If a signProfile[x] defines any of these fields: camera, otpCode, or options, that signer stops inheriting the global validations entirely — even for fields it did not include. Any field missing from that signProfile[x] resolves to false (for camera/otpCode) or an empty object (for options), regardless of what the global validations say.
Example: if you send "camera": true at the root but an individual signer only defines "options": { "otpCode": "email" } (without including "camera": true in that same signProfile[x]), that signer ends up with camera: false, even though the global validation has it set to true.
If you want a signer to keep a global validation while only customizing another one, you must explicitly repeat each relevant field (camera, otpCode) inside that same signProfile[x].
3. Key Rules
options.camera = 'identification'activates biometric comparison, but it will only work if the signer has identification, country, and identificationType defined.options.both = trueindicates that the signer must receive notifications via email and WhatsApp simultaneously; for this to be effective:options.whatsapp = true.options.cameraandoptions.otpCodeare only valid if, at that same level (root or inside the samesignProfile[x]),camera: trueorotpCode: trueexists respectively. For example,signProfile[x].options.camerarequiressignProfile[x].camera: truefor that same signer; it is not enough forcamerato betrueglobally. If you declareoptions.cameraoroptions.otpCodewithout its boolean counterpart at that same level, the process will not be valid.- Individual validations completely override the global ones for that signer: if a
signProfile[x]declarescamera,otpCode, oroptions, any field not included in that samesignProfile[x]resolves tofalse(or{}foroptions), without inheriting the global value. See the warning in section 2.
4. Examples:
Global Validations:
{
...,
"camera": true,
"otpCode": true,
"options": {
"camera": "identification",
"otpCode": "email",
}
"signProfile": [
{
"name": "Firmante 1",
"email": "example@auco.ai",
"phone": "+573000000000",
"identification": "123456789",
"identificationType": "CC",
"country": "CO"
},
{
"name": "Firmante 2",
"email": "example2@auco.ai",
"phone": "+573000000000",
"identification": "123456789",
"identificationType": "CC",
"country": "CO"
}
],
...
}
Individual Validations:
{
...,
"signProfile": [
{
"name": "Firmante 1",
"email": "example@auco.ai",
"phone": "+573000000000",
"camera": true,
"otpCode": true,
"identification": "123456789",
"identificationType": "CC",
"country": "CO"
"options": {
"camera": "identification",
"whatsapp": true,
"otpCode": "email"
}
}
],
...
}