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.

Schlüssel anfragen

Ü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.

bash Authorization-Header in jeder Anfrage
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.

python Python: 24 Türchen in zwei Anfragen
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

MethodePfadZweck
POST/v1/calendarsEinen Kalender anlegen.
GET/v1/calendars/{id}Einen Kalender auslesen.
GET/v1/calendarsDeine 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}/doorsAlle Türchen eines Kalenders mit Öffnungszeiten und Inhalt.
PUT/v1/calendars/{id}/doorsBis 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/mediaEin Bild, Video, eine Audiodatei oder einen Download für ein Türchen hochladen.
GET/v1/backgroundsHintergrunddesigns, Vorlagenstile und Tags.
GET/v1/calendars/{id}/statsAufrufe, Türchen-Öffnungen, Klicks und Teilnahmen.
GET/v1/calendars/{id}/stats/exportTägliche Statistiken als CSV (Enterprise).
GET/v1/accountTarif, 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).

javascript Node.js: Kalender mit Branding und Hintergrund
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();
FeldTypBeschreibung
titlestring, requiredWird über dem Kalender angezeigt. Bis zu 255 Zeichen.
descriptionstringKurzer Text unter dem Titel. Bis zu 2000 Zeichen.
start_datedateTag von Türchen 1. Standard: 1. Dezember. Premium.
end_datedateTag des letzten Türchens. Der Zeitraum darf höchstens 50 Tage umfassen. Premium.
opening_timeHH:MMLokale Uhrzeit, zu der sich jedes Türchen öffnet, zum Beispiel 08:00. Premium.
timezonestringName der IANA-Zeitzone, zum Beispiel Europe/London oder America/New_York. Standard: Europe/Berlin.
template_stylestringEiner der über 100 Türchen-Stile aus /v1/backgrounds.
background_imagestringSchlüssel eines Hintergrunddesigns aus dem Katalog.
custom_color#RRGGBBMarkenfarbe als Hex-Wert. Premium.
door_colorsobjectEigene Türchenfarben über dem gewählten Stil: door, accent und number als Hex-Werte. null behält die Farben des Stils. Premium.
custom_logo_urlstringHTTPS-URL deines Logos, das über den Türchen angezeigt wird. Premium.
animationstringHintergrund-Animation: none, snow, flurry (dichtes Schneegestöber) oder stars (funkelnde Sterne). Standard: snow. In jedem Tarif kostenlos.
snow_enabledbooleanÄltere Kurzform, true bei snow oder flurry. false setzt animation auf none.
is_publicbooleanfalse 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.
passwordstringBesucher müssen dieses Passwort eingeben, bevor sie den Kalender sehen. Wird nur als Hash gespeichert. Enterprise.
tracking_codestringDein eigenes Analytics- oder Pixel-Snippet, das auf der öffentlichen Seite geladen wird. Enterprise.
metadataobjectBis 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

json Antwort auf POST /v1/calendars
{
  "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
}
FeldTypBeschreibung
idstringStabile ID, verwende sie in allen weiteren Aufrufen.
slugstringTeil 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_urlstringDer Link, den du teilst. Öffnet den Kalender auf adventskalendererstellen.de.
door_countintegerAnzahl der Türchen, immer gleich der Zahl der Tage von start_date bis end_date.
doors_filledintegerWie viele Türchen bereits Inhalt haben.
password_protectedbooleantrue, wenn ein Passwort gesetzt ist. Das Passwort selbst wird nie zurückgegeben.
livemodebooleanfalse 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.

bash Kalender, die am 10. Dezember laufen
curl -G https://api.adventskalendererstellen.de/v1/calendars \
  -H "Authorization: Bearer $ACM_API_KEY" \
  -d active_on=2026-12-10 \
  -d limit=50
json Antwort mit Cursor
{
  "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.

bash Türchen eine Stunde früher öffnen und Schneefall einschalten
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.

bash Ein Gutschein hinter Türchen 7
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"
  }'
