Die Business-API kann Nachrichten erstellen, den Versandstatus prüfen, offene Sendungen zurückziehen und Kontakte verwalten. Webhooks melden wichtige Zustandsänderungen zuverlässig an Ihre Software.
Schnellstart
Erzeugen Sie im Konto unter Schnittstelle & Webhooks einen Schlüssel. Er wird genau einmal vollständig angezeigt. SchlüsselBot speichert nur seine Prüfsumme.
curl -X POST https://schluesselbot.de/v1/messages \
-H "Authorization: Bearer sb_live_XXXXXXXX_…" \
-H "Idempotency-Key: auftrag-4711-versand-1" \
-H "Content-Type: application/json" \
-d '{
"recipient_email": "empfaenger@firma.de",
"message": "Zugang: kunde42 / T7!kq2wZ",
"ttl_hours": 48,
"sender_name": "Kanzlei Weber"
}'
Für Server-zu-Server-Aufrufe genügt der Bearer-Schlüssel. Externe Browser-Anwendungen brauchen zusätzlich einen beim Schlüssel freigegebenen Origin, zum Beispiel https://portal.firma.de.
Berechtigungen
| Scope | Erlaubt |
|---|---|
messages:send | Nachrichten und bereits clientseitig verschlüsselte Anhänge senden |
messages:read | Status einer eigenen API-Sendung abfragen |
messages:withdraw | Eine noch offene eigene Sendung dauerhaft sperren und entfernen |
contacts:read | Eigene Kontakte lesen und durchsuchen |
contacts:write | Eigene Kontakte anlegen, ändern und löschen |
Nachrichten
/v1/messagesScope messages:send/v1/send bleibt als kompatibler Alias bestehen. Verwenden Sie bei automatischen Wiederholungen immer einen eindeutigen Idempotency-Key. Derselbe Schlüssel mit demselben Inhalt liefert 24 Stunden die identische Antwort; anderer Inhalt ergibt HTTP 409.
message erreicht der Klartext kurz den SchlüsselBot-Arbeitsspeicher und wird dort verschlüsselt. Für Anbieterblindheit verschlüsselt Ihre Anwendung selbst, sendet ciphertext und verteilt den Schlüssel getrennt mit delivery_mode: "separate". Ein übermitteltes fragment ermöglicht die automatische E-Mail-Zustellung, erreicht dann aber ebenfalls den Server.| Feld | Pflicht | Inhalt |
|---|---|---|
recipient_email | ja | Empfängeradresse |
message | alternativ | Klartext bis 256 KB, serverseitig im Speicher verschlüsselt |
ciphertext | alternativ | Base64: 12-Byte-Nonce + AES-256-GCM-Chiffrat + 16-Byte-Tag |
fragment | für automatische Zustellung | 32-Byte-Schlüssel als 43 Zeichen base64url ohne Padding |
attachment_ciphertext | nein | Bereits verschlüsselter Dateicontainer, bis 100 MB Rohdaten |
delivery_mode | nein | automatic oder separate |
ttl_hours | nein | 1 bis 168, Standard 48 |
sender_name | nein | Anzeigename bis 80 Zeichen |
personal_note | nein | Mail-Notiz bis 500 Zeichen; fremde Links werden entfernt |
notify_email | nein | E-Mail für den Zustellnachweis nach Abruf |
{
"id": "8f3c…",
"link": "https://schluesselbot.de/r/8f3c…#kQ2…",
"expires_at": "2026-08-20T09:00:00+00:00",
"modus": "vom Server verschlüsselt",
"delivery": "automatic",
"mail_sent": true,
"has_attachment": false
}
/v1/messages/{id}Scope messages:readLiefert ready, consumed, withdrawn, expired oder bei einem vorübergehend nicht prüfbaren Tresor unknown. Ein Ausfall wird nie fälschlich als Abruf gemeldet.
/v1/messages/{id}Scope messages:withdrawSperrt den Vorgang zuerst dauerhaft und entfernt ihn anschließend aus dem Tresor. Scheitert die physische Löschung vorübergehend, bleibt die Sendung trotzdem unöffnungsbar und die Bereinigung wird automatisch wiederholt.
Kontakte
Kontaktnamen und E-Mail-Adressen liegen in der Datenbank AES-256-GCM-verschlüsselt. API-Antworten werden nicht zwischengespeichert.
| Methode | Pfad | Scope | Funktion |
|---|---|---|---|
| GET | /v1/contacts?q=&cursor=&limit= | contacts:read | Suchen und seitenweise auflisten, höchstens 100 je Seite |
| POST | /v1/contacts | contacts:write | {"name":"Anna","email":"anna@example.de"} |
| GET | /v1/contacts/{id} | contacts:read | Einzelnen Kontakt laden |
| PATCH | /v1/contacts/{id} | contacts:write | Name oder Adresse teilweise ändern |
| DELETE | /v1/contacts/{id} | contacts:write | Kontakt löschen |
Webhooks
Wählbare Ereignisse: created, consumed, withdrawn, expired und delivery_failed. SchlüsselBot speichert jedes Ereignis vor dem ersten Zustellversuch dauerhaft. Erwartet wird HTTP 2xx innerhalb von fünf Sekunden. Bei Fehlern folgen bis zu acht Versuche über ungefähr drei Tage: nach 1 Minute, 5 Minuten, 15 Minuten, 1 Stunde und danach in größeren Abständen.
{
"api_version": "v1",
"event_id": "consumed:8f3c…",
"event": "consumed",
"zeit": "2026-08-19T10:12:33+00:00",
"daten": {"id": "8f3c…", "mit_anhang": false}
}
X-SchluesselBot-Event: consumed
X-SchluesselBot-Event-Id: consumed:8f3c…
X-SchluesselBot-Delivery: wd_…
X-SchluesselBot-Signature: sha256=<HMAC-SHA256 des unveränderten Roh-Rumpfs>
Prüfen Sie die Signatur über den unveränderten Request-Body und behandeln Sie event_id idempotent. Das Geheimnis wird beim Anlegen einmal angezeigt und bei SchlüsselBot separat AES-256-GCM-verschlüsselt gespeichert.
// PHP
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $webhookSecret);
if (!hash_equals($expected, $_SERVER['HTTP_X_SCHLUESSELBOT_SIGNATURE'] ?? '')) {
http_response_code(401); exit;
}
Webhook-Ziele müssen öffentlich erreichbar, HTTPS und ohne Umleitung erreichbar sein. Private, Loopback-, Link-Local-, Dokumentations- und Tailscale/CGNAT-Netze sind gesperrt; die aufgelöste öffentliche IP wird für den tatsächlichen Verbindungsaufbau fest angeheftet.
Fehler und Grenzen
- 400 ungültige Angaben · 401 Schlüssel ungültig · 403 Scope, Tarif oder Origin nicht erlaubt · 409 Dublette/Idempotenzkonflikt · 413 zu groß · 429 Versandgrenze · 502/503 vorübergehender Betriebsfehler.
- Maximal 10 aktive API-Schlüssel, 10 Browser-Origins je Schlüssel und 5 Webhooks pro Business-Konto.
- Die API listet oder liest keine Nachrichteninhalte. Sie sind nur für den Empfänger und nur einmal lesbar.
- Bei 429, 502 oder 503
Retry-Afterbeachten und denselbenIdempotency-Keywiederverwenden.