Dazr Sign API: dokumentacja dla programistów

Szybki start

  1. Włącz Dazr Sign API. W portalu Sign otwórz Programiści i wybierz Włącz Dazr Sign API dla swojej aplikacji. Każda aplikacja Twojej organizacji jest tam widoczna, a także w konsoli Dazr Identity, z tym samym identyfikatorem klienta i sekretem; każde API włącza się osobno. Możesz tam też zarejestrować nową aplikację.
  2. Poproś o zakres sign. Przeprowadź użytkowników przez zwykły proces Zaloguj się przez Dazr Identity z scope=openid sign (dodaj offline_access, aby otrzymać token odświeżania). Ekran zgody informuje, że aplikacja może w ich imieniu przygotowywać i wysyłać dokumenty do podpisu oraz sprawdzać ich status. Wystarczy Dazr Sign API; aby prosić także o dane użytkowników (profile, email i pozostałe), trzeba włączyć również Dazr Identity API.
  3. Wywołuj API z tokenem dostępu. Adres bazowy to https://sign.dazr.eu/api/sign/v1. Wysyłaj Authorization: Bearer <access token> i JSON.
  4. Utwórz i wyślij dokument. Prześlij plik PDF z tagami tekstowymi i listą odbiorców, a następnie go wyślij albo otwórz okno przygotowania, aby dana osoba sama rozmieściła pola.
// 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"

Tagi tekstowe

Wpisz pola do pliku PDF jako tekst. Każdy tag zostaje zastąpiony polem tej samej lub większej wielkości, a tekst tagu jest zamalowany, więc osoby podpisujące nigdy go nie widzą.

TagPole
{{signature:1}}Podpis pierwszego odbiorcy
{{initials:2}}Inicjały drugiego odbiorcy
{{name:1}} {{date:1}}Imię i nazwisko oraz data podpisu, uzupełniane przez Dazr Sign
{{text:2:Company}}Pole tekstowe z etykietą Company
{{checkbox:2:Terms:optional}}Opcjonalne pole wyboru
{{company:1}}Nazwa firmy (uzupełniana, gdy osoba podpisuje w imieniu organizacji)

Liczba to pozycja odbiorcy w recipients, licząc od 1. Tag dla odbiorcy, którego nie podano, dodaje pustego odbiorcę do uzupełnienia w oknie przygotowania. Wyślij "text_tags": false, aby pominąć tagi. Możesz też wysłać fields z pozycjami w punktach (1/72 cala) od lewego górnego rogu strony: { "recipient": 1, "type": "signature", "page": 1, "x": 72, "y": 600, "width": 180, "height": 48 }. value w polu tekstowym, firmy lub wyboru ustala jego treść: osoba podpisująca ją widzi, ale nie może jej zmienić.

Utwórz wersję roboczą z "prepare": { "origin": "https://app.example.eu" }, a otrzymasz prepare_url. Otwórz go w oknie: dana osoba rozmieszcza odbiorców i pola w kompaktowym edytorze, a potem klika Wyślij lub Zapisz jako szablon. Dla osoby podpisującej, na którą przypada kolej, POST /documents/{id}/recipients/{recipient_id}/signing_url zwraca okno podpisu. Oba linki są ważne od 10 do 15 minut i działają jeden raz. W razie potrzeby osoba loguje się w oknie do Dazr Identity, adresem, na który wysłano dokument.

Po zakończeniu okno wysyła { type: 'dazr-sign', event, document_id, template_id, recipient_id, state } przez postMessage do strony, która je otworzyła, tylko jeśli ta strona znajduje się na jednym z originów okien Twojej aplikacji (domyślnie originy Twoich adresów przekierowania), i zamyka się. event to sent, saved, cancelled, signed lub declined. Z redirect_uri (jednym z zarejestrowanych adresów przekierowania) i state okno, które straciło stronę otwierającą, wraca tam z tymi samymi wartościami jako parametrami zapytania.

<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>

Jeśli Twoja strona wysyła Cross-Origin-Opener-Policy: same-origin, użyj zamiast tego same-origin-allow-popups, inaczej okno nie przekaże wyniku.

Podpisy kwalifikowane

Każda osoba podpisująca ma level: "advanced" (domyślnie: adres e-mail jest potwierdzany logowaniem w Dazr Identity) lub "qualified". Osoba składająca podpis kwalifikowany pobiera plik PDF w Dazr Sign, podpisuje go własnym kwalifikowanym podpisem elektronicznym (e-dowód, aplikacja do podpisu, taka jak itsme, certyfikat kwalifikowany w Adobe Acrobat Reader) i przesyła podpisany plik. Dazr Sign sprawdza go na unijnych listach zaufanych i przyjmuje tylko kwalifikowany podpis złożony dokładnie na przekazanym pliku. Dazr nie wydaje podpisów kwalifikowanych.

Ustaw poziom dla każdego odbiorcy: { "name": "Mario Rossi", "email": "mario@example.eu", "level": "qualified" }. Osoba składająca podpis kwalifikowany nie ma pól parafy. name_rule w dokumencie określa, co się dzieje, gdy imię i nazwisko w certyfikacie różni się od danych odbiorcy: "warn" (domyślnie: przyjęty, z name_matches false) lub "block" (odrzucony). Szablony zachowują poziom każdej roli, a from_template może podnieść rolę do "qualified".