json Das Türchen-Objekt
{
  "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:

TypTarifFelder und Darstellung
textFreetitle 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.
embedFreeurl eines YouTube- oder Vimeo-Videos, angezeigt als eingebetteter Player.
linkPremiumurl plus optional title und text, angezeigt als Button zu deiner Seite. data.button legt den Button-Text fest.
imagePremiummedia_id eines hochgeladenen Bildes, optional title und text als Bildunterschrift.
videoPremiummedia_id eines hochgeladenen MP4-Videos.
couponPremiumcoupon_code plus title und text. Der Code wird mit Kopieren-Button angezeigt. Wir erzeugen oder prüfen Codes nie; sie stammen aus deinem Shopsystem.
quizPremiumtext 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.
productPremiumtitle 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.
eventPremiumdata.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.
giveawayPremiumdata.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.
downloadPremiummedia_id einer hochgeladenen Datei plus text. Angezeigt mit Dateiname und Download-Button; data.button legt dessen Text fest.
surveyPremiumtext 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.
musicPremiummedia_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.

json Request-Body mit vier Inhaltstypen
{
  "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.

bash Eine Datei hochladen oder von einer URL 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" }'
json Das Medien-Objekt
{
  "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.

bash Nur Hintergründe mit dem Tag corporate
curl -G https://api.adventskalendererstellen.de/v1/backgrounds \
  -H "Authorization: Bearer $ACM_API_KEY" \
  -d tag=corporate
json Antwort
{
  "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.

json Antwort
{
  "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.

bash CSV-Export für den Dezember
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.

json GET /v1/account
{
  "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
}
FunktionAb TarifBetrifft
Premiumlink, image, video, coupon, quiz, product, event, giveaway, download, survey, musicTürchen mit Links, Bildern, Videos, Gutscheinen, Quiz, Produkten, Events, Gewinnspielen, Downloads, Umfragen und Musik.
PremiumtextHTML-Formatierung im Türchentext.
Premiumstart_date, end_date, opening_timeEigener Zeitraum und eigene Öffnungszeit statt 1. bis 24. Dezember um Mitternacht.
Premiumcustom_color, door_colors, custom_logo_urlEigene Markenfarbe, eigene Türchenfarben und eigenes Logo.
Premium/statsAufrufe und Türchen-Öffnungen.
EnterprisepasswordPasswortgeschützte Kalender.
Enterprisetracking_codeEigener Tracking- oder Pixel-Code auf der öffentlichen Seite.
Enterprise/stats/exportStatistiken 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.

EreignisWann
calendar.createdEin Kalender wurde angelegt, per API oder im Editor.
calendar.updatedEinstellungen eines Kalenders oder der Inhalt eines Türchens haben sich geändert.
calendar.deletedEin Kalender wurde gelöscht.
door.unlockedEin Türchen hat sich gerade geöffnet. Praktisch, um in derselben Minute eine Push-Nachricht oder einen Newsletter zu verschicken.
stats.dailyEinmal täglich, kurz nach Mitternacht in der Zeitzone des Kalenders: die Zahlen des Vortags. Ab Premium.
json Ereignis door.unlocked
{
  "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.

http Signatur-Header
ACM-Signature: t=1796626802,v1=9e4b1c7d2a...
python Python: die Signatur prüfen
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.

bash Einen Kalender sicher anlegen
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.

json 403, wenn ein Feld einen höheren Tarif braucht
{
  "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"
  }
}
TypStatusBedeutung
invalid_request400Die Anfrage kann nicht gelesen werden, zum Beispiel wegen kaputtem JSON oder eines unbekannten Feldes.
authentication_error401Fehlender, falscher oder gesperrter Schlüssel.
plan_error403Das Feld oder der Endpunkt braucht einen höheren Tarif. required_plan nennt ihn.
not_found404Kalender, Türchen oder Medium existiert in deinem Konto nicht.
conflict409Derselbe Idempotency-Key wurde mit einem anderen Body verwendet.
validation_error422Ein 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_limit429Zu viele Anfragen. Warte RateLimit-Reset Sekunden.
api_error500Unser Fehler. Versuch es später erneut und schick uns die request_id, falls es bestehen bleibt.

Limits

WertLimit
120 / minAnfragen pro Minute und Schlüssel. Jede Antwort trägt den aktuellen Stand in Headern.
≤ 50Türchen pro Kalender, durch den Zeitraum bestimmt.
2 MBBild-Upload: JPG, PNG, GIF, WebP.
20 MBVideo-Upload: MP4.
50Türchen pro Aufruf von PUT /doors.
24 hIdempotenz-Fenster: wie lange wir uns einen Schlüssel merken.
http Rate-Limit-Header
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.

http Eine Version festlegen
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": false und 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.

Schlüssel anfragen