Documentação da API
Base: https://focussign.com.br/api
Autenticação
Toda chamada de integração usa uma chave de API por tenant, enviada como Bearer token. Não há OAuth — é uma chave estática gerada uma vez e guardada no seu sistema.
Header obrigatório
Authorization: Bearer fs_live_7f2a9c...
A chave é gerada em Configurações → Integrações → API/Webhooks → Rotacionar chave. Ela aparece uma única vez, no instante da geração — depois disso só o prefixo mascarado fica visível. Rotacionar invalida a chave anterior imediatamente.
Uma requisição autenticada por chave é atribuída a um usuário sintético do tenant, não a uma pessoa — notificações internas sobre documentos criados por essa chave não aparecem para ninguém logado no painel. Comportamento esperado para uma integração via API.
Criar documento para assinatura
Envia o PDF e a lista de signatários. Cada signatário cadastrado recebe automaticamente o convite pelo canal escolhido — e a resposta já devolve o link de assinatura de cada um, caso prefira disparar você mesmo.
/api/assinaturasmultipart/form-data · autenticado| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| file | arquivo (PDF) | sim | Documento original a assinar. |
| nome | string | sim | Nome do documento, ex. "Holerite Setembro/2026 - João Silva". |
| signatarios | string (JSON) | sim | Array serializado — ver campos na seção 03. |
| mensagem | string | opcional | Recado exibido ao signatário antes de assinar. |
| prazoEm | string (ISO date) | opcional | Prazo do link. Sem isso, usa o padrão da plataforma. |
| sequencial | "true" | opcional | Só envie o campo quando for sequencial — cada signatário só recebe o convite após o anterior assinar. |
Exemplo · curl
curl -X POST https://focussign.com.br/api/assinaturas \
-H "Authorization: Bearer fs_live_7f2a9c..." \
-F "nome=Holerite Setembro/2026 - João Silva" \
-F 'signatarios=[{"nome":"João Silva","email":"joao@empresa.com","telefone":"11988887777","documento":"12345678900","metodo":"whatsapp"}]' \
-F "file=@holerite-joao-setembro.pdf;type=application/pdf"Resposta · 201 Created
{
"id": "87c74195-abff-44f7-827b-ff024a495ddd",
"signatarios": [
{
"signatarioId": "37658091-44f9-4bca-8328-64ea0c2b42b4",
"nome": "João Silva",
"email": "joao@empresa.com",
"telefone": "11988887777",
"metodo": "whatsapp",
"link": "https://focussign.com.br/assinar/xsElwooQRId1..."
}
]
}signatarios[].link só existe nesta resposta. O token que sustenta o link é hasheado no banco logo em seguida — essa é a única janela em que ele é legível. Se você quer enviar o link pelo seu próprio canal de WhatsApp, capture-o já nesta chamada.
Cadastro de signatário
Cada item do array "signatarios" aceita os campos abaixo. "nome" e "email" sempre obrigatórios; "telefone" só quando o canal é WhatsApp.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| nome | string | sim | Nome completo exibido na tela de assinatura e no certificado. |
| string | sim | Usado sempre para o código de verificação (OTP), independente do canal do convite. | |
| telefone | string | se metodo=whatsapp | DDD + número, com ou sem 55 na frente — o código do país é completado automaticamente antes de repassar para a API da Meta. |
| documento | string | opcional | CPF do signatário, incluído no certificado de autenticidade. |
| papel | string | opcional | Texto livre — "Signatário", "Testemunha", etc. |
| metodo | email · whatsapp · sms · presencial | padrão email | Canal usado para entregar o convite (o código de verificação em si sempre vai por e-mail). |
| ordem | número | opcional | Só importa quando o documento é sequencial. |
Antes desta data, "metodo: whatsapp" existia mas não funcionava de verdade — o sistema tentava enviar pela API da Meta usando o e-mail do signatário no lugar do telefone, e nenhum telefone sequer existia no cadastro. Hoje isso é validado na criação: mandar whatsapp sem telefone retorna 400.
Webhooks — confirmação de recebimento e assinatura
É assim que você sabe, sem consultar nada, que o documento foi aberto e assinado. Configure a URL uma vez; a partir daí toda mudança de estado é entregue via POST.
/api/webhooksautenticado · configuração únicaRegistrar sua URL
curl -X POST https://focussign.com.br/api/webhooks \
-H "Authorization: Bearer fs_live_7f2a9c..." \
-H "Content-Type: application/json" \
-d '{"url":"https://seusistema.com.br/webhooks/focussign","eventos":"documento.visualizado,documento.assinado,documento.concluido"}'| Evento | Quando dispara | dados |
|---|---|---|
| documento.enviado | documento criado e convites enviados | {documentoId, nome} |
| documento.visualizado | signatário abriu o link pela 1ª vez | {documentoId, signatarioId} |
| documento.assinado | esse signatário específico assinou | {documentoId, signatarioId} |
| documento.concluido | todos os signatários assinaram | {documentoId, nome, hashVerificacao} |
| documento.recusado | signatário recusou assinar | {documentoId, signatarioId, motivo} |
Para comprovar que o destinatário recebeu e assinou, os dois que importam são documento.visualizado e documento.assinado.
POST recebido na sua URL
Headers:
X-Focus-Sign-Event: documento.assinado
X-Focus-Sign-Signature: sha256=e3b0c44298fc1c14...
Body:
{
"evento": "documento.assinado",
"dados": { "documentoId": "87c74195...", "signatarioId": "37658091..." },
"criadoEm": "2026-09-07T03:16:50.179Z"
}Verificar a assinatura HMAC · Node.js
const crypto = require("node:crypto");
function valido(corpoRaw, assinaturaHeader, secret) {
const esperado = "sha256=" + crypto
.createHmac("sha256", secret)
.update(corpoRaw)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(assinaturaHeader),
Buffer.from(esperado)
);
}Entrega em memória, não é uma fila durável: até 3 tentativas (backoff de 5s e 10s) e timeout de 10s por tentativa. Se o processo reiniciar no meio de um retry, aquela entrega se perde silenciosamente. Para um caso crítico como comprovação de recebimento, reconcilie periodicamente via GET /assinaturas/:id em vez de confiar só no webhook.
Link de assinatura e PDF final
O link já vem na resposta da criação (seção 02). Depois de assinado, o PDF certificado fica disponível por dois caminhos.
/api/assinaturas/:id/pdfautenticadoRetorna o PDF assinado (ou o original, se ainda não concluído) como application/pdf. Use o id do documento, devolvido na criação.
/verificar/:hash/pdfrota pública, sem tokenO hash vem no payload do webhook documento.concluido (campo hashVerificacao). Não expira e não depende do token de nenhum signatário — é a forma mais estável de guardar o comprovante a longo prazo.
Consultar status do documento
Consulta pontual do estado atual e do histórico de eventos.
/api/assinaturas/:idautenticadoResposta · 200
{
"id": "87c74195-abff-44f7-827b-ff024a495ddd",
"nome": "Holerite Setembro/2026 - João Silva",
"status": "assinado",
"signatarios": [
{
"nome": "João Silva",
"status": "assinado",
"assinadoEm": "2026-09-07T14:02:11.000Z",
"ip": "189.45.12.203"
}
],
"hashVerificacao": "a7f79670-98d5..."
}status do documento: rascunho · aguardando · assinado · recusado · expirado · cancelado. status por signatário: pendente · visualizado · assinado · recusado.
Limitações atuais
Para não ter surpresa integrando: o que existe hoje, exatamente como existe.
O envio automático de convite por WhatsApp (feito pelo Focus Sign, com metodo: whatsapp) depende do tenant ter uma conta Meta Business/WhatsApp Cloud API própria configurada em Configurações → Integrações. Sem isso, o convite cai em log interno e ninguém recebe nada — o link ainda vem certo na resposta da API, então seu sistema pode enviá-lo por conta própria independente disso.
Webhooks são entregues em memória (seção 04) — reconcilie periodicamente via GET /assinaturas/:id se a confirmação de recebimento for crítica para o seu fluxo.
Esta página cobre o que a integração de assinaturas precisa hoje; endpoints de gestão interna (pastas, clientes, modelos etc.) não fazem parte deste escopo.
Referência rápida
Todos os endpoints desta página, em uma tabela.
| Endpoint | Uso |
|---|---|
POST /api/assinaturas | Cria documento + signatários, devolve os links de assinatura |
POST /api/webhooks | Registra a URL de callback (feito uma vez) |
GET /api/assinaturas/:id | Status atual + histórico de eventos do documento |
GET /api/assinaturas/:id/pdf | PDF assinado, autenticado |
GET /verificar/:hash/pdf | PDF assinado, público, via hash do certificado |