---
title: "Criar sessão de confiança"
method: POST
path: "/v1/trust-sessions"
tags: ["TrustSessions"]
---

# Criar sessão de confiança

`POST /v1/trust-sessions`

## Request

- Base URL: `https://api.signdocs.com.br`
- URL: `https://api.signdocs.com.br/v1/trust-sessions`
- Auth: HTTP bearer

Cria uma Sessão de Confiança — autenticação verificável sem necessidade de documento.
Cria atomicamente transação (com `purpose=ACTION_AUTHENTICATION`), etapas e token de embed.
Retorna sessionId, url e clientSecret. O link entregue ao usuário final é
`{url}?cs={clientSecret}` — a `url` sozinha não abre.

Diferenças em relação a `/v1/signing-sessions`:
- `action` (tipo + descrição) é **obrigatório** e descreve a ação sendo autenticada
- `document` **não é aceito** — para fluxos com documento, use `/v1/signing-sessions`
- O `purpose` é fixado em `ACTION_AUTHENTICATION` (não precisa ser informado)
- O pacote de evidências retorna `document: null` e `action` preenchido

Requer scope `transactions:write` e a flag `featureFlags.trustSessionsEnabled` no tenant.
A cota consumida é `monthlyTrustSessions` + `dailyTrustSessions`; as etapas (OTP, biometria,
SERPRO, ICP-Brasil) continuam descontando das mesmas dimensões por-etapa já existentes.

## Headers

- `X-Idempotency-Key` string, uuid

## Request body

