---
title: "Adicionar sessão de signatário ao envelope"
method: POST
path: "/v1/envelopes/{envelopeId}/sessions"
tags: ["Envelopes"]
---

# Adicionar sessão de signatário ao envelope

`POST /v1/envelopes/{envelopeId}/sessions`

## Request

- Base URL: `https://api.signdocs.com.br`
- URL: `https://api.signdocs.com.br/v1/envelopes/{envelopeId}/sessions`
- Auth: HTTP bearer

Adiciona uma sessão de assinatura para um signatário no envelope. Retorna a URL
e clientSecret para integração. O link entregue àquele signatário é
`{url}?cs={clientSecret}` — a `url` sozinha não abre.

Suporta idempotência via header `X-Idempotency-Key`. Use uma chave
**distinta por signatário** (o corpo muda a cada `signerIndex`): reenviar
a mesma chave devolve a resposta original, incluindo o `clientSecret` —
que só é retornado nesta resposta e não pode ser recuperado depois.

Requer scope `transactions:write`.

## Path parameters

- `envelopeId` string, required

## Headers

- `X-Idempotency-Key` string, uuid

## Request body

- AddEnvelopeSessionRequest: Requisição para adicionar uma sessão de signatário ao envelope.
  - `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.
      - `userExternalId` string, required: Identificador externo do usuário no sistema do integrador.
      - `cpf` string, required: CPF do signatário (11 dígitos, sem pontuação).
      - `cnpj` string: CNPJ do signatário (14 dígitos, sem pontuação).
      - `email` string, email: E-mail do signatário (obrigatório para etapas OTP).
      - `phone` string: Telefone do signatário em formato E.164.
      - `birthDate` string, date: Data de nascimento do signatário (YYYY-MM-DD).
      - `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**.
    - object
      - `name` string, required: Nome completo do signatário.
      - `userExternalId` string, required: Identificador externo do usuário no sistema do integrador.
      - `cpf` string: CPF do signatário (11 dígitos, sem pontuação).
      - `cnpj` string, required: CNPJ do signatário (14 dígitos, sem pontuação).
      - `email` string, email: E-mail do signatário (obrigatório para etapas OTP).
      - `phone` string: Telefone do signatário em formato E.164.
      - `birthDate` string, date: Data de nascimento do signatário (YYYY-MM-DD).
      - `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**.
  - `policy` object, required: Política de verificação de identidade da sessão.
    - `profile` string, required: Perfil de verificação de identidade.
  - `purpose` 'DOCUMENT_SIGNATURE' | 'ACTION_AUTHENTICATION': Finalidade da sessão.
  - `signerIndex` integer, required: Índice do signatário no envelope (mínimo 1). Define a ordem em modo SEQUENTIAL.
  - `returnUrl` string, uri: URL de retorno após conclusão desta sessão. Sobrescreve a URL do envelope.
  - `cancelUrl` string, uri: URL de retorno em caso de cancelamento. Sobrescreve a URL do envelope.
  - `metadata` object: Metadados livres específicos desta sessão.
  - `deliverVia` string[]: Canais pelos quais a SignDocs entrega o link de assinatura a este signatário; cada signatário escolhe os seus. Omita para manter o comportamento anterior: apenas o e-mail de convite. Num envelope `SEQUENTIAL`, o signatário posterior não recebe link antes da sua vez; quando ela chega, recebe pelos canais escolhidos aqui. O envio é admitido nesta chamada, com a verificação de cota, porque depois não há a quem devolver um 429. Provisionamento e kill switch são conferidos de novo no momento do envio. Se nenhum canal pedido conseguir entregar, o signatário recebe o convite por e-mail quando tem endereço e o envelope tem `owner`. WhatsApp e Telegram são habilitados **sob demanda**: o tenant pede ao time comercial, e não é algo que se liga pelo painel. Pedir um canal que o tenant não tem retorna **403** antes de qualquer gravação. `whatsapp` exige `signer.phone` em E.164. `whatsappInviteSent: true` significa que a Meta **aceitou** a mensagem, não que ela foi entregue ou lida; em qualquer outro caso o campo é omitido da resposta. Se a Meta reportar falha depois e o signatário tiver e-mail, a SignDocs reenvia o convite por e-mail automaticamente, com um link novo, diferente do que veio nesta resposta; nenhum webhook, campo ou endpoint informa esse reenvio. Um número que respondeu "parar", "sair" ou "stop" deixa de receber mensagens da SignDocs por WhatsApp. `telegram` exige `signer.cpf` e só alcança signatários que já registraram o próprio CPF no bot da SignDocs. `telegramInviteSent` vem na resposta sempre que o convite por Telegram é tentado nesta chamada, `false` quando não chegou. Cada envio por WhatsApp ou Telegram consome a cota de mensagens do tenant. Esgotada a cota, a requisição é recusada com **429** antes de qualquer gravação; com o canal suspenso por kill switch, com **503**. Credenciais de sandbox também enviam mensagens reais por WhatsApp e consomem a cota de mensagens de sandbox.

## Response `201`

Sessão de signatário adicionada com sucesso.

- AddEnvelopeSessionResponse: Resposta da adição de sessão de signatário ao envelope.
  - `sessionId` string, required: Identificador único da sessão.
  - `transactionId` string, required: Identificador da transação subjacente.
  - `signerIndex` integer, required: Índice do signatário no envelope.
  - `status` 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED' | 'FAILED', required: Status da sessão de assinatura.
  - `url` string, uri, required: Endereço da página de assinatura hospedada. **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 signatário é `{url}?cs={clientSecret}`, com o `clientSecret` URL-encoded. Sem o parâmetro `cs` a página abre em tela de erro. No navegador não é preciso montar nada — 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).
  - `inviteSent` boolean: Verdadeiro quando a SignDocs enviou um e-mail de convite para `signer.email`. Só é populado quando o envelope foi criado com `owner` e `signer.email` é diferente de `owner.email` (case-insensitive).
  - `whatsappInviteSent` boolean: `true` quando a Meta aceitou a mensagem com o link para `signer.phone`. Aceitar não é entregar: a entrega é confirmada depois, por webhook da Meta, e não é exposta pela API. Omitido em qualquer outro caso (número que pediu para não receber mensagens, falha no envio) e só considerado quando `deliverVia` incluiu `whatsapp`.
  - `telegramInviteSent` boolean: Resultado da entrega por Telegram. `false` significa que o signatário não tem CPF registrado no bot, ou que o envio falhou — em ambos os casos o link não chegou por esse canal. Só é populado quando `deliverVia` incluiu `telegram`.

## 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`.
- `404`: Recurso não encontrado.
- `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)
