Guias de Desenvolvimento

Política e Conformidade

Signing Sessions

Sessão de Confiança

Modelos de Solução

Guias dos SDKs

Sessão de Confiança — Guia de Visão Geral

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.

Todas as 7 rotas (POST/GET /v1/trust-sessions + GET /v1/trust-sessions/{id} + POST /{id}/advance + GET /{id}/status + POST /{id}/cancel + POST /{id}/resend-otp) estão disponíveis em HML. As rotas de Sessão de Confiança e Assinatura Expressa compartilham os mesmos handlers internos; o mesmo sessionId resolve em ambas as famílias de URL.

Sumário

  1. Visão Geral
  2. Comparação com Assinatura Expressa
  3. Criar Sessão
  4. Página Hospedada
  5. Polling e Webhook
  6. Pacote de Evidências
  7. Cotas e Feature Flag
  8. Fluxo Completo (Script)

Convenções

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

1. Visão Geral

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)   │                                   │
       │<─────────────────────────────────│                                   │

2. Comparação com Assinatura Expressa

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.


3. Criar Sessão

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.


4. Página Hospedada

Quando o usuário abre a URL, a página hospedada:

  1. Exibe a badge "Sessão de Confiança" no topo (diferencia visualmente de uma assinatura de documento).
  2. Não renderiza preview de PDF — pula direto para a confirmação do signatário.
  3. Mostra a action.description em destaque ("Você está prestes a confirmar: Aprovar liberação do empréstimo consignado…").
  4. Conduz as etapas configuradas pela policy.profile (OTP, biometria facial, SERPRO, etc.).
  5. Ao concluir, gera o pacote de evidências e redireciona para o returnUrl.

O domínio é o mesmo da Assinatura Expressa (sign.signdocs.com.br) — não é necessário whitelist adicional no seu firewall.


5. Polling e Webhook

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.


6. Pacote de Evidências

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.


7. Cotas e Feature Flag

A criação de Sessão de Confiança requer:

  1. Feature flag ativa. featureFlags.trustSessionsEnabled = true no TENANT_CONFIG. Se desativada, a API retorna 403 Forbidden com type: "feature-not-enabled". Solicite ao seu CS.
  2. Cota disponível. A criação decrementa monthlyTrustSessions + dailyTrustSessions. Quando atingido, a API retorna 429 Too Many Requests com headers RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.
  3. Cotas por etapa. As etapas de OTP, biometria, SERPRO e ICP-Brasil continuam decrementando suas próprias dimensões (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).


8. Fluxo Completo (Script)

#!/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 .

Próximos passos