- CreateTrustSessionRequest: Requisição para criar uma Sessão de Confiança. Espelha `CreateSigningSessionRequest` com duas diferenças importantes: - `action` é **obrigatório** (descreve a ação sendo autenticada) - `document` **não é aceito** (rejeitado com 400 BadRequest) O `purpose` é fixado em `ACTION_AUTHENTICATION` pelo backend — se enviado, deve coincidir.
  - `action` ActionMetadata, required: Metadados da ação autenticada (para `ACTION_AUTHENTICATION`).
    - `type` string, required: Tipo da ação.
    - `description` string, required: Descrição da ação.
    - `reference` string: Referência externa da ação.
  - `policy` Policy, required: Política de verificação de identidade da transação.
    - `profile` 'CLICK_ONLY' | 'CLICK_PLUS_OTP' | 'BIOMETRIC' | 'BIOMETRIC_PLUS_OTP' | 'DIGITAL_CERTIFICATE' | 'BIOMETRIC_SERPRO' | 'BIOMETRIC_SERPRO_AUTO_FALLBACK' | 'BIOMETRIC_DOCUMENT_FALLBACK' | 'CUSTOM', required: Perfis de política de verificação pré-definidos. Cada perfil resolve para uma lista ordenada de etapas (`StepType`): - `CLICK_ONLY`: CLICK_ACCEPT - `CLICK_PLUS_OTP`: CLICK_ACCEPT, OTP_CHALLENGE, OTP_VERIFY - `BIOMETRIC`: BIOMETRIC_LIVENESS, BIOMETRIC_MATCH - `BIOMETRIC_PLUS_OTP`: BIOMETRIC_LIVENESS, BIOMETRIC_MATCH, OTP_CHALLENGE, OTP_VERIFY - `DIGITAL_CERTIFICATE`: CLICK_ACCEPT, DIGITAL_SIGN_A1 - `BIOMETRIC_SERPRO`: BIOMETRIC_LIVENESS, BIOMETRIC_MATCH, SERPRO_IDENTITY_CHECK - `BIOMETRIC_SERPRO_AUTO_FALLBACK`: as mesmas etapas de `BIOMETRIC_SERPRO`, mais uma etapa DOCUMENT_PHOTO_MATCH criada em estado `DORMANT`. Se a base governamental estiver indisponível, a etapa SERPRO passa a `SKIPPED` e a dormente é ativada, sem derrubar a assinatura em andamento. - `BIOMETRIC_DOCUMENT_FALLBACK`: BIOMETRIC_LIVENESS, DOCUMENT_PHOTO_MATCH — para signatários sem cadastro biométrico prévio, comparando a prova de vida com a foto de um documento oficial. - `CUSTOM`: etapas definidas em `policy.customSteps`. `BIOMETRIC`, `BIOMETRIC_PLUS_OTP`, `BIOMETRIC_SERPRO`, `BIOMETRIC_SERPRO_AUTO_FALLBACK` e `BIOMETRIC_DOCUMENT_FALLBACK` exigem cota biométrica provisionada para o tenant.
    - `customSteps` StepType[]: Etapas customizadas (apenas quando `profile` = `CUSTOM`).
    - `minSimilarity` number, double: Limiar mínimo de similaridade facial exigido desta transação, para as etapas `BIOMETRIC_MATCH` e `DOCUMENT_PHOTO_MATCH`. **Só aperta, nunca afrouxa.** O valor precisa ser maior ou igual ao limiar configurado para o tenant; um valor abaixo dele retorna 400 informando o mínimo vigente, em vez de ser ignorado em silêncio — afrouxar a verificação de identidade é decisão do tenant, não da requisição. Documentos de maior risco podem assim exigir mais confiança que o padrão da conta, sem reconfigurar o tenant. Aceita tanto percentual (`95`) quanto fração (`0.95`).
    - `minLivenessConfidence` number, double: Limiar mínimo de confiança de vivacidade (`BIOMETRIC_LIVENESS`) exigido desta transação. Mesmo enquadramento do `minSimilarity`: só aperta, e um valor abaixo do mínimo do tenant retorna 400. Quando o tenant não define limiar de vivacidade próprio, qualquer valor válido é aceito.
  - `signer` union, required: Dados do signatário. É obrigatório informar pelo menos um entre `cpf` e `cnpj`.
    - object
      - `name` string, required: Nome completo do signatário.
      - `email` string, email: E-mail do signatário (obrigatório para etapas OTP).
      - `userExternalId` string, required: Identificador externo do usuário no sistema do integrador.
      - `displayName` string: Nome de exibição do signatário.
      - `cpf` string, required: CPF do signatário (11 dígitos, sem pontuação). Obrigatório se `cnpj` não for informado.
      - `cnpj` string: CNPJ do signatário (14 dígitos, sem pontuação). Obrigatório se `cpf` não for informado.
      - `phone` string: Telefone do signatário em formato E.164. Obrigatório quando `otpChannel` é `sms` ou `whatsapp`, ou quando `deliverVia` inclui `whatsapp`.
      - `otpChannel` 'email' | 'sms' | 'whatsapp' | 'telegram': Canal de entrega do OTP, escolhido por signatário. Independente do canal usado para entregar o link de assinatura: um convite por WhatsApp pode ter OTP por e-mail, e um convite por e-mail pode ter OTP por WhatsApp. `sms` e `whatsapp` exigem `signer.phone` e o canal habilitado para o tenant (`sms.enabled` / `whatsapp.enabled`); caso contrário o passo de OTP falha com **422**. No WhatsApp, um número que pediu para não receber mensagens também falha com 422, com uma mensagem que orienta a escolher outro canal. `telegram` exige `telegram.enabled` no tenant. O código chega pelo bot da SignDocs quando o signatário já registrou o próprio CPF nele; sem registro, é enviado por telefone (Telegram Gateway) se o tenant tiver essa opção habilitada, e caso contrário o passo falha com **422** de imediato. Ao criar a sessão, `otpChannel: telegram` ainda exige `signer.email` quando a política tem OTP. Um OTP por WhatsApp ou pelo Telegram Gateway consome a cota de mensagens do tenant; esgotada, o envio é recusado com **429**.
      - `otpChannelSelectable` boolean: Quando `true`, a tela de assinatura hospedada permite que o signatário escolha o canal (entre os de `availableOtpChannels`) que recebe o OTP no momento da assinatura e troque de canal durante o fluxo. Padrão `false` — integrações existentes mantêm um único canal fixo e o backend recusa um canal escolhido pelo signatário se este campo não estiver definido.
    - object
      - `name` string, required: Nome completo do signatário.
      - `email` string, email: E-mail do signatário (obrigatório para etapas OTP).
      - `userExternalId` string, required: Identificador externo do usuário no sistema do integrador.
      - `displayName` string: Nome de exibição do signatário.
      - `cpf` string: CPF do signatário (11 dígitos, sem pontuação). Obrigatório se `cnpj` não for informado.
      - `cnpj` string, required: CNPJ do signatário (14 dígitos, sem pontuação). Obrigatório se `cpf` não for informado.
      - `phone` string: Telefone do signatário em formato E.164. Obrigatório quando `otpChannel` é `sms` ou `whatsapp`, ou quando `deliverVia` inclui `whatsapp`.
      - `otpChannel` 'email' | 'sms' | 'whatsapp' | 'telegram': Canal de entrega do OTP, escolhido por signatário. Independente do canal usado para entregar o link de assinatura: um convite por WhatsApp pode ter OTP por e-mail, e um convite por e-mail pode ter OTP por WhatsApp. `sms` e `whatsapp` exigem `signer.phone` e o canal habilitado para o tenant (`sms.enabled` / `whatsapp.enabled`); caso contrário o passo de OTP falha com **422**. No WhatsApp, um número que pediu para não receber mensagens também falha com 422, com uma mensagem que orienta a escolher outro canal. `telegram` exige `telegram.enabled` no tenant. O código chega pelo bot da SignDocs quando o signatário já registrou o próprio CPF nele; sem registro, é enviado por telefone (Telegram Gateway) se o tenant tiver essa opção habilitada, e caso contrário o passo falha com **422** de imediato. Ao criar a sessão, `otpChannel: telegram` ainda exige `signer.email` quando a política tem OTP. Um OTP por WhatsApp ou pelo Telegram Gateway consome a cota de mensagens do tenant; esgotada, o envio é recusado com **429**.
      - `otpChannelSelectable` boolean: Quando `true`, a tela de assinatura hospedada permite que o signatário escolha o canal (entre os de `availableOtpChannels`) que recebe o OTP no momento da assinatura e troque de canal durante o fluxo. Padrão `false` — integrações existentes mantêm um único canal fixo e o backend recusa um canal escolhido pelo signatário se este campo não estiver definido.
  - `returnUrl` string, uri: URL de retorno após conclusão. O `session_id` será adicionado como query parameter.
  - `cancelUrl` string, uri: URL de retorno em caso de cancelamento pelo usuário.
  - `metadata` object: Metadados livres (chave-valor). Chaves até 256 chars, valores até 1024 chars.
  - `locale` 'pt-BR' | 'en' | 'es': Idioma da página de autenticação hospedada.
  - `expiresInMinutes` integer: Tempo de expiração em minutos (5 a 1440). Padrão 60.
  - `appearance` SigningSessionAppearance: Configuração visual da página de assinatura hospedada.
    - `brandColor` string: Cor primária da marca (hex).
    - `logoUrl` string, uri: URL HTTPS do logotipo da empresa.
    - `companyName` string: Nome da empresa exibido na página.
    - `backgroundColor` string: Cor de fundo (hex).
    - `textColor` string: Cor do texto (hex).
    - `buttonTextColor` string: Cor do texto dos botões (hex).
    - `borderRadius` string: Raio de borda dos elementos (formato "Npx").
    - `headerStyle` 'full' | 'minimal' | 'none': Estilo do cabeçalho da página.
    - `fontFamily` 'system-ui' | 'Inter' | 'Roboto' | 'Open Sans' | 'Lato' | 'Montserrat' | 'Source Sans Pro' | 'Nunito' | 'Poppins' | 'Raleway' | 'Ubuntu': Família tipográfica.
  - `owner` Owner: Identidade do solicitante da assinatura (quem cria a sessão/envelope), distinta do signatário. Quando informado, a SignDocs: 1. **Envia automaticamente um e-mail de convite** para `signer.email` no momento da criação da sessão, se `signer.email` for diferente de `owner.email` (case-insensitive). Em envelopes, cada signatário recebe seu próprio convite. 2. **Notifica o solicitante por e-mail** quando cada signatário concluir a assinatura, com o protocolo de evidência e link para o verificador. Omitir `owner` mantém o comportamento padrão: o integrador entrega a URL de assinatura por seus próprios canais e usa webhooks para acompanhar o status.
    - `email` string, email: E-mail do solicitante. Recebe notificações de conclusão.
    - `name` string: Nome do solicitante (usado na saudação dos e-mails).
  - `deliverVia` string[]: Canais pelos quais a SignDocs entrega o link da sessão ao signatário. Mesmas regras e respostas de `deliverVia` em `CreateSigningSessionRequest`: omita para manter apenas o e-mail de convite; `whatsapp` e `telegram` são habilitados sob demanda (403 se o tenant não tem o canal), consomem a cota de mensagens (429) e respeitam o kill switch (503).

