Healthchecks-API: Checks per API v2 anlegen und abfragen

Mit der Healthchecks-API (Teil der API v2 von IPv64.net) legst du Checks per Skript an, änderst, pausierst und löschst sie, fragst Messwerte, Ereignisse und Störungen ab und verwaltest Benachrichtigungskanäle, Wartungsfenster und Nodes. Die Feldnamen sind dieselben wie in der API von Node64, sodass Skripte gegen beide gleich aussehen.

Überblick: Basis-URL, Format und Fehler

Alle Pfade dieser Seite beginnen mit /hc2 und hängen an die Basis-URL der API v2:

https://ipv64.net/api/v2
  • Methoden: GET, POST, PATCH und DELETE. Wer nur GET und POST senden kann, schickt POST mit dem Header X-HTTP-Method-Override: PATCH (bzw. DELETE).
  • Anfragen als JSON (Content-Type: application/json), höchstens 1 MB. PATCH ändert nur die mitgeschickten Felder.
  • Antworten als JSON im Umschlag {"data": …, "meta": {…}}; meta gibt es nur bei Listen mit Seitenangaben. DELETE antwortet mit 204 ohne Inhalt.
  • Zeiten im Format ISO 8601 mit Zeitzone, in Antworten immer UTC (z. B. 2026-10-26T08:15:00.000Z).
  • Die vollständige Beschreibung als OpenAPI 3.1 (Bereich „Healthchecks 2.0“) gibt es unter ipv64.net/api_v2_docs.

Fehler

Fehler kommen nach RFC 9457 als application/problem+json mit einem festen Fehlercode in code:

{
  "type": "https://ipv64.net/api/v2/errors#limit_reached",
  "title": "Forbidden",
  "status": 403,
  "detail": "Online-Limit erreicht: 10 von 10 Messstellen belegt, benötigt werden 2 weitere. …",
  "code": "limit_reached",
  "errors": ["Online-Limit erreicht: …"]
}
HTTPCodes (Auswahl)Bedeutung
401unauthenticated, invalid_tokenAPI-Key fehlt, ist ungültig oder abgelaufen, oder das Konto ist nicht aktiv
403limit_reachedMessstellen-Limit der Kontoklasse erreicht
404not_foundCheck, Kanal, Wartungsfenster, Testlauf oder Node nicht gefunden
409move_requires_test, unchanged, not_verified, disabled, node_channelAktion im aktuellen Zustand nicht möglich (Details in detail)
422invalid_healthcheck, private_target, invalid_type, move_rejected, invalid_channel, invalid_code …Eingabe ungültig; bei Checks und Kanälen stehen alle Meldungen in errors
429rate_limited, sms_limitzu viele Anfragen bzw. Tageslimit für SMS erreicht
502delivery_failedNachricht konnte nicht zugestellt werden

Authentifizierung und Limits

Die API nutzt deine API-Keys aus Account > API (siehe Konto: API-Keys). Den Key schickst du nur im Header – nie in der URL:

curl "https://ipv64.net/api/v2/hc2/account" -H "Authorization: Bearer DEIN_API_KEY"
curl "https://ipv64.net/api/v2/hc2/account" -H "X-API-Key: DEIN_API_KEY"
Der API-Key hat volle Rechte

Ein API-Key darf alles im Konto, nicht nur Healthchecks. Für einen Cronjob, der nur einen Push melden soll, brauchst du keinen API-Key – dafür gibt es die Push-URL mit dem Token des Checks.

Limits

  • Allgemein: je Konto bis 300 Anfragen auf einmal, danach 10 pro Sekunde; je IP-Adresse 600 auf einmal, danach 20 pro Sekunde. Fehlgeschlagene Anmeldungen: 20, danach 12 pro Minute je IP. Die Header RateLimit-Limit und RateLimit-Remaining zeigen den Stand; bei 429 nennt Retry-After die Wartezeit in Sekunden.
  • Testnachrichten: eine pro 30 Sekunden je Kanal.
  • Bestätigungscodes: 5 Codes pro Stunde, 10 Eingabeversuche pro Stunde – gemeinsam mit dem Portal.
  • Versand über einen IPv64-Kanal (/send): 30 auf einmal, danach 30 pro Stunde, höchstens 200 pro Tag; SMS zusätzlich nach dem Tageslimit deiner Kontoklasse.
  • Die Grenzen der Kontoklasse für Healthchecks (Online-Messstellen, Online-Messungen pro Tag, Standorte je Check) gelten auch per API, siehe Limits.

