Desenvolvedores

API e webhooks do AI Sign

Crie documentos, defina quem assina, envie para assinatura e receba cada evento no seu sistema — com as mesmas regras do painel. Disponível no plano Empresa.

criar-documento.sh
# 1. cria o documento
curl -X POST https://aisign.talkhub.me/api/v1/documentos \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title":"Contrato de prestação de serviços"}'

# resposta
{ "id": "3f6c2a1e-8b0d-4c57-9a7e-2d4f1b6e9c10" }

# 2. envia o PDF
curl -X POST https://aisign.talkhub.me/api/v1/documentos/$ID/arquivo \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -F "arquivo=@contrato.pdf;type=application/pdf"

Visão geral

A API do AI Sign é REST, com JSON sobre HTTPS. Tudo o que ela faz respeita as regras do painel: limites do plano, validação do PDF, trilha de auditoria e certificação no envio. Os documentos criados pela API aparecem no painel da organização, e os do painel podem ser consultados pela API.

Plano Empresa. A API e os webhooks fazem parte do plano Empresa: é nele que a organização cria tokens de API e cadastra webhooks.

Endereço base de todas as rotas:

URL base
https://aisign.talkhub.me/api/v1

Autenticação

Crie um token nas configurações da organização, na área de API. O token começa com ais_ e é mostrado uma única vez — o AI Sign guarda só o hash dele. Trate-o como uma senha: use variável de ambiente e nunca o coloque em código do navegador.

Envie o token em todas as requisições, no cabeçalho Authorization:

Cabeçalho
Authorization: Bearer ais_…

Fluxo de envio

  1. Crie o documento (fica em rascunho).
  2. Envie o PDF do documento — ou crie a partir de um modelo, informando template_id.
  3. Defina os signatários: quem assina, por qual canal, com qual tipo de assinatura e em que ordem.
  4. Posicione os campos de cada signatário nas páginas.
  5. Envie para assinatura. O AI Sign anexa a página de verificação, certifica o PDF e dispara os convites.
  6. Acompanhe pelos webhooks ou consultando o documento.
  7. Baixe o PDF final assinado e o relatório de assinaturas.

Endpoints

RotaO que faz
POST/documentosCria um documento em rascunho.
POST/documentos/:id/arquivoEnvia o PDF (multipart, campo arquivo).
PUT/documentos/:id/signatariosDefine a lista de signatários.
PUT/documentos/:id/camposDefine os campos de cada signatário.
POST/documentos/:id/enviarEnvia o documento para assinatura.
GET/documentos/:idConsulta documento, signatários, campos e trilha.
GET/documentos/:id/pdf?versao=final|relatorioBaixa o PDF assinado ou o relatório de assinaturas.
POST/documentos/:id/signatarios/:rid/linkGera um novo link de assinatura para um signatário.

Criar documento

POST/documentos — cria o documento em rascunho e devolve o id.

curl
curl -X POST https://aisign.talkhub.me/api/v1/documentos \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Contrato de prestação de serviços",
    "message": "Segue o contrato para assinatura.",
    "signing_order": "sequencial",
    "expires_at": "2026-11-30T23:59:00-03:00",
    "external_ref": "pedido-1042"
  }'
CampoDescrição
titleObrigatório. Título do documento, até 200 caracteres.
messageMensagem enviada junto com o convite (opcional).
signing_orderparalelo (padrão) ou sequencial.
expires_atPrazo em ISO 8601 (opcional). Depois dele, o documento expira.
external_refSua referência interna, até 120 caracteres (opcional).
template_idCria a partir de um modelo da organização (opcional): copia o PDF e a mensagem.

Enviar o PDF

POST/documentos/:id/arquivo — envio multipart/form-data com o PDF no campo arquivo. Aceita só PDF sem senha, com até 25 MB e 500 páginas. Trocar o arquivo apaga os campos já posicionados.

curl
curl -X POST https://aisign.talkhub.me/api/v1/documentos/$ID/arquivo \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -F "arquivo=@contrato.pdf;type=application/pdf"

# resposta
{ "ok": true, "sha256": "9f2c41e7…", "paginas": 3, "page_sizes": [ … ] }

Signatários

PUT/documentos/:id/signatarios — recebe a lista completa (até 50) e substitui a anterior. Para manter um signatário já criado, inclua o id dele. A resposta traz o id de cada um, usado nos campos.

curl
curl -X PUT https://aisign.talkhub.me/api/v1/documentos/$ID/signatarios \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "name": "Ana Souza", "email": "ana@exemplo.com.br", "position": 1,
      "channel": "email", "auth_method": "otp_email", "signature_type": "simples" },
    { "name": "Bruno Lima", "phone": "+55 11 99999-0000", "position": 2,
      "channel": "whatsapp", "auth_method": "otp_whatsapp", "signature_type": "icp" }
  ]'

# resposta
{ "signatarios": [ { "id": "a1b2…", "name": "Ana Souza" }, { "id": "c3d4…", "name": "Bruno Lima" } ] }
CampoValores
nameObrigatório, de 2 a 120 caracteres.
email / phonePelo menos um. O canal email exige e-mail; whatsapp exige telefone (DDD + número; sem código do país, assume +55).
rolesignatario (padrão), aprovador ou observador.
positionOrdem de 1 a 50, usada quando signing_order é sequencial.
channelemail (padrão), whatsapp ou ambos.
auth_methodotp_email (padrão), otp_whatsapp ou nenhum.
signature_typesimples (padrão, assinatura eletrônica) ou icp (certificado ICP-Brasil).

Campos

PUT/documentos/:id/campos — recebe a lista completa de campos (até 400) e substitui a anterior. Posição e tamanho são em porcentagem da página (0 a 100), contados a partir do canto superior esquerdo.

