API SafySign
Envio de documento para assinatura
Endpoint único para integrar ERPs e SaaS. O body é JSON com o PDF em Base64 e a lista de destinatários com posições de assinatura.
Endpoint
POST https://api.safysign.com/create-envelope-signature
Autenticação
Use uma API Key criada em Configurações → API Keys, com o escopo envelopes:write. Envie o secret no header:
Authorization: Bearer ssk_live_…O secret é exibido apenas na criação. Em caso de vazamento, revogue a key no dashboard (efeito imediato) e gere outra. Login com e-mail/senha continua disponível para o aplicativo, mas não é o caminho recomendado para integrações servidor-a-servidor.
Payload
Body esperado em POST /create-envelope-signature:
POST/create-envelope-signature
{
"folder": "320777",
"name": "CONTRATO DE VENDAS AME",
"file": "data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDIgMCBSL01lZGlhQm94WzAgMCA2MTIgNzkyXS9Db250ZW50cyA0IDAgUj4+CmVuZG9iago...",
"silent_mode": false,
"width_page": 800,
"recipients": [
{
"send_to": "cliente@email.com",
"message": "Seu contrato está pronto para assinatura",
"subject": "Assinatura TAC - Contrato",
"fullname": "João da Silva",
"cpf": "12345678901",
"birthdate": "15/03/1990",
"doubleauth": false,
"allow_selfie": true,
"allow_document": false,
"allow_document_back": false,
"allow_cpf": false,
"allow_birth_date": false,
"signature_type": "Assinatura Eletrônica",
"send_finished": false,
"expire_date": "2026-08-27",
"signature_mode": "all",
"certificate": false,
"fields": [
{
"type": "signature",
"page": 1,
"width": 100,
"height": 100,
"xPos": 350,
"yPos": 1050,
"align": "right"
}
]
}
]
}curl -X POST "https://api.safysign.com/create-envelope-signature" \
-H "Authorization: Bearer ssk_live_…" \
-H "Content-Type: application/json" \
-d @payload.jsonfolder: aceito no JSON por compatibilidade, mas ignorado pela SafySign (a pasta é definida pela conta). Pode manter sem quebrar a chamada.
Campos da raiz
folderstring · opcional
Identificador de pasta.
namestring · obrigatório
Nome do documento / envelope (ex.: CONTRATO DE VENDAS AME).
filestring (base64) · obrigatório
PDF em Base64, com prefixo data:application/pdf;base64,.
silent_modeboolean · opcional
false = dispara convite aos destinatários por EMAIL. true = só retorna links, sem envio automático.
width_pagenumber · opcional
Largura de referência da página para as coordenadas de fields (no exemplo: 800).
recipientsarray · obrigatório
Lista de signatários. Mínimo 1 item.
recipients[]
send_tostring · obrigatório
E-mail (ou destino) do signatário.
fullnamestring · obrigatório
Nome completo.
subjectstring · opcional
Assunto do convite.
messagestring · opcional
Corpo da mensagem do convite.
cpfstring · opcional
CPF do signatário.
birthdatestring · opcional
Data de nascimento (ex.: 15/03/1990).
doubleauthboolean · opcional
Autenticação em duas etapas.
allow_selfieboolean · opcional
Exige selfie na assinatura.
allow_documentboolean · opcional
Exige foto do documento (frente).
allow_document_backboolean · opcional
Exige foto do documento (verso).
allow_cpfboolean · opcional
Exige confirmação de CPF.
allow_birth_dateboolean · opcional
Exige confirmação de data de nascimento.
signature_typestring · opcional
Tipo de assinatura (ex.: Assinatura Eletrônica).
send_finishedboolean · opcional
Notifica ao concluir o fluxo.
expire_datestring · opcional
Validade do convite (ex.: 2026-08-27).
signature_modeall | draw | text | upload · opcional
Modos de assinatura aceitos. No exemplo: all.
certificateboolean · opcional
Exige certificado digital.
fieldsarray · opcional
Posições dos widgets no PDF.
fields[]
Coordenadas no sistema do width_page: xPos, yPos, width, height.
typestring · obrigatório
Tipo do campo — no exemplo: signature.
pagenumber · obrigatório
Página do PDF (começando em 1).
widthnumber · obrigatório
Largura do campo.
heightnumber · obrigatório
Altura do campo.
xPosnumber · obrigatório
Posição horizontal.
yPosnumber · obrigatório
Posição vertical.
alignstring · opcional
Alinhamento (ex.: right).
Resposta (200)
Em sucesso a SafySign devolve { envelope, provider, delivery_channel }. O objeto provider é a resposta bruta da PlugSign (files/upload/requests):
{
"envelope": {
"id": "019fae21-6032-7bb7-a07b-893853524903",
"user_id": "…",
"company_id": "…",
"status": 2,
"provider_signature_request_id": "9M0ghnd0FWoOf3GYk2OsbjzAp1uGsIh7",
"expiration_at": null,
"documents": [],
"signatories": [],
"created_at": "2026-07-29T13:47:30.664Z",
"updated_at": "2026-07-29T13:47:30.664Z"
},
"provider": {
"data": {
"id": 6231204,
"signing_key": "9M0ghnd0FWoOf3GYk2OsbjzAp1uGsIh7",
"document": "r5fNcbVSPUj4DfaGoYwaUawOVnJxNPIZ",
"email": "cliente@email.com",
"status": "Pending",
"message": "Seu contrato está pronto para assinatura",
"expire_date": "28/08/2026 00:00:00"
},
"message": "Sua solicitação foi criada com sucesso!",
"silent_mode": [
{
"url": "https://signer.safysign.com/view/r5fNcbVSPUj4DfaGoYwaUawOVnJxNPIZ?signingKey=9M0ghnd0FWoOf3GYk2OsbjzAp1uGsIh7",
"email": "cliente@email.com"
}
]
},
"delivery_channel": "Silent"
}envelope.id— ID interno do envelopeenvelope.status—2Em assinatura,3Concluídoenvelope.provider_signature_request_id—provider.data.signing_keyprovider.data.document— document key na PlugSign (útil para download)provider.silent_mode[]— links por destinatário quando o canal é Silent/WhatsApp (url+email). Em e-mail automático esse array pode não vir.delivery_channel— canal efetivo (Email,WhatsAppouSilent)envelope.documentssó é preenchido se enviarstorage_document: true
Webhooks
Após a conclusão, cancelamento ou recusa, a plataforma envia um POST para cada endpoint ativo da sua conta. Cadastre a URL do seu ERP para receber atualizações de status de forma assíncrona, sem precisar consultar a API.
Se um secret foi cadastrado, ele é reenviado no header x-webhook-secret (comparação direta — não é HMAC). Correlacione provider_signature_request_id / signing_key com o envelope.provider_signature_request_id retornado na criação do envelope.
Eventos disponíveis
signature.created— envelope criadosignature.completed— envelope concluído
Lista completa: GET https://api.safysign.com/webhook-endpoints/events. O dispatch ocorre quando o provedor reporta status final (FINISH, SIGNED, DECLINED, CANCELLED) e envia o payload abaixo a todos os endpoints ativos.
Cadastro de endpoints
Base: https://api.safysign.com/webhook-endpoints. Requer autenticação Bearer com escopos webhooks:read (listagem) e webhooks:write (criação, edição e remoção). Também é possível cadastrar endpoints em Configurações → Webhooks no painel.
GET /webhook-endpointsendpoint · opcional
Lista endpoints (query: page, per_page, search, active, event).
GET /webhook-endpoints/:idendpoint · opcional
Detalhe de um endpoint (secret omitido; retorna has_secret).
POST /webhook-endpointsendpoint · opcional
Cadastra URL de recebimento. Retorna secret na resposta de criação.
PATCH /webhook-endpoints/:idendpoint · opcional
Atualiza url, events, active, description ou secret.
DELETE /webhook-endpoints/:idendpoint · opcional
Remove o cadastro (204 No Content).
Campos do body (POST / PATCH)
urlstring (URL) · obrigatório
URL HTTPS do ERP que receberá os POSTs de evento.
secretstring · opcional
Chave reenviada no header x-webhook-secret em cada POST outbound.
eventsstring[] · obrigatório
Um ou mais: signature.created, signature.completed.
activeboolean · opcional
Padrão true. false pausa o envio sem apagar o cadastro.
descriptionstring · opcional
Rótulo interno (ex.: “ERP produção”).
{
"url": "https://erp.suaempresa.com.br/api/safysign/webhooks",
"secret": "sua-chave-secreta-compartilhada",
"events": ["signature.created", "signature.completed"],
"active": true,
"description": "Produção — atualização de pedidos"
}Exemplos de consumo da API de cadastro
curl -X POST "https://api.safysign.com/webhook-endpoints" \
-H "Authorization: Bearer ssk_live_…" \
-H "Content-Type: application/json" \
-d '{"url":"https://erp.suaempresa.com.br/api/safysign/webhooks","secret":"sua-chave-secreta","events":["signature.created","signature.completed"],"active":true}'curl "https://api.safysign.com/webhook-endpoints?page=1&per_page=20" \
-H "Authorization: Bearer ssk_live_…"Payload enviado ao seu ERP
Quando um status final chega do provedor, a SafySign faz POST na url cadastrada com corpo semelhante a:
{
"provider_signature_request_id": "bry-request-uuid",
"signing_key": "bry-request-uuid",
"document_key": null,
"status": 3
}status segue o enum numérico do envelope (ex.: 3 = Concluído, 4 = Cancelado, 5 = Recusado).
Recebedor no ERP (Node.js)
Valide o header x-webhook-secret antes de processar. Responda 2xx para confirmar o recebimento.
import express from "express";
const app = express();
app.use(express.json({ type: "application/json" }));
app.post("/api/safysign/webhooks", (req, res) => {
const secret = process.env.SAFYSIGN_WEBHOOK_SECRET;
const incoming = req.headers["x-webhook-secret"];
if (secret && incoming !== secret) {
return res.status(401).json({ error: "Secret inválido" });
}
const { provider_signature_request_id, status, signing_key, document_key } = req.body;
// Atualize o pedido/contrato no ERP conforme o status do envelope
console.log(provider_signature_request_id, signing_key, document_key, status);
return res.status(200).json({ received: true });
});
app.listen(3000);