curl --request POST \
--url https://api.id.zapsign.com.br/v1/validations/{id}/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"code": "483920"
}
'const url = 'https://api.id.zapsign.com.br/v1/validations/{id}/verify';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({code: '483920'})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));import requests
url = "https://api.id.zapsign.com.br/v1/validations/{id}/verify"
payload = { "code": "483920" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.id.zapsign.com.br/v1/validations/{id}/verify"
payload := strings.NewReader("{\n \"code\": \"483920\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.id.zapsign.com.br/v1/validations/{id}/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'code' => '483920'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.id.zapsign.com.br/v1/validations/{id}/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"code\": \"483920\"\n}"
response = http.request(request)
puts response.read_body{
"object": "validation",
"id": "val_2W7HJ9RC4XKQ0ZB58NDT3PMFY6",
"type": "phone_ownership",
"status": "completed",
"result": "passed",
"reason_code": null,
"external_id": "pedido_12345",
"created_at": "2026-08-07T14:00:00Z",
"resolved_at": "2026-08-07T14:02:11Z",
"validation_url": null,
"expires_at": "2026-08-07T14:10:00Z",
"attempts_remaining": 0,
"details": null
}Confirmar o código de uma validação
Confirma o código que a pessoa recebeu no WhatsApp e fecha a validação de posse de telefone.
curl --request POST \
--url https://api.id.zapsign.com.br/v1/validations/{id}/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"code": "483920"
}
'const url = 'https://api.id.zapsign.com.br/v1/validations/{id}/verify';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({code: '483920'})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));import requests
url = "https://api.id.zapsign.com.br/v1/validations/{id}/verify"
payload = { "code": "483920" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.id.zapsign.com.br/v1/validations/{id}/verify"
payload := strings.NewReader("{\n \"code\": \"483920\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.id.zapsign.com.br/v1/validations/{id}/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'code' => '483920'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.id.zapsign.com.br/v1/validations/{id}/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"code\": \"483920\"\n}"
response = http.request(request)
puts response.read_body{
"object": "validation",
"id": "val_2W7HJ9RC4XKQ0ZB58NDT3PMFY6",
"type": "phone_ownership",
"status": "completed",
"result": "passed",
"reason_code": null,
"external_id": "pedido_12345",
"created_at": "2026-08-07T14:00:00Z",
"resolved_at": "2026-08-07T14:02:11Z",
"validation_url": null,
"expires_at": "2026-08-07T14:10:00Z",
"attempts_remaining": 0,
"details": null
}O código que a pessoa digitou
Quando você criou a validação em posse de telefone por WhatsApp, a pessoa recebeu um código no WhatsApp. Peça esse código na sua tela e mande aqui o que ela digitou, com oid daquela validação no path.
Ela tem 3 tentativas e 10 minutos. Toda resposta traz attempts_remaining e expires_at, então leia esses campos em vez de contar do seu lado.
Só validações de posse de telefone se confirmam por código. Qualquer outro tipo responde 422 validation_not_verifiable.
Como ler o desfecho
Um código errado também responde200. O que aconteceu está no corpo:
status | result | O que aconteceu |
|---|---|---|
pending | null | Código errado, ainda há tentativas |
completed | passed | O telefone é da pessoa |
completed | not_passed | As tentativas acabaram |
expired | null | Os 10 minutos venceram |
O que não gasta tentativa
Umcode que não seja só dígitos é recusado antes de chegar ao provedor, com 400 invalid_param_value. Um erro de digitação não custa uma tentativa da pessoa.
Um 500 é erro nosso, não resposta da pessoa. Repita a chamada com o mesmo Idempotency-Key e o mesmo código.Authorizations
Sua chave de API no cabeçalho Authorization: Bearer sk_.... Crie e revogue chaves no painel ou pelos endpoints de Chaves de API.
Headers
Torna a operação segura para retentativa. Reenviar a mesma chave repete a resposta original em vez de executar a operação de novo.
1 - 256^[A-Za-z0-9_-]{1,256}$Path Parameters
Identificador da validação.
Body
Código que a pessoa recebeu, para confirmar uma validação.
Código recebido, apenas dígitos.
^[0-9]+$"483920"
Response
Recurso da validação depois da tentativa, em qualquer desfecho.
Resultado de uma validação.
Sempre validation.
validation Identificador único da validação.
"val_0NQW3MVYJYQ453E95V3V1T76AV"
Tipo da validação.
| Valor | O que é |
|---|---|
cpf_phone_match | Vínculo entre CPF e telefone |
sim_swap | Troca de chip |
liveness_document_match | Prova de vida + documento |
phone_ownership | Posse do telefone, por código no WhatsApp |
liveness_cpf_match | Prova de vida + CPF |
telco_financial_capacity | Capacidade financeira via operadora |
Os quatro primeiros têm endpoint de criação. Os outros dois podem aparecer em consultas e listagens de contas que os usam por outros canais.
liveness_document_match, liveness_cpf_match, cpf_phone_match, sim_swap, telco_financial_capacity, phone_ownership Estado atual.
| Valor | O que é |
|---|---|
pending | Criada, aguardando o titular concluir o fluxo hospedado ou devolver o código |
completed | Resolvida; veja result |
failed | Não foi possível concluir |
expired | O prazo venceu sem conclusão |
pending, completed, failed, expired Resultado de negócio. É null enquanto status for pending.
| Valor | Aparece em |
|---|---|
match / no_match | cpf_phone_match |
recent_swap / no_recent_swap | sim_swap |
passed / not_passed | liveness_document_match, liveness_cpf_match, phone_ownership |
high_capacity / moderate_capacity / low_capacity | telco_financial_capacity |
unknown | Qualquer tipo, quando a fonte não deu uma resposta conclusiva. O motivo vem em reason_code. |
passed, not_passed, match, no_match, recent_swap, no_recent_swap, high_capacity, moderate_capacity, low_capacity, unknown Por que o resultado foi o que foi. É null quando o resultado não precisa de explicação. Acompanha unknown na maioria dos casos, e também not_passed quando a validação foi recusada por um motivo específico.
| Valor | O que é |
|---|---|
liveness_failed | Prova de vida não confirmada |
face_mismatch | O rosto não corresponde ao documento |
spoof_detected | Suspeita de fraude na captura |
document_tampered | Indícios de adulteração no documento |
document_invalid | Documento inválido ou não aceito |
document_unreadable | O documento não pôde ser lido |
cpf_reference_not_found | CPF não encontrado na base de referência |
data_unavailable | Dados indisponíveis na fonte consultada |
phone_not_covered | Telefone sem cobertura para a consulta |
invalid_code | O código enviado não confere, e as tentativas acabaram |
liveness_failed, face_mismatch, spoof_detected, document_tampered, document_invalid, document_unreadable, cpf_reference_not_found, data_unavailable, phone_not_covered, invalid_code A referência de correlação que você enviou na criação.
Data de criação em ISO-8601.
Data de resolução em ISO-8601. É null enquanto não resolvida.
URL para onde redirecionar o titular. Preenchida nas validações hospedadas; null nas síncronas.
Quando a validação vence, em ISO-8601. Preenchida nas validações hospedadas e nas que enviam um código; null nas síncronas.
Quantas chamadas de verificação ainda serão aceitas. Preenchida nos tipos que enviam um código para a pessoa devolver (hoje só phone_ownership) e null nos demais.
Vale 0 assim que a validação é resolvida, em qualquer desfecho, porque nenhuma outra tentativa será aceita.
Dados extraídos, agrupados pela chave do type. Hoje só liveness_document_match produz detalhes, e só com status igual a completed. Nos demais casos é null.
Show child attributes
Show child attributes
Was this page helpful?