curl
curl -X PUT https://aisign.talkhub.me/api/v1/documentos/$ID/campos \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "recipient_id": "a1b2…", "type": "assinatura", "page": 3, "x": 10, "y": 78, "w": 30, "h": 7 },
    { "recipient_id": "a1b2…", "type": "data", "page": 3, "x": 45, "y": 80, "w": 18, "h": 4 },
    { "recipient_id": "c3d4…", "type": "assinatura", "page": 3, "x": 60, "y": 78, "w": 30, "h": 7 }
  ]'

Tipos: assinatura, rubrica, nome, email, data, texto e checkbox. Opcionais: required (padrão true) e label, o rótulo mostrado a quem assina.

Enviar para assinatura

POST/documentos/:id/enviar — confere o PDF, os signatários, os campos e o limite do plano; anexa a página de verificação, certifica o PDF e envia os convites. A partir daqui, o documento não pode mais ser editado.

curl
curl -X POST https://aisign.talkhub.me/api/v1/documentos/$ID/enviar \
  -H "Authorization: Bearer $AISIGN_TOKEN"

Consultar

GET/documentos/:id — devolve documento (com o status: rascunho, enviado, concluido, recusado, cancelado ou expirado), signatarios (com o status de cada um), campos e trilha, a trilha de auditoria com os hashes.

curl
curl https://aisign.talkhub.me/api/v1/documentos/$ID \
  -H "Authorization: Bearer $AISIGN_TOKEN"

Baixar o PDF

GET/documentos/:id/pdf?versao=final baixa o PDF assinado (disponível quando o documento é concluído); versao=relatorio baixa o relatório de assinaturas. Também aceita original e atual.

curl
curl "https://aisign.talkhub.me/api/v1/documentos/$ID/pdf?versao=final" \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -o contrato-assinado.pdf

curl "https://aisign.talkhub.me/api/v1/documentos/$ID/pdf?versao=relatorio" \
  -H "Authorization: Bearer $AISIGN_TOKEN" \
  -o relatorio-de-assinaturas.pdf

POST/documentos/:id/signatarios/:rid/link — gera um link novo para o signatário :rid e devolve { "url": "…" }. Útil para entregar o convite pelo seu próprio canal. O link anterior deixa de valer, e o documento precisa estar enviado.

curl
curl -X POST https://aisign.talkhub.me/api/v1/documentos/$ID/signatarios/$RID/link \
  -H "Authorization: Bearer $AISIGN_TOKEN"

Webhooks

Cadastre uma URL HTTPS e escolha os eventos nas configurações da organização. A cada evento, o AI Sign faz um POST com JSON. Responda com status 2xx em até 15 segundos; se a entrega falhar, o AI Sign tenta de novo, com intervalos crescentes, até 5 tentativas no total.

EventoQuando acontece
documento.enviadoO documento foi enviado para assinatura.
documento.visualizadoUm signatário abriu o documento.
documento.assinadoUm signatário assinou (ou um aprovador aprovou).
documento.concluidoTodos assinaram; o PDF final e o relatório estão prontos.
documento.recusadoUm signatário recusou, com o motivo.
documento.canceladoO remetente cancelou o documento.
documento.expiradoO prazo terminou sem que todos assinassem.

Corpo de exemplo de documento.concluido:

documento.concluido
{
  "evento": "documento.concluido",
  "ocorrido_em": "2026-10-26T13:05:12.418Z",
  "dados": {
    "documento_id": "3f6c2a1e-8b0d-4c57-9a7e-2d4f1b6e9c10",
    "titulo": "Contrato de prestação de serviços",
    "hash_final": "7c90b2e6a1f8…",
    "url_verificacao": "https://aisign.talkhub.me/verificar/3f6c2a1e-…"
  }
}

Cabeçalhos enviados: X-AiSign-Event (o evento), X-AiSign-Delivery (id da entrega, o mesmo nas novas tentativas) e X-AiSign-Signature.

Verificar a assinatura

Cada webhook tem um segredo próprio. O cabeçalho tem o formato X-AiSign-Signature: t=<timestamp>,v1=<assinatura>, em que t é o horário do envio em segundos (Unix) e v1 é o HMAC-SHA256, em hexadecimal, de t + "." + corpo com o segredo do webhook. Calcule sobre o corpo bruto, antes de interpretar o JSON, compare em tempo constante e recuse carimbos antigos.

verificar-webhook.js · Node.js
import crypto from 'node:crypto';

// corpoBruto: o corpo da requisição exatamente como chegou (string)
export function webhookValido(corpoBruto, cabecalho, segredo, toleranciaSeg = 300) {
  const partes = Object.fromEntries(
    String(cabecalho || '').split(',').map((p) => p.trim().split('='))
  );
  const t = Number(partes.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranciaSeg) return false;
  const esperado = crypto.createHmac('sha256', segredo).update(`${partes.t}.${corpoBruto}`).digest('hex');
  const a = Buffer.from(esperado), b = Buffer.from(partes.v1 || '');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Erros e limites

Os erros vêm sempre no mesmo formato, com o status HTTP correspondente:

Erro
{ "error": { "code": "conflito", "message": "Signatários só mudam em rascunho." } }
StatusCódigoQuando
400invalidoDados inválidos (o campo details pode trazer o motivo).
401nao_autorizadoToken ausente, inválido ou revogado.
402limite_do_planoO plano não inclui o recurso ou o limite do mês acabou.
403proibidoO token não tem o escopo necessário para a ação.
404nao_encontradoDocumento ou signatário não existe nesta organização.
409conflitoA ação não cabe no status atual (por exemplo, editar um documento já enviado).
429muitas_requisicoesLimite de requisições atingido. Aguarde e tente de novo.

Dúvidas sobre a integração? Fale com o suporte.