REST API for cron jobs
Manage cron jobs, heartbeats, server monitoring and status pages via HTTP and JSON – from scripts, CI pipelines or your own programs. The API can do the same as your account and as our MCP interface for AI assistants.
API key
Create the key in your account under AI access → Connect without a browser. It has the form <account number>:<token>, does not expire and can be renewed or revoked there at any time. Send it with every call as a bearer token:
Authorization: Bearer 12345:3f9a…
The API is included in the Unlimited plan, including the 14-day trial. Base URL:
https://www.cronjob.de/api/v1
Examples
List all cron jobs
curl https://www.cronjob.de/api/v1/jobs \ -H "Authorization: Bearer $CRONJOB_KEY"
Create a cron job, daily at 3:30
curl -X POST https://www.cronjob.de/api/v1/jobs \
-H "Authorization: Bearer $CRONJOB_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Backup",
"url": "https://example.com/backup.php",
"cron": "30 3 * * *"}'What failed in the last 24 hours?
curl "https://www.cronjob.de/api/v1/failures?hours=24" \ -H "Authorization: Bearer $CRONJOB_KEY"
Switch a cron job off
curl -X PUT https://www.cronjob.de/api/v1/jobs/123456/active \
-H "Authorization: Bearer $CRONJOB_KEY" \
-H "Content-Type: application/json" \
-d '{"active": false}'Responses are JSON. Times are in German time (Europe/Berlin). Prefer a tool? Load the OpenAPI description into Postman, Insomnia or a code generator.
All endpoints
All endpoints are also machine-readable in the OpenAPI description. With GET, parameters go in the URL (?limit=5), otherwise as JSON in the body. Deleting requires the name (confirm_name) or the status page slug (confirm_slug) as a safeguard.
Open in Swagger view Click an endpoint to see its description and parameters. Fields marked * are required.
Cron jobs and heartbeats
GET/jobsCronjobs auflisten
Listet alle Cronjobs des Nutzers mit dekodiertem Zeitplan sowie Methode, Body, Kopfzeilen und Basic-Auth-Benutzer. type unterscheidet Cronjobs, die Cronjob.de aufruft ("http"), von Heartbeats ("heartbeat": der Job läuft woanders und meldet sich unter ping_url, status nennt den Zustand). Cronjobs mit Endsignal tragen end_signal_minutes, end_signal_url und end_signal_state.
No parameters.
POST/jobsCronjob anlegen
Legt einen neuen Cronjob an: Cronjob.de ruft die URL nach Zeitplan auf. Zeitplan entweder als schedule-Objekt oder als cron-Ausdruck (eines von beiden ist Pflicht). Ohne Angabe wird die URL per GET aufgerufen. Mit end_signal_minutes meldet das aufgerufene Skript zusätzlich sein Ende (Antwort mit end_signal_url und snippets). Liefert den angelegten Job zurück. Für Jobs, die woanders laufen und nur überwacht werden sollen: POST /heartbeats. Um eine Website, einen Server oder eine API auf Erreichbarkeit zu überwachen: POST /monitors (Serverüberwachung), NICHT POST /jobs.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
name* string · JSON-Body |
Name des Jobs (max. 255 Zeichen). |
url* string · JSON-Body |
Aufzurufende URL, muss mit http:// oder https:// beginnen. |
schedule object · JSON-Body |
Zeitplan als Objekt mit Zahlen-Listen: minute (0-59), hour (0-23), day (1-31), month (1-12), weekday (0=Sonntag … 6=Samstag). Jede Liste muss mindestens einen Wert haben. Beispiel täglich 06:30: {"minute":[30],"hour":[6],"day":[1..31],"month":[1..12],"weekday":[0..6]}. Wichtig: Sind day UND weekday eingeschränkt, müssen BEIDE zutreffen (UND), nicht eines von beiden wie bei Unix-cron. Das ist ein Merkmal: day 8-14 plus weekday 3 ergibt genau den zweiten Mittwoch im Monat, day 25-31 plus weekday 1 den letzten Montag. Wer nur Wochentage meint, setzt day auf alle Werte 1-31; wer nur Monatstage meint, weekday auf 0-6. Alle Uhrzeiten gelten in deutscher Zeit (Europe/Berlin, MEZ/MESZ); Zeiten in UTC oder einer anderen Zeitzone vorher umrechnen. |
cron string · JSON-Body |
Alternative zu schedule: klassischer Cron-Ausdruck mit 5 Feldern "min std tag monat wochentag", z. B. "*/5 * * * *" (alle 5 Minuten) oder "30 6 * * 1-5" (Mo-Fr 06:30). Unterstützt *, Listen (1,15), Bereiche (1-5), Schritte (*/10, 1-30/5), Wochentag 0 oder 7 = Sonntag, sowie @hourly, @daily, @weekly, @monthly, @yearly. Hinweis: Sind Tag UND Wochentag eingeschränkt, müssen hier BEIDE zutreffen (UND), nicht eines von beiden wie bei Unix-cron. Damit geht "0 3 8-14 * 3" = jeder zweite Mittwoch im Monat, was klassisches cron nur mit einem Shell-Test kann. Ein aus einer bestehenden Crontab übernommener Ausdruck läuft hier deshalb seltener als dort. Uhrzeiten gelten in deutscher Zeit (Europe/Berlin, MEZ/MESZ). |
active boolean · JSON-Body |
Job aktiv? Standard: true. |
folder_id integer · JSON-Body |
Ordner-ID (0 = unsortiert). Alternativ folder_name. |
folder_name string · JSON-Body |
Ordnername; wird angelegt, falls nicht vorhanden. |
end_signal_minutes integer · JSON-Body |
Endsignal für einen Cronjob, den Cronjob.de aufruft: Das aufgerufene Skript meldet am Ende unter end_signal_url, dass es durchgelaufen ist. Kommt diese Meldung nicht innerhalb von end_signal_minutes nach dem Aufruf, warnt Cronjob.de – so fällt auch ein Skript auf, das mit Status 200 antwortet, aber vorzeitig abbricht. 1 bis 1440 schaltet ein (Frist in Minuten), 0 schaltet aus. Ab Unlimited. Für Jobs, die woanders laufen, ist POST /heartbeats richtig. |
method string · JSON-Body |
HTTP-Methode. Standard GET. Values: GET, POST, PUT, PATCH, DELETE, HEAD |
body string · JSON-Body |
Anfrage-Body. Nur bei POST, PUT, PATCH und DELETE. |
content_type string · JSON-Body |
Content-Type des Bodys, etwa application/json. Höchstens 120 Zeichen. |
headers array<object> · JSON-Body |
Eigene Kopfzeilen, höchstens 20. Host, Content-Length, Transfer-Encoding und Connection sind gesperrt. |
auth_user string · JSON-Body |
Benutzername für HTTP-Basic-Auth. |
auth_password string · JSON-Body |
Passwort für HTTP-Basic-Auth. Nur schreibbar; gelesen wird nur auth_password_set. |
expect_contains string · JSON-Body |
Antwortprüfung: Text, der in der Antwort stehen muss (z. B. "OK"), sonst gilt der Lauf als fehlgeschlagen. Höchstens 100 Zeichen, Groß-/Kleinschreibung spielt keine Rolle. Geprüft wird die ganze Antwort bis 1 MB, nur bei Status 2xx/3xx. Leerer String schaltet die Prüfung aus. Ab Unlimited. |
expect_not_contains string · JSON-Body |
Antwortprüfung: Text, der NICHT in der Antwort stehen darf (z. B. "FEHLER"). Höchstens 100 Zeichen, Groß-/Kleinschreibung spielt keine Rolle. Leerer String schaltet aus. Ab Unlimited. |
detect_errors boolean · JSON-Body |
Antwortprüfung: typische Fehlermeldungen als Fehler werten, ohne Rücksicht auf Groß-/Kleinschreibung (PHP "Fatal error", "Parse error", "Uncaught Exception/Error", Python "Traceback (most recent call last)", Java "Exception in thread", Node "UnhandledPromiseRejection", WordPress "kritischen Fehler auf" / "There has been a critical error on", Laravel "Whoops, looks like something went wrong"). |
notify_after_failures integer · JSON-Body |
Wann melden: 1 = beim ersten Fehlschlag (Standard), 2 bis 10 = erst nach so vielen Fehlschlägen in Folge, 0 = nie (Fehler werden nur protokolliert). Ab Plus. |
retries integer · JSON-Body |
Bei Aussetzern wiederholen: 0 = aus (Standard), 1 bis 3 weitere Versuche kurz nacheinander, nur bei Fehlern, bei denen der Aufruf das Skript nicht erreicht hat: Verbindung abgelehnt, TLS-Verbindung gescheitert, HTTP 408, 429, 502, 503, 521, 522, 523, 525. Nie nach 500, 504, 524, Zeitüberschreitung oder Weiterleitung. Die Warnung wartet die Wiederholungen ab. Ab Plus. |
expires_at string · JSON-Body |
Ablaufdatum: ab dann ist der Cronjob aus (Zeitplan und Protokoll bleiben). Format "YYYY-MM-DD HH:MM", deutsche Zeit, muss in der Zukunft liegen. Leerer String entfernt das Ablaufdatum. Einmaliger Lauf (z. B. nur am 31.12.2026 um 8 Uhr): Zeitplan mit Tag und Monat (0 8 31 12 *) und expires_at auf 0:00 Uhr am Folgetag. Enddatum (bis zum 15.11.): normaler Zeitplan und expires_at auf 0:00 Uhr am Tag danach. |
GET/jobs/{job_id}Cronjob ansehen
Details zu einem Cronjob inkl. dekodiertem Zeitplan, nächster Ausführung, den erweiterten Aufrufeinstellungen (method, body, content_type, headers, auth_user, auth_password_set), der Antwortprüfung (expect_contains, expect_not_contains, detect_errors; response_check_paused nennt die Teile, die gespeichert sind, im aktuellen Tarif aber ruhen und nach einem Upgrade wieder gelten) und (Tarif U) run_stats: Dauer, Bytes und Fehlerflag der letzten bis zu 200 Läufe. Endsignal: end_signal_minutes (0 = aus), end_signal_url und end_signal_state (ok, waiting = noch keine Meldung, running = Frist läuft, missed = Ende ausgeblieben, failed = /fail gemeldet, paused = Job aus oder im Tarif nicht enthalten). Heartbeats (type "heartbeat"): ping_url, rhythm_minutes und grace_minutes (rhythm_minutes null = genauer Zeitplan, grace_minutes gilt dann ab dem Termin), status (waiting_for_first_ping, ok, running, missed, failed, stuck, paused) und expected_by: bis dahin muss die nächste Meldung da sein.
| Parameter | Description |
|---|---|
job_id* integer · path |
PATCH/jobs/{job_id}Cronjob ändern
Ändert einen bestehenden Cronjob oder Heartbeat. Nur übergebene Felder werden geändert. headers ersetzt immer die komplette Liste; eine leere Liste entfernt alle Kopfzeilen. Liefert den Job danach zurück. Endsignal ("überwache, ob mein Cronjob bis zum Ende läuft"): end_signal_minutes bei einem Cronjob, den Cronjob.de aufruft – die Antwort enthält dann end_signal_url und snippets mit der Zeile für das Ende des Skripts. Bei Heartbeats (type "heartbeat") änderbar: name, active, rhythm_minutes und grace_minutes, oder ein genauer Zeitplan (cron oder schedule) mit grace_minutes.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
job_id* integer · path |
|
name string · JSON-Body |
|
url string · JSON-Body |
|
schedule object · JSON-Body |
Zeitplan als Objekt mit Zahlen-Listen: minute (0-59), hour (0-23), day (1-31), month (1-12), weekday (0=Sonntag … 6=Samstag). Jede Liste muss mindestens einen Wert haben. Beispiel täglich 06:30: {"minute":[30],"hour":[6],"day":[1..31],"month":[1..12],"weekday":[0..6]}. Wichtig: Sind day UND weekday eingeschränkt, müssen BEIDE zutreffen (UND), nicht eines von beiden wie bei Unix-cron. Das ist ein Merkmal: day 8-14 plus weekday 3 ergibt genau den zweiten Mittwoch im Monat, day 25-31 plus weekday 1 den letzten Montag. Wer nur Wochentage meint, setzt day auf alle Werte 1-31; wer nur Monatstage meint, weekday auf 0-6. Alle Uhrzeiten gelten in deutscher Zeit (Europe/Berlin, MEZ/MESZ); Zeiten in UTC oder einer anderen Zeitzone vorher umrechnen. |
cron string · JSON-Body |
Alternative zu schedule: klassischer Cron-Ausdruck mit 5 Feldern "min std tag monat wochentag", z. B. "*/5 * * * *" (alle 5 Minuten) oder "30 6 * * 1-5" (Mo-Fr 06:30). Unterstützt *, Listen (1,15), Bereiche (1-5), Schritte (*/10, 1-30/5), Wochentag 0 oder 7 = Sonntag, sowie @hourly, @daily, @weekly, @monthly, @yearly. Hinweis: Sind Tag UND Wochentag eingeschränkt, müssen hier BEIDE zutreffen (UND), nicht eines von beiden wie bei Unix-cron. Damit geht "0 3 8-14 * 3" = jeder zweite Mittwoch im Monat, was klassisches cron nur mit einem Shell-Test kann. Ein aus einer bestehenden Crontab übernommener Ausdruck läuft hier deshalb seltener als dort. Uhrzeiten gelten in deutscher Zeit (Europe/Berlin, MEZ/MESZ). |
active boolean · JSON-Body |
|
folder_id integer · JSON-Body |
|
folder_name string · JSON-Body |
|
end_signal_minutes integer · JSON-Body |
Endsignal für einen Cronjob, den Cronjob.de aufruft: Das aufgerufene Skript meldet am Ende unter end_signal_url, dass es durchgelaufen ist. Kommt diese Meldung nicht innerhalb von end_signal_minutes nach dem Aufruf, warnt Cronjob.de – so fällt auch ein Skript auf, das mit Status 200 antwortet, aber vorzeitig abbricht. 1 bis 1440 schaltet ein (Frist in Minuten), 0 schaltet aus. Ab Unlimited. Für Jobs, die woanders laufen, ist POST /heartbeats richtig. |
rhythm_minutes integer · JSON-Body |
Nur Heartbeats: Rhythmus in Minuten: so oft meldet sich der Job mindestens (1 bis 20160 = 14 Tage), z. B. 60 = stündlich, 1440 = täglich. Gewarnt wird, wenn nach der letzten Meldung rhythm_minutes plus grace_minutes vergehen, ohne dass eine neue kommt – egal, zu welcher Uhrzeit der Job läuft. Nicht zusammen mit schedule. |
grace_minutes integer · JSON-Body |
Nur Heartbeats: Spielraum in Minuten (1 bis 10080 = 7 Tage): so viel später als erwartet darf die Meldung kommen. Ohne Angabe beim Rhythmus 1 bis 15 Minuten je nach Rhythmus, beim Zeitplan 15 Minuten. Für Jobs mit schwankender Laufzeit großzügiger wählen. |
method string · JSON-Body |
HTTP-Methode. Standard GET. Values: GET, POST, PUT, PATCH, DELETE, HEAD |
body string · JSON-Body |
Anfrage-Body. Nur bei POST, PUT, PATCH und DELETE. |
content_type string · JSON-Body |
Content-Type des Bodys, etwa application/json. Höchstens 120 Zeichen. |
headers array<object> · JSON-Body |
Eigene Kopfzeilen, höchstens 20. Host, Content-Length, Transfer-Encoding und Connection sind gesperrt. |
auth_user string · JSON-Body |
Benutzername für HTTP-Basic-Auth. |
auth_password string · JSON-Body |
Passwort für HTTP-Basic-Auth. Nur schreibbar; gelesen wird nur auth_password_set. |
expect_contains string · JSON-Body |
Antwortprüfung: Text, der in der Antwort stehen muss (z. B. "OK"), sonst gilt der Lauf als fehlgeschlagen. Höchstens 100 Zeichen, Groß-/Kleinschreibung spielt keine Rolle. Geprüft wird die ganze Antwort bis 1 MB, nur bei Status 2xx/3xx. Leerer String schaltet die Prüfung aus. Ab Unlimited. |
expect_not_contains string · JSON-Body |
Antwortprüfung: Text, der NICHT in der Antwort stehen darf (z. B. "FEHLER"). Höchstens 100 Zeichen, Groß-/Kleinschreibung spielt keine Rolle. Leerer String schaltet aus. Ab Unlimited. |
detect_errors boolean · JSON-Body |
Antwortprüfung: typische Fehlermeldungen als Fehler werten, ohne Rücksicht auf Groß-/Kleinschreibung (PHP "Fatal error", "Parse error", "Uncaught Exception/Error", Python "Traceback (most recent call last)", Java "Exception in thread", Node "UnhandledPromiseRejection", WordPress "kritischen Fehler auf" / "There has been a critical error on", Laravel "Whoops, looks like something went wrong"). |
notify_after_failures integer · JSON-Body |
Wann melden: 1 = beim ersten Fehlschlag (Standard), 2 bis 10 = erst nach so vielen Fehlschlägen in Folge, 0 = nie (Fehler werden nur protokolliert). Ab Plus. |
retries integer · JSON-Body |
Bei Aussetzern wiederholen: 0 = aus (Standard), 1 bis 3 weitere Versuche kurz nacheinander, nur bei Fehlern, bei denen der Aufruf das Skript nicht erreicht hat: Verbindung abgelehnt, TLS-Verbindung gescheitert, HTTP 408, 429, 502, 503, 521, 522, 523, 525. Nie nach 500, 504, 524, Zeitüberschreitung oder Weiterleitung. Die Warnung wartet die Wiederholungen ab. Ab Plus. |
expires_at string · JSON-Body |
Ablaufdatum: ab dann ist der Cronjob aus (Zeitplan und Protokoll bleiben). Format "YYYY-MM-DD HH:MM", deutsche Zeit, muss in der Zukunft liegen. Leerer String entfernt das Ablaufdatum. Einmaliger Lauf (z. B. nur am 31.12.2026 um 8 Uhr): Zeitplan mit Tag und Monat (0 8 31 12 *) und expires_at auf 0:00 Uhr am Folgetag. Enddatum (bis zum 15.11.): normaler Zeitplan und expires_at auf 0:00 Uhr am Tag danach. |
DELETE/jobs/{job_id}Cronjob löschen
Löscht einen Cronjob oder Heartbeat samt Verlauf endgültig. Zur Sicherheit muss confirm_name exakt dem Namen entsprechen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
job_id* integer · path |
|
confirm_name* string · JSON-Body |
Exakter Name des zu löschenden Jobs. |
GET/jobs/{job_id}/historyAufrufprotokoll lesen
Die letzten 20 Ausführungen eines Jobs (Zeitpunkt, Fehlerstatus, Ausgabe).
| Parameter | Description |
|---|---|
job_id* integer · path |
GET/jobs/{job_id}/timelineVerlauf der letzten Wochen
Verlauf eines Jobs über die letzten 30 Tage (Tarif Plus) bzw. 90 Tage (Unlimited): je Tag Anzahl der Aufrufe, davon fehlgeschlagen, Laufzeit im Schnitt und höchstens, dazu die Fehlerzeiträume (gleiche Fehler hintereinander zusammengefasst, mit Einordnung und Rat). recorded_since nennt den ersten aufgezeichneten Tag. Für einzelne Läufe mit Ausgabe: GET /jobs/{job_id}/history.
| Parameter | Description |
|---|---|
job_id* integer · path |
PUT/jobs/{job_id}/activeCronjob an- oder abschalten
Aktiviert oder deaktiviert einen Cronjob oder Heartbeat. Einen pausierten Heartbeat einschalten geht, solange die Tarifgrenze für gleichzeitig aktive Heartbeats nicht erreicht ist.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
job_id* integer · path |
|
active* boolean · JSON-Body |
POST/jobs/{job_id}/moveCronjob verschieben
Verschiebt einen Cronjob in einen anderen Ordner (folder_id 0 = unsortiert, oder folder_name).
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
job_id* integer · path |
|
folder_id integer · JSON-Body |
|
folder_name string · JSON-Body |
POST/jobs/{job_id}/runCronjob jetzt ausführen
Ruft einen Cronjob sofort einmal auf, wie „Jetzt ausführen“ im Konto (auch wenn er ausgeschaltet ist; er bleibt dann aus). Das Ergebnis steht nach wenigen Sekunden in GET /jobs/{job_id}/history. Nicht für Heartbeats – die meldet der eigene Server.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
job_id* integer · path |
POST/heartbeatsHeartbeat anlegen
Legt einen Heartbeat an – für einen Job, den NICHT Cronjob.de aufruft, sondern der woanders läuft: Crontab auf dem eigenen Server, Backup-Skript, n8n, Make, Laravel, Supabase, Vercel, Netlify, GitHub Actions. Der Job ruft nach jedem Lauf seine ping_url auf; bleibt diese Meldung aus, warnt Cronjob.de. Läuft das Skript dagegen als Cronjob bei Cronjob.de (Cronjob.de ruft seine URL auf), ist das Endsignal richtig: PATCH /jobs/{job_id} mit end_signal_minutes. Zeit entweder als Rhythmus (rhythm_minutes, dazu grace_minutes) oder als genauer Zeitplan (schedule als Cron-Ausdruck, dazu grace_minutes) – für "läuft jede Nacht um 3 Uhr" passt schedule "0 3 * * *". Liefert den Heartbeat mit ping_url, status "waiting_for_first_ping" und snippets: fertige Zeilen für linux (Crontab, meldet den Exit-Code mit /$?), php, python und node. Gib dem Nutzer die passende Zeile zum Einbauen; überwacht wird ab der ersten Meldung. alerts nennt, wer gewarnt wird. Hatte das Konto noch keine Warnregel für Heartbeats, wird wie im Assistenten die Kontoadresse eingetragen (alerts.added) – sag dem Nutzer, wohin die Warnungen gehen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
name* string · JSON-Body |
Name des Heartbeats (max. 255 Zeichen), z. B. "Nächtliches Backup". |
rhythm_minutes integer · JSON-Body |
Rhythmus in Minuten: so oft meldet sich der Job mindestens (1 bis 20160 = 14 Tage), z. B. 60 = stündlich, 1440 = täglich. Gewarnt wird, wenn nach der letzten Meldung rhythm_minutes plus grace_minutes vergehen, ohne dass eine neue kommt – egal, zu welcher Uhrzeit der Job läuft. Nicht zusammen mit schedule. |
grace_minutes integer · JSON-Body |
Spielraum in Minuten (1 bis 10080 = 7 Tage): so viel später als erwartet darf die Meldung kommen. Ohne Angabe beim Rhythmus 1 bis 15 Minuten je nach Rhythmus, beim Zeitplan 15 Minuten. Für Jobs mit schwankender Laufzeit großzügiger wählen. |
schedule string · JSON-Body |
Genauer Zeitplan als Cron-Ausdruck mit 5 Feldern "min std tag monat wochentag" in deutscher Zeit, z. B. "0 3 * * *" (täglich 3:00) oder "30 6 * * 1-5", auch @daily, @weekly. Sind Tag UND Wochentag eingeschränkt, müssen beide zutreffen (UND). Gewarnt wird, wenn grace_minutes nach einem Termin keine Meldung da ist. Nicht zusammen mit rhythm_minutes; für "jede Minute" rhythm_minutes 1 nehmen. |
paused boolean · JSON-Body |
Pausiert anlegen? Standard false. Ein pausierter Heartbeat wird mit seiner nächsten Meldung wieder aktiv. |
GET/failuresFehlgeschlagene Aufrufe suchen
Listet fehlgeschlagene Aufrufe ueber ALLE Cronjobs des Kontos, neueste zuerst. Ein Aufruf gilt als fehlgeschlagen, wenn er eine Fehlermeldung hinterlassen hat; erfolgreiche Aufrufe haben keine. Das Aufrufprotokoll umfasst die letzten 20 Laeufe je Cronjob; wie weit das zurueckreicht, haengt davon ab, wie oft ein Job laeuft. coverage_complete_since nennt den Zeitpunkt, ab dem alle Cronjobs lueckenlos abgedeckt sind - diesen Zeitraum bitte in der Antwort nennen, damit klar ist, worauf sich das Ergebnis bezieht. Das ist eine Eigenschaft des Protokolls und kein Mangel: KEINE Vorschlaege machen, daran etwas zu aendern. notify_after_failures sagt, wann der Kunde benachrichtigt wird: 1 = sofort, 2 bis 10 = erst nach so vielen Fehlschlaegen in Folge, 0 = nie (der Kunde nimmt Fehler dieses Jobs bewusst hin).
| Parameter | Description |
|---|---|
hours integer · query |
Zeitraum rueckwaerts in Stunden. Standard 24, hoechstens 168 (sieben Tage). |
limit integer · query |
Hoechstzahl der Eintraege. Standard 50, hoechstens 200. |
GET/foldersOrdner auflisten
Listet alle Ordner des Nutzers.
No parameters.
POST/foldersOrdner anlegen
Legt einen neuen Ordner an (oder liefert den vorhandenen gleichen Namens).
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
name* string · JSON-Body |
Ordnername (max. 100 Zeichen). |
Server monitoring and SSL
GET/monitorsServerüberwachungen auflisten
Listet die Serverüberwachungen (Website-/Server-Monitoring unter „Überwachung“): Cronjob.de ruft jede Seite jede Minute ab und warnt bei einer Störung. Je Eintrag Zustand (state: ok, suspected = erster Fehlschlag, wird bestätigt; checking = Gegenprüfung von einem zweiten Server; down = bestätigte Störung; blocked = Seite sperrt unsere Abrufe), seit wann, Grund, letzte Antwortzeit, Verfügbarkeit der letzten 30 Tage und wer gewarnt wird.
No parameters.
POST/monitorsServerüberwachung anlegen
Legt eine Serverüberwachung an (Menü „Überwachung“) – richtig für „überwache meine Website/meinen Server/meine API“: Cronjob.de ruft die Adresse jede Minute ab, bestätigt einen Ausfall von einem zweiten Server und warnt dann. NICHT dafür POST /jobs verwenden: Ein Cronjob ruft eine Adresse auf, um dort etwas auszulösen. Ab Unlimited, höchstens 50 je Konto. Gewarnt werden die Standardkontakte (GET /contacts); andere Empfänger mit PUT /alert-recipients (scope "monitor").
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
name string · JSON-Body |
Name, höchstens 120 Zeichen. Ohne Angabe der Domainname. |
url* string · JSON-Body |
Adresse der Seite mit http:// oder https://, öffentlich erreichbar (keine internen Netze). |
active boolean · JSON-Body |
Aktiv? Standard true. Aktiv angelegt wird nur, wenn die Seite die erste Prüfung sofort besteht; sonst kommt der Befund als Fehler zurück (z. B. Firewall sperrt den User-Agent "Cronjob.de"). Pausiert anlegen umgeht die Prüfung. |
must_contain array<string> · JSON-Body |
Texte, die auf der Seite stehen müssen (höchstens 5, je bis 190 Zeichen). Fehlt einer, gilt die Seite als gestört. Leere Liste entfernt alle. |
must_not_contain array<string> · JSON-Body |
Texte, die NICHT auf der Seite stehen dürfen, z. B. "Wartungsmodus" (höchstens 5). Leere Liste entfernt alle. |
detect_error_page boolean · JSON-Body |
Typische Fehlerseiten erkennen (PHP Fatal error, WordPress "kritischer Fehler", Datenbankfehler …), auch wenn der Server Status 200 schickt. Standard true. |
detect_empty boolean · JSON-Body |
Leere oder fast leere Antwort als Störung werten. Standard true. |
quiet_from string · JSON-Body |
Ruhezeit Beginn "HH:MM" (deutsche Zeit), z. B. "02:00". In der Ruhezeit wird gemessen, aber nicht gewarnt; eine Störung, die danach noch besteht, wird gemeldet. Zusammen mit quiet_to; beide "" entfernt die Ruhezeit. |
quiet_to string · JSON-Body |
Ruhezeit Ende "HH:MM". |
GET/monitors/{monitor_id}Serverüberwachung ansehen
Details einer Serverüberwachung: Regeln, Zustand, Verfügbarkeit (24 h, 7 und 30 Tage), Antwortzeiten (Mittel, 95. Perzentil, Maximum der letzten 24 h), Störungen der letzten 90 Tage, versandte Warnungen der letzten 30 Tage und das SSL-Zertifikat der Adresse.
| Parameter | Description |
|---|---|
monitor_id* integer · path |
PATCH/monitors/{monitor_id}Serverüberwachung ändern
Ändert eine Serverüberwachung. Nur übergebene Felder werden geändert. Ändern sich Adresse oder Regeln einer aktiven Überwachung, muss die Seite die neue Prüfung sofort bestehen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
monitor_id* integer · path |
|
name string · JSON-Body |
Name, höchstens 120 Zeichen. Ohne Angabe der Domainname. |
url string · JSON-Body |
Adresse der Seite mit http:// oder https://, öffentlich erreichbar (keine internen Netze). |
active boolean · JSON-Body |
Aktiv? Standard true. Aktiv angelegt wird nur, wenn die Seite die erste Prüfung sofort besteht; sonst kommt der Befund als Fehler zurück (z. B. Firewall sperrt den User-Agent "Cronjob.de"). Pausiert anlegen umgeht die Prüfung. |
must_contain array<string> · JSON-Body |
Texte, die auf der Seite stehen müssen (höchstens 5, je bis 190 Zeichen). Fehlt einer, gilt die Seite als gestört. Leere Liste entfernt alle. |
must_not_contain array<string> · JSON-Body |
Texte, die NICHT auf der Seite stehen dürfen, z. B. "Wartungsmodus" (höchstens 5). Leere Liste entfernt alle. |
detect_error_page boolean · JSON-Body |
Typische Fehlerseiten erkennen (PHP Fatal error, WordPress "kritischer Fehler", Datenbankfehler …), auch wenn der Server Status 200 schickt. Standard true. |
detect_empty boolean · JSON-Body |
Leere oder fast leere Antwort als Störung werten. Standard true. |
quiet_from string · JSON-Body |
Ruhezeit Beginn "HH:MM" (deutsche Zeit), z. B. "02:00". In der Ruhezeit wird gemessen, aber nicht gewarnt; eine Störung, die danach noch besteht, wird gemeldet. Zusammen mit quiet_to; beide "" entfernt die Ruhezeit. |
quiet_to string · JSON-Body |
Ruhezeit Ende "HH:MM". |
DELETE/monitors/{monitor_id}Serverüberwachung löschen
Löscht eine Serverüberwachung. Zur Sicherheit muss confirm_name exakt dem Namen entsprechen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
monitor_id* integer · path |
|
confirm_name* string · JSON-Body |
PUT/monitors/{monitor_id}/activeServerüberwachung an- oder abschalten
Pausiert eine Serverüberwachung oder schaltet sie wieder ein (beim Einschalten ohne neue Prüfung).
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
monitor_id* integer · path |
|
active* boolean · JSON-Body |
GET/ssl-certificatesSSL-Zertifikate ansehen
SSL-Zertifikate aller https-Adressen des Kontos (aus Cronjobs und Serverüberwachungen): gültig bis, Resttage, Aussteller, Prüffehler. Cronjob.de prüft täglich und warnt vor dem Ablauf (Empfänger: PUT /alert-recipients mit scope "ssl").
No parameters.
Notifications
GET/contactsBenachrichtigungen ansehen
Die Kontakte für Warnungen (E-Mail, Slack/Discord/Teams, Telegram, eigener Webhook, SMS) mit ID, ob Standardkontakt und ob bestätigt (fremde E-Mail-Adressen bekommen erst nach ihrem Bestätigungslink Warnungen). Dazu rules: wer wofür gewarnt wird – mode "standard" (die Standardkontakte), "custom" (contact_ids) oder "off" – für alle Cronjobs, einzelne Ordner, alle Heartbeats, einzelne Heartbeats, alle Serverüberwachungen, einzelne Überwachungen und SSL.
No parameters.
POST/contactsKontakt für Warnungen anlegen
Legt einen Kontakt für Warnungen an. type "email" (ab Plus), "chat" (Webhook-Adresse aus Slack, Discord oder Microsoft Teams, ab Unlimited) oder "webhook" (eigener HTTPS-Endpunkt, ab Unlimited; das Signatur-Geheimnis steht im Konto unter Benachrichtigungen › Bearbeiten). Eine fremde E-Mail-Adresse (nicht die des Kontos oder eines Team-Zugangs) bekommt eine Mail mit Bestätigungslink und erst danach Warnungen – sag das dem Nutzer. Telegram lässt sich nur im Konto verbinden. Gibt es den Kontakt schon, kommt der vorhandene zurück.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
type* string · JSON-Body |
Values: email, chat, webhook |
target* string · JSON-Body |
E-Mail-Adresse bzw. Webhook-Adresse. |
name string · JSON-Body |
Anzeigename, optional (z. B. "Bereitschaft"). |
standard boolean · JSON-Body |
Standardkontakt? Standardkontakte bekommen alles, wofür keine eigene Auswahl gilt. Standard false. |
cc boolean · JSON-Body |
Nur E-Mail: in Kopie (CC) statt als Empfänger. |
PUT/alert-recipientsEmpfänger der Warnungen festlegen
Legt fest, wer wofür gewarnt wird. scope: "all_cronjobs", "folder" (id = Ordner-ID, 0 = unsortiert), "all_heartbeats", "heartbeat" (id = Job-ID des Heartbeats), "all_monitors", "monitor" (id = Überwachungs-ID), "ssl". mode "standard" = die Standardkontakte (bzw. die Einstellung der Gruppe darüber), "custom" = genau contact_ids, "off" = niemand. Nur bestätigte Kontakte werden tatsächlich benachrichtigt.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
scope* string · JSON-Body |
Values: all_cronjobs, folder, all_heartbeats, heartbeat, all_monitors, monitor, ssl |
id integer · JSON-Body |
Nur bei folder, heartbeat und monitor. |
mode* string · JSON-Body |
Values: standard, custom, off |
contact_ids array<integer> · JSON-Body |
Bei mode "custom": IDs aus GET /contacts. |
Status pages
GET/status-pagesStatusseiten auflisten
Die öffentlichen Statusseiten des Kontos (status.cronjob.de/<slug>/) mit Titel, Adresse, ob online, Sprache und den gezeigten Einträgen (Serverüberwachungen und Cronjobs mit Anzeigename). Nur für Inhaber des Kontos.
No parameters.
POST/status-pagesStatusseite anlegen
Legt eine öffentliche Statusseite an (status.cronjob.de/<slug>/): zeigt Besuchern die Verfügbarkeit ausgewählter Serverüberwachungen und Cronjobs der letzten 90 Tage. Ab Unlimited, höchstens 10 Seiten, nur für Inhaber. Ohne entries werden alle Serverüberwachungen der Domain aus link übernommen. Ein Logo lässt sich nur im Konto hochladen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
title* string · JSON-Body |
Titel, höchstens 80 Zeichen. |
slug string · JSON-Body |
Adresse status.cronjob.de/<slug>/: 3 bis 40 Zeichen a-z, 0-9 und Bindestrich. Ohne Angabe aus dem Titel. |
link string · JSON-Body |
Link zur eigenen Website (optional, "" entfernt). |
language string · JSON-Body |
Values: de, en |
show_incidents boolean · JSON-Body |
Vorfälle der letzten 30 Tage zeigen. Standard true. |
published boolean · JSON-Body |
Öffentlich schalten (true) oder offline (false). Öffentlich geht nur mit bezahltem Unlimited oder in der Testphase mit Unlimited-Abo; sonst wird der Wunsch gemerkt und die Seite geht nach der Zahlung von selbst online. |
entries array<object> · JSON-Body |
Einträge der Seite in dieser Reihenfolge (höchstens 30). Ersetzt die ganze Liste. |
PATCH/status-pages/{status_page_id}Statusseite ändern
Ändert eine Statusseite. Nur übergebene Felder werden geändert; entries ersetzt die ganze Liste.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
status_page_id* integer · path |
|
title string · JSON-Body |
Titel, höchstens 80 Zeichen. |
slug string · JSON-Body |
Adresse status.cronjob.de/<slug>/: 3 bis 40 Zeichen a-z, 0-9 und Bindestrich. Ohne Angabe aus dem Titel. |
link string · JSON-Body |
Link zur eigenen Website (optional, "" entfernt). |
language string · JSON-Body |
Values: de, en |
show_incidents boolean · JSON-Body |
Vorfälle der letzten 30 Tage zeigen. Standard true. |
published boolean · JSON-Body |
Öffentlich schalten (true) oder offline (false). Öffentlich geht nur mit bezahltem Unlimited oder in der Testphase mit Unlimited-Abo; sonst wird der Wunsch gemerkt und die Seite geht nach der Zahlung von selbst online. |
entries array<object> · JSON-Body |
Einträge der Seite in dieser Reihenfolge (höchstens 30). Ersetzt die ganze Liste. |
DELETE/status-pages/{status_page_id}Statusseite löschen
Löscht eine Statusseite; sie ist danach nicht mehr erreichbar. confirm_slug muss exakt dem slug entsprechen.
Changes data: Unlimited or trial only.
| Parameter | Description |
|---|---|
status_page_id* integer · path |
|
confirm_slug* string · JSON-Body |
Limits and errors
- At most 120 calls per minute, of which at most 60 changing calls per hour. Beyond that the API answers with 429.
- Errors come as
{"error": "…"}with a matching status: 400 invalid input, 401 missing or wrong key, 403 plan does not allow changes, 404 not found, 405 wrong method. - We log every change made via the API with time and IP address.
- Team invitations and payments only work in the account.
Questions
- Is there a REST API for Cronjob.de?
- Yes. At https://www.cronjob.de/api/v1 you reach cron jobs, heartbeats, server monitoring, SSL certificates, notifications and status pages via HTTP and JSON. You authenticate with an API key as a bearer token. An OpenAPI description is at https://www.cronjob.de/api/v1/openapi.json.
- Which plan do I need?
- Unlimited, including the 14-day trial. Reading and changing are both included.
- REST API or MCP – which should I use?
- Both can do the same. If you work with Claude, ChatGPT or Cursor, use MCP: the assistant knows every command on its own, you need no key, no documentation and no code, and simply say what should happen. The REST API pays off when a fixed script or CI pipeline should do the same thing again and again.