KivoSign

API de modelos

Crie documentos a partir de modelos reutilizáveis pela API.

Documentos e modelos estão sendo descontinuados e substituídos por envelopes. Leia o guia de migração.

Este guia pode não refletir os endpoints ou parâmetros mais recentes. Para uma referência sempre atualizada, consulte a especificação OpenAPI.

Usar um envelope de modelo

Novas integrações devem criar documentos a partir de um envelope de modelo usando a API de envelopes.

POST /envelope/use
Content-Type: multipart/form-data

A requisição usa multipart/form-data:

ParteTipoObrigatórioDescrição
payloadJSONSimID do envelope de modelo, dados dos destinatários e configurações do documento
filesArquivo(s)NãoPDFs substitutos referenciados em customDocumentData

Schema do payload

CampoTipoObrigatórioDescrição
envelopeIdstringSimID do envelope de modelo
externalIdstringNãoSeu identificador para o envelope de documento criado
recipientsarrayNãoDados dos destinatários, mapeados para os destinatários do modelo
distributeDocumentbooleanNãoSe true, cria o documento como pendente e já o distribui
customDocumentDataarrayNãoMapeia os PDFs substitutos enviados para os itens do modelo
folderIdstringNãoPasta onde criar o documento
prefillFieldsarrayNãoValores de campos a pré-preencher antes da distribuição
overrideobjectNãoValores do modelo a sobrescrever no documento criado
attachmentsarrayNãoAnexos em forma de link a incluir no documento
formValuesobjectNãoValores de formulário do PDF a aplicar

Cada destinatário aceita os campos:

CampoTipoObrigatórioDescrição
idnumberSimID do destinatário no envelope de modelo
emailstringSimE-mail do destinatário
namestringNãoNome de exibição do destinatário
signingOrdernumberNãoPosição do destinatário na assinatura sequencial

Cada item de customDocumentData mapeia um arquivo enviado para um item do modelo:

CampoTipoObrigatórioDescrição
identifierstring | numberSimNome do arquivo enviado ou índice do arquivo (começando em zero)
envelopeItemIdstringSimItem do envelope de modelo cujo PDF será substituído

Exemplos

curl -X POST "https://app.kivosign.com.br/api/v2/envelope/use" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -F 'payload={
    "envelopeId": "envelope_template123",
    "externalId": "contrato-2025-001",
    "recipients": [
      {
        "id": 1,
        "email": "joao.silva@exemplo.com",
        "name": "João Silva"
      }
    ],
    "prefillFields": [
      {
        "id": 101,
        "type": "text",
        "value": "Engenheiro de Software Sênior"
      }
    ],
    "distributeDocument": false
  }'

Resposta

{
  "id": "envelope_document123",
  "recipients": [
    {
      "id": 1,
      "name": "João Silva",
      "email": "joao.silva@exemplo.com",
      "token": "recipient_token",
      "role": "SIGNER",
      "signingOrder": 1,
      "signingUrl": "https://app.kivosign.com.br/sign/recipient_token"
    }
  ]
}

Distribuir o envelope criado

Se você não informar distributeDocument ou usar false, distribua o documento criado com POST /envelope/distribute. A resposta confirma o envio e traz a URL de assinatura de cada destinatário.

const distributionResponse = await fetch(
  'https://app.kivosign.com.br/api/v2/envelope/distribute',
  {
    method: 'POST',
    headers: {
      Authorization: 'api_xxxxxxxxxxxxxxxx',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      envelopeId: document.id,
    }),
  },
);

const distribution = await distributionResponse.json();
console.log('URL de assinatura:', distribution.recipients[0].signingUrl);
{
  "success": true,
  "id": "envelope_document123",
  "recipients": [
    {
      "id": 1,
      "name": "João Silva",
      "email": "joao.silva@exemplo.com",
      "token": "recipient_token",
      "role": "SIGNER",
      "signingOrder": 1,
      "signingUrl": "https://app.kivosign.com.br/sign/recipient_token"
    }
  ]
}

Referência dos endpoints de modelo descontinuados