Konto und Einstellungen

GET /hc2/account

Kontoklasse, Limits und Verbrauch:

{"data": {
  "plan": "Supporter",
  "online_measuring_points": {"used": 6, "limit": 10},
  "locations_per_check": 2,
  "checks_per_day": {"used": 2817, "limit": 8192},
  "sms_per_day": 50,
  "locations": [{"code": "fsn", "name": "Falkenstein"}, {"code": "nbg", "name": "Nürnberg"}],
  "nodes": {"total": 1, "online": 1},
  "checks": 12
}}

limit: null heißt unbegrenzt; bei sms_per_day steht dafür 0.

GET und PATCH /hc2/settings

Ruhezeiten und Sammelmeldung des Kontos (siehe Benachrichtigungen). Erlaubte Schlüssel:

SchlüsselWert
notify.quiet_enabledtrue/false (gespeichert als 1/0)
notify.quiet_from, notify.quiet_toUhrzeit HH:MM
notify.quiet_daysWochentage 1 (Mo) bis 7 (So), als Liste oder "1,2,3"
notify.quiet_tzZeitzone, z. B. Europe/Berlin
notify.rate_per_hour0 bis 1000 (0 = unbegrenzt)
notify.batch_threshold0 bis 100
notify.batch_window_seconds0 bis 600
curl -X PATCH "https://ipv64.net/api/v2/hc2/settings" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"notify.quiet_enabled": true, "notify.quiet_from": "23:00", "notify.quiet_to": "06:30"}'

Checks verwalten

Methode und PfadWirkung
GET /hc2/checksalle Checks; Filter: type, state, execution, node_id, tag, group, q (Suche in Name und Ziel)
POST /hc2/checksCheck anlegen → 201 mit dem Check
GET /hc2/checks/{token}ein Check mit Messstellen (sources) und Verfügbarkeit (availability_percent für 24h, 30d, 1y)
PATCH /hc2/checks/{token}Felder ändern (siehe unten zum Ausführungsort)
DELETE /hc2/checks/{token}Check mit allen Messdaten löschen → 204; war er Monitor im DNS Failover, nennt der Header Warning: 299 die Policies
POST /hc2/checks/{token}/pause, /resumepausieren bzw. fortsetzen; Antwort: der Check
POST /hc2/checks/{token}/runsofort prüfen: lokale und hybride Checks → 202 mit command_id je Node; Online-Checks → 200 mit queued: false (sie laufen im Intervall); Push-Checks → 422 not_applicable

Felder eines Checks

FeldStandard beim AnlegenHinweis
typehttphttp, keyword, json, dns, icmp, tcp, port, cert, push, docker, whois
name–Pflicht, bis 200 Zeichen
target–URL, Host, IP, Domain oder Container – je nach Typ; bei push leer
params{}Einstellungen des Typs (siehe Parameter je Typ)
interval_seconds60lokal ab 5, online/hybrid ab 20, bis 86400; WHOIS ab 3600
retry_interval_seconds20ab 5, höchstens das Intervall
retries, stabilize1, 30–10 bzw. 1–20
connect_timeout_seconds, timeout_seconds5, 100,5–60 bzw. 1–120 (online höchstens 30 bzw. 60)
ip_modeautoauto, ipv4, ipv6, both
executiononlineonline, local, both
nodes bzw. node_id–messende Nodes (Liste von IDs) bzw. eine Node; Pflicht bei local/both
locationsalle Standortez. B. ["nbg","fsn"]; gekürzt auf die Standorte deiner Kontoklasse
policyallall, any, majority
notify_down, notify_up, notify_degradedtrue, true, falsewofür benachrichtigt wird
channels[]Kanal-IDs; leer = Standardkanäle
repeat_minutes0Erinnerung, 0–10080
critical, invert, pausedfalse
group, tags, descriptionleerGruppe bis 100 Zeichen; Tags als Liste oder Text
parentleerToken des übergeordneten Checks

