Eine sichere API für digitale Signaturen
Integrieren Sie unterschreib.es in CRM-, ERP- oder Branchenlösungen – mit einer durchdachten REST-API, vollständiger OpenAPI-Spezifikation, Webhooks und Token-Authentifizierung. Deutsch gehostet, ohne US-Tracking.
Business-Feature. Token erzeugen Sie in der App unter Verwaltung → API-Tokens (nur Inhaber).
Authentifizierung
Jeder Request trägt Ihr API-Token als Bearer-Token im Authorization-Header. Tokens gehören dem Team, sind ausschließlich gehasht gespeichert (wir können sie nicht zurückgeben) und lassen sich mit optionalem Ablaufdatum ausstatten sowie jederzeit widerrufen.
Authorization: Bearer ues_...
Die vollständige, interaktive Referenz mit „Try it"-Funktion finden Sie unter https://api.unterschreib.es/docs. Die reine OpenAPI-Spezifikation liegt unter /swagger/v1/swagger.json.
Der Flow im Überblick
- Dokument hochladen –
POST /v1/documents(PDF + Titel). - Empfänger anlegen –
POST /v1/documents/{id}/requestsje Empfänger:in inkl. Position. - Optional konfigurieren –
PATCH /v1/documents/{id}für Frist, Erinnerungen, Reihenfolge, Projekt/Tags. - Versand starten –
POST /v1/documents/{id}/sendverschickt die Einladungen. - Status abfragen –
GET /v1/documents/{id}oder per Webhook (siehe unten). - Signiertes PDF abholen –
GET /v1/documents/{id}/file.
Beispiel: Dokument hochladen
curl -X POST https://api.unterschreib.es/v1/documents \
-H "Authorization: Bearer ues_..." \
-F "file=@vertrag.pdf" \
-F "title=Kaufvertrag PKW"
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", "ues_...");
using var form = new MultipartFormDataContent();
form.Add(new StreamContent(File.OpenRead("vertrag.pdf")), "file", "vertrag.pdf");
form.Add(new StringContent("Kaufvertrag PKW"), "title");
var resp = await http.PostAsync("https://api.unterschreib.es/v1/documents", form);
resp.EnsureSuccessStatusCode();
var doc = await resp.Content.ReadFromJsonAsync<JsonElement>();
Console.WriteLine(doc.GetProperty("id").GetString());
const form = new FormData();
form.append("file", fileInput.files[0]);
form.append("title", "Kaufvertrag PKW");
const res = await fetch("https://api.unterschreib.es/v1/documents", {
method: "POST",
headers: { Authorization: "Bearer ues_..." },
body: form,
});
const doc = await res.json();
console.log(doc.id);
Antwort: JSON mit der ID des erzeugten Dokuments. Nutzen Sie diese ID für die weiteren Aufrufe.
Endpoints
| Methode | Pfad | Zweck |
|---|---|---|
GET | /v1/documents | Dokumente auflisten (paginiert: ?status=&skip=&take=, Header X-Total-Count). |
POST | /v1/documents | PDF hochladen (multipart, max. 25 MB). |
GET | /v1/documents/{id} | Dokument inkl. Signaturanforderungen abrufen. |
PATCH | /v1/documents/{id} | Entwurf ändern: Titel, Frist, Erinnerungen, Reihenfolge, Projekt, Tags. |
DELETE | /v1/documents/{id} | Dokument löschen (Soft-Delete). |
GET | /v1/documents/{id}/file | Aktuelles PDF herunterladen. |
POST | /v1/documents/{id}/send | Versand der Einladungen starten. |
GET | /v1/documents/{id}/requests | Signaturanforderungen auflisten. |
POST | /v1/documents/{id}/requests | Signaturanforderung anlegen (Position als 0–1 normalisierte Rechteck-Koordinaten). Optional mit SMS-2FA: requiresSmsTwoFactor: true plus signerPhone (Mobilnummer aus EU/EWR, Schweiz oder UK) – beides nur gemeinsam. |
DELETE | /v1/documents/{id}/requests/{rid} | Signaturanforderung löschen. |
Alle Parameter, Schemata und Beispiele stehen in der interaktiven Referenz.
Fehler & Statuscodes
Fehler kommen einheitlich als Problem Details (application/problem+json) zurück:
{
"type": "about:blank",
"title": "Ungültige Anfrage",
"status": 400,
"detail": "Nur PDF erlaubt."
}
401– Token fehlt, ist ungültig, abgelaufen oder widerrufen.402– Aktion durch das Tariflimit blockiert.404– Ressource nicht gefunden (oder nicht im eigenen Team).429– Rate-Limit erreicht (siehe rechts).
Rate-Limits
Zum Schutz vor Missbrauch ist die Anzahl der Anfragen pro Token begrenzt; das Volumen selbst ist unbegrenzt. Wird das Limit erreicht, antwortet die API mit 429 und einem Retry-After-Header (Sekunden):
HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/problem+json
Warten Sie die angegebene Zeit ab und wiederholen Sie den Request. Für teure Aktionen (Upload, Versand) gilt ein strengeres Limit.
Webhooks
Statt zu pollen, lassen Sie sich benachrichtigen. Registrieren Sie Endpoints unter Verwaltung → Webhooks und abonnieren Sie Events:
signature.signed– eine Unterschrift wurde geleistet.document.completed– alle Empfänger haben unterschrieben.signature.rejected– ein:e Empfänger:in hat abgelehnt.document.expired– die Frist wurde überschritten.
Payload
{
"event": "document.completed",
"occurredAt": "2026-07-28T13:00:00Z",
"document": {
"id": "3f2a...",
"title": "Kaufvertrag PKW",
"status": "Completed",
"completedAt": "2026-07-28T13:00:00Z"
},
"signingRequest": null
}
Header: X-UES-Event, X-UES-Delivery, X-UES-Timestamp, X-UES-Signature. Fehlgeschlagene Zustellungen werden mit steigendem Abstand wiederholt; dauerhaft unerreichbare Endpoints werden automatisch deaktiviert.
Signatur prüfen
Die Signatur ist ein HMAC-SHA256 über timestamp + "." + rawBody mit Ihrem Endpoint-Secret:
const crypto = require("crypto");
function verify(secret, timestamp, rawBody, signature) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(timestamp + "." + rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(signature));
}