Pular para o conteúdo

Modelos, papéis e campos

Um modelo é um contrato reutilizável. Ele tem um nome, um único rascunho e qualquer número de versões publicadas. Os envelopes são sempre criados a partir de uma versão publicada, que é imutável: editar um modelo significa salvar um novo rascunho e publicá-lo como a próxima versão. Os envelopes já enviados mantêm a versão que fixaram.

GET /v1/templates/tpl_…
{
"id": "tpl_3kQ9xV2mLp",
"organization": "org_…",
"name": "Mutual NDA",
"description": "Two-party NDA, US law",
"latestVersion": 3,
"draftVersion": 4,
"createdAt": "2026-10-01T09:12:44.120Z",
"updatedAt": "2026-10-12T16:03:10.981Z"
}

Os ids são strings com prefixo (tpl_, tplv_, tfl_, env_, rcp_, ses_, lnk_, evt_, whk_, whd_, …); os carimbos de data e hora seguem a RFC 3339 em UTC.

O modo Sobreposição (source: "pdf") parte de um documento enviado. Os campos são retângulos posicionados nas páginas dele em pontos PDF (1/72 pol.), com origem no canto superior esquerdo da página e índice de página a partir de 0. Um .docx enviado é convertido em PDF uma única vez (LibreOffice, mantendo o layout do Word; fontes que o arquivo não incorpora podem ser substituídas) e, a partir daí, é um PDF como qualquer outro: o arquivo informa convertedFrom: "docx". As versões em Sobreposição também podem conter edições de conteúdo (texto editado no lugar, corretivo, caixas de texto, imagens, operações de página), aplicadas quando a versão é publicada.

O modo Documento (source: "document") armazena o próprio contrato como rich text (JSON do ProseMirror) com chips de variável como {{client.name}}, blocos de campo em linha, seções condicionais (mantidas só quando uma expressão showIf é verdadeira) e seções e linhas de tabela repetíveis (uma por item de uma variável do tipo array). Cada envelope renderiza o próprio PDF, e as posições dos campos são lidas dessa renderização. No painel, o modo Documento é “Começar com um documento em branco”. Pela API, um arquivo do Word também pode ser importado para o modo Documento com POST /v1/templates/{id}/import: as {{tags}} viram variáveis ou campos, e as linhas de assinatura (“Signature: ____”, “By: ____”, “Date: ____”) viram blocos de campo.

Novo modelo oferece dois pontos de partida:

  • Enviar documento: uma única área para soltar arquivos .pdf e .docx de até 25 MB. Os arquivos do Word são convertidos em PDF e abertos no editor com um lembrete para conferir o layout convertido antes de posicionar os campos. Pequenas correções são feitas diretamente no PDF (“Editar conteúdo”); para uma reescrita maior, altere o arquivo do Word e envie-o de novo.
  • Começar com um documento em branco: escreva o contrato no modo Documento.

O modo Editar conteúdo do editor muda o que os signatários veem sem alterar o arquivo enviado. A ferramenta padrão, Editar texto, destaca os blocos de texto da página (linhas e parágrafos agrupados a partir da camada de texto do PDF); clique em um deles, ou chegue até ele com Tab e pressione Enter, para editá-lo no lugar, com a mesma posição, tamanho, cor, alinhamento e fonte. Ctrl/Cmd+Enter salva, Esc cancela, e cada edição pode ser revertida na lista de edições. As edições podem ser desfeitas como qualquer outra alteração. As outras ferramentas adicionam corretivo, caixas de texto e imagens, e inserem, excluem, reordenam ou giram páginas.

Uma edição de texto no lugar é armazenada como dois itens que compartilham um group: um corretivo sobre o bloco original (na cor de fundo da página) e um item de texto diagramado dentro do bloco, com a altura de linha e a primeira linha de base do bloco:

edits.items (excerpt)
[
{ "id": "whiteout_k2", "kind": "whiteout", "group": "blk_k1", "page": 0, "color": "#FFFFFF",
"rect": { "x": 71, "y": 209.9, "width": 452, "height": 26.9 } },
{ "id": "text_k3", "kind": "text", "group": "blk_k1", "page": 0, "rect": { "x": 72, "y": 210.9, "width": 451, "height": 24.9 },
"text": "1. Purpose. The Parties wish to evaluate a joint venture…", "original": "1. Purpose. The Parties wish to evaluate a possible business relationship…",
"size": 10.5, "lineHeight": 15.23, "baseline": 7.54, "padding": 0, "align": "left", "color": "#0B0F1A",
"face": { "source": "pdf", "name": "ABCDEF+Calibri", "fallback": "carlito" }, "font": "helvetica" }
]

