sevDesk Integration¶
sevDesk ist die Buchhaltungslösung für Rechnungen und Belege.
Verwendung¶
| Feature | sevDesk Endpoint | Suite Feature |
|---|---|---|
| Rechnungen | /Invoice |
Auto-Generierung nach Kauf |
| Kontakte | /Contact |
Kunden-Sync |
| Belege | /Voucher |
Eingangsrechnungen |
| Reports | /Report |
Dashboard KPIs |
API Authentifizierung¶
Kein OAuth
sevDesk verwendet statische API Keys, kein OAuth. Token sicher in Cloudflare Secrets speichern!
Endpoints¶
Kontakte (Customers)¶
# Alle Kontakte
GET https://my.sevdesk.de/api/v1/Contact
?depth=1
&limit=100
# Kontakt erstellen
POST https://my.sevdesk.de/api/v1/Contact
{
"name": "Hans Mustermann",
"customerNumber": "K-2026-001",
"email": "hans@email.de",
"phone": "+49 170 1234567",
"category": {
"id": 3,
"objectName": "Category"
}
}
Rechnungen (Invoices)¶
# Rechnung erstellen
POST https://my.sevdesk.de/api/v1/Invoice
{
"invoiceNumber": "RE-2026-0001",
"contact": {
"id": 123,
"objectName": "Contact"
},
"invoiceDate": "2026-01-15",
"deliveryDate": "2026-01-15",
"status": 100,
"taxRate": 19,
"invoiceType": "RE"
}
# Position hinzufügen
POST https://my.sevdesk.de/api/v1/InvoicePos
{
"invoice": { "id": 456, "objectName": "Invoice" },
"name": "MORELO Palace 90G - Anzahlung",
"quantity": 1,
"price": 50000,
"taxRate": 19
}
# Rechnung versenden
POST https://my.sevdesk.de/api/v1/Invoice/{id}/sendViaEmail
{
"email": "kunde@email.de",
"subject": "Ihre Rechnung RE-2026-0001",
"text": "Anbei Ihre Rechnung..."
}
# PDF herunterladen
GET https://my.sevdesk.de/api/v1/Invoice/{id}/getPdf
Status Codes¶
| Status | Bedeutung |
|---|---|
| 100 | Entwurf |
| 200 | Offen |
| 1000 | Bezahlt |
SonicJS Integration¶
Route: /api/integrations/sevdesk¶
// src/routes/integrations/sevdesk.ts
import { Hono } from 'hono';
const app = new Hono();
const SEVDESK_BASE = 'https://my.sevdesk.de/api/v1';
// Proxy mit Caching
app.get('/contacts', async (c) => {
const cacheKey = 'sevdesk:contacts';
const cached = await c.env.KV.get(cacheKey, 'json');
if (cached) return c.json(cached);
const response = await fetch(`${SEVDESK_BASE}/Contact?depth=1`, {
headers: { Authorization: c.env.SEVDESK_API_KEY }
});
const data = await response.json();
await c.env.KV.put(cacheKey, JSON.stringify(data), {
expirationTtl: 300 // 5 min
});
return c.json(data);
});
// Rechnung erstellen
app.post('/invoices', async (c) => {
const body = await c.req.json();
// Validierung
if (!body.contactId || !body.items?.length) {
return c.json({ error: 'Missing contactId or items' }, 400);
}
// 1. Rechnung anlegen
const invoiceRes = await fetch(`${SEVDESK_BASE}/Invoice`, {
method: 'POST',
headers: {
Authorization: c.env.SEVDESK_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
contact: { id: body.contactId, objectName: 'Contact' },
invoiceDate: new Date().toISOString().split('T')[0],
status: 100, // Entwurf
taxRate: 19,
invoiceType: 'RE'
})
});
const { objects: invoice } = await invoiceRes.json();
// 2. Positionen hinzufügen
for (const item of body.items) {
await fetch(`${SEVDESK_BASE}/InvoicePos`, {
method: 'POST',
headers: {
Authorization: c.env.SEVDESK_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
invoice: { id: invoice.id, objectName: 'Invoice' },
name: item.name,
quantity: item.quantity,
price: item.price,
taxRate: 19
})
});
}
// Cache invalidieren
await c.env.KV.delete('sevdesk:invoices');
return c.json({ invoiceId: invoice.id });
});
export default app;
Dashboard KPIs¶
Umsatz abrufen¶
// Monatlicher Umsatz
app.get('/kpis/revenue', async (c) => {
const year = new Date().getFullYear();
const response = await fetch(
`${SEVDESK_BASE}/Report/profitAndLoss?startDate=${year}-01-01&endDate=${year}-12-31`,
{ headers: { Authorization: c.env.SEVDESK_API_KEY } }
);
const { objects } = await response.json();
return c.json({
revenue: objects.netRevenue,
expenses: objects.expenses,
profit: objects.profit
});
});
Rate Limits¶
| Limit | Wert |
|---|---|
| Requests/Minute | 100 |
| Bulk Operations | 20/min |
| PDF Downloads | 30/min |