Die Antwort enthält zusätzlich token, node_id, node_name, nodes (mit Namen), revision, created_at, updated_at und state mit state, since, last_check_at, last_status, last_latency_ms, last_reason, last_message, down_since und last_push_at. Push-Checks haben dazu ein Objekt push (siehe Push-URL). Der Zustand ist einer von up, down, degraded, flapping, stabilizing, dependent, pending und paused; „nicht überwacht“ und „Kontingent aufgebraucht“ erkennst du an pending mit last_reason unchecked bzw. quota_exhausted.

Parameter je Typ (params)

TypSchlüssel in params
http, keyword, jsonmethod, accept_status (z. B. "200-299,301"), follow_redirects, max_redirects, basic_user, basic_password, headers (Objekt), body, insecure_tls, cert_min_days (per API ohne Standard, also aus); nur keyword: keyword, keyword_absent; nur json: json_rules, json_any
dnsrecord_type, resolver (system, server, authoritative), server, expect (any, contains, equals, regex, nxdomain, public_ip), values (Liste), min_ttl, dnssec
icmpcount, max_loss_percent, max_latency_ms
tcpport, send, expect, tls
portport, expect (open oder closed)
certport (Standard 443), min_days, server_name, skip_chain, skip_hostname
whoissource (auto, rdap, whois), min_days, contains (Liste)
pushperiod_seconds, grace_seconds

json_rules ist eine Liste aus Objekten {"path": "status", "op": "eq", "value": "ok"} mit den Vergleichen eq, ne, lt, le, gt, ge, contains, not_contains, regex, exists, not_exists – oder die Textform wie im Formular. Grenzen und Bedeutung aller Werte stehen unter Check-Typen.

Beispiele

HTTPS-Check von beiden Standorten anlegen:

curl -X POST "https://ipv64.net/api/v2/hc2/checks" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "http", "name": "Webseite", "target": "https://example.com/",
       "interval_seconds": 60, "locations": ["nbg", "fsn"],
       "params": {"accept_status": "200-299", "cert_min_days": 14}}'

Push-Check für ein nächtliches Backup:

curl -X POST "https://ipv64.net/api/v2/hc2/checks" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "push", "name": "Backup NAS", "params": {"period_seconds": 86400, "grace_seconds": 3600}}'

Gestörte Checks auflisten, einen Check pausieren:

curl "https://ipv64.net/api/v2/hc2/checks?state=down" -H "Authorization: Bearer DEIN_API_KEY"
curl -X POST "https://ipv64.net/api/v2/hc2/checks/DEIN_CHECK_TOKEN/pause" -H "Authorization: Bearer DEIN_API_KEY"

Fehler beim Anlegen: 422 invalid_healthcheck (ungültige Eingabe), 422 private_target (privates Ziel online), 403 limit_reached (Messstellen-Limit).

Ausführungsort ändern (Umhängen)

Ändert ein PATCH execution, die Nodes oder die Standorte, speichert die API alle anderen Felder, lässt den Ausführungsort aber unverändert und antwortet mit 409 move_requires_test. Den Wechsel machst du mit einem Testlauf – oder du schickst "force_move": true mit, dann wird ohne Test umgestellt.

Methode und PfadWirkung
POST /hc2/checks/{token}/moveTestlauf starten; Body: execution (Pflicht), nodes oder node_id, locations → 202 mit dem Testlauf
GET /hc2/testruns/{id}Stand des Testlaufs
curl -X POST "https://ipv64.net/api/v2/hc2/checks/DEIN_CHECK_TOKEN/move" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" -d '{"execution": "both", "nodes": ["DEINE_NODE_ID"], "locations": ["nbg", "fsn"]}'
{"data": {"id": 4711, "status": "ok", "target": "both", "applied": true,
  "results": [{"source": "ipv64 Nürnberg", "ok": true, "message": "ipv4 up 23.4 ms"}, …]}}

Frage den Testlauf alle 2 Sekunden ab, höchstens 60 Sekunden lang. status ist pending, ok (Wechsel übernommen, applied: true), failed (bleibt wie bisher) oder expired (keine Antwort in 60 Sekunden, dann mit error). Fehler beim Start: 409 unchanged (läuft schon so), 422 move_rejected (z. B. Node offline, Fernverwaltung aus, privates Ziel, Limit, Docker-Check).

Messwerte, Ereignisse, Störungen und Statistik