Todos os endpoints /template/* abaixo estão descontinuados. Use a API de envelopes em novas integrações e siga Migrando para envelopes para trocar as chamadas existentes. A referência antiga fica aqui para apoiar a migração.

Objeto modelo (legado)

O objeto modelo tem as seguintes propriedades:

PropriedadeTipoDescrição
idnumberIdentificador único do modelo
envelopeIdstringID do envelope associado
typestringTipo do modelo: PRIVATE ou PUBLIC
visibilitystringQuem pode ver: EVERYONE, ADMIN, MANAGER_AND_ABOVE
titlestringTítulo do modelo
externalIdstring | nullSeu identificador próprio
publicTitlestring | nullTítulo público (para modelos públicos)
publicDescriptionstring | nullDescrição pública (para modelos públicos)
userIdnumberID do usuário dono
teamIdnumber | nullID da equipe, se pertencer a uma equipe
folderIdstring | nullPasta que contém o modelo
createdAtstringData/hora ISO 8601
updatedAtstringData/hora ISO 8601
recipientsarrayDestinatários pré-definidos, com papéis e campos
fieldsarrayCampos de assinatura e de formulário do modelo
templateMetaobjectConfigurações de e-mail, opções de assinatura e URL de redirecionamento
directLinkobject | nullConfiguração do link direto, se ativado

Exemplo de objeto modelo

{
  "id": 123,
  "envelopeId": "envelope_abc123xyz",
  "type": "PRIVATE",
  "visibility": "EVERYONE",
  "title": "Contrato de trabalho",
  "externalId": "modelo-ct-001",
  "publicTitle": null,
  "publicDescription": null,
  "userId": 1,
  "teamId": 5,
  "folderId": null,
  "createdAt": "2025-01-10T08:00:00.000Z",
  "updatedAt": "2025-01-10T08:30:00.000Z",
  "recipients": [
    {
      "id": 1,
      "email": "colaborador@exemplo.com",
      "name": "Colaborador",
      "role": "SIGNER",
      "signingOrder": 1
    },
    {
      "id": 2,
      "email": "rh@empresa.com.br",
      "name": "Gerente de RH",
      "role": "SIGNER",
      "signingOrder": 2
    }
  ],
  "fields": [
    {
      "id": 101,
      "type": "SIGNATURE",
      "page": 1,
      "positionX": 10,
      "positionY": 80,
      "width": 30,
      "height": 5,
      "recipientId": 1
    }
  ],
  "templateMeta": {
    "subject": "Seu contrato de trabalho",
    "message": "Por favor, revise e assine seu contrato de trabalho.",
    "redirectUrl": "https://exemplo.com/boas-vindas"
  },
  "directLink": null
}

Listar modelos (descontinuado)

Consulta uma lista paginada de modelos.

GET /template

Parâmetros de consulta

ParâmetroTipoDescrição
pageintegerNúmero da página (padrão: 1)
perPageintegerResultados por página (padrão: 10, máx.: 100)
typestringFiltra por tipo: PRIVATE ou PUBLIC
folderIdstringFiltra pelo ID da pasta
orderByColumnstringCampo de ordenação (só createdAt)
orderByDirectionstringDireção: asc ou desc (padrão: desc)

Exemplos

# Listar todos os modelos
curl -X GET "https://app.kivosign.com.br/api/v2/template" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx"

# Filtrar por tipo e paginar
curl -X GET "https://app.kivosign.com.br/api/v2/template?type=PRIVATE&page=1&perPage=20" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx"

Resposta

{
  "data": [
    {
      "id": 123,
      "envelopeId": "envelope_abc123",
      "type": "PRIVATE",
      "title": "Contrato de trabalho",
      "createdAt": "2025-01-10T08:00:00.000Z",
      "updatedAt": "2025-01-10T08:30:00.000Z",
      "recipients": [
        {
          "id": 1,
          "email": "colaborador@exemplo.com",
          "name": "Colaborador",
          "role": "SIGNER"
        }
      ]
    }
  ],
  "count": 25,
  "currentPage": 1,
  "perPage": 10,
  "totalPages": 3
}

Consultar modelo (descontinuado)

Consulta um modelo pelo ID.

GET /template/{templateId}

Parâmetros de caminho

ParâmetroTipoDescrição
templateIdnumberO ID do modelo

Exemplos

curl -X GET "https://app.kivosign.com.br/api/v2/template/123" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx"

Resposta

Retorna o objeto modelo completo, com destinatários, campos e metadados.


Criar documento a partir de modelo (descontinuado)

Cria um documento usando o endpoint de modelo descontinuado.

Este endpoint não processa marcadores em PDF. Use POST /envelope/create para posicionar campos por marcador.

POST /template/use

Corpo da requisição

CampoTipoObrigatórioDescrição
templateIdnumberSimID do modelo a usar
recipientsarraySimDados dos destinatários (mapeados para os do modelo)
distributeDocumentbooleanNãoSe true, envia o documento aos destinatários na hora
externalIdstringNãoSeu identificador para o documento criado
folderIdstringNãoID da pasta onde criar o documento
prefillFieldsarrayNãoValores de campos a pré-preencher antes do envio
overrideobjectNãoSobrescreve configurações do modelo neste documento
formValuesobjectNãoValores de formulário do PDF a inserir

Lista de destinatários

Cada destinatário precisa ter:

CampoTipoObrigatórioDescrição
idnumberSimID do destinatário no modelo
emailstringSimE-mail do destinatário
namestringNãoNome de exibição do destinatário

Exemplos

# Criar documento a partir do modelo
curl -X POST "https://app.kivosign.com.br/api/v2/template/use" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123,
    "recipients": [
      {
        "id": 1,
        "email": "joao.silva@exemplo.com",
        "name": "João Silva"
      },
      {
        "id": 2,
        "email": "maria.souza@empresa.com.br",
        "name": "Maria Souza"
      }
    ],
    "distributeDocument": true,
    "externalId": "contrato-2025-001"
  }'

# Criar documento com campos pré-preenchidos
curl -X POST "https://app.kivosign.com.br/api/v2/template/use" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123,
    "recipients": [
      {
        "id": 1,
        "email": "joao.silva@exemplo.com",
        "name": "João Silva"
      }
    ],
    "prefillFields": [
      {
        "id": 101,
        "type": "text",
        "value": "Engenheiro de Software Sênior"
      },
      {
        "id": 102,
        "type": "number",
        "value": "85000"
      },
      {
        "id": 103,
        "type": "date",
        "value": "2025-02-01"
      }
    ],
    "distributeDocument": true
  }'

Resposta

O endpoint retorna o objeto documento legado completo. Os campos selecionados abaixo mostram o id numérico legado e o envelopeId canônico. Os destinatários não trazem signingUrl.

{
  "id": 789,
  "envelopeId": "envelope_xyz789",
  "status": "PENDING",
  "source": "TEMPLATE",
  "title": "Contrato de trabalho",
  "externalId": "contrato-2025-001",
  "recipients": [
    {
      "id": 1,
      "envelopeId": "envelope_xyz789",
      "documentId": 789,
      "templateId": null,
      "email": "joao.silva@exemplo.com",
      "name": "João Silva",
      "role": "SIGNER",
      "signingStatus": "NOT_SIGNED",
      "signingOrder": 1
    }
  ]
}

Para enviar um documento criado com distributeDocument: false e receber os links de assinatura, chame POST /envelope/distribute com o envelopeId dele:

const document = await response.json();

const distributionResponse = await fetch(`${BASE_URL}/envelope/distribute`, {
  method: 'POST',
  headers: {
    Authorization: API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    envelopeId: document.envelopeId,
  }),
});

const distribution = await distributionResponse.json();
console.log('URL de assinatura:', distribution.recipients[0].signingUrl);

Sobrescrever configurações do modelo (descontinuado)

Ao criar um documento a partir de um modelo, você pode sobrescrever várias configurações:

const response = await fetch(`${BASE_URL}/template/use`, {
  method: 'POST',
  headers: {
    Authorization: API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    templateId: 123,
    recipients: [{ id: 1, email: 'signatario@exemplo.com', name: 'Signatário' }],
    override: {
      title: 'Título personalizado do documento',
      subject: 'Assunto personalizado do e-mail',
      message: 'Mensagem personalizada do e-mail',
      timezone: 'America/Sao_Paulo',
      dateFormat: 'dd/MM/yyyy',
      redirectUrl: 'https://exemplo.com/redirecionamento',
      language: 'pt-BR',
      typedSignatureEnabled: true,
      uploadSignatureEnabled: false,
      drawSignatureEnabled: true,
    },
    distributeDocument: true,
  }),
});

Opções de sobrescrita

CampoTipoDescrição
titlestringTítulo do documento
subjectstringAssunto do e-mail
messagestringCorpo do e-mail
timezonestringFuso horário dos campos de data
dateFormatstringFormato de data
redirectUrlstringURL de redirecionamento após a assinatura
languagestringCódigo do idioma do documento
typedSignatureEnabledbooleanPermite assinatura digitada
uploadSignatureEnabledbooleanPermite enviar imagem da assinatura
drawSignatureEnabledbooleanPermite assinatura desenhada

Pré-preencher campos (descontinuado)

Pré-preencha valores de campos ao criar um documento a partir de um modelo. Útil para preencher dados já conhecidos antes do envio.

Tipos de campo suportados

TipoFormato do valorDescrição
textstringValor do campo de texto
numberstringValor numérico como string
datestring (ISO 8601)Data no formato YYYY-MM-DD
radiostringValor da opção selecionada
checkboxlista de stringsValores das opções marcadas
dropdownstringValor selecionado na lista

Schema do campo pré-preenchido

type PrefillField = {
  id: number; // ID do campo no modelo
  type: string; // Tipo do campo (precisa ser igual ao do modelo)
  label?: string; // Sobrescrita opcional do rótulo
  placeholder?: string; // Placeholder opcional (só text/number)
  value: string | string[]; // Valor a pré-preencher
};

Exemplo: pré-preencher vários tipos de campo

const response = await fetch(`${BASE_URL}/template/use`, {
  method: 'POST',
  headers: {
    Authorization: API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    templateId: 123,
    recipients: [{ id: 1, email: 'signatario@exemplo.com', name: 'Signatário' }],
    prefillFields: [
      // Campo de texto
      {
        id: 101,
        type: 'text',
        value: 'João Silva',
      },
      // Campo numérico
      {
        id: 102,
        type: 'number',
        value: '50000',
      },
      // Campo de data
      {
        id: 103,
        type: 'date',
        value: '2025-03-15',
      },
      // Opção única
      {
        id: 104,
        type: 'radio',
        value: 'clt',
      },
      // Múltipla escolha
      {
        id: 105,
        type: 'checkbox',
        value: ['saude', 'odonto', 'vale-refeicao'],
      },
      // Lista suspensa
      {
        id: 106,
        type: 'dropdown',
        value: 'engenharia',
      },
    ],
    distributeDocument: true,
  }),
});

O tipo informado em prefillFields precisa ser igual ao tipo real do campo no modelo. Se não for, a requisição retorna erro.


Atualizar modelo (descontinuado)

Atualiza as propriedades de um modelo.

POST /template/update

Corpo da requisição

CampoTipoObrigatórioDescrição
templateIdnumberSimID do modelo
dataobjectNãoPropriedades do modelo a atualizar
metaobjectNãoConfigurações de e-mail e assinatura a atualizar

Exemplos

curl -X POST "https://app.kivosign.com.br/api/v2/template/update" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123,
    "data": {
      "title": "Contrato de trabalho (revisado)",
      "visibility": "ADMIN"
    },
    "meta": {
      "subject": "Atualizado: seu contrato de trabalho",
      "redirectUrl": "https://exemplo.com/novo-redirecionamento"
    }
  }'

Duplicar modelo (descontinuado)

Cria uma cópia de um modelo existente.

POST /template/duplicate

Corpo da requisição

CampoTipoObrigatórioDescrição
templateIdnumberSimID do modelo

Exemplos

curl -X POST "https://app.kivosign.com.br/api/v2/template/duplicate" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123
  }'

Excluir modelo (descontinuado)

Exclui um modelo.

POST /template/delete

Corpo da requisição

CampoTipoObrigatórioDescrição
templateIdnumberSimID do modelo

Exemplos

curl -X POST "https://app.kivosign.com.br/api/v2/template/delete" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123
  }'

Resposta

{
  "success": true
}

Modelos com link direto permitem que o destinatário crie e assine documentos sem que você precise criar cada documento. Quando o destinatário abre o link direto, um novo documento é criado automaticamente a partir do modelo.

POST /template/direct/create
CampoTipoObrigatórioDescrição
templateIdnumberSimID do modelo
directRecipientIdnumberNãoID do destinatário que assina pelo link direto
curl -X POST "https://app.kivosign.com.br/api/v2/template/direct/create" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123,
    "directRecipientId": 1
  }'

Resposta

{
  "id": 456,
  "token": "abc123xyz",
  "templateId": 123,
  "directTemplateRecipientId": 1,
  "enabled": true,
  "createdAt": "2025-01-15T10:00:00.000Z"
}

Ativa ou desativa um link direto existente.

POST /template/direct/toggle
curl -X POST "https://app.kivosign.com.br/api/v2/template/direct/toggle" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123,
    "enabled": false
  }'
POST /template/direct/delete
curl -X POST "https://app.kivosign.com.br/api/v2/template/direct/delete" \
  -H "Authorization: api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 123
  }'

PDF personalizado (descontinuado)

Ao criar um documento a partir de um modelo, você pode trocar o PDF do modelo por um PDF próprio usando o parâmetro customDocumentData. Isso é útil quando o PDF é gerado dinamicamente, mas você quer reaproveitar os destinatários e campos do modelo.

Para usar um PDF personalizado:

  1. Consulte o modelo para obter o envelopeItemId do PDF que deseja substituir
  2. Inclua customDocumentData na requisição template/use, mapeando cada envelopeItemId para um novo arquivo

As posições dos campos do modelo são mantidas no novo PDF. Garanta que o PDF substituto tenha o mesmo layout de páginas para que os campos fiquem no lugar certo.

Veja a especificação OpenAPI para o schema completo da requisição.


Tipos de modelo (legado)

TipoDescrição
PRIVATEAcessível apenas pelo dono e pelos membros da equipe
PUBLICPode ser compartilhado publicamente com um link direto

Exemplo completo (legado): fluxo de contrato (descontinuado)

Este exemplo mostra um fluxo completo usando modelos para enviar contratos.

const API_TOKEN = process.env.KIVOSIGN_API_TOKEN;
const BASE_URL = 'https://app.kivosign.com.br/api/v2';

async function sendEmploymentContract(employeeData: {
  email: string;
  name: string;
  position: string;
  salary: number;
  startDate: string;
}) {
  // 1. Consultar o modelo para obter os IDs de destinatários e campos
  const templateResponse = await fetch(`${BASE_URL}/template/456`, {
    headers: { Authorization: API_TOKEN },
  });
  const template = await templateResponse.json();

  // 2. Encontrar o destinatário do colaborador
  const employeeRecipient = template.recipients.find(
    (r) => r.role === 'SIGNER' && r.signingOrder === 1
  );

  // 3. Encontrar os campos a pré-preencher
  const positionField = template.fields.find(
    (f) => f.fieldMeta?.label === 'Cargo'
  );
  const salaryField = template.fields.find(
    (f) => f.fieldMeta?.label === 'Salário'
  );
  const startDateField = template.fields.find(
    (f) => f.type === 'DATE'
  );

  // 4. Criar o documento a partir do modelo com os dados pré-preenchidos
  const documentResponse = await fetch(`${BASE_URL}/template/use`, {
    method: 'POST',
    headers: {
      Authorization: API_TOKEN,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      templateId: 456,
      recipients: [
        {
          id: employeeRecipient.id,
          email: employeeData.email,
          name: employeeData.name,
        },
      ],
      prefillFields: [
        {
          id: positionField.id,
          type: 'text',
          value: employeeData.position,
        },
        {
          id: salaryField.id,
          type: 'number',
          value: employeeData.salary.toString(),
        },
        {
          id: startDateField.id,
          type: 'date',
          value: employeeData.startDate,
        },
      ],
      override: {
        subject: `Contrato de trabalho de ${employeeData.name}`,
        message: `Olá ${employeeData.name},\n\nPor favor, revise e assine seu contrato de trabalho.`,
      },
      distributeDocument: false,
      externalId: `contrato-ct-${Date.now()}`,
    }),
  });

  const document = await documentResponse.json();

  // 5. Distribuir o envelope e obter os links de assinatura
  const distributionResponse = await fetch(`${BASE_URL}/envelope/distribute`, {
    method: 'POST',
    headers: {
      Authorization: API_TOKEN,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      envelopeId: document.envelopeId,
    }),
  });
  const distribution = await distributionResponse.json();

  return {
    envelopeId: document.envelopeId,
    signingUrl: distribution.recipients[0].signingUrl,
  };
}

const result = await sendEmploymentContract({
  email: 'joao.silva@exemplo.com',
  name: 'João Silva',
  position: 'Engenheiro Sênior',
  salary: 120000,
  startDate: '2025-03-01',
});

console.log('Documento criado:', result.envelopeId);
console.log('URL de assinatura:', result.signingUrl);

Veja também

Nesta página