QES mit Mitgliedern und Freigabe-Link
Eine qualifizierte elektronische Signatur (QES) braucht ein persönliches Zertifikat. Bei uns gehört jedes Zertifikat einem Mitglied Ihrer Organisation – einer Person mit oder ohne Login. Externe Empfänger eines Vorgangs unterschreiben einfach (SES) oder fortgeschritten (AES); qualifiziert unterschreiben nur Mitglieder.
Dieser Guide führt vom Mitglied über das Zertifikat bis zur Unterschrift – per API, in einem Vorgang oder über einen Freigabe-Link.
1. Mitglied anlegen
POST /v1/members
Authorization: Bearer qgw_test_…
Idempotency-Key: 5b2e…
Content-Type: application/json
{ "firstName": "Anna", "lastName": "Weber", "email": "anna.weber@example.com", "externalId": "hr-0815" }
Das legt eine Person ohne Login an (loginStatus: NO_LOGIN), etwa eine Geschäftsführerin, die nur unterschreibt. Scope members:manage. Mitglieder lesen Sie mit GET /v1/members und GET /v1/members/{id}.
2. Zertifikat bestellen
POST /v1/certificates
Authorization: Bearer qgw_test_…
Idempotency-Key: 7d41…
Content-Type: application/json
{ "memberId": "0192f1b0-0000-7000-8000-00000000010f", "kind": "OTP" }
kind: OTP: Die Person unterschreibt jedes Mal mit einem Einmalcode aus der App ihres Zertifikatsausstellers.kind: AUTOMATIC: Unterschriften ohne Code, nur mit der Einwilligung der Person zum automatischen Signieren (siehe Schritt 4).
Scope certificates:purchase. Die Antwort enthält identificationUrl: Die Person identifiziert sich einmalig über unseren Link (sie bekommt ihn auch per E-Mail). Mit einem Test-Schlüssel wird im Testmodus bestellt und nichts berechnet. Was eine Bestellung kostet, sehen Sie vorher mit POST /v1/cost-estimates (Guide „Kosten per API“).
Den Stand verfolgen Sie mit GET /v1/certificates/{id} (lifecycleState) oder per Webhook: certificate.ordered, certificate.activated, certificate.credentials_invalid, certificate.expiring, certificate.state_changed (Scope certificates:read).
3. Zugangsdaten hinterlegen und testen
- Zertifikate mit Einmalcodes (
OTP): Nur die Person selbst gibt ihre Zugangsdaten ein, in ihrer eigenen Sitzung im Dashboard; über die API lassen sie sich nicht setzen (403 / 9006). - Automatische Zertifikate:
PUT /v1/certificates/{id}/credentialsspeichert Benutzername und PIN verschlüsselt – nur mit gültiger Einwilligung der Person. Danach prüftPOST /v1/certificates/{id}/testdie Zugangsdaten mit einer Testsignatur. - Testmodus:
POST /v1/certificates/{id}/sandbox-credentialshinterlegt die Zugangsdaten der Sandbox an einem Test-Zertifikat, ohne sie Ihnen zu zeigen.
4. Einwilligung zum automatischen Signieren
Automatisch – also ohne Code – darf nur unterschrieben werden, wenn die Person zugestimmt hat. POST /v1/certificates/{id}/consent-request schickt ihr einen persönlichen Link; sie legt fest, wofür die Einwilligung gilt (Kanäle API, DASHBOARD, ENVELOPE, BATCH, optional bestimmte Schlüssel, Vorlagen, ein Tageslimit und ein Ablaufdatum) und kann sie jederzeit widerrufen. Die API selbst erteilt nie eine Einwilligung. Änderungen melden certificate.consent_changed-Ereignisse.
5. Unterschreiben
Einzelne Dokumente
POST /v1/signatures
Authorization: Bearer qgw_test_…
Idempotency-Key: 1c9a…
Content-Type: application/json
{ "documentId": "0192f1b0-0000-7000-8000-000000000103", "certificateId": "0192f1b0-0000-7000-8000-00000000010e",
"placement": { "page": 1, "x": 391, "y": 36, "width": 168, "height": 39 } }
certificateId wählt das Zertifikat; Ihre Systeme halten nie eine PIN. Bei OTP-Zertifikaten gehört der aktuelle Code als certificateOtp dazu – er gilt nur kurz und muss deshalb von der Person selbst kommen. Sitzt die Person nicht vor Ihrer Oberfläche, nutzen Sie den Freigabe-Link (unten). Ergebnis: GET /v1/signatures/{id}, Download GET /v1/signatures/{id}/content; mehrere Dokumente in einem Aufruf: POST /v1/signature-batches.
Antwortzeit und Wiederholungen
POST /v1/signaturesantwortet in der Regel innerhalb von 25 Sekunden; die Vorbereitung großer Dokumente (Laden, Signaturfeld, Bild) zählt mit und wird nicht abgebrochen. Die Antwort ist: fertig mit 200 oder, wenn der Signaturdienst bis dahin nicht fertig ist, mit 202status: WAIT_SIGNundRetry-After: 2. Die Signatur wird dann im Hintergrund fertig und nie ein zweites Mal ausgelöst; das Ergebnis kommt an Ihrencallback, mit Webhook-Abo alssignature.completedund überGET /v1/signatures/{id}(frühestens nachRetry-AfterSekunden abfragen). Lehnt der Signaturdienst sie erst danach ab, kommt genau einmalsignature.failed(Webhook undcallback),GETzeigtstatus: REJECTEDmiterror(bei 9019 miterror.reason:signature_refused,timestamp_failedoderrejected).- Stellen Sie das Zeitlimit Ihres Clients auf mindestens 30 Sekunden (25 Sekunden plus Puffer). Anfragen mit
certificateOtpwarten wie bisher auf den Signaturdienst (bis zu 90 Sekunden). - Senden Sie immer einen
Idempotency-Key. Eine Wiederholung mit demselben Schlüssel antwortet 409 / 9008, solange die Signatur noch läuft („läuft noch, kurz warten“), danach mit der fertigen Signatur (200, dieselbeid). Ein 202 wird nie als Antwort gespeichert; eine Wiederholung zeigt immer den aktuellen Stand. - Der erste Aufruf nach einer längeren Ruhepause kann beim Signaturdienst länger dauern als die folgenden.
- Viele Dokumente auf einmal:
Prefer: respond-async(sofort 202, die Signaturen laufen über die Warteschlange des Gateways) oderPOST /v1/signature-batches.
Sichtbares Signaturbild
Mit placement zeichnet der Gateway das Signaturbild selbst: Siegel, „Qualifiziert elektronisch signiert“, die Unterschrift (Name in Handschrift oder die hinterlegte Unterschrift mit signerImage.template: "signer") und darunter eine Zeile je Angabe – mit appearance.showDate: true Datum und Uhrzeit in der Zeitzone Ihrer Organisation mit ihrem Abstand zu UTC (05.10.2026 22:54 UTC+2, im Winter UTC+1; Einstellung im Dashboard, Standard Europe/Berlin), dann appearance.reason (bis 120 Zeichen), bei Bedarf über mehrere Zeilen umbrochen. Die Unterschrift behält dabei mindestens 45 % der Höhe, die Schrift wird bis 5 pt verkleinert. Passt der Grund trotzdem nicht ganz, wird er im Bild mit „…“ gekürzt und die Signatur meldet options.appearance.reasonTruncated: true (Antwort von POST /v1/signatures, GET /v1/signatures/{id} – auch für jedes Dokument aus POST /v1/signature-batches –, Ereignisse); signiert wird trotzdem, und der vollständige Grund steht in der Signatur selbst. Empfohlene Mindestgrößen des Feldes (Breite × Höhe in pt, gemessen mit üblichem deutschem Text):
| Inhalt des Bildes | Name in Handschrift | Eigene Unterschrift mit Name (showName) |
|---|---|---|
| Datum, kein Grund | 140 × 40 | 140 × 50 |
| Datum und Grund bis 40 Zeichen | 180 × 60 | 200 × 75 |
| Datum und Grund bis 120 Zeichen | 260 × 80 | 260 × 100 |
Ein Feld von 170 × 60 pt fasst Datum und etwa 40 Zeichen Grund, 140 × 40 pt nur das Datum. Kleinere Felder sind erlaubt (ab 16 × 16 pt); Datum und Name werden dann kleiner, der Grund früher gekürzt.
In einem Vorgang
Tragen Sie das Mitglied als Empfänger mit memberId und signatureLevel: "QES" ein. Ist es an der Reihe, unterschreibt es im Dashboard (Aufgaben, GET /v1/members/{id}/tasks zeigt sie Ihrem System), über einen Freigabe-Link oder – bei automatischen Zertifikaten mit passender Einwilligung – per POST /v1/envelopes/{id}/recipients/{recipientId}/sign (Scope envelopes:sign, standardmäßig aus).
Über einen Freigabe-Link
Für Mitglieder mit OTP-Zertifikat: POST /v1/signing-approvals schickt der Person einen Link auf unsere Seite, auf der sie die Liste der Dokumente prüft und je Dokument ihren Code eingibt – ohne Login. Ablauf, Zustände, Ereignisse und Fehler beschreibt der Guide „Freigabe-Links“. Freigabe-Links stehen zur Verfügung, sobald sie in Ihrer Installation freigeschaltet sind; bis dahin antworten die Routen mit 422 / 9012 approval_not_available.
Hinweise
- Live-Unterschriften beachten das monatliche Ausgabenlimit Ihrer Organisation (403 / 9017 bei hartem Limit).
/v1/signersist ein abgekündigter Alias von/v1/members(HeaderDeprecationundLink); neue Integrationen nutzen/v1/membersund/v1/certificates.