Methode und PfadParameterInhalt
GET /hc2/checks/{token}/measurementslimit (1–5000, Standard 200), since, until, sourceEinzelmessungen, neueste zuerst: time, source, source_label, status (up/down), latency_ms, reason, message, family, details
GET /hc2/checks/{token}/events, GET /hc2/eventslimit (1–1000, Standard 100), before, after, sinceEreignisse eines Checks bzw. aller Checks: id, token, source, kind, time, from_state, to_state, reason, message, duration_seconds, flaps, silent, incident_id
GET /hc2/checks/{token}/incidentslimit (1–500, Standard 50)Störungen eines Checks
GET /hc2/incidentslimit (1–1000, Standard 100), open=true, sinceStörungen aller Checks: id, token, name, status (open/closed), started_at, ended_at, duration_seconds, reason, message, sources
GET /hc2/checks/{token}/statsrange: 24h (Standard), 7d, 30d, 1yVerfügbarkeit und Latenz (min, Mittel, max) gesamt und je Messstelle, dazu eine Zeitreihe je Stunde (24h, 7d) bzw. je Tag (30d, 1y)
  • Messstellen (source): loc:nbg bzw. loc:fsn für die IPv64-Standorte, node:NODE_ID für eine Node, push für Pushes.
  • Einzelmessungen hebt IPv64.net nur kurz auf; für längere Zeiträume nimm /stats.
  • Seiten bei Ereignissen: meta enthält limit, has_more und next_before (bzw. next_after, wenn du mit after vorwärts blätterst). Den Wert gibst du bei der nächsten Anfrage als before bzw. after mit.
  • silent: true heißt: Zu diesem Ereignis wurde keine Nachricht verschickt.
curl "https://ipv64.net/api/v2/hc2/checks/DEIN_CHECK_TOKEN/stats?range=30d" -H "Authorization: Bearer DEIN_API_KEY"
curl "https://ipv64.net/api/v2/hc2/incidents?open=true" -H "Authorization: Bearer DEIN_API_KEY"

Push-URL für Cronjobs

Pushes laufen nicht über die API v2 und brauchen keinen API-Key. Jeder Push-Check hat in der Antwort ein Objekt push:

FeldInhalt
urlhttps://ipv64.net/health.php?token=TOKEN – die Push-URL
hub_urleine gleichwertige Adresse direkt am Healthchecks-Server
node_pathPfad an der Node (/api/push/TOKEN) bei lokalen und hybriden Push-Checks, sonst null
# OK melden
curl -fsS -m 10 "https://ipv64.net/health.php?token=DEIN_PUSH_TOKEN"
# Störung melden
curl -fsS -m 10 "https://ipv64.net/health.php?token=DEIN_PUSH_TOKEN&status=down&msg=backup+fehlgeschlagen"

Parameter: status=down oder fail für eine Störung, msg bzw. message für eine Meldung (bis 500 Zeichen). Die Antwort ist OK. Höchstens 60 Pushes pro Minute je Token; Pushes zählen gegen das Tageskontingent. Mehr unter Push-Checks.

Benachrichtigungskanäle

Methode und PfadWirkung
GET /hc2/channel-typesalle Kanaltypen mit ihren Feldern (key, label, kind, required, secret, options, default) und needs_verification
GET /hc2/channels, GET /hc2/channels/{id}Kanäle; Geheimnisse fehlen in config, secrets_set nennt die gesetzten
POST /hc2/channelsKanal anlegen: type, name, config, enabled (Standard true), default (Standard false), lang (de/en), notify_down, notify_up → 201, bei E-Mail/SMS mit verification_required: true
PATCH /hc2/channels/{id}ändern; weggelassene Geheimnisse bleiben. Bei Kanälen einer Node nur Name und Schalter (config → 409 node_channel)
DELETE /hc2/channels/{id}löschen und aus allen Checks entfernen → 204
POST /hc2/channels/{id}/testTestnachricht → {"sent": true, "queued_at_node": false}; nur bestätigte Kanäle
POST /hc2/channels/{id}/verify/sendBestätigungscode an E-Mail bzw. Handynummer senden (gilt 15 Minuten)
POST /hc2/channels/{id}/verifymit {"code": "123456"} bestätigen; falsch oder abgelaufen: 422 invalid_code
POST /hc2/channels/{id}/sendeigene Nachricht über einen bestätigten, aktiven Kanal ipv64_mail, ipv64_sms oder app: subject, text (Pflicht), optional kind, event_id, source