## Response `201`

Sessão de confiança criada com sucesso.

- CreateTrustSessionResponse: Resposta da criação de Sessão de Confiança.
  - `sessionId` string, required: Identificador único da sessão de confiança.
  - `transactionId` string, required: Identificador da transação subjacente.
  - `status` 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED' | 'FAILED', required: Status da sessão de assinatura.
  - `url` string, uri, required: Endereço da página de autenticação hospedada (mesmo domínio `sign.signdocs.com.br` usado pela Assinatura Expressa — o widget detecta automaticamente o `purpose` e ajusta o título, esconde a visualização do PDF e exibe a etiqueta "Sessão de Confiança"). **Não é um link utilizável sozinho**: o `clientSecret` é a autenticação da sessão e precisa viajar na query string. O link entregue ao usuário final é `{url}?cs={clientSecret}`, com o `clientSecret` URL-encoded. Sem o parâmetro `cs` a página abre em tela de erro. No navegador o SDK JS deriva a URL do próprio `clientSecret` (`sd.checkout()` abre em popup, `sd.redirect()` redireciona).
  - `clientSecret` string, required: Token de sessão para autenticação no widget/redirect. Formato `ss_secret_` + JWT.
  - `expiresAt` string, date-time, required: Data/hora de expiração da sessão (ISO 8601 UTC).
  - `createdAt` string, date-time, required: Data/hora de criação (ISO 8601 UTC).
  - `inviteSent` boolean: Verdadeiro quando a SignDocs enviou um e-mail de convite para `signer.email` no momento da criação. Só é populado quando `owner` foi informado e `signer.email` é diferente de `owner.email` (case-insensitive).

