NeuAlles unterschreiben, versiegelt. Jedes PDF direkt im Dokument ausfüllen und unterschreiben, auch Scans, und jedes Exemplar versiegelt.Was neu ist
Entwickler · Webhooks

Ereignisse, signiert und gesendet an Ihren eigenen Endpunkt.

Wenn ein Dokument versendet, geöffnet, unterschrieben, abgelehnt oder zurückgezogen wird oder eine Rechnung versendet, geöffnet oder bezahlt wird, kann Qasha das Ereignis als JSON an Ihren Endpunkt senden, signiert mit einem Geheimnis, das nur Sie und Qasha kennen.

Einrichten

Öffnen Sie in Qasha „Integrations“ und verbinden Sie „Webhooks“ mit:

Endpunkt
Wohin Ereignisse gesendet werden. Er muss mit https:// beginnen und darf keine interne oder private Netzwerkadresse sein.
Signiergeheimnis
Ein Geheimnis Ihrer Wahl, verschlüsselt in Qasha gespeichert. Jede Anfrage wird damit signiert.
Ereignisse
Welche der zehn Ereignisse dieser Endpunkt erhält.

Ereignisse

EreignisWann es gesendet wird
document.issuedEin Dokument wird zur Unterschrift versendet
recipient.viewedEine unterzeichnende Person öffnet ein Dokument
recipient.signedJemand unterschreibt
document.completedAlle haben unterschrieben
recipient.declinedJemand lehnt die Unterschrift ab
document.voidedEin Dokument wird zurückgezogen
document.recalledEin Dokument wird zur Änderung zurückgerufen
invoice.issuedEine Rechnung wird versendet
invoice.viewedEin Kunde öffnet eine Rechnung
payment.recordedEine Zahlung wird erfasst

Die Anfrage

Jedes Ereignis ist ein POST mit JSON-Body. X-Qasha-Event nennt das Ereignis, und X-Qasha-Signature enthält sha256=, gefolgt vom HMAC-SHA256 des Bodys mit Ihrem Signiergeheimnis, hexadezimal.

Anfrage
POST /qasha-events HTTP/1.1
Host: example.com
Content-Type: application/json
X-Qasha-Event: recipient.signed
X-Qasha-Signature: sha256=5d0f2c…e91a

{
  "event": "recipient.signed",
  "description": "Ada Obi signed “Master services agreement”.",
  "title": "Master services agreement",
  "url": "https://<your-qasha-address>/?document=<document id>",
  "details": { "name": "Ada Obi", "email": "ada@northwind.example" },
  "at": "2026-11-06T10:42:07.512Z"
}
event
Der Name des Ereignisses, wie in X-Qasha-Event.
description
Ein Satz, der beschreibt, was passiert ist, bereit, einer Person gezeigt zu werden (heute auf Englisch).
title
Der Titel des Dokuments oder die Nummer der Rechnung.
url
Ein Link zum Dokument in Qasha. Bei Rechnungs- und Zahlungsereignissen ein Link zum Workspace.
details
Was zum Ereignis passt: name und email (der unterzeichnenden Person), reason (bei einer Ablehnung), amount und currency (bei einer Zahlung, der Betrag in Untereinheiten wie Cent), reference und by (wer gehandelt hat).
at
Wann diese Zustellung erfolgte, in ISO 8601 UTC.

Signaturen prüfen

Berechnen Sie den HMAC-SHA256 des rohen Bodys, genau so, wie er ankam und vor jedem Parsen, mit Ihrem Signiergeheimnis. Vergleichen Sie ihn in konstanter Zeit mit dem Header und lehnen Sie die Anfrage ab, wenn sie sich unterscheiden.

Node.js (Express)
import crypto from 'node:crypto';
import express from 'express';

const app = express();
const secret = process.env.QASHA_SIGNING_SECRET;

// Check the signature against the raw body, exactly as it arrived.
app.post('/qasha-events', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(req.body).digest('hex');
  const given = req.get('X-Qasha-Signature') || '';
  const valid = given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);

  const event = JSON.parse(req.body.toString('utf8'));
  queue.add(event); // do the work later
  res.sendStatus(204); // and answer at once
});
Python (Flask)
import hashlib, hmac, os
from flask import Flask, abort, request

app = Flask(__name__)
SECRET = os.environ["QASHA_SIGNING_SECRET"].encode()

@app.post("/qasha-events")
def qasha_events():
    body = request.get_data()  # the raw body, exactly as it arrived
    expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-Qasha-Signature", "")):
        abort(401)
    queue.put(request.get_json())  # do the work later
    return "", 204                 # and answer at once

Antworten und Wiederholungen

Zugestellt
Jede 2xx-Antwort innerhalb von 5 Sekunden.
Fehlgeschlagen
Jede andere Antwort oder keine Antwort innerhalb von 5 Sekunden.
Wiederholt
Frühestens 5 Minuten, 30 Minuten, 2 Stunden, 12 Stunden und einen Tag nach jedem Fehlschlag, nacheinander. Wiederholungen laufen, während Ihr Team Qasha nutzt, daher kann eine später als geplant ankommen.
Aufgegeben
Nachdem die letzte Wiederholung fehlgeschlagen ist. Der letzte Fehler bleibt an der Integration sichtbar, wo sich das Ereignis von Hand erneut senden lässt.

Gute Praxis

  • Erst antworten, dann arbeiten. Legen Sie das Ereignis in eine Warteschlange und antworten Sie mit einem 2xx, deutlich innerhalb der 5 Sekunden.
  • Ereignisse können mehrfach kommen. Eine Zustellung, deren Antwort verloren ging, kann erneut gesendet werden. Machen Sie Ihren Handler wiederholbar, etwa indem Sie vor dem Handeln den aktuellen Stand des Dokuments prüfen.
  • Nicht auf die Reihenfolge verlassen. Nach einer Wiederholung können Ereignisse außer der Reihe ankommen; nutzen Sie at und den Stand des Dokuments, nicht die Ankunftsreihenfolge.
  • Das Geheimnis vorsichtig wechseln. Ändern Sie es in Qasha und an Ihrem Endpunkt gleichzeitig, oder akzeptieren Sie während des Wechsels beide.

Qasha mit dem Rest Ihres Stacks verbinden.

Wir gehen mit Ihnen die Ereignisse durch, die Ihre Systeme brauchen, und wie Sie sie sicher empfangen.