Każdy podpis pozostaje ważny: kolejne podpisy i końcowa pieczęć Dazr są dodawane jako aktualizacje przyrostowe, a ścieżka audytu takiego dokumentu to osobny opieczętowany plik PDF pod GET /documents/{id}/audit.pdf. Odbiorcy w dokumentach i webhookach mają level, a po złożeniu podpisu kwalifikowanego także 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 lub CAdES) i name_matches. Każda inna wartość level daje 400 invalid_level.

Webhooki

Ustaw adres URL webhooka dla aplikacji w portalu Sign, w sekcji Programiści. Sekret podpisu zobaczysz jeden raz. Dazr Sign wysyła sign.document.sent, viewed, signed, completed, declined, voided i expired dla dokumentów utworzonych przez Twoją aplikację, ze statusem dokumentu i odbiorców, nigdy z treścią. Nieudane dostarczenia są ponawiane po 5 minutach, 30 minutach, 2, 6, 12 i 24 godzinach; dziennik dostarczeń pokazuje każdą próbę i pozwala wysłać ją ponownie.

// 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: [...] } } }

Dokumentacja

Wszystkie ścieżki zaczynają się od https://sign.dazr.eu/api/sign/v1. Czas w formacie ISO 8601, w UTC.

ŻądanieCo robi
POST /documentsTworzy wersję roboczą z pliku PDF: file w base64, przesyłanie multipart (file oraz data jako JSON) lub upload_id. Opcjonalnie: title, message, recipients, fields, signing_order, deadline_days, reminder_days, send, prepare.
POST /documents/from_templateTworzy wersję roboczą z szablonu: template_id, recipients jako { role, name, email }, values według identyfikatora lub etykiety pola.
GET /documentsWyświetla dokumenty Twojej aplikacji dla tej osoby, od najnowszych: limit (do 100), cursor, status.
GET /documents/{id}Dokument wraz ze statusem, odbiorcami i polami.
POST /documents/{id}/sendWysyła wersję roboczą.
POST /documents/{id}/remindPrzypomina osobom, na które przypada kolej podpisu (najwyżej raz na godzinę).
POST /documents/{id}/voidAnuluje dokument oczekujący na podpis, z opcjonalnym reason.
DELETE /documents/{id}Usuwa wersję roboczą lub zamknięty dokument.
POST /documents/{id}/prepare_urlNowe okno przygotowania dla wersji roboczej: origin, redirect_uri, state.
POST /documents/{id}/recipients/{recipient_id}/signing_urlOkno podpisu dla osoby, na którą przypada kolej: origin, redirect_uri, state.
GET /documents/{id}/original.pdfPlik PDF w wysłanej postaci.
GET /documents/{id}/signed.pdfZapieczętowana kopia, gdy wszyscy podpiszą.
GET /documents/{id}/audit.jsonŚcieżka audytu: zdarzenia, skróty i osoby podpisujące.
GET /documents/{id}/audit.pdfOsobna, opieczętowana ścieżka audytu dokumentu z podpisami kwalifikowanymi, gdy wszyscy podpiszą.
POST /uploadsRozpoczyna przesyłanie w częściach dla plików PDF powyżej 4 MB: size. Następnie PUT /uploads/{upload_id}/parts/{n} z surowymi bajtami każdej części.
GET /templatesSzablony danej osoby wraz z rolami i polami.
GET /templates/{id}Jeden szablon.
POST /templatesZapisuje jeden z dokumentów Twojej aplikacji jako szablon: document_id, name.
DELETE /templates/{id}Usuwa szablon.

Przy tworzeniu dokumentu wysyłaj nagłówek Idempotency-Key: ten sam klucz i ta sama treść w ciągu 24 godzin zwracają ten sam dokument (nagłówek Idempotent-Replayed: true) zamiast drugiego.

Błędy i limity

Błędy mają status HTTP i treść w rodzaju { "error": { "code": "not_found", "message": "..." } }, czasem ze szczegółami, takimi jak index.

StatusKody
400invalid_field, invalid_recipients, invalid_email, not_pdf, pdf_unreadable, pdf_encrypted, invalid_origin, invalid_redirect_uri, unknown_role, unknown_field
401unauthenticated, invalid_token (wygasł lub został cofnięty albo dana osoba usunęła Twoją aplikację)
403insufficient_scope, sign_api_disabled
404not_found (także dla dokumentów, których Twoja aplikacja nie utworzyła), template_not_found
409not_draft, not_sent, not_your_turn, not_signable, signer_without_fields, no_signers, void_first, idempotency_in_progress
413pdf_too_large, too_large, quota
422idempotency_key_reused
429rate_limited, z nagłówkiem Retry-After

Przekazanie aplikacji

Aplikacja może przejść do innej organizacji zarejestrowanej w Dazr, przyciskiem Przekaż aplikację w jej ustawieniach. Z włączonym Dazr Sign API może trafić tylko do zweryfikowanej organizacji, a osoba z rolą właściciela lub administratora musi ją przyjąć w ciągu 14 dni. Dokumentacja dla deweloperów Dazr Identity opisuje każdy krok.