So funktioniert Stielpreis
Hochzeitsangebot per API anlegen: Schlüssel, Endpunkte und Beispiel mit Antwort
Hochzeitsangebot per API anlegen: Schlüssel, Endpunkte, Beispiel mit Antwort, Fehler und was der Server rechnet. Die Stielpreis-API für Skripte und KI-Agenten.
Stand 10. November 2026 · 8 Min. Lesezeit · von Stielpreis, der Software für Hochzeitsfloristik
Ein Hochzeitsangebot per API legst du mit einer JSON-Anfrage an die Stielpreis-API v1 an: Sie erzeugt eine komplette Hochzeit mit Positionen und Kunden-Link im Konto einer Floristin. Die Anfrage nennt Blumen mit Namen und Stielzahl, aber keine Preise und keine Summen: Die rechnet der Server. Du brauchst einen API-Schlüssel, den du im Header „Authorization: Bearer“ mitschickst.
Wofür ist die API gedacht?
Gedacht ist sie für ein Programm, das beschreibt, was eine Floristin im Rechner eintippen würde: Blumen nach Namen, Stiele je Stück, Stunden, Faktor. Der Server preist die Blumen, lässt die Rechenlogik von Stielpreis laufen und liefert die Summen und den Link fürs Brautpaar zurück. Typisch ist ein KI-Agent, der aus einer Anfrage ein Angebot entwirft, oder ein Skript, das Anfragen aus einem anderen System übernimmt. Gedacht ist das für Entwicklerinnen und Floristinnen mit technischer Hilfe.
Was die API nicht tut:
- Sie ändert, liest oder löscht keine bestehende Hochzeit. Es gibt nur das Anlegen.
- Sie stellt weder Angebotsdokumente noch Rechnungen aus und erfasst keine Zahlungen.
- Sie löst keine Annahme aus. Die gibt das Brautpaar selbst auf dem Link ab, siehe Annahme per Klick.
- Sie versendet nichts. Den Link, den sie zurückgibt, schickst du selbst.
Wie meldest du dich mit dem API-Schlüssel an?
Jeder Aufruf braucht einen Schlüssel im Header:
Authorization: Bearer sp_live_XXXXXXXX
Hier steht sp_live_XXXXXXXX für deinen eigenen Schlüssel, der länger ist. Ein Schlüssel gehört zu genau einem Konto, und alles, was die API liest oder schreibt, gilt für dieses Konto. Fehlt der Schlüssel oder ist er falsch geschrieben, unbekannt oder widerrufen, antwortet der Server mit 401.
Angelegt werden Schlüssel auf der Kommandozeile mit einem Skript im Stielpreis-Code (scripts/api-key.ts, Befehle create, list und revoke). Dafür braucht es Zugriff auf die Datenbank, und das Konto muss existieren, die Floristin hat sich also einmal angemeldet. Der Schlüssel wird nur beim Anlegen einmal angezeigt. Gespeichert werden nur sein SHA-256-Wert und die ersten 16 Zeichen, mit denen er sich finden und auflisten lässt. Lege ihn in eine Umgebungsvariable und nicht in den Code, in einen Chat oder in ein Repository.
Welche Endpunkte gibt es?
Die Adresse in den Beispielen ist https://stielpreis.de.
| Endpunkt | Was er tut |
|---|---|
POST /api/v1/weddings | Legt eine Hochzeit mit Status Angebot an, mit Positionen, Kunden-Link, Eintrag im Verlauf und Preisgedächtnis wie beim Speichern im Rechner |
GET /api/v1/catalog?q= | Sucht im Katalog und in den eigenen Materialien des Kontos, bis 50 Treffer, und nennt den Preis je Stiel oder Stück, den POST ansetzen würde |
GET /api/v1/schema | Gibt das JSON Schema (Draft 2020-12) des POST-Bodys zurück, erzeugt aus dem Schema, mit dem der Server prüft |
Im Body stehen coupleName (Pflicht, wird zur Überschrift des Angebots), optional eventDate (JJJJ-MM-TT), venue, customerAddress und showImages (Standard true), dazu positions mit 1 bis 50 Einträgen. Jede Position hat eine von vier Arten:
treatment | Das ist es | Felder | Steuer |
|---|---|---|---|
werkstueck | ein gebundenes Stück, in der App eine Werkstattkarte | name, qty, materials, laborHours je Stück, optional hourlyRateCents, wastePct, factor | 7 % bei frischen Blumen oder Grün, 19 % wenn das ganze Material zubehoer ist |
ware | Ware wie verkauft | name, qty, unitNetPriceCents, category | 7 % bei schnittblume und gruen, 19 % bei zubehoer |
dienstleistung | Aufbau, Dekoration vor Ort, eigene Beratung | name, qty, unitNetPriceCents | 19 % |
lieferung | Lieferung der fertigen Stücke | name, qty, unitNetPriceCents | 7 %, wenn alle anderen Positionen 7 % haben, sonst 19 % mit "taxHint": "lieferung_19" |
Materialien eines Werkstücks sind catalog (name, qty) oder custom (name, category, myPriceCents, qty). Die qty einer Blume gilt für ein Stück, nicht für alle.
Hochzeitsangebot per API anlegen: ein Beispiel von der Anfrage bis zur Antwort
Der Strauß ist die Boho-Beispielkarte aus dem Rechner, dazu eine Zeile für Lieferung und Aufbau. Der Request:
curl -s https://stielpreis.de/api/v1/weddings \
-H "Authorization: Bearer $STIELPREIS_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f0d3c9e-hochzeit-lena-jonas" \
--data @wedding.json
wedding.json:
{
"coupleName": "Lena & Jonas",
"eventDate": "2027-06-12",
"venue": "Gutshof am See",
"positions": [
{
"treatment": "werkstueck",
"name": "Brautstrauß Boho",
"qty": 1,
"laborHours": 0,
"hourlyRateCents": 4500,
"wastePct": 12,
"factor": 3,
"materials": [
{ "kind": "catalog", "name": "Dahlie (Cafe au Lait)", "qty": 3 },
{ "kind": "catalog", "name": "Ranunkel Clooney", "qty": 5 },
{ "kind": "catalog", "name": "Lisianthus (gefuellt weiss)", "qty": 4 },
{ "kind": "catalog", "name": "Skabiose (Witwenblume)", "qty": 4 },
{ "kind": "catalog", "name": "Jungfer im Gruenen (Nigella)", "qty": 5 },
{ "kind": "catalog", "name": "Amaranth (Fuchsschwanz)", "qty": 3 },
{ "kind": "catalog", "name": "Pampasgras (Federrispe)", "qty": 2 },
{ "kind": "catalog", "name": "Olive (Olivenzweig)", "qty": 3 },
{ "kind": "catalog", "name": "Eukalyptus Parvifolia", "qty": 4 },
{ "kind": "catalog", "name": "Ruscus (Italian)", "qty": 4 },
{ "kind": "catalog", "name": "Sprayrose (Gartenrose-Typ, gefuellt)", "qty": 4 },
{ "kind": "catalog", "name": "Ammi (Falsche Bischofskraut)", "qty": 5 }
]
},
{ "treatment": "dienstleistung", "name": "Lieferung und Aufbau", "qty": 1, "unitNetPriceCents": 5000 }
]
}
Die Antwort, 201 Created, hier gekürzt (je Material steht zusätzlich match, Kennung und Link sind Platzhalter):
{
"weddingId": 42,
"customerUrl": "https://stielpreis.de/a/<token>",
"taxMode": "regelbesteuert",
"totals": {
"netCents": 25070,
"taxCents": 2355,
"grossCents": 27425,
"blocks": [
{ "rate": 7, "netCents": 20070, "taxCents": 1405, "grossCents": 21475 },
{ "rate": 19, "netCents": 5000, "taxCents": 950, "grossCents": 5950 }
]
},
"positions": [
{ "name": "Brautstrauß Boho", "unitNetCents": 20070, "rate": 7, "taxHint": "trocken_gemischt",
"breakdown": { "materialCents": 5973, "materialWithWasteCents": 6690, "wareneinsatzPct": 33.3, "factor": 3 } },
{ "name": "Lieferung und Aufbau", "unitNetCents": 5000, "rate": 19, "taxHint": null }
],
"warnings": []
}
Nachgerechnet mit der Rechenlogik von Stielpreis (Beispielrechnung mit geschätzten Großhandelspreisen aus dem Katalog): Der Strauß kostet netto 200,70 €, die Lieferung 50,00 €, zusammen 250,70 € netto. Dazu kommen 14,05 € USt bei 7 % und 9,50 € bei 19 %, der Gesamtbetrag ist 274,25 €. Das Material mit Verschnitt ist 66,90 €, das sind 33,3 % vom Preis, unter der Warnschwelle von 40 %. trocken_gemischt steht dabei, weil das Pampasgras im Katalog als getrocknetes Material (Zubehör) geführt wird: Der Strauß bleibt bei 7 %, ob er noch als frischer Strauß gilt, klärst du mit deiner Steuerberatung. Die Grundlagen zu 7 und 19 % stehen in Umsatzsteuer in der Hochzeitsfloristik.


