Modelos, funções e campos
Um modelo é um contrato reutilizável. 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 guardar um novo rascunho e publicá-lo como a versão seguinte. 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_, …);
as datas e horas 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 carregado. Os campos são retângulos colocados nas
respetivas páginas em pontos PDF (1/72 pol.), com a origem no canto superior esquerdo da página e índice de página a
partir de 0. Um .docx carregado é convertido em PDF uma única vez (LibreOffice, mantendo o esquema do Word; os
tipos de letra que o ficheiro não incorpora podem ser substituídos) e, a partir daí, é um PDF como qualquer outro: o
ficheiro indica convertedFrom: "docx". As versões em Sobreposição também podem incluir
edições de conteúdo (texto editado no próprio local, corretor, caixas de texto, imagens, operações
de página), aplicadas quando a versão é publicada.
O modo Documento (source: "document") guarda o próprio contrato como texto formatado (JSON do ProseMirror) com
marcadores de variável como {{client.name}}, blocos de campo em linha, secções condicionais (mantidas apenas
quando uma expressão showIf é verdadeira) e secções e linhas de tabela repetíveis (uma por cada elemento de
uma variável do tipo array). Cada envelope gera o seu próprio PDF, e as posições dos campos são lidas desse
resultado. No painel, o modo Documento corresponde a «Começar com um documento em branco». Através da API, também é
possível importar um ficheiro do Word para o modo Documento com POST /v1/templates/{id}/import: as {{tags}}
passam a variáveis ou campos e as linhas de assinatura («Signature: ____», «By: ____», «Date: ____») passam a
blocos de campo.
No painel
Seção intitulada “No painel”Novo modelo oferece dois pontos de partida:
- Carregar documento: uma única zona para largar ficheiros
.pdfe.docxaté 25 MB. Os ficheiros do Word são convertidos em PDF e abertos no editor com um lembrete para verificar o esquema convertido antes de colocar os campos. As pequenas correções são feitas diretamente no PDF («Editar conteúdo»); para uma reescrita maior, altere o ficheiro do Word e volte a carregá-lo. - Começar com um documento em branco: redija 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 altera o que os signatários veem sem tocar no ficheiro carregado. A sua ferramenta predefinida, Editar texto, realça os blocos de texto da página (linhas e parágrafos agrupados a partir da camada de texto do PDF); clique num deles, ou chegue até ele com Tab e prima Enter, para o editar no próprio local, com a mesma posição, tamanho, cor, alinhamento e tipo de letra. Ctrl/Cmd+Enter guarda, Esc cancela, e cada edição pode ser revertida na lista de edições. As edições podem ser anuladas como qualquer outra alteração. As outras ferramentas acrescentam corretor, caixas de texto e imagens, e inserem, eliminam, reordenam ou rodam páginas.
Uma edição de texto no próprio local é guardada como dois elementos que partilham um group: um corretor sobre o
bloco original (na cor de fundo da página) e um elemento de texto composto 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 o tipo de letra: o tipo de letra incorporado no PDF quando consegue desenhar todos os caracteres do
novo texto; caso contrário, um tipo de letra incluído com métricas compatíveis (sans Arimo para Helvetica/Arial,
serif Tinos para Times, mono Cousine para Courier, carlito Carlito para Calibri) com o peso e o estilo
correspondentes. O texto faz translineação dentro do bloco; quando precisa de mais linhas do que o original, a edição
expande-se para o espaço livre por baixo, e o editor recusa-se a guardá-la quando não há espaço («o texto não cabe —
encurte-o ou crie espaço»). O editor e a API partilham o código de composição e de tipos de letra, pelo que o PDF
publicado corresponde à pré-visualização linha a linha.
As edições só podem alterar um rascunho. A publicação aplica-as a um novo PDF base cujo SHA-256 é o documentHash
da versão (o hash do que os signatários veem); o original carregado é mantido como sourceFile da versão, e o
rascunho seguinte parte dele com as mesmas edições. O corretor tapa o conteúdo visualmente; o texto original
continua no ficheiro por baixo, pelo que não constitui uma ocultação segura.
Funções
Seção intitulada “Funções”As funções são as partes do contrato. Os destinatários de um envelope são associados às funções através da key.
{ "key": "client", "label": "Client", "kind": "signer", "order": 1, "verification": "none" }| Propriedade | Significado |
|---|---|
key |
Identificador em minúsculas (^[a-z][a-z0-9_]*$) utilizado pelos campos e pelos destinatários do envelope |
kind |
signer (tem de ter um campo de assinatura ou de rubrica), approver, form_filler ou cc (recebe, nunca assina) |
order |
Ordem de encaminhamento a partir de 1. As funções com a mesma ordem assinam em paralelo; a ordem seguinte começa quando terminam |
verification |
Como o destinatário da função comprova a sua identidade: none (predefinição: apenas a ligação de assinatura única) ou email_otp (a ligação 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 constam do esquema, mas ainda não estão disponíveis para assinatura: um modelo que
utilize 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 associa ou pré-preenche 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, só de leitura;overflow: o que fazer quando um valor não cabe na caixa:shrink(predefiniçã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 envia com cada envelope; os
sampleVariables da versão são um exemplo. POST /v1/envelopes valida as suas variables com base nesse esquema e
comunica 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, gere uma pré-visualização com marca de água de qualquer versão com
POST /v1/templates/{id}/versions/{version}/render ({ "variables": { … } } → PDF) ou crie o envelope com
?dry_run=true.
Criar um modelo através da API
Seção intitulada “Criar um modelo através da API”A maioria das equipas concebe os modelos no editor do painel. Tudo o que este faz está disponível através da 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 inclui o id do ficheiro (tfl_…), o número de páginas e as dimensões das páginas.PUT /v1/templates/{id}/draftcomroles,fields,variables(efile, ousource: "document"comcontent). Os rascunhos são guardados tal como estão; ainda nada é verificado.POST /v1/templates/{id}/publish. A publicação analisa o rascunho: a função de cada campo existe, cada função de signatário tem um campo de assinatura, os campos cabem nas páginas, os campos de opção e de lista pendente têm opções, as expressões são válidas. Os problemas são devolvidos 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 tenha sido utilizado por um envelope
ou por uma ligação de assinatura pode ser eliminado; caso contrário, o DELETE responde 409 in-use.