face escolhe a fonte: a fonte incorporada do PDF quando ela consegue desenhar todos os caracteres do novo texto; caso contrário, uma fonte incluída com métricas compatíveis (sans Arimo para Helvetica/Arial, serif Tinos para Times, mono Cousine para Courier, carlito Carlito para Calibri) no peso e estilo correspondentes. O texto quebra dentro do bloco; quando precisa de mais linhas que o original, a edição avança sobre o espaço livre abaixo dele, e o editor se recusa a salvá-la quando não há espaço (“o texto não cabe — encurte-o ou abra espaço”). O editor e a API compartilham o código de diagramação e de fontes, então o PDF publicado corresponde à pré-visualização linha por linha.

As edições só podem alterar um rascunho. A publicação as aplica a um novo PDF base cujo SHA-256 é o documentHash da versão (o hash do que os signatários veem); o original enviado é mantido como sourceFile da versão, e o próximo rascunho parte dele com as mesmas edições. O corretivo cobre o conteúdo visualmente; o texto original continua no arquivo por baixo, então ele não é uma tarja segura.

Os papéis são as partes do contrato. Os destinatários de um envelope são associados aos papéis pela key.

{ "key": "client", "label": "Client", "kind": "signer", "order": 1, "verification": "none" }
Propriedade Significado
key Identificador em minúsculas (^[a-z][a-z0-9_]*$) usado pelos campos e pelos destinatários do envelope
kind signer (precisa ter um campo de assinatura ou de rubrica), approver, form_filler ou cc (recebe, nunca assina)
order Ordem de roteamento a partir de 1. Papéis com a mesma ordem assinam em paralelo; a ordem seguinte começa quando eles terminam
verification Como o destinatário do papel comprova quem é: none (padrão: só o link de assinatura exclusivo) ou email_otp (o link mais um código enviado por e-mail). Um destinatário pode substituí-lo; consulte verificação do signatário

passkey, id_check e sms_otp aparecem no esquema, mas ainda não estão disponíveis para assinatura: um modelo que usa passkey ou id_check não pode ser publicado, e os códigos por SMS ainda não são entregues.

{
"id": "client_signature",
"type": "signature",
"role": "client",
"label": "Signature",
"required": true,
"rect": { "page": 1, "x": 72, "y": 610, "width": 220, "height": 48 }
}

Tipos de campo: signature, initials, name, email, date_signed, text, number, date, checkbox, radio, dropdown, attachment, formula, stamp e variable_text (preenchido a partir de uma variável pelo remetente, não por um signatário). Os campos também podem ter:

  • variable: um JSON Pointer para as variáveis (/client/name) que vincula ou preenche previamente o campo;
  • options para radio e dropdown;
  • validation: pattern, min, max, maxLength ou um format (email, phone, date, number, currency);
  • showIf: uma condição sobre variáveis e outros campos, como plan != "free";
  • formula: um valor calculado, somente leitura;
  • overflow: o que fazer quando um valor não cabe na caixa: shrink (padrão), wrap ou reject.

As variables de uma versão são um JSON Schema (draft 2020-12) para os dados que você envia com cada envelope; os sampleVariables da versão são um exemplo. POST /v1/envelopes valida suas variables contra ele e informa cada problema com um JSON Pointer:

{
"type": "https://bonafidesign.com/problems/validation-error",
"title": "Validation failed",
"status": 422,
"detail": "The request is invalid.",
"errors": [
{ "pointer": "/variables/client/name", "message": "is required", "hint": "Provide a value for 'name'." }
]
}

Para ver o resultado antes de enviar, renderize uma pré-visualização com marca d’água de qualquer versão com POST /v1/templates/{id}/versions/{version}/render ({ "variables": { … } } → PDF) ou crie o envelope com ?dry_run=true.

A maioria das equipes cria os modelos no editor do painel. Tudo o que ele faz está disponível pela API:

  1. POST /v1/templates com { "name": "Mutual NDA" }.
  2. POST /v1/templates/{id}/files com o PDF (ou .docx) como corpo (Content-Type: application/pdf) ou como o campo multipart file. Até 25 MB. A resposta traz o id do arquivo (tfl_…), o número de páginas e os tamanhos das páginas.
  3. PUT /v1/templates/{id}/draft com roles, fields, variables (e file, ou source: "document" com content). Os rascunhos são salvos como estão; nada é verificado ainda.
  4. POST /v1/templates/{id}/publish. A publicação analisa o rascunho: o papel de cada campo existe, todo papel de signatário tem um campo de assinatura, os campos cabem nas páginas, os campos de opção e de lista suspensa têm opções, as expressões são válidas. Os problemas voltam como 422 com ponteiros como /fields/3/rect.
Janela do terminal
curl https://api.bonafidesign.com/v1/templates/tpl_3kQ9xV2mLp/files \
-H "Authorization: Bearer $BONA_FIDE_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @nda.pdf

Os endpoints de versão aceitam um número, latest ou draft: GET /v1/templates/{id}/versions/latest, GET /v1/templates/{id}/versions/2/document (o PDF base). Um modelo que nunca foi usado por um envelope ou por um link de assinatura pode ser excluído; caso contrário, o DELETE responde 409 in-use.