Die Sunventory API.
Ihre Daten gehören Ihnen, und Ihre Systeme können sie abholen: die Sunventory API liefert Baustellen, Stücklisten und Lieferungen als REST-Schnittstelle. Ihr ERP kann zusätzlich die Stückliste einer Baustelle schreiben und sich per Webhook benachrichtigen lassen, sobald Lieferungen ankommen. Erfasst wird auf der Baustelle mit der App, ausgewertet wird, wo Sie wollen.
Das Muster ist bewusst das, was Integratoren kennen: REST mit
OpenAPI-Spezifikation, API-Schlüssel mit Scopes, ein idempotenter
Stücklisten-Upsert über external_ref und signierte
Webhooks mit At-least-once-Zustellung und Event-Deduplizierung,
wie man es von Stripe und GitHub kennt.
https://app.sunventory.de/api/v1
Authentifizierung
Jede Anfrage trägt einen API-Schlüssel Ihres Kontos als Bearer-Token. Schlüssel erstellt und widerruft die Bauleitung in der Web-Plattform unter Einstellungen, API. Ein Schlüssel gilt für das ganze Konto, wird bei der Erstellung genau einmal angezeigt und verliert beim Widerruf sofort seine Gültigkeit.
Beim Erstellen wählen Sie den Zugriff: nur lesen oder lesen und
schreiben. Die schreibenden Endpunkte, also Stücklisten-Import
und Webhook-Verwaltung, verlangen einen Schlüssel mit
Schreibzugriff. Ein Lese-Schlüssel bekommt dort
403 insufficient_scope. Bestehende Schlüssel bleiben
unverändert reine Lese-Schlüssel.
curl https://app.sunventory.de/api/v1/sites \
-H "Authorization: Bearer svk_ihr_schluessel" Endpunkte
Lesen steht jedem Schlüssel offen, Schreiben nur Schlüsseln mit
Schreibzugriff. Listen sind seitenweise abrufbar
(limit bis 500, offset), Lieferungen
zusätzlich filterbar über site_id,
supplier, from, to
(jeweils JJJJ-MM-TT) und status
(pending oder confirmed).
-
GET /sitesAlle Baustellen des Kontos. -
GET /sites/{id}Eine Baustelle. -
GET /sites/{id}/bomDie Stückliste mit Soll, bestätigter und offener Menge je Position. -
PUT /sites/{id}/bomStückliste importieren: Positionen anlegen oder aktualisieren, idempotent über external_ref. Braucht Schreibzugriff. -
GET /deliveriesLieferungen mit Positionen und Lieferschein-Fotos, filterbar nach Baustelle, Lieferant, Zeitraum und Status. -
GET /deliveries/{id}Eine Lieferung. -
GET /deliveries.csvDieselben Lieferungen als CSV, eine Zeile je Position. -
GET/POST/DELETE /webhooksWebhooks verwalten. Braucht Schreibzugriff. -
POST /webhooks/{id}/testEin signiertes Test-Event an den Endpunkt schicken.
Die vollständige Beschreibung aller Felder liefert die Maschine selbst: openapi.json im OpenAPI-3.1-Format, ohne Schlüssel abrufbar.
Beispiele
Lieferfortschritt einer Baustelle
curl "https://app.sunventory.de/api/v1/sites/{id}/bom" \
-H "Authorization: Bearer svk_…" {
"data": [{
"supplier": "Canadian Solar",
"product": "HiKu7 CS7L-590MS 590W bifazial",
"planned_quantity": 169500,
"delivered_quantity": 8297,
"pending_quantity": 1188,
"last_delivery_at": "2026-05-27",
…
}]
} Bestätigte Lieferungen eines Monats als CSV
curl "https://app.sunventory.de/api/v1/deliveries.csv?status=confirmed&from=2026-07-01&to=2026-07-31" \
-H "Authorization: Bearer svk_…" -o lieferungen.csv Jede Lieferung führt ihre Lieferschein-Fotos als signierte, zeitlich begrenzte URLs mit. Wer den Beleg zur Buchung braucht, lädt ihn direkt aus der Antwort.
Stückliste importieren
PUT /sites/{id}/bom übernimmt Bestellpositionen aus
Ihrem ERP in die Stückliste der Baustelle, bis zu 1000 Positionen
je Anfrage, alles in einer Transaktion. Der Anker ist
external_ref, zum Beispiel Bestellnummer und Zeile
aus Dynamics 365: Positionen mit bekannter Referenz werden
aktualisiert, neue werden angelegt. Geben Sie jeder Position eine
stabile external_ref, dann darf derselbe Import
beliebig oft laufen und erzeugt nie Duplikate; nur Positionen
ohne Referenz werden bei jedem Lauf neu angelegt. Eine
Aktualisierung übernimmt die Position vollständig, auch leere
optionale Felder überschreiben den Bestand.
curl -X PUT "https://app.sunventory.de/api/v1/sites/{id}/bom" \
-H "Authorization: Bearer svk_…" \
-H "Content-Type: application/json" \
-d '{
"positions": [
{ "external_ref": "PO-4711/10", "supplier": "Canadian Solar",
"product": "PV-Modul CS7N 700 MB-T", "category": "PV-Module",
"planned_quantity": 196000, "unit": "Stück" },
{ "external_ref": "PO-4711/20", "supplier": "LAPP",
"product": "Solarkabel H1Z2Z2-K 6 mm²",
"planned_quantity": 84000, "unit": "m" }
]
}' { "created": 2, "updated": 0, "data": [ … ] }
Die Antwort führt die betroffenen Positionen in denselben Feldern
wie GET /sites/{id}/bom, inklusive bereits
gelieferter Mengen. Beim zweiten identischen Lauf meldet sie
"created": 0, "updated": 2. Zwei Regeln geben dem
Import seine Sicherheit: Positionen mit verknüpften Lieferungen
behalten ihre ID, der Liefernachweis bleibt also stehen. Und die
API löscht nie. Positionen, die im Import fehlen, bleiben
unberührt; entfernt wird bewusst nur in der App.
Webhooks
Statt zu pollen, lassen Sie sich benachrichtigen: ein Webhook
ruft Ihr System auf, sobald auf der Baustelle eine Lieferung
erfasst (delivery.created) oder von der Bauleitung
bestätigt (delivery.confirmed) wird. Registriert
wird mit einem Schreib-Schlüssel:
curl -X POST https://app.sunventory.de/api/v1/webhooks \
-H "Authorization: Bearer svk_…" \
-H "Content-Type: application/json" \
-d '{ "url": "https://erp.example.com/hooks/sunventory",
"events": ["delivery.created", "delivery.confirmed"] }'
Die Antwort enthält genau einmal das Signatur-Secret
(whsec_…). Jedes Event kommt als POST mit diesem
Umschlag; data ist die Lieferung in denselben
Feldern wie GET /deliveries/{id}, inklusive
frisch signierter Foto-URLs:
{
"event_id": "8f14e45f-…",
"event": "delivery.created",
"timestamp": "2026-08-26T09:41:00.000Z",
"webhook_id": "6512bd43-…",
"data": { … }
}
Die Zustellung ist at-least-once, wie bei Stripe und GitHub:
dasselbe Event kann mehrfach ankommen, trägt dann aber dieselbe
event_id. Ihr Konsument dedupliziert also über die
event_id und antwortet mit einem 2xx innerhalb von
10 Sekunden. Bei Fehlern versucht Sunventory die Zustellung drei
weitere Male, nach 1, 10 und 60 Minuten. Nach 20 Fehlschlägen in
Folge wird der Webhook deaktiviert; den Zustand sehen Sie unter
Einstellungen, API und per GET /webhooks.
Jede Zustellung ist signiert. Der Header
X-Sunventory-Signature: t=<unix>,v1=<hmac>
trägt einen HMAC-SHA256 über t + "." + rohen Body
mit Ihrem Secret. Prüfen Sie die Signatur und lehnen Sie
Zeitstempel ab, die älter als etwa 5 Minuten sind, das schützt
vor Replays:
# Python
import hmac, hashlib, time
def verify(header, secret, raw_body):
t, v1 = (part.split("=", 1)[1] for part in header.split(","))
mac = hmac.new(secret.encode(), (t + ".").encode() + raw_body, hashlib.sha256)
fresh = abs(time.time() - int(t)) < 300
return fresh and hmac.compare_digest(mac.hexdigest(), v1)
Zum Einrichten schickt
POST /webhooks/{id}/test ein signiertes
Test-Event und meldet direkt zurück, ob Ihr Endpunkt es
angenommen hat.
Business Central, SAP und Co.
Die API ist bewusst schlicht gehalten: HTTPS, JSON, CSV. Damit spricht sie jedes System, das Wareneingänge aufnehmen kann, ohne eigenen Konnektor.
- Microsoft Dynamics 365 Business Central liest die Endpunkte per Power Automate oder direkt aus AL über den HttpClient.
- SAP bindet die Schnittstelle über die Integration Suite (CPI) oder jede andere HTTP-fähige Middleware an.
- Für alles andere ist der CSV-Export der kürzeste Weg: eine Zeile je Position, UTF-8, direkt importierbar.
Sie planen eine Anbindung und wollen sie nicht selbst bauen? Schreiben Sie uns, wir richten sie im Rahmen eines Pilotprojekts mit ein.
Verlässlichkeit
- Version 1 ist ein Vertrag: Felder kommen hinzu, werden aber nicht umbenannt und nicht entfernt.
- Schreiben können nur Schlüssel mit Schreibzugriff, und nur die Stückliste. Erfassung und Bestätigung bleiben in der App und der Web-Plattform, gelöscht wird über die API nie, der Nachweis bleibt unverändert.
- Je Schlüssel sind 120 Anfragen pro Minute frei, genug für minütliche Abgleiche. Antworten tragen die üblichen RateLimit-Header.
- Betrieb in einem Rechenzentrum in Deutschland, wie die ganze Plattform. Details in der Datenschutzerklärung.