Integrando com Bubble
Use o API Connector com o header Authorization marcado como Private e um Backend Workflow para o webhook.
Secret key
API Connector → Shared headers → Authorization: Bearer <chave> com "Private" marcado.
Arquitetura
Workflow Bubble → API Connector (server-side) → AssinAPI. Webhook → Backend Workflow (API) → Thing do contrato.
Criar envelope
- Cria um envelope (rascunho).
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: POST
URL: https://sandbox.api.assinapi.com.br/v1/envelopes
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Header: Content-Type: application/json
Body (JSON):
{
"title": "Contrato de prestação de serviços",
"expirationDays": 7
}
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Enviar PDF
- Anexa o PDF ao envelope. O SHA-256 é calculado pela AssinAPI.
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: POST
URL: https://sandbox.api.assinapi.com.br/v1/envelopes/ENVELOPE_ID/documents
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Body: multipart/form-data — campo "file" (PDF)
Alternativa low-code: POST /documents com JSON { "filename": "contrato.pdf", "contentBase64": "<PDF em base64>" }
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Adicionar signatário
- Adiciona um signatário (CPF obrigatório na assinatura avançada).
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: POST
URL: https://sandbox.api.assinapi.com.br/v1/envelopes/ENVELOPE_ID/signers
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Header: Content-Type: application/json
Body (JSON):
{
"name": "João da Silva",
"email": "joao@email.com",
"cpf": "529.982.247-25",
"authenticationMethod": "EMAIL_OTP"
}
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Enviar para assinatura
- Envia para assinatura. A resposta traz os signingLinks.
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: POST
URL: https://sandbox.api.assinapi.com.br/v1/envelopes/ENVELOPE_ID/send
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Header: Content-Type: application/json
Body (JSON):
{
"notify": true
}
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Consultar status
- Consulta status do envelope e dos signatários.
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: GET
URL: https://sandbox.api.assinapi.com.br/v1/envelopes/ENVELOPE_ID
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Baixar documento assinado
- Retorna URLs temporárias do PDF assinado, certificado e manifesto.
- Plugins → API Connector. Marque o header Authorization como "Private" para que a chave nunca vá ao navegador.
text
Bubble — API Connector
Método: GET
URL: https://sandbox.api.assinapi.com.br/v1/envelopes/ENVELOPE_ID/evidence
Header: Authorization: Bearer <ASSINAPI_SECRET_KEY> (privado)
Resposta de erro: { "error": { "code", "message", "hint", "requestId" } }Receber webhooks
- Valide SEMPRE a assinatura HMAC (X-Signature) usando o corpo bruto.
- Rejeite eventos com X-Timestamp com mais de 5 minutos e deduplique por X-Event-Id.
- Responda 2xx rapidamente; processe de forma assíncrona. Falhas são reenviadas com backoff exponencial.
- Plataformas low-code: receba o webhook em um backend (Supabase Edge Function, Cloudflare Worker ou n8n com Code node) para validar o HMAC.
text
1) Registre o endpoint:
curl -X POST "https://sandbox.api.assinapi.com.br/v1/webhooks" \
-H "Authorization: Bearer $ASSINAPI_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://seu-sistema.com/api/webhooks/assinapi", "events": ["envelope.completed", "signer.signed"] }'
# Guarde o "secret" (whsec_…) retornado em ASSINAPI_WEBHOOK_SECRET
2) No receptor, calcule:
HMAC_SHA256(secret, X-Event-Id + "." + X-Timestamp + "." + corpo_bruto)
e compare com X-Signature (formato v1=<hex>).