Dazr Sign API: documentatie voor ontwikkelaars
Bereid documenten voor en verstuur ze ter ondertekening vanuit je eigen software, namens de mensen die deze gebruiken. Ondertekenaars tekenen zoals altijd met Dazr Sign: aangemeld met Dazr Identity, op hun beurt, één keer.
- Snel aan de slag
- Teksttags
- Pop-ups
- Gekwalificeerde handtekeningen
- Webhooks
- Naslag
- Fouten en limieten
- Overdrachten
Snel aan de slag
- Schakel de Dazr Sign API in. Open in het Sign-portaal Ontwikkelaars en kies Dazr Sign API inschakelen voor je app. Elke app van je organisatie staat daar en in de console van Dazr Identity, met dezelfde client-ID en hetzelfde secret; elke API schakel je apart in. Je kunt daar ook een nieuwe app registreren.
- Vraag de scope
signaan. Stuur mensen door de gebruikelijke flow van Inloggen met Dazr Identity metscope=openid sign(voegoffline_accesstoe voor een refresh token). Het toestemmingsscherm vermeldt dat je app namens hen documenten mag voorbereiden en ter ondertekening versturen, en de status ervan mag zien. Dit werkt met alleen de Dazr Sign API; wie ook gegevens van mensen vraagt (profile,emailen de andere), heeft ook de Dazr Identity API nodig. - Roep de API aan met het toegangstoken. Het basisadres is
https://sign.dazr.eu/api/sign/v1. StuurAuthorization: Bearer <access token>en JSON. - Maak een document en verstuur het. Upload een pdf met teksttags en een lijst ontvangers en verstuur het, of open de voorbereidingspop-up zodat de persoon zelf de velden plaatst.
// 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"
Teksttags
Typ de velden als tekst in de pdf. Elke tag wordt vervangen door een veld van dezelfde grootte of groter, en de tagtekst wordt overschilderd, zodat ondertekenaars die nooit zien.
| Tag | Veld |
|---|---|
{{signature:1}} | Handtekening van de eerste ontvanger |
{{initials:2}} | Paraaf van de tweede ontvanger |
{{name:1}} {{date:1}} | Naam en datum van ondertekening, ingevuld door Dazr Sign |
{{text:2:Company}} | Een tekstveld met het label Company |
{{checkbox:2:Terms:optional}} | Een optioneel selectievakje |
{{company:1}} | Bedrijfsnaam (ingevuld wanneer de persoon namens een organisatie tekent) |
Het getal is de positie van de ontvanger in recipients, vanaf 1. Een tag voor een ontvanger die je niet hebt opgegeven, voegt een lege ontvanger toe, in te vullen in de voorbereidingspop-up. Stuur "text_tags": false om tags te negeren. Je kunt ook fields sturen met posities in punten (1/72 inch) vanaf de linkerbovenhoek van de pagina: { "recipient": 1, "type": "signature", "page": 1, "x": 72, "y": 600, "width": 180, "height": 48 }. Een value op een tekst-, bedrijfs- of selectievakveld legt het vast: de ondertekenaar ziet het en kan het niet wijzigen.
Pop-ups: voorbereiden en ondertekenen
Maak een concept met "prepare": { "origin": "https://app.example.eu" } en je krijgt een prepare_url. Open die in een pop-up: de persoon plaatst ontvangers en velden in een compacte editor en klikt dan op Versturen of Opslaan als sjabloon. Voor een ondertekenaar die aan de beurt is, geeft POST /documents/{id}/recipients/{recipient_id}/signing_url een ondertekenpop-up. Beide links zijn 10 tot 15 minuten geldig en werken één keer. Zo nodig meldt de persoon zich in de pop-up aan bij Dazr Identity, met het adres waarnaar het document is verstuurd.
Als het klaar is, stuurt de pop-up { type: 'dazr-sign', event, document_id, template_id, recipient_id, state } met postMessage naar de pagina die hem opende, alleen als die pagina op een van de pop-uporigins van je app staat (standaard de origins van je redirect-URI’s), en sluit dan. event is sent, saved, cancelled, signed of declined. Met redirect_uri (een van je geregistreerde redirect-URI’s) en state keert een pop-up die zijn opener kwijt is daarheen terug, met dezelfde waarden als queryparameters.
<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>
Als je pagina Cross-Origin-Opener-Policy: same-origin stuurt, gebruik dan same-origin-allow-popups, anders kan de pop-up niets terugmelden.
Gekwalificeerde handtekeningen
Elke ondertekenaar heeft een level: "advanced" (standaard: het e-mailadres wordt bevestigd door in te loggen met Dazr Identity) of "qualified". Een gekwalificeerde ondertekenaar downloadt de pdf in Dazr Sign, ondertekent die met een eigen gekwalificeerde elektronische handtekening (een elektronische identiteitskaart, een ondertekeningsapp zoals itsme, een gekwalificeerd certificaat in Adobe Acrobat Reader) en uploadt het ondertekende bestand. Dazr Sign controleert het tegen de EU-vertrouwenslijsten en accepteert het alleen als het een gekwalificeerde handtekening is op precies het bestand dat Dazr Sign meegaf. Dazr geeft zelf geen gekwalificeerde handtekeningen uit.
Stel het niveau per ontvanger in: { "name": "Mario Rossi", "email": "mario@example.eu", "level": "qualified" }. Een gekwalificeerde ondertekenaar heeft geen paraafvelden. name_rule op het document bepaalt wat er gebeurt als de naam op het certificaat afwijkt van de naam van de ontvanger: "warn" (standaard: geaccepteerd, met name_matches false) of "block" (geweigerd). Sjablonen bewaren het niveau van elke rol, en from_template kan een rol verhogen naar "qualified".
Elke handtekening blijft geldig: latere handtekeningen en het afsluitende Dazr-zegel worden als incrementele updates toegevoegd, en de audittrail van zo’n document is een aparte verzegelde pdf op GET /documents/{id}/audit.pdf. Ontvangers in documenten en webhooks hebben level en, zodra een gekwalificeerde ondertekenaar heeft ondertekend, 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 of CAdES) en name_matches. Elk ander level geeft 400 invalid_level.
Webhooks
Stel in het Sign-portaal onder Ontwikkelaars een webhook-URL in voor je app. Je krijgt het ondertekeningssecret één keer te zien. Dazr Sign stuurt sign.document.sent, viewed, signed, completed, declined, voided en expired voor de documenten die je app heeft gemaakt, met de status van het document en van de ontvangers, nooit de inhoud. Mislukte leveringen worden opnieuw geprobeerd na 5 minuten, 30 minuten, 2, 6, 12 en 24 uur; het leveringslog toont elke poging en kan er een opnieuw versturen.
// 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: [...] } } }
Naslag
Alle paden beginnen met https://sign.dazr.eu/api/sign/v1. Tijden zijn ISO 8601 in UTC.
| Verzoek | Wat het doet |
|---|---|
POST /documents | Maakt een concept van een pdf: file in base64, een multipart-upload (file plus data als JSON) of een upload_id. Optioneel: title, message, recipients, fields, signing_order, deadline_days, reminder_days, send, prepare. |
POST /documents/from_template | Maakt een concept van een sjabloon: template_id, recipients als { role, name, email }, values per veld-ID of label. |
GET /documents | Toont de documenten van je app voor deze persoon, nieuwste eerst: limit (tot 100), cursor, status. |
GET /documents/{id} | Het document met zijn status, ontvangers en velden. |
POST /documents/{id}/send | Verstuurt een concept. |
POST /documents/{id}/remind | Herinnert de ondertekenaars die aan de beurt zijn (hooguit één keer per uur). |
POST /documents/{id}/void | Annuleert een document dat ter ondertekening uitstaat, met een optionele reason. |
DELETE /documents/{id} | Verwijdert een concept of een afgesloten document. |
POST /documents/{id}/prepare_url | Een nieuwe voorbereidingspop-up voor een concept: origin, redirect_uri, state. |
POST /documents/{id}/recipients/{recipient_id}/signing_url | Een ondertekenpop-up voor een ondertekenaar die aan de beurt is: origin, redirect_uri, state. |
GET /documents/{id}/original.pdf | De pdf zoals hij is verstuurd. |
GET /documents/{id}/signed.pdf | De verzegelde kopie, zodra iedereen heeft getekend. |
GET /documents/{id}/audit.json | Het auditspoor: gebeurtenissen, hashes en ondertekenaars. |
GET /documents/{id}/audit.pdf | De aparte, verzegelde audittrail van een document met gekwalificeerde ondertekenaars, zodra iedereen heeft ondertekend. |
POST /uploads | Start een upload in delen voor pdf’s groter dan 4 MB: size. Daarna PUT /uploads/{upload_id}/parts/{n} met de ruwe bytes van elk deel. |
GET /templates | De sjablonen van de persoon, met hun rollen en velden. |
GET /templates/{id} | Eén sjabloon. |
POST /templates | Slaat een van de documenten van je app op als sjabloon: document_id, name. |
DELETE /templates/{id} | Verwijdert een sjabloon. |
Stuur een header Idempotency-Key mee wanneer je een document maakt: dezelfde sleutel en body binnen 24 uur geven hetzelfde document terug (header Idempotent-Replayed: true) in plaats van een tweede.
Fouten en limieten
Fouten hebben een HTTP-status en een body zoals { "error": { "code": "not_found", "message": "..." } }, soms met details zoals index.
| Status | Codes |
|---|---|
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 (verlopen of ingetrokken, of de persoon heeft je app verwijderd) |
403 | insufficient_scope, sign_api_disabled |
404 | not_found (ook voor documenten die je app niet heeft gemaakt), 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, met een header Retry-After |
- Pdf’s tot 25 MB en 200 pagina’s, zonder wachtwoord. Verzoeken tot 4 MB; grotere pdf’s gaan via
/uploads. - Tot 20 ontvangers en 400 velden per document, 100 sjablonen per persoon. Documenten en sjablonen tellen mee voor de Dazr-opslag van de persoon.
- 120 verzoeken per minuut per persoon per app, 30 nieuwe documenten per 10 minuten en 30 verzendingen per uur.
- Toegangstokens zijn 10 minuten geldig. Gebruik het refresh token (
offline_access) om een nieuw te krijgen.
Een app overdragen
Een app kan naar een andere organisatie op Dazr verhuizen, via App overdragen in de instellingen van de app. Met de Dazr Sign API aan kan dat alleen naar een geverifieerde organisatie, en een eigenaar of beheerder daar moet binnen 14 dagen accepteren. De ontwikkelaarsdocumentatie van Dazr Identity beschrijft elke stap.
- Documenten die je app vóór de overdracht heeft gemaakt, blijven bij de mensen van wie ze zijn. De app ziet ze niet meer via de API en er worden geen webhooks meer voor verstuurd.
- De webhook-URL en de pop-up-origins blijven. Het ondertekeningsgeheim voor webhooks wordt vernieuwd en één keer getoond aan wie accepteert.
- Toegangstokens en refresh-tokens van vóór de overdracht werken niet meer, en mensen geven bij hun volgende keer inloggen opnieuw toestemming. Sjablonen zijn van mensen en veranderen niet.
- Aantallen documenten in het Sign-portaal beginnen opnieuw bij de overdracht.