Für Entwickler

API, Webhooks und Widget, kostenlos

Frag freie Zeiten ab, erstelle und storniere Buchungen aus deiner Software, erhalte zu jeder Änderung eine signierte Benachrichtigung und bau deinen Kalender in deine Website ein. Wofür andere Geld verlangen, ist hier kostenlos.

Kostenlos starten · Zu API und Webhooks

Authentifizierung

Erstelle einen Schlüssel unter Einstellungen → API und Webhooks. Wähle „Nur lesen“ (Terminarten, Verfügbarkeit und Buchungen) oder „Lesen und buchen“ (zusätzlich buchen, verschieben, absagen und Einmal-Links erstellen). Der Schlüssel wird nur ein einziges Mal angezeigt.

Schick ihn im Header X-API-Key mit. Alle Routen liegen unter https://calendavibe.com/api/v1. Ein Schlüssel sieht und ändert nur die Daten seines eigenen Kontos.

Deine Terminarten

curl https://calendavibe.com/api/v1/event-types \
  -H "X-API-Key: cvwh_…"

Routen

RouteWas sie tutSchlüssel
GET /meDein Konto und die Art des SchlüsselsNur lesen
GET /event-typesDeine Terminarten, mit ihrem öffentlichen LinkNur lesen
GET /event-types/{id}/slots?from&to&timezoneDie freien Zeiten, wie deine Seite sie anbietetNur lesen
GET /bookings?status=upcoming|past|cancelled|allDeine Buchungen (mit Cursor paginiert)Nur lesen
GET /bookings/{id}Eine BuchungNur lesen
POST /bookingsEin Zeitfenster buchenLesen und buchen
POST /bookings/{id}/rescheduleDie Uhrzeit ändernLesen und buchen
POST /bookings/{id}/cancelAbsagenLesen und buchen
POST /single-use-linksEin Link, der nur eine einzige Buchung zulässtLesen und buchen

Buchen (mit Idempotency-Key, damit eine wiederholte Anfrage nie doppelt bucht)

curl -X POST https://calendavibe.com/api/v1/bookings \
  -H "X-API-Key: cvwh_…" -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1234" \
  -d '{
    "eventTypeId": "ckx…",
    "startTime": "2026-11-03T09:00:00.000Z",
    "guest": { "name": "Ana García", "email": "ana@example.com", "timezone": "Europe/Madrid", "locale": "es" },
    "consent": true
  }'

Regeln für Buchungen

Eine Buchung über die API folgt denselben Regeln wie deine Seite: nur wirklich freie Zeiten (auch in deinem Kalender), der Gast bekommt seine E-Mails und erscheint in deinen Kontakten.

Schick consent: true mit, wenn der Gast in deinem Formular der Verarbeitung seiner Daten zugestimmt hat.

Fragen zwei Systeme gleichzeitig dasselbe Zeitfenster an, bekommt das zweite 409 SLOT_UNAVAILABLE und wählt ein anderes. Mit demselben Idempotency-Key liefert eine wiederholte Anfrage 24 Stunden lang dieselbe Buchung zurück.

Ein bezahlter Termin lässt sich nicht über die API buchen: Die Antwort ist 402 PAYMENT_REQUIRED mit bookingUrl, dem Link, über den der Gast bucht und bezahlt.

Limits

Kostenloser Plan: 60 Aufrufe pro Minute und 10.000 pro Tag und Konto, dazu bis zu 10 Webhooks. Mit Closevibe mehr.

Über dem Limit lautet die Antwort 429 mit dem Header Retry-After.

Fehler haben immer die Form { "error": { "code", "message" } }.

Webhooks

Füge unter Einstellungen → API und Webhooks eine Ziel-URL hinzu (https und öffentlich erreichbar) und wähle die Benachrichtigungen: Neue Buchung (meeting.booked), Absage (meeting.cancelled), Neue Uhrzeit (meeting.rescheduled) und Zahlung erhalten (meeting.paid).

Jede Benachrichtigung ist ein POST mit den Daten der Buchung, nie mit dem privaten Link des Gastes. Fällt dein Server aus, versuchen wir es nach 1 Min., 5 Min., 30 Min., 2 Std., 6 Std. und 12 Std. erneut. Nach 20 Fehlschlägen in Folge wird die URL deaktiviert und wir schicken dir eine E-Mail.

Prüfe die Signatur: Der Header X-Webhook-Signature ist sha256= und der HMAC-SHA256 des Bodys genau so, wie er ankommt, mit dem Signatur-Secret dieser URL.

Eine Benachrichtigung

{
  "id": "evt_…",
  "event": "meeting.booked",
  "createdAt": "2026-11-01T10:15:00.000Z",
  "data": {
    "booking": {
      "id": "ckx…", "status": "CONFIRMED",
      "eventType": { "id": "ckx…", "slug": "primera-consulta", "name": "Primera consulta", "duration": 30 },
      "startTime": "2026-11-03T09:00:00.000Z", "endTime": "2026-11-03T09:30:00.000Z", "timezone": "Europe/Madrid",
      "guest": { "name": "Ana García", "email": "ana@example.com", "phone": null, "timezone": "Europe/Madrid", "locale": "es", "notes": null },
      "answers": [{ "question": "Motivo", "answer": "Revisión" }],
      "meetingUrl": "https://meet.google.com/…", "payment": null
    }
  }
}

Die Signatur prüfen (Node.js)

const crypto = require('crypto');

// rawBody: the request body exactly as received (a Buffer or string, before JSON.parse).
function isFromCalendaVibe(rawBody, header, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return header && expected.length === header.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}

Widget für deine Website

Direkt in der Seite oder als Pop-up (Button oder Bubble), in deiner Farbe und deiner Sprache. Kennst du den Besucher schon, übergib Name und E-Mail, dann sind sie vorausgefüllt. Auf dem Handy nimmt das Pop-up den ganzen Bildschirm ein und schließt sich mit dem X oder mit Esc.

Bucht jemand im Widget, empfängt deine Seite das Event calendavibe:booked mit der Uhrzeit und der Terminart.

In der Seite

<div class="calendavibe-inline" data-url="https://calendavibe.com/ana/primera-consulta"
     data-color="#6d28d9" data-lang="es"></div>
<script src="https://calendavibe.com/embed.js" async></script>

Pop-up über einen Button oder eine Bubble

<a href="https://calendavibe.com/ana/primera-consulta" data-calendavibe-popup
   data-color="#6d28d9" data-name="Ana García" data-email="ana@example.com">Reservar</a>

<script src="https://calendavibe.com/embed.js" async
        data-calendavibe-bubble="https://calendavibe.com/ana" data-text="Reservar" data-color="#6d28d9"></script>

Häufige Fragen

Kostet das etwas?

Nein. Die API, die Webhooks und das Widget sind im kostenlosen Plan enthalten, mit den Limits oben.

Funktioniert das mit Zapier oder Make?

Ja: Nutze ihr HTTP-Modul mit deinem Schlüssel für die API und einen CalendaVibe-Webhook als Auslöser.

Kann ich einen Termin über die API abrechnen?

Nein: Der Gast bezahlt auf deiner Seite. Die API gibt dir den Link, den du ihm schickst.