Was rechnet der Server, und was schickst du?
Du schickst Namen, Mengen und, wo es keinen Katalogpreis gibt, deinen Einkaufspreis. Der Server nimmt den Rest aus dem Konto:
- Preise der Katalogblumen: der Preis, den das Konto sich gemerkt hat (
"match": "own"), sonst die Mitte der Katalogspanne je Stiel ("match": "catalog"). Beicustomgilt deinmyPriceCents("match": "custom"). - Faktor, Verschnitt und Stundensatz, wenn du sie weglässt, aus den Rechner-Standards der Einstellungen.
- Besteuerung: regelbesteuert oder Kleinunternehmerin kommt aus dem Konto, nicht aus der Anfrage.
- Summen, Steuer je Satz und Warnungen:
faktor_niedrigundwareneinsatz_hoch. Sie warnen nur, die Hochzeit wird trotzdem angelegt. Wann sie auslösen, steht in Wareneinsatz zu hoch: wann Stielpreis warnt. - Gültigkeit und Bedingungen: Die Gültigkeit läuft ab dem Anlegen, die Zahl der Tage kommt aus den Einstellungen. Anzahlung, Änderungsfrist und Zahlungshinweis liest der Link aus dem Konto.
Unbekannte Felder lehnt der Server ab. Ein Client, der selbst grossCents mitschickt, bekommt ein 400 statt einer stillschweigend ignorierten Zahl. Das Konto bleibt die einzige Quelle für Preise und Summen.
Wie gehst du mit Fehlern um?
| Status | Wann |
|---|---|
201 | Angelegt, oder die Antwort eines früheren Aufrufs mit demselben Idempotency-Key (Header Idempotent-Replayed: true) |
400 invalid_request | Ungültiges JSON, Schemaverstoß, ungültiger Idempotency-Key oder unbekanntes Material. issues[].path zeigt auf das Feld, bei unbekannten Materialien kommen suggestions aus dem Katalog |
401 unauthorized | Kein gültiger Schlüssel |
403 free_limit | Das Konto ist im Free-Tarif und hat schon seine eine Hochzeit. Die API überschreibt sie nie, anders als der Rechner |
422 idempotency_key_reused | Derselbe Key mit anderem Body |
Ein unbekannter Name sieht so aus:
{
"error": "invalid_request",
"issues": [
{
"path": ["positions", 0, "materials", 0, "name"],
"code": "unknown_material",
"message": "\"Dahlie Blaumond\" is neither in the catalog nor among the account's own materials. Pick a name from GET /api/v1/catalog?q=..., or send it with kind \"custom\", a category and myPriceCents.",
"suggestions": ["Dahlie", "Dahlie (Cafe au Lait)", "Dahlie Wizard of Oz", "Dahlie Karma-Serie"]
}
]
}
Beim 400 korrigierst du die Anfrage anhand von issues und sendest sie erneut. Bei einem Timeout oder Netzfehler wiederholst du sie mit demselben Idempotency-Key (1 bis 255 sichtbare ASCII-Zeichen, einer je Hochzeit), dann entsteht keine zweite Hochzeit.
Wie hängst du einen KI-Agenten an?
Damit ein Agent ein Hochzeitsangebot per API anlegt, holst du das Schema einmal und gibst es ihm als Eingabeschema eines Werkzeugs, ein zweites Werkzeug sucht Blumennamen über GET /api/v1/catalog. Die Kennung des Werkzeugaufrufs eignet sich als Idempotency-Key, auf ein 400 gibst du issues als Ergebnis zurück. Ein ausführliches Beispiel steht in docs/api.md im Stielpreis-Code.
Häufige Fehler
- Menge der Blume für alle Stücke angegeben.
qtyim Material gilt für ein Stück. Acht gleiche Tischgestecke sindqty: 8an der Position. - Trockenware als
schnittblumeeingetragen. Getrocknetes, Gebleichtes, Gefärbtes und Zubehör gehören inzubehoermit 19 %. - Den Namen aus dem Gedächtnis schreiben. Suche ihn mit
GET /api/v1/catalog?q=, sonst kommtunknown_material. - Den Schlüssel im Code oder Chat hinterlassen. Wer ihn hat, legt Hochzeiten in deinem Konto an. Er lässt sich mit
revokewiderrufen. - Den Link ungeprüft weitergeben. Die Hochzeit liegt wie jede andere unter „Meine Hochzeiten“. Prüfe Positionen und Summe im Rechner über „Bearbeiten“, bevor das Brautpaar sie sieht. Wie der Link aussieht, steht in Das Angebot als Link ans Brautpaar.
Häufige Fragen
- Wie lege ich ein Hochzeitsangebot per API an?
- Mit einem POST an /api/v1/weddings, dem API-Schlüssel im Header und einem JSON-Body mit coupleName und positions. Die Antwort enthält die Summen und den Link fürs Brautpaar (customerUrl).
- Wofür ist die Stielpreis-API gedacht?
- Ein Programm, meist ein KI-Agent oder ein Skript, legt damit ein komplettes Hochzeitsangebot im Konto einer Floristin an: Hochzeit, Positionen und Kunden-Link wie beim Speichern im Rechner.
- Wie authentifiziere ich mich bei der API?
- Mit einem API-Schlüssel im Header „Authorization: Bearer sp_live_...“. Ein Schlüssel gehört zu genau einem Konto. Er wird auf der Kommandozeile angelegt, eine Seite in den Einstellungen gibt es dafür nicht.
- Muss meine Anfrage Preise und Summen enthalten?
- Nein. Für Katalogblumen schickst du nur Name und Menge. Preise und Summen rechnet der Server. Schickst du selbst Summen, lehnt er die Anfrage mit 400 ab.
- Was passiert, wenn ich die Anfrage wiederhole?
- Mit einem Idempotency-Key gibt der Server beim zweiten Senden dieselbe Antwort zurück, ohne eine zweite Hochzeit anzulegen. Ohne Key entsteht bei jedem Senden eine neue, soweit dein Tarif es zulässt.
- Kann ich mit der API ein Angebot ändern, Rechnungen erstellen oder die Annahme auslösen?
- Nein. Die API legt Hochzeiten an und liest den Katalog und das Schema. Ändern, Dokumente, Zahlungen und die Annahme laufen weiter über Stielpreis selbst.