Sandbox e Dados de Teste
O sandbox é uma cópia completa do pipeline de verificação com suas próprias credenciais e seus próprios dados. Use-o para construir e validar sua integração antes que qualquer cliente real a utilize.
Acesso
| O que você precisa | Como obter |
|---|---|
| URL base do sandbox | Emitida pela Inyo no onboarding |
client_id / client_secret | Emitidos pela Inyo no onboarding, separados dos de produção |
webhookSecret | Emitido pela Inyo no onboarding, separado do de produção |
| Acesso de rede | Suas faixas de IP de saída devem estar na lista de permissões — envie-as ao seu contato na Inyo |
Uma webhookUrl registrada | Opcional, mas necessária para exercitar a entrega de webhooks. Um túnel funciona durante o desenvolvimento |
Credenciais de sandbox e de produção nunca são intercambiáveis, e uma verificação em sandbox nunca é uma base válida para uma decisão real de onboarding.
Duas Formas de Obter um Resultado
O sandbox realiza análise real de documentos por padrão — o mesmo pipeline de extração, autenticidade, prova de vida e correspondência facial da produção. Envie imagens e o resultado vem delas: uma captura borrada falha de verdade, um documento vencido é recusado de verdade.
Ele também aceita um número de documento reservado que dita todo o resultado da verificação, como funciona um número de cartão de teste em pagamentos. Envie um em prefill.documentNumber e a sessão é finalizada na criação já com um resultado completo — sem imagens, sem câmera, sem chamada a provedor. Veja Resultados de Verificação Simulados.
Qual usar:
| Número reservado | Capturas reais | |
|---|---|---|
| Serve para | Provar que seu código trata cada resultado | Provar que o pipeline se comporta com documentos que você realmente possui |
| Precisa de | Um prefill que descreva uma pessoa | Uma câmera, ou imagens que você possa enviar |
| Determinismo | Exato — o mesmo valor sempre produz as mesmas linhas | Análise real; uma captura limítrofe pode cair para qualquer lado |
| Cobre | Os oito resultados catalogados | Tudo, inclusive combinações que o catálogo não nomeia |
Todo resultado carrega um campo
provider:
Valor Significado "inyo"Uma análise real produziu este resultado "inyo-simulated"Um número de documento reservado o ditou
"inyo-simulated"nunca aparece em produção.
Resultados de Verificação Simulados
Envie um número reservado em prefill.documentNumber e a sessão é finalizada na criação com um resultado completo. Cada valor nomeia um cenário: uma linha de base limpa, ou essa mesma linha com uma checagem desviando.
capture_exhausted é a exceção às duas metades dessa frase — veja a linha dele abaixo.
curl --request POST \
--url https://{FQDN}/v1/sessions \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"userRef": "user-123",
"prefill": {
"firstName": "Ada", "lastName": "Lovelace", "dateOfBirth": "1990-04-17",
"documentType": "drivers_license", "documentNumber": "99900104",
"issuingCountry": "USA", "issuingState": "PA"
}
}'
A resposta já vem com "status": "completed", e document_authentic falhou.
O catálogo
Cada tipo alcança os oito cenários. Envie o número com o documentType e a jurisdição indicados — um valor reservado é reconhecido por esse par exato.
Envie
issuingCountry: "USA". Um valor de passaporte ou de carteira de identidade só é reconhecido quando o país é informado, e nada avisa quando ele falta: o número é tratado como um número comum, a sessão fica pendente e espera por uma captura que nunca chega. Uma carteira de motorista também é reconhecida só peloissuingState, mas envie os dois.
| Cenário | A checagem em que desvia | drivers_license USA/PA | identity_card USA | passport USA |
|---|---|---|---|---|
clean | — tudo passa | 99900101 | 99900201 | 999003001 |
document_expired | document_not_expired | 99900102 | 99900202 | 999003002 |
document_unreadable | document_readable | 99900103 | 99900203 | 999003003 |
document_not_authentic | document_authentic | 99900104 | 99900204 | 999003004 |
portrait_mismatch | face_match | 99900105 | 99900205 | 999003005 |
screen_recapture | document_scene_clear | 99900106 | 99900206 | 999003006 |
sanctions_hit | sanctions_clear | 99900107 | 99900207 | 999003007 |
capture_exhausted | capture_attempts, e as checagens que a captura abandonada nunca alcançou | 99900108 | 99900208 | 999003008 |
capture_exhausted modela um portador que esgotou as tentativas, então é o único cenário que não desvia uma única checagem: a captura não rendeu nada, toda checagem que dependia dela fica não avaliada, e a sessão termina failed em vez de completed, sem decisão alguma.
O nome do cenário é o mesmo token que a sessão registra e pelo qual o console operacional filtra — um só vocabulário para você, seu gerente de conta e o analista que revisa a sessão.
Um desvio é uma checagem, não uma decisão. O que cada valor fixa é qual checagem falha; a decisão decorre da pontuação e do modo de decisionamento do seu tenant, e sob decisionamento não gerenciado não existe campo decision algum. Leia o resultado em vez de presumir o alvo.
O que uma sessão simulada faz de diferente
| Finalizada na criação | A resposta já traz o status terminal. A URL do widget continua sendo retornada para que sua integração não mude, mas o link de captura é inerte — uma captura enviada contra ele é recusada |
| Servidor a servidor | POST /v1/verifications responde com o identificador como qualquer outra chamada, e o resultado simulado é lido em GET /v1/verifications/{verificationId} ou enviado ao seu webhook — então uma execução no sandbox ensaia o formato inteiro, entrega incluída. Ele ainda exige frontImage — a imagem é lida para a impressão digital da requisição e descartada, nunca analisada. Dois cenários são recusados ali: capture_exhausted, porque uma porta que já tem todas as capturas não tem orçamento de retentativas a esgotar, e portrait_mismatch a menos que você também envie selfieImage |
| Atraso do webhook | No caminho de sessão o webhook é levemente atrasado, para que não chegue antes do seu próprio registro da sessão existir |
Marcada pelo provider | O resultado reporta provider: "inyo-simulated" — na resposta da API e no corpo do webhook, que não tem cabeçalhos para carregar um marcador. X-Inyo-Simulated: true é um cabeçalho de resposta apenas do validador de número de documento, não das respostas de sessão ou de verificação |
Duas recusas que você vai encontrar
Ambas são 422 na criação da sessão, e ambas são deliberadas — um resultado ditado que sua conta não poderia ter produzido ensinaria seu código a esperar um estado que ele nunca verá em produção.
| Causa | O que fazer |
|---|---|
Falta prefill.firstName, prefill.lastName ou prefill.dateOfBirth | Um resultado ditado afirma que o documento foi lido, e um documento legível produz uma pessoa. Envie os três |
O cenário desvia em uma checagem que sua conta não habilitou — por exemplo sanctions_hit sem triagem de sanções | Use um cenário que sua configuração consiga produzir, ou peça ao seu contato na Inyo para habilitar a checagem |
Apenas sandbox. Esses valores são armados por ambiente. Se um deles retornar um veredito comum e a sessão ficar aguardando uma captura, peça ao seu contato na Inyo para habilitar a simulação no seu tenant de sandbox.
Não são um fixture para sua suíte automatizada. Use-os enquanto constrói e comprova uma integração — manualmente, ou em um teste que você roda deliberadamente. Para uma suíte que roda a cada commit, capture um desses resultados uma vez e reproduza-o a partir do seu próprio mock em vez de nos chamar: seus testes ficam rápidos, continuam verdes quando nosso sandbox está fora do ar, e não dependem de um ambiente compartilhado que você não controla.
O Validador de Número de Documento
Uma superfície separada do catálogo acima: ele verifica o formato de um número declarado e nunca olha uma imagem nem executa uma verificação. Use-o quando precisar de um veredito valid, não de um resultado.
curl --request POST \
--url https://{FQDN}/v1/validators/document-number \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{"documentType": "drivers_license", "number": "not-a-number", "issuingCountry": "USA", "issuingState": "PA"}'
{
"documentType": "drivers_license",
"issuingCountry": "USA",
"issuingState": "PA",
"valid": false,
"rule": "drivers_license:USA:PA",
"detail": "document number does not match the PA license format"
}
Use-o para confirmar seu tratamento dos três estados — true, false e null para uma jurisdição desconhecida. Veja Validador de Número de Documento.
Números de Documento de Teste Reservados
Estes respondem apenas à checagem de formato do número do documento. Não são os valores que ditam uma sessão — esses estão em Resultados de Verificação Simulados. Todo valor listado nesta página que não esteja naquele catálogo responde somente ao validador.
A checagem de formato do número do documento aceita um pequeno conjunto de valores reservados que retornam o veredito escolhido sob demanda. Use-os quando precisar de um resultado valid específico — mais comumente a partir da criação de remetente de remessas, que executa essa checagem em todo documento declarado — sem antes ter de aprender o formato real de numeração de uma jurisdição.
Somente no sandbox. Esses valores são habilitados por ambiente; se os valores abaixo retornarem um veredito comum, peça ao seu contato Inyo para habilitá-los no seu tenant de sandbox.
Todo tipo capturável publica os três estados de valid, então você pode exercitar seu próprio tratamento por tipo sem precisar aprender o formato real de numeração de uma jurisdição. ssn e itin trazem apenas um valor de aprovação — veja abaixo.
documentType | issuingCountry | issuingState | number | valid |
|---|---|---|---|---|
drivers_license | USA | PA | 99900001 | true |
drivers_license | USA | PA | 99900002 | false |
drivers_license | USA | PA | 99900003 | null |
drivers_license | BRA | — | 99900000070 | true |
drivers_license | BRA | — | 99900000188 | false |
drivers_license | BRA | — | 99900000296 | null |
passport | USA | — | 999000001 | true |
passport | USA | — | 999000002 | false |
passport | USA | — | 999000003 | null |
identity_card | MEX | — | XXXX000101HXXXXX01 | true |
identity_card | MEX | — | XXXX000101HXXXXX02 | false |
identity_card | MEX | — | XXXX000101HXXXXX03 | null |
ssn | USA | — | 078051120 | true |
itin | USA | — | 912891234 | true |
As linhas de identity_card são mexicanas porque não existe regra para carteiras de identidade dos EUA — um valor americano seria um caso de teste para uma verificação que não existe. A CURP codifica o nome e a data de nascimento do titular, então o campo de nome todo em X é estruturalmente válido e não pode colidir com uma pessoa real.
Pelo mesmo motivo, os valores de cenário de identity_card dos EUA no catálogo acima retornam valid: null em vez de true: uma carteira de identidade dos EUA não tem regra de formato, então document_number_valid fica genuinamente não avaliada para ela — armada ou não. Todo outro valor de cenário retorna o veredito que a regra real da sua jurisdição lhe dá.
Envie cada número com o issuingCountry e o issuingState indicados. Um valor reservado é reconhecido por esse par exato, portanto o mesmo número em qualquer outra jurisdição é validado pelas regras comuns.
curl --request POST \
--url https://{FQDN}/v1/validators/document-number \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{"documentType": "drivers_license", "number": "99900002", "issuingCountry": "USA", "issuingState": "PA"}'
{
"documentType": "drivers_license",
"issuingCountry": "USA",
"issuingState": "PA",
"valid": false,
"rule": "reserved:drivers_license:PA:invalid",
"detail": "reserved sandbox test value — simulated invalid verdict"
}
Um resultado simulado carrega o cabeçalho de resposta X-Inyo-Simulated: true. Ele está presente apenas quando um valor reservado produziu o resultado, e ausente caso contrário — inclusive em produção, onde nunca aparece.
Os valores reservados são números reais e válidos no formato da sua jurisdição. Isso é deliberado: significa que uma regra de formato anterior — como a que a criação de remetente de remessas aplica antes de chamar essa checagem — deixa o valor passar em vez de rejeitá-lo antes, o que é justamente o que permite que
99900002chegue até nós e volte comofalse.A consequência é que onde os valores reservados não estão habilitados, eles retornam o veredito que as regras reais de formato lhes dão —
valid: truepara todos os valores, exceto o ITIN, que retornafalse, e os valores de carteira de identidade dos EUA, que retornamnullporque não existe regra de formato para eles. Um valor reservado nunca produz um resultado mais restritivo do que um número comum produziria, então deixar um no código não é um risco de segurança — mas ele deixa silenciosamente de simular, portanto não leve nenhum para produção.
912891234é o único valor que retornafalsecom a simulação desligada. Não existe um espécime de ITIN anulado como078-05-1120é para SSNs, então ele vem de um grupo que o IRS reserva para outros programas — a única forma de garantir que nunca pertencerá a uma pessoa real. O custo é que uma regra de formato anterior mais estrita pode rejeitá-lo antes que ele chegue a essa checagem. Se isso acontecer do seu lado, use-o diretamente contra este endpoint em vez de passar por um chamador que pré-valida.
Testando a Entrega de Resultados
A entrega vale a pena ser testada por si só, independentemente dos resultados de verificação:
- Verificação de assinatura — capture um corpo real de webhook do sandbox e sua
X-Inyo-Signature, e faça um teste unitário do seu verificador contra esses bytes exatos. Adicione um caso que altera um byte do corpo e afirma a rejeição, e um caso que re-serializa o JSON parseado e afirma a rejeição. Esses dois casos capturam o erro que quebra a maioria das integrações. Depois adicione três que capturam os que você só vai encontrar mais tarde: umt=vencido, fora da sua tolerância; um cabeçalho carregando umv2=extra que seu código não implementa (ele ainda deve validar nov1); e um cabeçalho repetindov1=duas vezes (ele deve ser rejeitado de imediato, não resolvido escolhendo um dos dois). - Comportamento de retry — retorne
500do seu endpoint e confirme que você vê até três tentativas, e depois nada. - Ordenação — reproduza duas notificações armazenadas de uma sessão fora de ordem e afirme que seu handler mantém a que tem o
notifiedAtmais alto. - Idempotência — entregue o mesmo resultado duas vezes e afirme que seu sistema não o processa em duplicidade.
Os passos 1, 3 e 4 não precisam de nenhuma chamada ao sandbox depois que você capturou um payload real.
Antes de Entrar em Produção
| Verificação | Por quê |
|---|---|
| A verificação de assinatura roda contra bytes brutos | A falha de produção mais comum |
Resultados concorrentes são resolvidos por notifiedAt | As entregas podem chegar fora de ordem |
| Um resultado concluído pode ser revertido | Overrides de controle de qualidade reentregam um resultado alterado |
502 faz retry em vez de recusar | É uma falha de infraestrutura, não um resultado do cliente |
| As credenciais de produção estão separadas e a URL base foi trocada | Tokens de sandbox não são válidos em produção |
| Nenhum número de documento reservado alcança caminhos de produção | Eles deixam de ditar fora do sandbox, então um esquecido falha silenciosamente em vez de ruidosamente |
Próximos Passos
- Primeiros Passos — o passo a passo de ponta a ponta
- Recebendo Resultados — assinaturas, retries e ordenação
