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.
{ "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.
Duas formas de criar
Seção intitulada “Duas formas de criar”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.
No painel
Seção intitulada “No painel”Novo modelo oferece dois pontos de partida:
- Enviar documento: uma única área para soltar arquivos
.pdfe.docxde 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.
Edições de conteúdo
Seção intitulada “Edições de conteúdo”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:
[ { "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;optionspararadioedropdown;validation:pattern,min,max,maxLengthou umformat(email,phone,date,number,currency);showIf: uma condição sobre variáveis e outros campos, comoplan != "free";formula: um valor calculado, somente leitura;overflow: o que fazer quando um valor não cabe na caixa:shrink(padrão),wrapoureject.
Variáveis
Seção intitulada “Variáveis”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.
Criando um modelo pela API
Seção intitulada “Criando um modelo pela API”A maioria das equipes cria os modelos no editor do painel. Tudo o que ele faz está disponível pela API:
POST /v1/templatescom{ "name": "Mutual NDA" }.POST /v1/templates/{id}/filescom o PDF (ou.docx) como corpo (Content-Type: application/pdf) ou como o campo multipartfile. Até 25 MB. A resposta traz o id do arquivo (tfl_…), o número de páginas e os tamanhos das páginas.PUT /v1/templates/{id}/draftcomroles,fields,variables(efile, ousource: "document"comcontent). Os rascunhos são salvos como estão; nada é verificado ainda.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 como422com ponteiros como/fields/3/rect.
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.pdfOs 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.