## Other responses

- `400`: Requisição inválida — parâmetros ausentes ou malformados.
- `401`: Autenticação ausente ou inválida.
- `403`: Permissões insuficientes para a operação solicitada. Inclui `purpose: "ACTION_AUTHENTICATION"` sem `featureFlags.trustSessionsEnabled`. A verificação é pelo `purpose`, não pela rota: vale em `/v1/transactions`, `/v1/signing-sessions` e `/v1/envelopes/{envelopeId}/sessions`, além de `/v1/trust-sessions`. O remédio é habilitar a flag para o tenant e provisionar a cota `monthlyTrustSessions`.
- `409`: Conflito de estado — a operação não pode ser realizada no estado atual do recurso.
- `422`: Entidade não processável — a requisição é sintaticamente válida mas semanticamente incorreta. Inclui o perfil de política não autorizado para o tenant. As rotas de criação (`/v1/transactions`, `/v1/signing-sessions` e `/v1/envelopes/{envelopeId}/sessions`) verificam a mesma regra, antes de cota, convite e gravação — a recusa não consome documento. As flags envolvidas são `featureFlags.customPolicyEnabled` (perfil `CUSTOM`), `serpro.enabled` (perfis SERPRO), `featureFlags.documentExtractionEnabled` (fallback por documento; `BIOMETRIC_SERPRO_AUTO_FALLBACK` exige as duas últimas) e `featureFlags.biometricRequired`. O remédio é habilitar a flag para o tenant. `signer.cpf` e `signer.birthDate`, exigidos pelos perfis SERPRO, são validados como **400** e não aqui: requisição malformada, corrigível na mesma chamada.
- `429`: Limite de requisições excedido.
- `500`: Erro interno do servidor.
- `503`: Serviço temporariamente indisponível.

---

[API](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api.md) · [All operations](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api/llms.txt) · [OpenAPI document](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api/revisions/2d3805aed161?raw)
