Autentique uma ação digital sem precisar de um documento. A Sessão de Confiança usa a mesma máquina de estado, mesma página hospedada e mesmo pacote de evidências da Assinatura Expressa — mas com purpose=ACTION_AUTHENTICATION no lugar de um PDF.
Procurando assinar um documento PDF? Você está no lugar errado — use o Quickstart: Assinar documento (Assinatura Expressa). Esta página cobre o fluxo sem documento.
Quando usar Sessão de Confiança: KYC, reverificação periódica, aprovação de transação, consentimento de teleconsulta, aceite de termos com biometria, autorização de operações em ERP/CRM, liberação de escrow, validação de profissional habilitado (advogado, contador, médico).
Procurando exemplos prontos? Veja Receitas de Sessão de Confiança.
| Item | Valor |
|---|---|
| Base URL (HML) | https://api-hml.signdocs.com.br |
| Base URL (Prod) | https://api.signdocs.com.br |
| Domínio Hospedado (HML) | https://sign-hml.signdocs.com.br |
| Domínio Hospedado (Prod) | https://sign.signdocs.com.br |
| Autenticação | OAuth2 client_credentials — Bearer JWT |
| Feature flag | featureFlags.trustSessionsEnabled no tenant (provisione com seu Customer Success) |
| Dimensão de cota | monthlyTrustSessions + dailyTrustSessions (consulte com seu CS) |
| Cotas de etapa | monthlyOtp, monthlyBiometric, monthlySerproIdentity continuam descontando da mesma forma |
A Sessão de Confiança encapsula um fluxo de autenticação verificável em uma única chamada de API. O usuário final é redirecionado para uma página hospedada pelo SignDocs Brasil que coleta as evidências de identidade (OTP, biometria, certificado ICP-Brasil) e gera um pacote de evidências assinado criptograficamente.
A diferença essencial em relação à Assinatura Expressa: não há documento. A "coisa sendo autenticada" é descrita no campo action (type + description) e fica registrada no pacote de evidências.
┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Seu Server │ │ SignDocs API │ │ Página Hosted │
└──────┬───────┘ └────────┬─────────┘ └────────┬────────┘
│ │ │
│ POST /v1/trust-sessions │ │
│ { action, signer, policy } │ │
│─────────────────────────────────>│ │
│ │ │
│ { sessionId, url, clientSecret }│ │
│<─────────────────────────────────│ │
│ │ │
│ Envia url+clientSecret ao usuário│ │
│ (email/SMS/WhatsApp/redirect) │ │
│ │ │
│ │ Usuário abre página │
│ │<──────────────────────────────────│
│ │ Coleta OTP/biometria/cert │
│ │ (badge "Sessão de Confiança" │
│ │ exibida no topo) │
│ │ │
│ │ Gera Evidence Pack │
│ │ (document: null, action: {...}) │
│ │ │
│ Webhook trust-session.completed │ │
│<─────────────────────────────────│ │
│ │ │
│ GET /v1/trust-sessions/{id}/ │ │
│ evidence │ │
│─────────────────────────────────>│ │
│ Evidence Pack assinado (.p7m) │ │
│<─────────────────────────────────│ │
| Aspecto | Assinatura Expressa | Sessão de Confiança |
|---|---|---|
| Endpoint | POST /v1/signing-sessions |
POST /v1/trust-sessions |
purpose |
DOCUMENT_SIGNATURE |
ACTION_AUTHENTICATION (fixo) |
| Documento PDF | Obrigatório (document.content) |
Não aceito (400 se enviado) |
Campo action |
Opcional | Obrigatório (type + description) |
| Página hospedada | Mostra preview do PDF + título "Assine este documento" | Esconde preview + título "Confirme sua identidade" + badge "Sessão de Confiança" |
| Evidence Pack | document: { hashAlg, hash }, action: null |
document: null, action: { type, description } |
| Cota descontada | monthlyTransactions + cotas por etapa |
monthlyTrustSessions + cotas por etapa |
| Verificador público | https://verificador.signdocs.com.br/{evidenceId} |
mesma URL, mostra a action no lugar do documento |
| Ideal para | Contratos, termos, NDAs, qualquer documento PDF | KYC, aprovação, consentimento, qualquer "ação" sem PDF |
Internamente, ambos compartilham o mesmo motor: máquina de estado de etapas (AdvanceSession), executores de OTP/biometria/SERPRO/ICP-Brasil, construtor de evidências, e a mesma página hospedada que detecta o purpose e ajusta o título e a estrutura visual.
curl -X POST https://api-hml.signdocs.com.br/v1/trust-sessions \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: 01JXYZ-uuid-aqui" \
-d '{
"action": {
"type": "approve_disbursement",
"description": "Aprovar liberação do empréstimo consignado #INSS-2026-007482 no valor de R$ 8.450,00"
},
"policy": {
"profile": "BIOMETRIC"
},
"signer": {
"name": "Maria Souza",
"cpf": "123.456.789-09",
"email": "maria.souza@example.com",
"phone": "+5511999990000",
"otpChannel": "email"
},
"returnUrl": "https://app.example.com/aprovado",
"cancelUrl": "https://app.example.com/cancelado",
"metadata": {
"internal_request_id": "INSS-2026-007482",
"branch": "SP-001"
},
"locale": "pt-BR",
"expiresInMinutes": 30
}'
Resposta 201 Created:
{
"sessionId": "01JXYZ...",
"transactionId": "01JXYZ...",
"status": "ACTIVE",
"url": "https://sign-hml.signdocs.com.br/s/01JXYZ...",
"clientSecret": "ss_secret_eyJhbGciOi...",
"expiresAt": "2026-05-08T14:30:00Z",
"createdAt": "2026-05-08T14:00:00Z"
}
A URL completa para o usuário final é url + "?cs=" + clientSecret. Você pode entregá-la por email, SMS, WhatsApp, ou redirect direto. Para uso embarcado (iframe / popup checkout) use o SDK Embed JS — veja Receitas.
Quando o usuário abre a URL, a página hospedada:
action.description em destaque ("Você está prestes a confirmar: Aprovar liberação do empréstimo consignado…").policy.profile (OTP, biometria facial, SERPRO, etc.).returnUrl.O domínio é o mesmo da Assinatura Expressa (sign.signdocs.com.br) — não é necessário whitelist adicional no seu firewall.
Polling leve (recomendado para fluxos server-side simples):
curl -X GET https://api-hml.signdocs.com.br/v1/trust-sessions/$SESSION_ID/status \
-H "Authorization: Bearer $JWT"
Resposta:
{
"sessionId": "01JXYZ...",
"transactionId": "01JXYZ...",
"status": "COMPLETED",
"completedAt": "2026-05-08T14:12:34Z",
"evidenceId": "ev_01JXYZ..."
}
Webhook (recomendado para alto volume):
Cadastre um webhook com escopo trust_session.* em POST /v1/webhooks. Eventos emitidos:
| Evento | Quando |
|---|---|
trust_session.created |
Logo após criação |
trust_session.completed |
Usuário completou todas as etapas |
trust_session.cancelled |
Sessão cancelada (pelo usuário ou via API) |
trust_session.expired |
TTL atingido sem conclusão |
trust_session.failed |
Falha definitiva em alguma etapa (ex: biometria) |
O payload inclui sessionId, transactionId, status, evidenceId e metadata.
Após COMPLETED, recupere o pacote assinado:
curl -X GET https://api-hml.signdocs.com.br/v1/trust-sessions/$SESSION_ID/evidence \
-H "Authorization: Bearer $JWT" \
-o evidence-$SESSION_ID.p7m
Ou consulte o JSON canônico via GET /v1/verify/{evidenceId} (público, sem auth). Estrutura abreviada:
{
"evidenceId": "ev_01JXYZ...",
"purpose": "ACTION_AUTHENTICATION",
"document": null,
"action": {
"type": "approve_disbursement",
"description": "Aprovar liberação do empréstimo consignado #INSS-2026-007482..."
},
"signer": { "cpf": "12345678909", "name": "Maria Souza", "email": "..." },
"steps": [
{ "type": "CLICK_ACCEPT", "status": "COMPLETED", "completedAt": "..." },
{ "type": "BIOMETRIC_LIVENESS", "status": "COMPLETED", "result": { "matchScore": 0.987 } }
],
"timestamps": { "createdAt": "...", "completedAt": "..." },
"ipAddress": "200.x.x.x",
"userAgent": "...",
"geolocation": { "lat": -23.55, "lon": -46.63 }
}
Veja Pacote de Evidências para o detalhamento completo dos campos e como apresentar isso a um juiz/regulador.
A criação de Sessão de Confiança requer:
featureFlags.trustSessionsEnabled = true no TENANT_CONFIG. Se desativada, a API retorna 403 Forbidden com type: "feature-not-enabled". Solicite ao seu CS.monthlyTrustSessions + dailyTrustSessions. Quando atingido, a API retorna 429 Too Many Requests com headers RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.monthlyOtp, monthlyBiometric, monthlySerproIdentity, monthlySigning). Uma Sessão de Confiança com perfil BIOMETRIC consome uma unidade de monthlyTrustSessions e uma unidade de monthlyBiometric.Cotas são não-reembolsáveis em cancelamento (mesma regra das monthlyTransactions).
#!/usr/bin/env bash
set -euo pipefail
API=https://api-hml.signdocs.com.br
CLIENT_ID="${SIGNDOCS_CLIENT_ID:?}"
CLIENT_SECRET="${SIGNDOCS_CLIENT_SECRET:?}"
# 1. Token
JWT=$(curl -s -X POST "$API/oauth2/token" \
-d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&scope=transactions:write transactions:read" \
| jq -r .access_token)
# 2. Criar sessão
RESP=$(curl -s -X POST "$API/v1/trust-sessions" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"action": {"type":"approve_payment","description":"Aprovar pagamento PIX de R$ 1.500,00"},
"policy": {"profile":"BIOMETRIC"},
"signer": {"name":"João","cpf":"123.456.789-09","email":"joao@example.com","otpChannel":"email"}
}')
SESSION_ID=$(echo "$RESP" | jq -r .sessionId)
URL=$(echo "$RESP" | jq -r .url)
CS=$(echo "$RESP" | jq -r .clientSecret)
echo "Envie ao usuário: ${URL}?cs=${CS}"
# 3. Polling
while true; do
STATUS=$(curl -s -X GET "$API/v1/trust-sessions/$SESSION_ID/status" \
-H "Authorization: Bearer $JWT" | jq -r .status)
echo "status=$STATUS"
[ "$STATUS" = "COMPLETED" ] && break
[ "$STATUS" = "FAILED" -o "$STATUS" = "EXPIRED" -o "$STATUS" = "CANCELLED" ] && exit 1
sleep 5
done
# 4. Recuperar pacote de evidências
EVIDENCE_ID=$(curl -s -X GET "$API/v1/trust-sessions/$SESSION_ID/status" \
-H "Authorization: Bearer $JWT" | jq -r .evidenceId)
curl -s -X GET "$API/v1/verify/$EVIDENCE_ID" | jq .