Adventskalender-API
Erstelle digitale Adventskalender aus deiner eigenen Software, fülle die Türchen und lies aus, wie oft jedes Türchen geöffnet wurde. Alles, was du im Editor auf adventskalendererstellen.de tun kannst, geht auch mit ein paar HTTP-Aufrufen.
Zuletzt aktualisiert: 2026-09-29
API-Schlüssel erhalten
Der Zugang zu API und MCP ist in Premium (199 € pro Jahr) und Enterprise (1.299 € pro Jahr) enthalten. Schreib an [email protected] mit der E-Mail-Adresse deines Kontos und wir schicken dir einen Testschlüssel und einen Live-Schlüssel.
Überblick
Die Adventskalender Erstellen-API ist eine JSON-REST-API. Du legst einen Kalender mit Zeitraum, Öffnungszeit und Design an und hinterlegst hinter jedem Türchen Inhalte. Der Kalender ist sofort unter seinem öffentlichen Link erreichbar, und jedes Türchen öffnet sich von selbst zur eingestellten Uhrzeit in der Zeitzone des Kalenders.
Typische Einsatzzwecke:
- Shops und Agenturen, die jeden Dezember für viele Marken einen Gutscheinkalender betreiben und nicht jedes Mal 24 Türchen von Hand füllen wollen.
- Newsletter- und CRM-Tools, die einen Adventskalender als Kampagnentyp anbieten.
- HR- und Kommunikationsteams, die einen Teamkalender aus einer Tabelle befüllen.
- Entwickler, die einen KI-Agenten den Kalender bauen lassen wollen; dafür gibt es den MCP-Server.
Basis-URL: https://api.adventskalendererstellen.de/v1. Alle Anfragen laufen über HTTPS, alle Bodys sind UTF-8-JSON, alle Zeitstempel im ISO-8601-Format.
Zugang und Preise
Der API-Zugang gehört zu den kostenpflichtigen Tarifen und kostet nichts extra. Es gibt keine Gebühren pro Aufruf.
- Premium (199 € pro Jahr): volle API mit allen Inhaltstypen, eigenen Terminen, Branding und Statistiken.
- Enterprise (1.299 € pro Jahr): zusätzlich Passwortschutz, Tracking-Codes und CSV-Export.
- Free: kein API-Schlüssel. Private Kalender bleiben im Editor auf adventskalendererstellen.de kostenlos.
Schlüssel vergeben wir von Hand. Schreib an [email protected] von der E-Mail-Adresse deines Kontos und erzähl uns kurz, was du baust. Meist bekommst du einen Testschlüssel und einen Live-Schlüssel noch am selben Werktag.
Die kostenpflichtigen Tarife sind für Unternehmen gedacht. Wenn du auf der API ein Produkt aufbaust, das viele Endkunden bedient, sag uns das in deiner Anfrage, damit wir die Limits passend für dich festlegen.
Authentifizierung
Sende deinen Schlüssel als Bearer-Token im Header Authorization. Schlüssel mit dem Präfix sk_test_ funktionieren im Testmodus, Schlüssel mit dem Präfix sk_live_ erzeugen echte, öffentliche Kalender.
curl https://api.adventskalendererstellen.de/v1/calendars \
-H "Authorization: Bearer $ACM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Northwind Coffee Advent Calendar",
"start_date": "2026-12-01",
"end_date": "2026-12-24",
"opening_time": "08:00",
"timezone": "Europe/Berlin",
"template_style": "cozy"
}'
Bewahre Schlüssel auf dem Server auf. Ein Schlüssel hat die Rechte des ganzen Kontos, also gehört er nie in Browser-Code oder eine mobile App. Wenn ein Schlüssel abfließt, schreib uns: Wir sperren ihn innerhalb weniger Minuten und schicken dir einen neuen.
Schnellstart
Der kürzeste Weg zum funktionierenden Kalender: anlegen, die Türchen in einem Aufruf füllen, den Link teilen.
import os, requests
API = "https://api.adventskalendererstellen.de/v1"
HEAD = {"Authorization": "Bearer " + os.environ["ACM_API_KEY"]}
cal = requests.post(f"{API}/calendars", headers=HEAD, json={
"title": "Team Advent Calendar 2026",
"start_date": "2026-12-01",
"end_date": "2026-12-24",
"opening_time": "09:00",
"timezone": "Europe/Copenhagen",
}).json()
doors = [{"day": d, "content_type": "text", "title": f"Day {d}",
"text": f"Surprise number {d} is waiting in the kitchen."}
for d in range(1, cal["door_count"] + 1)]
requests.put(f"{API}/calendars/{cal['id']}/doors", headers=HEAD,
json={"doors": doors}).raise_for_status()
print(cal["public_url"]) # share this link
Die Antwort des ersten Aufrufs enthält bereits door_count (aus dem Zeitraum abgeleitet) und public_url. Türchen ohne Inhalt zeigen einen freundlichen Platzhalter, bis du sie füllst.
Endpunkte
| Methode | Pfad | Zweck |
|---|---|---|
| POST | /v1/calendars | Einen Kalender anlegen. |
| GET | /v1/calendars/{id} | Einen Kalender auslesen. |
| GET | /v1/calendars | Deine Kalender auflisten, neueste zuerst. |
| PATCH | /v1/calendars/{id} | Einstellungen eines Kalenders ändern. Es werden nur die Felder geändert, die du sendest. |
| DELETE | /v1/calendars/{id} | Einen Kalender mit allen Türchen, Medien und Statistiken löschen. |
| GET | /v1/calendars/{id}/doors | Alle Türchen eines Kalenders mit Öffnungszeiten und Inhalt. |
| PUT | /v1/calendars/{id}/doors | Bis zu 50 Türchen in einem Aufruf schreiben. |
| GET | /v1/calendars/{id}/doors/{day} | Ein einzelnes Türchen auslesen. |
| PUT | /v1/calendars/{id}/doors/{day} | Den Inhalt eines einzelnen Türchens schreiben oder ersetzen. |
| POST | /v1/media | Ein Bild, Video, eine Audiodatei oder einen Download für ein Türchen hochladen. |
| GET | /v1/backgrounds | Hintergrunddesigns, Vorlagenstile und Tags. |
| GET | /v1/calendars/{id}/stats | Aufrufe, Türchen-Öffnungen, Klicks und Teilnahmen. |
| GET | /v1/calendars/{id}/stats/export | Tägliche Statistiken als CSV (Enterprise). |
| GET | /v1/account | Tarif, Kontingente und freigeschaltete Funktionen des Schlüssels. |
Kalender anlegen
POST /v1/calendars legt einen Kalender an und gibt ihn zurück. Nur title ist Pflicht; alles andere hat sinnvolle Standardwerte (1. bis 24. Dezember der kommenden Saison (nach dem 24. Dezember also im nächsten Jahr), Türchen öffnen um 00:00 Uhr, Zeitzone Europe/Berlin, Stil classic).
import { randomUUID } from "node:crypto";
const res = await fetch("https://api.adventskalendererstellen.de/v1/calendars", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ACM_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": randomUUID(),
},
body: JSON.stringify({
title: "Northwind Coffee Advent Calendar",
description: "A new offer behind every door until Christmas Eve.",
start_date: "2026-12-01",
end_date: "2026-12-24",
opening_time: "08:00",
timezone: "Europe/Berlin",
template_style: "corporate",
background_image: "golden-baubles",
custom_color: "#0F766E",
door_colors: { door: "#0F766E", accent: "#F5C451", number: "#FFFFFF" },
custom_logo_url: "https://cdn.northwind.example/logo.png",
animation: "stars",
metadata: { campaign: "xmas-2026" },
}),
});
const calendar = await res.json();
| Feld | Typ | Beschreibung |
|---|---|---|
| title | string, required | Wird über dem Kalender angezeigt. Bis zu 255 Zeichen. |
| description | string | Kurzer Text unter dem Titel. Bis zu 2000 Zeichen. |
| start_date | date | Tag von Türchen 1. Standard: 1. Dezember. Premium. |
| end_date | date | Tag des letzten Türchens. Der Zeitraum darf höchstens 50 Tage umfassen. Premium. |
| opening_time | HH:MM | Lokale Uhrzeit, zu der sich jedes Türchen öffnet, zum Beispiel 08:00. Premium. |
| timezone | string | Name der IANA-Zeitzone, zum Beispiel Europe/London oder America/New_York. Standard: Europe/Berlin. |
| template_style | string | Einer der über 100 Türchen-Stile aus /v1/backgrounds. |
| background_image | string | Schlüssel eines Hintergrunddesigns aus dem Katalog. |
| custom_color | #RRGGBB | Markenfarbe als Hex-Wert. Premium. |
| door_colors | object | Eigene Türchenfarben über dem gewählten Stil: door, accent und number als Hex-Werte. null behält die Farben des Stils. Premium. |
| custom_logo_url | string | HTTPS-URL deines Logos, das über den Türchen angezeigt wird. Premium. |
| animation | string | Hintergrund-Animation: none, snow, flurry (dichtes Schneegestöber) oder stars (funkelnde Sterne). Standard: snow. In jedem Tarif kostenlos. |
| snow_enabled | boolean | Ältere Kurzform, true bei snow oder flurry. false setzt animation auf none. |
| is_public | boolean | false blendet den Kalender für alle außer dir aus; wer den Link öffnet, sieht nur einen kurzen Hinweis, dass er noch nicht freigegeben ist. Standard: true. |
| password | string | Besucher müssen dieses Passwort eingeben, bevor sie den Kalender sehen. Wird nur als Hash gespeichert. Enterprise. |
| tracking_code | string | Dein eigenes Analytics- oder Pixel-Snippet, das auf der öffentlichen Seite geladen wird. Enterprise. |
| metadata | object | Bis zu 20 eigene Schlüssel-Wert-Paare, die unverändert und in jedem Webhook zurückgegeben werden. |
Wenn du ein Feld sendest, das dein Tarif nicht enthält, schlägt die ganze Anfrage mit 403 plan_error fehl und es wird nichts angelegt. Siehe Tarife und Funktionen.
Das Kalender-Objekt
{
"id": "cal_4Hq8nW2kLp",
"object": "calendar",
"slug": "k7x2mq9t",
"public_url": "https://adventskalendererstellen.de/c/k7x2mq9t/",
"title": "Northwind Coffee Advent Calendar",
"description": "A new offer behind every door until Christmas Eve.",
"start_date": "2026-12-01",
"end_date": "2026-12-24",
"door_count": 24,
"opening_time": "08:00",
"timezone": "Europe/Berlin",
"template_style": "corporate",
"background_image": "golden-baubles",
"custom_color": "#0F766E",
"door_colors": { "door": "#0F766E", "accent": "#F5C451", "number": "#FFFFFF" },
"custom_logo_url": "https://cdn.northwind.example/logo.png",
"animation": "stars",
"snow_enabled": false,
"is_public": true,
"password_protected": false,
"tracking_code": null,
"doors_filled": 0,
"created_at": "2026-09-29T09:14:03Z",
"metadata": { "campaign": "xmas-2026" },
"livemode": true
}
| Feld | Typ | Beschreibung |
|---|---|---|
| id | string | Stabile ID, verwende sie in allen weiteren Aufrufen. |
| slug | string | Teil des öffentlichen Links, beim Anlegen zufällig. Über die API nur lesbar; ändern kannst du ihn im Editor (Kleinbuchstaben, Ziffern und Bindestriche, 3 bis 60 Zeichen). |
| public_url | string | Der Link, den du teilst. Öffnet den Kalender auf adventskalendererstellen.de. |
| door_count | integer | Anzahl der Türchen, immer gleich der Zahl der Tage von start_date bis end_date. |
| doors_filled | integer | Wie viele Türchen bereits Inhalt haben. |
| password_protected | boolean | true, wenn ein Passwort gesetzt ist. Das Passwort selbst wird nie zurückgegeben. |
| livemode | boolean | false bei Kalendern, die mit einem Testschlüssel angelegt wurden. |
Auflisten, ändern und löschen
GET /v1/calendars gibt deine Kalender seitenweise zurück, mit bis zu 100 pro Seite. Mit active_on bekommst du nur Kalender, deren Zeitraum diesen Tag enthält; mit metadata[campaign]=xmas-2026 filterst du nach deinen eigenen Metadaten.
curl -G https://api.adventskalendererstellen.de/v1/calendars \
-H "Authorization: Bearer $ACM_API_KEY" \
-d active_on=2026-12-10 \
-d limit=50
{
"object": "list",
"data": [
{ "id": "cal_4Hq8nW2kLp", "title": "Northwind Coffee Advent Calendar", "...": "..." },
{ "id": "cal_9Tz3pR6wQs", "title": "Team Advent Calendar 2026", "...": "..." }
],
"has_more": false,
"next_cursor": null
}
Ist has_more true, übergib next_cursor als cursor, um die nächste Seite zu erhalten.
PATCH /v1/calendars/{id} ändert nur die Felder, die du sendest. Wenn du den Zeitraum verkürzt, bleiben Türchen hinter dem neuen Ende erhalten, sind aber ausgeblendet; verlängerst du ihn wieder, kommen sie mit ihrem Inhalt zurück.
curl -X PATCH https://api.adventskalendererstellen.de/v1/calendars/cal_4Hq8nW2kLp \
-H "Authorization: Bearer $ACM_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "opening_time": "07:00", "animation": "snow" }'
DELETE /v1/calendars/{id} entfernt den Kalender, alle Türchen, hochgeladenen Medien und Statistiken endgültig. Der öffentliche Link liefert danach 404.
Türchen
Ein Kalender hat genau ein Türchen pro Tag seines Zeitraums, gezählt ab 1. Türchen werden nicht einzeln angelegt oder gelöscht; du schreibst nur ihren Inhalt.
PUT /v1/calendars/{id}/doors/{day} setzt den Inhalt eines Türchens und ersetzt, was vorher darin war.
curl -X PUT https://api.adventskalendererstellen.de/v1/calendars/cal_4Hq8nW2kLp/doors/7 \
-H "Authorization: Bearer $ACM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content_type": "coupon",
"title": "Door 7: 20 % off all filter coffee",
"text": "Valid today only, online and in store.",
"coupon_code": "ADVENT07"
}'
{
"object": "door",
"calendar_id": "cal_4Hq8nW2kLp",
"day": 7,
"date": "2026-12-07",
"unlocks_at": "2026-12-07T08:00:00+01:00",
"unlocked": false,
"unlocked_override": false,
"content_type": "coupon",
"title": "Door 7: 20 % off all filter coffee",
"text": "Valid today only, online and in store.",
"url": null,
"coupon_code": "ADVENT07",
"data": {},
"media": null,
"opens": 0
}
unlocks_at wird immer mit dem Offset der Zeitzone des Kalenders angegeben. opens zählt, wie oft Besucher dieses Türchen geöffnet haben; es wird nur bei Premium und Enterprise gefüllt.
Inhaltstypen
Jedes Türchen hat genau einen content_type. Diese Felder nutzt er:
| Typ | Tarif | Felder und Darstellung |
|---|---|---|
| text | Free | title und text. Ab Premium darf text einfaches HTML enthalten (Absätze, Überschriften, fett, kursiv, Listen, Links, Bilder); Skripte, Styles und Event-Attribute werden entfernt. Bei Free ist es reiner Text. |
| embed | Free | url eines YouTube- oder Vimeo-Videos, angezeigt als eingebetteter Player. |
| link | Premium | url plus optional title und text, angezeigt als Button zu deiner Seite. data.button legt den Button-Text fest. |
| image | Premium | media_id eines hochgeladenen Bildes, optional title und text als Bildunterschrift. |
| video | Premium | media_id eines hochgeladenen MP4-Videos. |
| coupon | Premium | coupon_code plus title und text. Der Code wird mit Kopieren-Button angezeigt. Wir erzeugen oder prüfen Codes nie; sie stammen aus deinem Shopsystem. |
| quiz | Premium | text enthält die Frage oder das Rätsel, data.answer die Antwort. Mit data.options (bis zu 6 Antworten) wählen Besucher eine Antwort und sehen sofort, ob sie stimmt; ohne Auswahl decken sie die Antwort per Tippen auf. |
| product | Premium | title als Produktname, text als Beschreibung, optional media_id eines Produktbilds, data.price als Anzeigetext und url der Produktseite. data.button legt den Button-Text fest. |
| event | Premium | data.date (JJJJ-MM-TT, Pflicht), optional data.time (HH:MM) und data.location, dazu text und optional eine Anmelde-url. Besucher können den Termin als .ics-Datei in ihren eigenen Kalender übernehmen. |
| giveaway | Premium | data.prize, optional data.deadline (JJJJ-MM-TT), text mit den Teilnahmebedingungen und url deines Teilnahmeformulars. Wir sammeln keine Teilnahmen und losen nicht aus; das läuft über dein Formular. |
| download | Premium | media_id einer hochgeladenen Datei plus text. Angezeigt mit Dateiname und Download-Button; data.button legt dessen Text fest. |
| survey | Premium | text enthält die Frage, data.options 2 bis 6 Antworten. Jeder Browser stimmt einmal ab und sieht danach das Ergebnis. Wenn du die Antworten änderst, werden die Stimmen zurückgesetzt. |
| music | Premium | media_id einer hochgeladenen Audiodatei oder url einer Spotify- oder SoundCloud-Seite, optional data.artist. |
Wann sich Türchen öffnen
Türchen n öffnet sich am Tag start_date + (n - 1) days zur Uhrzeit opening_time in der timezone des Kalenders. Die Zeitzone des Besuchers spielt keine Rolle: Ein Kalender mit 08:00 Uhr Europe/Berlin öffnet Türchen 1 in London um 07:00 Uhr und in New York um 02:00 Uhr.
Vor diesem Zeitpunkt zeigt die öffentliche Seite das Türchen als geschlossen, und die API für die öffentliche Seite verrät den Inhalt nicht. Du als Besitzer siehst immer alle Türchen.
Um ein Türchen früher zu öffnen (für eine Vorschau, eine Pressemitteilung oder einen Bonustag), setze am Türchen "unlocked_override": true. Setzt du es zurück auf false, ist das Türchen bis zu seiner regulären Zeit wieder geschlossen.
Änderungen an opening_time oder timezone gelten sofort für alle Türchen, die noch nicht offen sind. Bereits geöffnete Türchen bleiben offen.
Viele Türchen auf einmal füllen
PUT /v1/calendars/{id}/doors nimmt eine Liste mit bis zu 50 Türchen entgegen. Türchen, die du nicht aufführst, bleiben unverändert. Der Aufruf gilt ganz oder gar nicht: Ist ein Türchen ungültig, wird kein Türchen geschrieben, und der Fehler nennt Tag und Feld.
{
"doors": [
{ "day": 1, "content_type": "text", "title": "Welcome", "text": "<p>Glad you are here.</p>" },
{ "day": 2, "content_type": "embed", "url": "https://www.youtube.com/watch?v=abc123" },
{ "day": 3, "content_type": "link", "title": "Our winter blend", "url": "https://northwind.example/winter" },
{ "day": 4, "content_type": "image", "media_id": "med_2Kd7sF1vXp" }
]
}
Dieser Aufruf ist die richtige Wahl, wenn du einen Kalender aus einer Tabelle oder einem Produktfeed befüllst. Er zählt als eine Anfrage gegen das Rate-Limit.
Bilder und Videos
Lade Dateien mit POST /v1/media hoch und verweise dann mit der zurückgegebenen id als media_id in einem Türchen darauf. Du kannst die Datei als Multipart-Formulardaten senden oder uns eine öffentliche source_url nennen, die wir abrufen.
curl https://api.adventskalendererstellen.de/v1/media \
-H "Authorization: Bearer $ACM_API_KEY" \
-F "[email protected]" \
-F "calendar_id=cal_4Hq8nW2kLp"
# or let us fetch it from a public URL
curl https://api.adventskalendererstellen.de/v1/media \
-H "Authorization: Bearer $ACM_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "calendar_id": "cal_4Hq8nW2kLp", "source_url": "https://cdn.northwind.example/door-04.webp" }'
{
"id": "med_2Kd7sF1vXp",
"object": "media",
"calendar_id": "cal_4Hq8nW2kLp",
"kind": "image",
"mime_type": "image/webp",
"bytes": 184322,
"url": "https://adventskalendererstellen.de/media/4711/door-04.webp/",
"created_at": "2026-09-29T09:20:41Z"
}
- Bilder: JPG, PNG, GIF oder WebP, bis zu 2 MB.
- Videos: MP4, bis zu 20 MB.
- Audio: MP3, M4A oder OGG, bis zu 10 MB.
- Downloads: PDF, ZIP, EPUB, DOCX, XLSX, PPTX oder TXT, bis zu 10 MB.
- Medien gehören zu einem Kalender und werden zusammen mit ihm gelöscht.
- Medien-Uploads erfordern Premium oder Enterprise.
Designs und Hintergründe
GET /v1/backgrounds gibt den Hintergrundkatalog, die über 100 Türchen-Stile und die Tags zurück, nach denen du filtern kannst. Verwende den key eines Hintergrunds als background_image, wenn du einen Kalender anlegst.
curl -G https://api.adventskalendererstellen.de/v1/backgrounds \
-H "Authorization: Bearer $ACM_API_KEY" \
-d tag=corporate
{
"object": "list",
"data": [
{ "key": "golden-baubles", "name": "Golden Baubles", "tags": ["festive", "elegant", "corporate"],
"thumb_url": "https://adventskalendererstellen.de/backgrounds/thumbs/golden-baubles.webp/" },
{ "key": "nordic-office", "name": "Nordic Office", "tags": ["minimalist", "corporate"],
"thumb_url": "https://adventskalendererstellen.de/backgrounds/thumbs/nordic-office.webp/" }
],
"template_styles": ["classic", "winter", "modern", "cozy", "corporate", "snowfall",
"candycane", "forest", "starlight", "gingerbread", "nordic", "midnight",
"plaid-red", "knit-red", "window-red", "bauble-red", "polka-red", "gift-kraft",
"frost-mint", "flat-retro", "starlight-teal", "knit-cream", "window-blue", "bauble-gold",
"gift-cranberry", "gift-frosted", "gift-pastel", "gift-emerald", "frost-lavender", "frost-blush",
"frost-glacier", "frost-silver", "flat-sorbet", "flat-ocean", "flat-mono", "flat-xmas",
"cabin-birch", "cabin-red", "cabin-green", "cabin-blue", "card-teal", "card-navy",
"card-dark", "card-cream", "card-green", "snowfall-teal", "snowfall-plum", "snowfall-red",
"snowfall-green", "snowfall-grey", "stripes-mint", "stripes-gold", "stripes-blue", "stripes-berry",
"stripes-cocoa", "forest-dusk", "forest-snow", "forest-red", "forest-midnight", "forest-pine",
"starlight-silver", "starlight-rose", "starlight-red", "starlight-green", "iced-pink", "iced-choc",
"iced-mint", "iced-honey", "linen-blue", "linen-green", "linen-red", "linen-dark",
"lacquer-silver", "lacquer-red", "lacquer-green", "lacquer-blue", "lacquer-rose", "plaid-green",
"plaid-blue", "plaid-buffalo", "plaid-grey", "plaid-camel", "plaid-mix", "knit-green",
"knit-navy", "knit-grey", "knit-mix", "window-green", "window-wood", "window-white",
"window-mix", "bauble-silver", "bauble-blue", "bauble-mix", "bauble-pink", "polka-green",
"polka-navy", "polka-pink", "polka-cream", "polka-mix", "knit-teal", "bauble-plum",
"stripes-frost", "card-red"],
"tags": ["festive", "nature", "cozy", "elegant", "minimalist", "cartoon",
"kids", "dogs", "cats", "corporate", "romantic"]
}
Statistiken
GET /v1/calendars/{id}/stats gibt die Aufrufe der Kalenderseite, die Aufrufe der letzten sieben Tage, Aufrufe und Öffnungen pro Tag sowie je Türchen die Öffnungen und die Aktionen darin zurück (actions: Klicks auf Knöpfe, kopierte Gutscheincodes, Quiz-Antworten, Gewinnspiel-Teilnahmen und Umfrage-Stimmen, je Besucher einmal gezählt). Statistiken gehören zu Premium und Enterprise.
{
"object": "calendar_stats",
"calendar_id": "cal_4Hq8nW2kLp",
"views": 18342,
"views_last_7_days": 6120,
"door_opens": 41877,
"daily": [
{ "date": "2026-12-01", "views": 2410, "opens": 3904 },
{ "date": "2026-12-02", "views": 2265, "opens": 3517 }
],
"doors": [
{ "day": 1, "type": "coupon", "opens": 3904, "actions": 1288 },
{ "day": 2, "type": "quiz", "opens": 3517, "actions": 2140 },
{ "day": 3, "type": "text", "opens": 3288, "actions": 0 }
],
"generated_at": "2026-12-03T10:00:00Z"
}
Bei Enterprise liefert /stats/export dieselben Daten pro Tag als CSV, bereit für eine Tabelle oder dein BI-Tool.
curl -L -o opens.csv \
"https://api.adventskalendererstellen.de/v1/calendars/cal_4Hq8nW2kLp/stats/export?from=2026-12-01&to=2026-12-24" \
-H "Authorization: Bearer $ACM_API_KEY"
# date,day,views,unique_visitors,door_opens,actions
# 2026-12-01,1,2410,1873,3904,612
Wir zählen Aufrufe und Öffnungen ohne Cookies und ohne IP-Adressen im Klartext zu speichern. Siehe Datenschutz.
Tarife und Funktionen
Dein Schlüssel hat die Funktionen deines Tarifs. GET /v1/account zeigt sie an.
{
"object": "account",
"plan": "enterprise",
"renews_at": "2027-09-12",
"calendars": { "used": 14, "limit": null },
"features": {
"media": true, "html": true, "custom_dates": true, "branding": true,
"analytics": true, "password": true, "tracking_code": true, "csv_export": true
},
"livemode": true
}
| Funktion | Ab Tarif | Betrifft |
|---|---|---|
| Premium | link, image, video, coupon, quiz, product, event, giveaway, download, survey, music | Türchen mit Links, Bildern, Videos, Gutscheinen, Quiz, Produkten, Events, Gewinnspielen, Downloads, Umfragen und Musik. |
| Premium | text | HTML-Formatierung im Türchentext. |
| Premium | start_date, end_date, opening_time | Eigener Zeitraum und eigene Öffnungszeit statt 1. bis 24. Dezember um Mitternacht. |
| Premium | custom_color, door_colors, custom_logo_url | Eigene Markenfarbe, eigene Türchenfarben und eigenes Logo. |
| Premium | /stats | Aufrufe und Türchen-Öffnungen. |
| Enterprise | password | Passwortgeschützte Kalender. |
| Enterprise | tracking_code | Eigener Tracking- oder Pixel-Code auf der öffentlichen Seite. |
| Enterprise | /stats/export | Statistiken als CSV. |
Die Anzahl der Kalender ist in den kostenpflichtigen Tarifen nicht begrenzt.
Webhooks
Nenne uns einen HTTPS-Endpunkt, und wir senden dorthin ein Ereignis, sobald in deinem Konto etwas passiert. Jedes Ereignis ist ein POST mit einem JSON-Body.
| Ereignis | Wann |
|---|---|
| calendar.created | Ein Kalender wurde angelegt, per API oder im Editor. |
| calendar.updated | Einstellungen eines Kalenders oder der Inhalt eines Türchens haben sich geändert. |
| calendar.deleted | Ein Kalender wurde gelöscht. |
| door.unlocked | Ein Türchen hat sich gerade geöffnet. Praktisch, um in derselben Minute eine Push-Nachricht oder einen Newsletter zu verschicken. |
| stats.daily | Einmal täglich, kurz nach Mitternacht in der Zeitzone des Kalenders: die Zahlen des Vortags. Ab Premium. |
{
"id": "evt_7Nc2vB5xRt",
"type": "door.unlocked",
"created_at": "2026-12-07T07:00:02Z",
"livemode": true,
"data": {
"calendar_id": "cal_4Hq8nW2kLp",
"day": 7,
"unlocks_at": "2026-12-07T08:00:00+01:00",
"public_url": "https://adventskalendererstellen.de/c/k7x2mq9t/",
"metadata": { "campaign": "xmas-2026" }
}
}
Jede Anfrage trägt einen ACM-Signature-Header mit einem Zeitstempel und einem HMAC-SHA256 von timestamp.body, signiert mit deinem Webhook-Secret.
ACM-Signature: t=1796626802,v1=9e4b1c7d2a...
import hmac, hashlib, os, time
SECRET = os.environ["ACM_WEBHOOK_SECRET"].encode()
def verify(header: str, raw_body: bytes) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
ts, sig = parts["t"], parts["v1"]
if abs(time.time() - int(ts)) > 300:
return False
expected = hmac.new(SECRET, ts.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
Antworte innerhalb von 10 Sekunden mit einem beliebigen 2xx-Status. Bekommen wir kein 2xx, versuchen wir es 24 Stunden lang mit wachsenden Abständen erneut. Ereignisse können mehrfach eintreffen; nutze id, um Duplikate zu ignorieren.
Idempotenz
Sende bei jedem POST einen Idempotency-Key-Header mit. Bricht die Verbindung ab und du sendest dieselbe Anfrage innerhalb von 24 Stunden mit demselben Schlüssel erneut, bekommst du die ursprüngliche Antwort zurück statt eines zweiten Kalenders.
curl https://api.adventskalendererstellen.de/v1/calendars \
-H "Authorization: Bearer $ACM_API_KEY" \
-H "Idempotency-Key: 3f6c1a2e-8d4b-4e0f-9b7a-5c2d1e0f9a88" \
-H "Content-Type: application/json" \
-d @calendar.json
PUT und PATCH sind von Natur aus idempotent und brauchen den Header nicht.
Fehler
Fehler kommen mit einem passenden HTTP-Status und einem Body, der dir sagt, was du korrigieren musst.
{
"error": {
"type": "plan_error",
"code": "feature_not_in_plan",
"message": "Password protection is part of the Enterprise plan.",
"field": "password",
"required_plan": "enterprise",
"request_id": "req_5Xk1dM8pWq"
}
}
| Typ | Status | Bedeutung |
|---|---|---|
| invalid_request | 400 | Die Anfrage kann nicht gelesen werden, zum Beispiel wegen kaputtem JSON oder eines unbekannten Feldes. |
| authentication_error | 401 | Fehlender, falscher oder gesperrter Schlüssel. |
| plan_error | 403 | Das Feld oder der Endpunkt braucht einen höheren Tarif. required_plan nennt ihn. |
| not_found | 404 | Kalender, Türchen oder Medium existiert in deinem Konto nicht. |
| conflict | 409 | Derselbe Idempotency-Key wurde mit einem anderen Body verwendet. |
| validation_error | 422 | Ein Wert ist nicht erlaubt, zum Beispiel ein Zeitraum über 50 Tage, eine Türchennummer außerhalb des Zeitraums oder ein Bild über 2 MB. field benennt ihn. |
| rate_limit | 429 | Zu viele Anfragen. Warte RateLimit-Reset Sekunden. |
| api_error | 500 | Unser Fehler. Versuch es später erneut und schick uns die request_id, falls es bestehen bleibt. |
Limits
| Wert | Limit |
|---|---|
| 120 / min | Anfragen pro Minute und Schlüssel. Jede Antwort trägt den aktuellen Stand in Headern. |
| ≤ 50 | Türchen pro Kalender, durch den Zeitraum bestimmt. |
| 2 MB | Bild-Upload: JPG, PNG, GIF, WebP. |
| 20 MB | Video-Upload: MP4. |
| 50 | Türchen pro Aufruf von PUT /doors. |
| 24 h | Idempotenz-Fenster: wie lange wir uns einen Schlüssel merken. |
RateLimit-Limit: 120
RateLimit-Remaining: 117
RateLimit-Reset: 41
Wenn du für eine große Kampagne Ende November mehr brauchst, schreib uns, bevor sie startet.
Versionierung
Die Version ist Teil des Pfads (/v1). Innerhalb von v1 kommt nur Neues dazu: neue Endpunkte, neue optionale Felder, neue Ereignistypen. Dein Code sollte Felder ignorieren, die er nicht kennt.
Änderungen, die Integrationen brechen könnten, bekommen eine neue Datumsversion. Du kannst eine per Header festlegen; ohne Header nutzt dein Schlüssel die Version, die bei seiner Ausstellung aktuell war.
ACM-Version: 2026-09-01
Inkompatible Änderungen kündigen wir mindestens sechs Monate vorher per E-Mail an und veröffentlichen sie nie zwischen dem 15. November und dem 6. Januar, solange Kalender laufen.
Testmodus
Mit einem sk_test_-Schlüssel funktioniert alles wie im Live-Modus, mit drei Unterschieden:
- Testkalender haben
"livemode": falseund ihr öffentlicher Link zeigt ein „Test“-Banner. - Testkalender werden nicht von Suchmaschinen indexiert und nach 30 Tagen gelöscht.
- Du kannst bei einem GET auf ein Türchen oder einen Kalender
"simulate_date": "2026-12-07T08:00:00Z"mitsenden, um zu sehen, welche Türchen zu diesem Zeitpunkt offen wären.
Webhooks aus dem Testmodus haben "livemode": false, sodass ein Endpunkt beide verarbeiten kann.
Datenschutz
Deine Kalender und ihre Inhalte gehören dir. Wir nutzen sie nur, um den Kalender anzuzeigen, und für nichts anderes.
- Besucher brauchen kein Konto, und wir setzen auf öffentlichen Kalendern keine Tracking-Cookies.
- Für Aufrufe und Öffnungen speichern wir nur einen Hash der IP-Adresse, nie die Adresse selbst.
- Passwörter geschützter Kalender werden nur als Hash gespeichert.
- Hosting und Datenverarbeitung finden in der EU statt. Ein Auftragsverarbeitungsvertrag nach DSGVO ist auf Anfrage erhältlich.
- Ein Tracking-Code, den du selbst einbindest (Enterprise), läuft in deiner Verantwortung; die Einwilligung deiner Besucher dafür einzuholen, ist deine Aufgabe.
Support
Fragen zur API, zu einem Schlüssel oder zu einem Webhook gehen an [email protected]. Gib immer die request_id aus dem Fehler oder den Response-Headern an; damit finden wir deine Anfrage in Sekunden.
Enterprise-Kunden erhalten bevorzugten Support, und in den Wochen vor dem 1. Dezember beantworten wir API-Fragen innerhalb eines Werktags.
API-Schlüssel erhalten
Der Zugang zu API und MCP ist in Premium (199 € pro Jahr) und Enterprise (1.299 € pro Jahr) enthalten. Schreib an [email protected] mit der E-Mail-Adresse deines Kontos und wir schicken dir einen Testschlüssel und einen Live-Schlüssel.