Entwickler: API & MCP
Versende Briefe direkt aus deinen Anwendungen heraus — CRM, Buchhaltung, Support-Tools, eigene Skripte über die REST-API, oder lass deine KI-Agenten (Claude, Cursor & Co.) Briefe verfassen und versenden über den MCP-Server. PDF hochladen oder Text übergeben, Abrechnung über dein Doxio-Konto, Status-Updates per Webhook. Keine separate Vertragsabwicklung nötig.
Überblick
- REST über HTTPS, JSON-Bodies, Base-URL
https://doxio.org/api/v1 - Eingabe: fertig gerendertes PDF (max. 20 Seiten, A4)
- Abrechnung: vom Guthaben deines Doxio-Kontos
- Status-Updates: Polling oder signierter Webhook
- Versand: Pingen / Deutsche Post, DIN-5008-konform
Authentifizierung
Jeder Request benötigt einen API-Schlüssel im Header. Es werden zwei Schreibweisen unterstützt:
Authorization: Bearer dx_live_AbcDef…
# oder
X-API-Key: dx_live_AbcDef… Test-Schlüssel beginnen mit dx_test_ und versenden Briefe nicht
tatsächlich (Provider-Test-Modus). Live-Schlüssel beginnen mit dx_live_.
Briefe senden
POST /api/v1/letters — erstellt einen Auftrag,
bucht das Guthaben ab und übermittelt den Brief an den Druckdienst. Antwort: 202 Accepted.
Request
POST /api/v1/letters
Authorization: Bearer dx_live_…
Content-Type: application/json
Idempotency-Key: 4f0c2c0c-8b1e-4a5e-8a2a-fb6b1a9c8a32 # optional
{
"sender": {
"name": "Max Mustermann",
"company": "Musterfirma GmbH",
"street": "Musterstraße 1",
"zip": "12345",
"city": "Berlin",
"country": "DE"
},
"recipient": {
"name": "Erika Beispiel",
"street": "Beispielweg 7",
"zip": "54321",
"city": "Hamburg",
"country": "DE"
},
"pdfBase64": "JVBERi0xLjQK…",
"registeredMailType": "none", // "none"
"isColor": false,
"isDuplex": true,
"webhookUrl": "https://example.com/webhooks/doxio", // optional per-letter override
"metadata": { "yourRef": "INV-2026-0042" } // optional, wird mit jedem Webhook mitgesendet
} Response (202)
{
"id": "5e8b9c30-1a2b-4f3c-9d4e-7a6f8e9d0c1b",
"status": "submitted",
"provider": "pingen",
"providerLetterId": "0193d4d2-7c4f-7000-8a1f-...",
"pricing": { "base": 2.99, "registered": 0, "postage": 0, "total": 2.99 },
"metadata": { "yourRef": "INV-2026-0042" },
"createdAt": "2026-05-19T10:23:00.000Z",
"updatedAt": "2026-05-19T10:23:01.412Z",
"errorMessage": null
} curl-Beispiel
curl -X POST https://doxio.org/api/v1/letters \
-H "Authorization: Bearer $DOXIO_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.jsonValidierung & Preisabfrage
Vor dem Versand kannst du das PDF und die Adressen prüfen — ohne Guthaben-Abbuchung. Ideal in einer Iterationsschleife, wenn du selbst PDFs erzeugst.
POST /api/v1/letters/validate
Gleicher Body wie beim Senden (ohne webhookUrl, metadata). Liefert { valid, error?, pricing, totalPages }. Häufige Fehler:
Adresse außerhalb des DIN-5008-Adressfensters, störende Elemente im Adressbereich, ungültige Seitengröße.
POST /api/v1/letters/price
Reine Preisabfrage: Body { totalPages, registeredMailType? }.
Antwort enthält base, registered, postage, total, totalCents sowie balanceTotal / balanceTotalCents (der aus dem Guthaben tatsächlich abgebuchte Betrag, inkl. 0,50 € Rabatt).
Status abfragen & auflisten
GET /api/v1/letters/:id
Einzelner Brief. Liefert dieselbe Form wie der Send-Response. Status-Werte: created → paid → submitted → sent → delivered / failed.
GET /api/v1/letters?limit=25&cursor=<createdAt>
Liste aller Briefe des Schlüssels, sortiert nach Erstellung absteigend. Antwort: { data: [...], nextCursor }. nextCursor in den nächsten Request weitergeben.
POST /api/v1/letters/:id/cancel
Storniert einen Brief, falls der Druckdienst es unterstützt (sonst 501).
GET /api/v1/balance
Aktuelles Guthaben in Cent: { credits, updatedAt }.
Webhooks
Hinterlege beim Erstellen eines Schlüssels eine Webhook-URL. Bei jedem Statuswechsel sendet Doxio einen signierten POST.
Events: letter.submitted, letter.sent, letter.delivered, letter.failed.
Header
POST https://your-app.example.com/webhooks/doxio
User-Agent: Doxio-Webhook/1.0
Content-Type: application/json
X-Doxio-Event: letter.sent
X-Doxio-Delivery: 0193d4d2-7c4f-7000-8a1f-...
X-Doxio-Signature: t=1716115380,v1=2c0a... (HMAC-SHA256) Body
{
"id": "evt_1716115380_abcd12",
"event": "letter.sent",
"createdAt": "2026-05-19T10:23:00.000Z",
"data": {
"id": "5e8b9c30-1a2b-4f3c-9d4e-7a6f8e9d0c1b",
"status": "sent",
"provider": "pingen",
"providerLetterId": "0193d4d2-...",
"pricing": { "base": 2.99, "registered": 0, "postage": 0, "total": 2.99 },
"metadata": { "yourRef": "INV-2026-0042" },
"createdAt": "2026-05-19T10:23:00.000Z",
"updatedAt": "2026-05-19T10:25:11.000Z",
"errorMessage": null
}
} Signatur prüfen (Node.js)
import { createHmac, timingSafeEqual } from 'node:crypto'
function verify(header: string, rawBody: string, secret: string): boolean {
const m = header.match(/^t=(\d+),v1=([0-9a-f]+)$/)
if (!m) return false
const [, t, v1] = m
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(v1, 'hex'))
} Antworte mit einem 2xx-Status, sobald du den Event verarbeitet hast.
Bei Fehlern (Timeout 10s oder Status ≥ 400) wiederholt Doxio bis zu 8 Mal mit exponentiellem Backoff
(max. 1h zwischen Versuchen). Stelle deinen Handler idempotent ein.
Idempotenz
Sende beim POST /api/v1/letters einen Idempotency-Key-Header (z.B. ein UUID, einmalig pro
logischer Operation). Bei Wiederholung mit demselben Schlüssel erhältst du dieselbe Antwort wie beim ersten Aufruf —
es wird kein zweiter Brief erzeugt. Empfohlen in jeder produktiven Integration.
Fehlercodes
Alle Fehler folgen dem Schema { error: { code, message, details? } }.
| Status | Code | Wann? |
|---|---|---|
| 400 | invalid_request | Pflichtfeld fehlt oder Format ungültig. |
| 400 | invalid_pdf | PDF konnte nicht gelesen werden. |
| 400 | too_many_pages | Mehr als 20 Seiten. |
| 401 | unauthorized | API-Schlüssel fehlt. |
| 401 | invalid_api_key | Ungültiger oder widerrufener Schlüssel. |
| 402 | insufficient_balance | Guthaben reicht nicht für den Versand. |
| 403 | forbidden | Ressource gehört nicht zu diesem Schlüssel. |
| 404 | not_found | Brief existiert nicht. |
| 409 | not_submitted | Brief noch nicht an Druckdienst übermittelt (Cancel). |
| 429 | — | Rate Limit überschritten. |
| 501 | not_supported | Operation vom aktiven Druckdienst nicht unterstützt. |
| 502 | cancel_failed | Druckdienst hat Stornierung abgelehnt. |
Limits & Preise
- 60 Requests/Minute pro Schlüssel auf
/letters; 120 Requests/Minute pro IP global. - PDF max. 20 Seiten, Format A4.
- Preise identisch zum Self-Service-Tarif: 2,99 € pro Brief + Porto-Aufschlag ab 3 Seiten. Da API-Sendungen aus dem Guthaben bezahlt werden, gilt der Guthaben-Rabatt — effektiv 2,49 €. Details auf /preise.
- Abrechnung über das Guthaben deines Doxio-Kontos. Aufladen unter Konto → Guthaben.
- Personenbezogene Inhalte (PDF, Empfängeradresse) werden nach erfolgreicher Übergabe an den Druckdienst gelöscht (DSGVO Art. 17).
MCP-Server
Das Model Context Protocol ist ein offener Standard, über den KI-Assistenten externe Werkzeuge nutzen. Verbinde Doxio mit Claude, Cursor & Co. — und deine KI verfasst Briefe aus einer Beschreibung und versendet sie per Deutsche Post, ohne dass du Code schreibst oder API-Schlüssel verwaltest.
- Server-URL:
https://doxio.org/api/mcp(StreamableHTTP-Transport) - Anmeldung per Browser-Login (OAuth) — keine Schlüssel zum Kopieren oder Verwalten
- Abrechnung wie immer: vom Guthaben deines Doxio-Kontos — 2,49 € pro Brief (Pauschalpreis 2,99 € abzüglich 0,50 € Guthaben-Rabatt, zzgl. Optionen)
Verbinden
Claude Code
claude mcp add --transport http doxio https://doxio.org/api/mcp Cursor / Claude Desktop (mcp.json)
{
"mcpServers": {
"doxio": {
"url": "https://doxio.org/api/mcp"
}
}
} claude.ai
Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen → URL https://doxio.org/api/mcp eintragen.
Anmeldung (OAuth)
- 1. Verbindung hinzufügen — beim ersten Tool-Aufruf öffnet der Client ein Browserfenster.
- 2. Bei Doxio anmelden (oder Konto erstellen) und auf Erlauben klicken.
- 3. Fertig — die App kann nun in deinem Namen Briefe senden und deinen Kontostand lesen.
Du kannst eine Verbindung jederzeit unter Konto → API-Schlüssel → Verbundene Apps widerrufen. Danach schlagen weitere Aufrufe sofort fehl.
Verfügbare Tools
| Tool | Beschreibung |
|---|---|
| preview_letter | Rendert den Brief als PDF, gibt Seitenzahl + Preis zurück. Bucht nichts ab. |
| send_letter | ⚠️ Versendet den Brief und bucht den Preis vom Guthaben ab. Unwiderruflich. |
| get_letter_status | Status eines Briefs anhand seiner ID. |
| list_letters | Liste der zuletzt über diese Verbindung gesendeten Briefe. |
| get_balance | Aktuelles Doxio-Guthaben in Cent. |
| get_pricing | Preis für eine Sendung (Seitenzahl). |
Beispiel-Argumente für send_letter
{
"sender": { "name": "Max Mustermann", "street": "Musterstr. 1", "zip": "12345", "city": "Berlin" },
"recipient": { "company": "Stadtwerke München", "street": "Werkweg 5", "zip": "80331", "city": "München" },
"subject": "Kündigung Stromvertrag 12345",
"body": "Sehr geehrte Damen und Herren,\n\nhiermit kündige ich meinen Vertrag…",
}Sicherheit & Kosten
-
send_letterbucht echtes Geld ab (ab 2,49 € pro Brief aus dem Guthaben) und ist unwiderruflich. - Lass die KI zuerst
preview_letteraufrufen und den Versand von dir bestätigen. - MCP-Clients fragen standardmäßig vor jedem Tool-Aufruf um Erlaubnis — lass dies für
send_letteraktiviert. - Dein Guthaben ist die Obergrenze: ist es leer, kann kein Brief versendet werden.
Fragen oder Anregungen? mail@andreas-zeller.com