API do Dazr Sign: documentação para programadores
Prepare e envie documentos para assinatura a partir do seu próprio software, em nome das pessoas que o usam. Os signatários assinam com o Dazr Sign como habitualmente: com sessão iniciada no Dazr Identity, à vez, uma só vez.
- Início rápido
- Etiquetas de texto
- Janelas pop-up
- Assinaturas qualificadas
- Webhooks
- Referência
- Erros e limites
- Transferências
Início rápido
- Ative a API do Dazr Sign. No portal do Sign, abra Programadores e escolha Ativar a API do Dazr Sign para a sua aplicação. Todas as aplicações da sua organização aparecem aí e na consola do Dazr Identity, com o mesmo ID e segredo de cliente; cada API é ativada separadamente. Também pode registar aí uma nova aplicação.
- Peça o âmbito
sign. Envie as pessoas pelo fluxo habitual Iniciar sessão com Dazr Identity comscope=openid sign(acrescenteoffline_accesspara um refresh token). O ecrã de consentimento indica que a sua aplicação pode preparar e enviar documentos para assinatura em nome da pessoa e ver o seu estado. Isto funciona só com a API do Dazr Sign; pedir também dados das pessoas (profile,emaile os outros) exige que a API do Dazr Identity também esteja ativa. - Chame a API com o token de acesso. O endereço base é
https://sign.dazr.eu/api/sign/v1. EnvieAuthorization: Bearer <access token>e JSON. - Crie e envie um documento. Carregue um PDF com etiquetas de texto e uma lista de destinatários e depois envie-o, ou abra a janela de preparação para que a pessoa coloque os campos.
// Node 18+: create a document from a PDF with text tags, then send it
import fs from 'node:fs';
const api = 'https://sign.dazr.eu/api/sign/v1';
const headers = { Authorization: 'Bearer ' + accessToken, 'Content-Type': 'application/json' };
let res = await fetch(api + '/documents', {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': 'order-1042' },
body: JSON.stringify({
title: 'Service agreement',
file: fs.readFileSync('agreement.pdf').toString('base64'),
recipients: [
{ name: 'Alex Example', email: 'alex@example.eu' },
{ name: 'Sam Client', email: 'sam@client.example' },
],
}),
});
const { document } = await res.json();
res = await fetch(api + '/documents/' + document.id + '/send', { method: 'POST', headers });
console.log((await res.json()).document.status); // "sent"
Etiquetas de texto
Escreva os campos no PDF como texto. Cada etiqueta é substituída por um campo do mesmo tamanho ou maior, e o texto da etiqueta é coberto, para que os signatários nunca o vejam.
| Etiqueta | Campo |
|---|---|
{{signature:1}} | Assinatura do primeiro destinatário |
{{initials:2}} | Rubrica do segundo destinatário |
{{name:1}} {{date:1}} | Nome e data da assinatura, preenchidos pelo Dazr Sign |
{{text:2:Company}} | Um campo de texto com a legenda Empresa |
{{checkbox:2:Terms:optional}} | Uma caixa de verificação opcional |
{{company:1}} | Nome da empresa (preenchido quando a pessoa assina em nome de uma organização) |
O número é a posição do destinatário em recipients, a começar em 1. Uma etiqueta para um destinatário que não indicou acrescenta um destinatário vazio, a preencher na janela de preparação. Envie "text_tags": false para ignorar as etiquetas. Também pode enviar fields com posições em pontos (1/72 de polegada) a partir do canto superior esquerdo da página: { "recipient": 1, "type": "signature", "page": 1, "x": 72, "y": 600, "width": 180, "height": 48 }. Um value num campo de texto, empresa ou caixa de verificação fixa-o: o signatário vê-o e não o pode alterar.
Janelas pop-up: preparar e assinar
Crie um rascunho com "prepare": { "origin": "https://app.example.eu" } e recebe um prepare_url. Abra-o numa janela pop-up: a pessoa coloca destinatários e campos num editor compacto e depois clica em Enviar ou Guardar como modelo. Para um signatário cuja vez chegou, POST /documents/{id}/recipients/{recipient_id}/signing_url dá uma janela de assinatura. Ambas as ligações são válidas durante 10 a 15 minutos e funcionam uma vez. A pessoa inicia sessão com o Dazr Identity dentro da janela, se necessário, com o endereço para onde o documento foi enviado.
Quando termina, a janela envia { type: 'dazr-sign', event, document_id, template_id, recipient_id, state } com postMessage para a página que a abriu, só se essa página estiver numa das origens de pop-up da sua aplicação (por defeito, as origens dos seus URIs de redirecionamento), e fecha-se. event é sent, saved, cancelled, signed ou declined. Com redirect_uri (um dos seus URIs de redirecionamento registados) e state, uma janela que perdeu a página de origem volta para lá com os mesmos valores como parâmetros de consulta.
<script src="https://sign.dazr.eu/sdk.js"></script>
<script>
document.querySelector('#sign').addEventListener('click', async () => {
// Ask your server for the URL after the click: the popup opens at once.
const url = fetch('/my-server/prepare-url').then(r => r.json()).then(j => j.prepare_url);
const result = await DazrSign.open(url);
if (result.event === 'sent') showSent(result.document_id);
// 'closed': the window was closed; check the status with the API or a webhook
});
</script>
Se a sua página enviar Cross-Origin-Opener-Policy: same-origin, use same-origin-allow-popups, caso contrário a janela não consegue comunicar o resultado.
Assinaturas qualificadas
Cada signatário tem um level: "advanced" (a predefinição: o endereço de e-mail é confirmado ao iniciar sessão com o Dazr Identity) ou "qualified". Um signatário qualificado transfere o PDF no Dazr Sign, assina-o com a sua própria assinatura eletrónica qualificada (um cartão de cidadão, uma aplicação de assinatura como o itsme, um certificado qualificado no Adobe Acrobat Reader) e carrega o ficheiro assinado. O Dazr Sign verifica-o com as listas de confiança da UE e só o aceita se for uma assinatura qualificada exatamente sobre o ficheiro que entregou. O Dazr não emite assinaturas qualificadas.
Defina o nível por destinatário: { "name": "Mario Rossi", "email": "mario@example.eu", "level": "qualified" }. Um signatário qualificado não tem campos de rubrica. name_rule no documento indica o que acontece quando o nome no certificado difere do nome do destinatário: "warn" (a predefinição: aceite, com name_matches false) ou "block" (recusado). Os modelos mantêm o nível de cada função, e from_template pode elevar uma função a "qualified".
Todas as assinaturas continuam válidas: as assinaturas posteriores e o selo final do Dazr são acrescentados como atualizações incrementais, e o registo de auditoria de um documento destes é um PDF selado separado em GET /documents/{id}/audit.pdf. Os destinatários nos documentos e webhooks têm level e, depois de um signatário qualificado ter assinado, certificate: subject (common_name, given_name, surname, serial_number, country, organization, organization_identifier), issuer, serial, sha256, trust_service_provider, trusted_list_country, signing_time, trusted_timestamp, format (PAdES ou CAdES) e name_matches. Qualquer outro level dá 400 invalid_level.
Webhooks
Defina um URL de webhook para a sua aplicação no portal do Sign, em Programadores. Recebe o respetivo segredo de assinatura uma vez. O Dazr Sign envia sign.document.sent, viewed, signed, completed, declined, voided e expired para os documentos que a sua aplicação criou, com o estado do documento e o estado dos destinatários, nunca o conteúdo. As entregas falhadas são repetidas após 5 minutos, 30 minutos, 2, 6, 12 e 24 horas; o registo de entregas mostra cada tentativa e pode reenviar uma.
// Node: check the Dazr-Signature header (t=<unix time>,v1=<HMAC-SHA256 hex>)
import crypto from 'node:crypto';
export function verify(rawBody, header, secret) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || '');
if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
const want = crypto.createHmac('sha256', secret).update(m[1] + '.' + rawBody).digest();
return crypto.timingSafeEqual(want, Buffer.from(m[2], 'hex'));
}
// The body: { id, type: 'sign.document.completed', created, data: { document: { id, status, recipients: [...] } } }
Referência
Todos os caminhos começam por https://sign.dazr.eu/api/sign/v1. As horas estão em ISO 8601, em UTC.
| Pedido | O que faz |
|---|---|
POST /documents | Cria um rascunho a partir de um PDF: file em base64, um carregamento multipart (file e data como JSON) ou um upload_id. Opcional: title, message, recipients, fields, signing_order, deadline_days, reminder_days, send, prepare. |
POST /documents/from_template | Cria um rascunho a partir de um modelo: template_id, recipients como { role, name, email }, values por ID ou legenda do campo. |
GET /documents | Lista os documentos da sua aplicação para esta pessoa, os mais recentes primeiro: limit (até 100), cursor, status. |
GET /documents/{id} | O documento com o estado, os destinatários e os campos. |
POST /documents/{id}/send | Envia um rascunho. |
POST /documents/{id}/remind | Lembra os signatários cuja vez chegou (no máximo uma vez por hora). |
POST /documents/{id}/void | Cancela um documento em assinatura, com um reason opcional. |
DELETE /documents/{id} | Elimina um rascunho ou um documento encerrado. |
POST /documents/{id}/prepare_url | Uma nova janela de preparação para um rascunho: origin, redirect_uri, state. |
POST /documents/{id}/recipients/{recipient_id}/signing_url | Uma janela de assinatura para um signatário cuja vez chegou: origin, redirect_uri, state. |
GET /documents/{id}/original.pdf | O PDF tal como foi enviado. |
GET /documents/{id}/signed.pdf | A cópia selada, depois de todos terem assinado. |
GET /documents/{id}/audit.json | O registo de auditoria: eventos, hashes e signatários. |
GET /documents/{id}/audit.pdf | O registo de auditoria separado e selado de um documento com signatários qualificados, depois de todos terem assinado. |
POST /uploads | Inicia um carregamento por partes para PDF com mais de 4 MB: size. Depois PUT /uploads/{upload_id}/parts/{n} com os bytes de cada parte. |
GET /templates | Os modelos da pessoa, com as respetivas funções e campos. |
GET /templates/{id} | Um modelo. |
POST /templates | Guarda um dos documentos da sua aplicação como modelo: document_id, name. |
DELETE /templates/{id} | Elimina um modelo. |
Envie um cabeçalho Idempotency-Key quando cria um documento: a mesma chave e o mesmo corpo em 24 horas devolvem o mesmo documento (cabeçalho Idempotent-Replayed: true) em vez de um segundo.
Erros e limites
Os erros têm um estado HTTP e um corpo como { "error": { "code": "not_found", "message": "..." } }, por vezes com pormenores como index.
| Estatuto | Códigos |
|---|---|
400 | invalid_field, invalid_recipients, invalid_email, not_pdf, pdf_unreadable, pdf_encrypted, invalid_origin, invalid_redirect_uri, unknown_role, unknown_field |
401 | unauthenticated, invalid_token (expirado ou revogado, ou a pessoa removeu a sua aplicação) |
403 | insufficient_scope, sign_api_disabled |
404 | not_found (também para documentos que a sua aplicação não criou), template_not_found |
409 | not_draft, not_sent, not_your_turn, not_signable, signer_without_fields, no_signers, void_first, idempotency_in_progress |
413 | pdf_too_large, too_large, quota |
422 | idempotency_key_reused |
429 | rate_limited, com um cabeçalho Retry-After |
- PDF até 25 MB e 200 páginas, sem palavra-passe. Pedidos até 4 MB; os PDF maiores passam por
/uploads. - Até 20 destinatários e 400 campos por documento, 100 modelos por pessoa. Os documentos e modelos contam para o armazenamento Dazr da pessoa.
- 120 pedidos por minuto por pessoa e por aplicação, 30 documentos novos a cada 10 minutos e 30 envios por hora.
- Os tokens de acesso duram 10 minutos. Use o refresh token (
offline_access) para obter um novo.
Transferir uma aplicação
Uma aplicação pode passar para outra organização registada na Dazr, em Transferir aplicação, nas definições da aplicação. Com a API do Dazr Sign ativada, só pode passar para uma organização verificada, e um proprietário ou administrador dessa organização tem de a aceitar no prazo de 14 dias. A documentação para programadores do Dazr Identity descreve cada passo.
- Os documentos que a sua aplicação criou antes da transferência ficam com as pessoas a quem pertencem. A aplicação deixa de os ver através da API, e não são enviados webhooks relativos a eles.
- O URL do webhook e as origens dos pop-ups mantêm-se. O segredo de assinatura do webhook é renovado e mostrado uma única vez ao administrador que aceita.
- Os tokens de acesso e de atualização emitidos antes da transferência deixam de funcionar, e as pessoas aprovam novamente a aplicação no início de sessão seguinte. Os modelos pertencem às pessoas e não são afetados.
- As contagens de documentos no portal do Sign recomeçam a partir da transferência.