Kanaltypen und ihre config-Schlüssel: ipv64_mail (email), ipv64_sms (number), app (device_key, critical), telegram (bot_token, chat_id, silent), discord (webhook_url, username), slack und teams (webhook_url), matrix (server, token, room), ntfy (server, topic, token, user, password, priority_down, priority_up), gotify (server, app_token, priority), pushover (user_key, app_token, device, priority_down, priority_up), webhook (url, method, headers, body, insecure_tls), smtp (host, port, security, user, password, from, to). Bedeutung und Standardwerte: Kanaltypen. URLs und der SMTP-Host müssen öffentlich sein, SMTP nur über Port 25, 465, 587 oder 2525; sonst 422 invalid_channel mit den Meldungen in errors. Interne Ziele gehen nur über einen Kanal der Node.

curl -X POST "https://ipv64.net/api/v2/hc2/channels" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "ntfy", "name": "ntfy Handy", "default": true, "config": {"server": "https://ntfy.sh", "topic": "mein-geheimes-topic"}}'

Bei /send wird eine event_id, die in den letzten 24 Stunden schon erfolgreich verschickt wurde, nicht erneut gesendet (Antwort duplicate: true). Die Antwort nennt bei SMS in sms_left, wie viele SMS heute noch gehen (null = unbegrenzt).

Wartungsfenster

Methode und PfadWirkung
GET /hc2/maintenance, GET /hc2/maintenance/{id}Wartungsfenster
POST /hc2/maintenanceanlegen → 201
PATCH /hc2/maintenance/{id}ändern
DELETE /hc2/maintenance/{id}löschen → 204

Felder: name, start_at und end_at (ISO 8601, Pflicht, Ende nach Beginn), repeat (none, daily, weekly, monthly), repeat_until, tokens (Liste von Check-Tokens, leer = alle Checks) und active (Standard true).

curl -X POST "https://ipv64.net/api/v2/hc2/maintenance" -H "Authorization: Bearer DEIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Proxmox-Updates", "start_at": "2026-11-01T03:00:00+01:00", "end_at": "2026-11-01T04:00:00+01:00", "repeat": "weekly"}'

Nodes

Methode und PfadWirkung
GET /hc2/nodesNodes mit Healthchecks-Sync: node_id, name, location, version, timezone, modules, remote_mgmt, online, last_seen, last_sync, outbox_size, conflicts, linked_at
GET /hc2/nodes/{node_id}eine Node mit ihren lokalen und hybriden Checks
PATCH /hc2/nodes/{node_id}name, location, remote_mgmt (off, read, full)
POST /hc2/nodes/linkNode per Code verknüpfen: code (8 Zeichen), optional location, remote_mgmt (Standard full) → 202; die Node holt ihren Zugang in etwa 10 Sekunden selbst. Unbekannter oder abgelaufener Code: 404 code_unknown
DELETE /hc2/nodes/{node_id}Healthchecks-Sync trennen; keep_checks im JSON-Body (Standard true) führt Checks nur dieser Node online weiter, soweit möglich → {"unlinked": true, "checks_kept_online": 2, "checks_deleted": 1}
POST /hc2/nodes/{node_id}/commandsBefehl an die Node: name = run_check, pause, resume (je mit args.token), repair (Vollabgleich) oder resolve_conflict (args.id, args.keep = server/local) → 202
GET /hc2/nodes/{node_id}/commandsletzte Befehle (limit 1–200, Standard 20) mit done_at, ok, output
GET /node64/nodesdie Node-Übersicht: alle Node64-Container des Kontos mit Modulen, Merkmalen (Healthchecks-Sync, Honeypot-Sensor, CDN64-Tunnel, DynDNS), Zustand des Syncs und removed

Befehle nimmt die Node nur an, wenn ihre Fernverwaltung es erlaubt (siehe Fernverwaltung). Mit POST /node64/hello melden sich die Nodes selbst an; das brauchst du in eigenen Skripten nicht.

Fehler gefunden oder etwas fehlt? Schreibt uns im v64.tech-Forum. · Stand: 2026-11-04