Integrieren

@signido/sdk

Typisiert, ohne Abhängigkeiten, überall lauffähig. Idempotenzschlüssel und Signaturprüfung sind eingebaut statt dokumentiert.

Installation

pnpm add @signido/sdk

Benötigt Node 20 oder neuer, oder eine Laufzeit mit fetch und Web Crypto — jeder aktuelle Browser, Cloudflare Workers, Vercel Edge, Deno und Bun.

Drei Eigenschaften

  • Keine Abhängigkeiten. Nichts wird mitinstalliert. Ein SDK, das eine Validierungsbibliothek in ein fremdes Lockfile zieht, ist ein Versionskonflikt mit Ansage; eines, das ein Node-Builtin importiert, ist ein Build-Fehler auf einer Edge-Laufzeit.
  • Sicher, ohne dass man daran denken muss. Jeder Schreibzugriff trägt einen Idempotency-Key, ob der Aufrufende darüber nachgedacht hat oder nicht — die Folge eines wiederholten Versands ist eine zweite Kopie einer Vereinbarung in einem fremden Postfach. Wiederholungsversuche sind begrenzt und werden nur auf Anfragen angewandt, die der Server als Wiederholung erkennen kann.
  • Ein Fehlertyp. SignidoApiError mit code, status, requestId, details und fieldErrors(). Ein Transportfehler ist derselbe Typ mit status: 0 — man braucht nicht zwei catch-Formen, um „die API sagt nein“ von „die API antwortet nicht“ zu unterscheiden.

Verwendung

import { Signido, isSignidoApiError } from '@signido/sdk';

const signido = new Signido({
  apiKey: process.env.SIGNIDO_API_KEY,
  // Optional:
  // baseUrl: 'https://api.signido.de/api/v1',
  // timeoutMs: 30_000,
  // maxRetries: 2,
  // fetch: myFetch,   // eigener Agent, Proxy, Instrumentierung
});

// Eine Seite.
const first = await signido.documents.list({ limit: 50, status: 'COMPLETED' });

// Alle, ohne Cursor-Verwaltung.
for await (const document of signido.documents.listAll({ status: 'COMPLETED' })) {
  console.log(document.id);
}

// Ein Endpunkt, den diese SDK-Version noch nicht abbildet — mit
// Idempotenzschlüssel, Retry-Politik und typisiertem Fehler.
const usage = await signido.raw.get<{ signatures: number }>('/usage');
signido.documents
Anlegen, hochladen, auflisten, lesen, ändern, löschen, Seitenübersicht.
signido.signatureRequests
Aufträge, Dokumente, Empfänger, Felder, Versand, Abbruch, Erinnerung, Nachweisverlauf, Kostenvorschau.
signido.templates
Vorlagen lesen, verwalten und verwenden.
signido.contacts
Kontakte.
signido.webhooks
Endpunkte, Zustellprotokolle und erneutes Senden.
signido.raw
Der Transport, für eine Route, die diese SDK-Version noch nicht abbildet. Absichtlich offen: sonst schreibt jemand einen zweiten HTTP-Client und verliert dabei Idempotenz, Retry-Politik und den typisierten Fehler.

Pagination

Drei Methoden pro Liste: list liefert eine Seite samt pageInfo, listAll iteriert über alle Einträge, pages über alle Seiten. Nachgeladen wird erst, wenn die Schleife über das Ende der aktuellen Seite hinausläuft — ein break nach zwanzig Einträgen kostet genau eine Anfrage. Details unter Pagination.

Webhook-Signaturen prüfen

Der wichtigste Export des Pakets. Er prüft in konstanter Zeit, erzwingt ein Zeitfenster gegen Replays und akzeptiert bewusst nur den rohen Body — ein bereits geparstes Objekt anzunehmen wäre eine Einladung zu genau dem Fehler, den das Signaturschema verhindern soll.

import { verifyWebhookSignature } from '@signido/sdk';

const result = await verifyWebhookSignature({
  payload: rawBody,                      // die ROHEN Bytes als String
  signatureHeader: headers['signido-signature'],
  secret: process.env.SIGNIDO_WEBHOOK_SECRET,
  // toleranceSeconds: 300,              // Standard: fünf Minuten
});

if (!result.ok) {
  // 'MALFORMED_HEADER' | 'TIMESTAMP_OUT_OF_TOLERANCE' | 'SIGNATURE_MISMATCH'
  //
  // Drei Gründe statt eines Booleans, weil sie drei verschiedene Reaktionen
  // verlangen: ein Konfigurationswert, ein möglicher Angriff, ein Proxy,
  // der Header entfernt.
  console.warn(result.reason);
}

parseWebhookEvent macht dasselbe und gibt anschließend den geprüften Envelope zurück — in dieser Reihenfolge, weil die umgekehrte der Fehler ist. Alles zum Schema steht unter Webhooks.

Andere Sprachen

Für PHP und Python gibt es noch kein offizielles Paket. Beide lassen sich aus der OpenAPI-Spezifikation generieren — sie ist aus denselben Schemas erzeugt, mit denen die API validiert, also beschreibt sie, was tatsächlich erzwungen wird. Die Beispiele in dieser Dokumentation verwenden bis dahin httpx direkt, was für eine REST-API mit einem Header und JSON auch vollkommen ausreicht.