Domain-Beobachtungsliste
DomScan-API: Überwachen Sie Domänen auf Ablauf und Verfügbarkeitsänderungen. Erhalten Sie Benachrichtigungen, wenn registrierte Domänen verfügbar werden.
Domain-Beobachtungsliste
Überwachen Sie Domänen auf Ablauf und Verfügbarkeitsänderungen. Erhalten Sie Benachrichtigungen, wenn registrierte Domänen verfügbar werden.
Melden Sie sich mit Google an, um auf Ihre personalisierte Domain-Watchlist mit E-Mail-Benachrichtigungen, Webhooks und mehr zuzugreifen.
Erhalten Sie Benachrichtigungen per E-Mail, Telegram, Slack, Discord oder Webhook.
Rufen Sie alle Domänen in Ihrer Beobachtungsliste ab.
Paginiert: Sende limit (1 bis 100) und gib next_cursor als cursor zurück. Antworten enthalten has_more und next_cursor. Ohne limit wird die gesamte Liste zurückgegeben. Siehe Pagination.
Beispielantwort
{
"watchlist": [
{
"domain": "startup.com",
"added_at": "2024-01-15T10:30:00Z",
"status": "registered",
"expiry_date": "2025-01-15T00:00:00Z",
"days_until_expiry": 287,
"last_checked": "2024-03-01T12:00:00Z",
"notify_email": "[email protected]",
"check_count": 4
}
],
"total": 1,
"updated_at": "2024-03-01T12:00:00Z"
}
Antwortfelder
| Feld | Typ |
|---|---|
has_more |
boolean |
next_cursor |
string | null |
watchlist[] |
object[] |
watchlist[] |
object |
watchlist[].domain |
string |
watchlist[].added_at |
string |
watchlist[].status |
string |
watchlist[].last_checked |
string |
watchlist[].expiry_date |
string |
watchlist[].days_until_expiry |
integer |
watchlist[].notify_email |
string |
watchlist[].check_count |
integer |
total |
integer |
updated_at |
string |
Fügen Sie eine Domäne zu Ihrer Beobachtungsliste hinzu.
Anfragetext
{
"domain": "mydomain.com",
"notify_email": "[email protected]"
}
Antwortfelder
| Feld | Typ |
|---|---|
success |
boolean |
message |
string |
watchlist[] |
object[] |
watchlist[] |
object |
watchlist[].domain |
string |
watchlist[].added_at |
string |
watchlist[].status |
string |
watchlist[].last_checked |
string |
watchlist[].expiry_date |
string |
watchlist[].days_until_expiry |
integer |
watchlist[].notify_email |
string |
watchlist[].check_count |
integer |
total |
integer |
Beispielantwort
{
"success": true,
"message": "Added example.org to watchlist",
"watchlist": [
{
"domain": "example.com",
"added_at": "2026-06-02T09:12:00.000Z",
"last_checked": "2026-10-09T03:00:12.000Z",
"status": "expiring_soon",
"expiry_date": "2026-12-18T14:22:08Z",
"days_until_expiry": 70,
"notify_email": "[email protected]"
},
{
"domain": "example.org",
"added_at": "2026-10-09T10:15:30.000Z",
"status": "unknown",
"notify_email": "[email protected]"
}
],
"total": 2
}
Von Watchlist entfernen
curl -X DELETE -H "X-API-Key: your-api-key" "https://domscan.net/v1/watchlist?domain=mydomain.com"
Antwortfelder
| Feld | Typ |
|---|---|
success |
boolean |
message |
string |
domain |
string |
watchlist[] |
object[] |
watchlist[] |
object |
watchlist[].domain |
string |
watchlist[].added_at |
string |
watchlist[].status |
string |
watchlist[].last_checked |
string |
watchlist[].expiry_date |
string |
watchlist[].days_until_expiry |
integer |
watchlist[].notify_email |
string |
watchlist[].check_count |
integer |
total |
integer |
Beispielantwort
{
"success": true,
"message": "Request completed",
"domain": "example.com",
"watchlist": [
{
"domain": "example.com",
"added_at": "2026-08-27T12:00:00Z",
"status": "registered",
"last_checked": "2026-08-27T12:00:00Z",
"expiry_date": "2026-08-27T12:00:00Z",
"days_until_expiry": 1,
"notify_email": "[email protected]",
"check_count": 1
}
],
"total": 1
}
Läuft bald ab
Paginiert: Sende limit (1 bis 100) und gib next_cursor als cursor zurück. Antworten enthalten has_more und next_cursor. Ohne limit wird die gesamte Liste zurückgegeben. Siehe Pagination.
Beispielantwort
{
"expiring_domains": [
{
"domain": "renewal-window.com",
"status": "expiring_soon",
"expiry_date": "2026-05-12T00:00:00Z",
"days_until_expiry": 28,
"check_count": 11
}
],
"total": 1,
"threshold_days": 30
}
Antwortfelder
| Feld | Typ |
|---|---|
has_more |
boolean |
next_cursor |
string | null |
expiring_domains[] |
object[] |
expiring_domains[] |
object |
expiring_domains[].domain |
string |
expiring_domains[].added_at |
string |
expiring_domains[].status |
string |
expiring_domains[].last_checked |
string |
expiring_domains[].expiry_date |
string |
expiring_domains[].days_until_expiry |
integer |
expiring_domains[].notify_email |
string |
expiring_domains[].check_count |
integer |
total |
integer |
threshold_days |
integer |
Verfügbar
Paginiert: Sende limit (1 bis 100) und gib next_cursor als cursor zurück. Antworten enthalten has_more und next_cursor. Ohne limit wird die gesamte Liste zurückgegeben. Siehe Pagination.
Beispielantwort
{
"available_domains": [
{
"domain": "startupdrop.ai",
"status": "available",
"last_checked": "2026-04-14T08:30:00Z",
"check_count": 18
}
],
"total": 1,
"message": "Diese Domains aus Ihrer Beobachtungsliste sind jetzt zur Registrierung verfügbar!"
}
Antwortfelder
| Feld | Typ |
|---|---|
has_more |
boolean |
next_cursor |
string | null |
available_domains[] |
object[] |
available_domains[] |
object |
available_domains[].domain |
string |
available_domains[].added_at |
string |
available_domains[].status |
string |
available_domains[].last_checked |
string |
available_domains[].expiry_date |
string |
available_domains[].days_until_expiry |
integer |
available_domains[].notify_email |
string |
available_domains[].check_count |
integer |
total |
integer |
message |
string |
Alarm-Webhooks
Empfangen Sie Überwachungsalarme als signierte JSON-POST-Anfragen an Ihren eigenen HTTPS-Endpunkten. Verwalten Sie Endpunkte mit einem API-Schlüssel oder, wenn Sie angemeldet sind, in den Monitor-Einstellungen.
Ereignistypen
| Monitor | Ereignisse |
|---|---|
| Verfügbarkeit, Ablauf und Status der Watchlist | domain.available domain.expiring_30 domain.expiring_14 domain.expiring_7 domain.expiring_1 domain.status_change |
| Überwachung von Domain-Änderungen | domain.dns_changed domain.certificate_changed domain.registration_changed domain.hosting_changed domain.technology_changed domain.email_security_changed |
| Markenüberwachung (neue ähnliche Registrierungen) | brand.threat_detected |
| Alarm-Abonnements der Beobachtungsliste (Zertifikate, Preise, DNS-Einträge, ähnliche Domains) | ssl.expiring ssl.expired ssl.changed price.dropped dns.changed typosquat.detected |
| Asynchrone Jobs (kostenlos, nur für Jobs, die mit notify_webhook erstellt wurden) | job.completed job.failed job.cancelled |
| Testereignis (kostenlos) | webhook.test |
Leitfaden zur Webhook-Alarm-API lesen
Preise
Jeder mit einer 2xx-Antwort an einen Endpunkt zugestellte Alarm kostet 2 Credits. Die Credits werden unmittelbar vor dem ersten Versuch reserviert und erstattet, wenn die Zustellung fehlschlägt, abgebrochen oder der Endpunkt gelöscht wird. Testereignisse sind kostenlos. Reicht das Guthaben nicht aus, wird der Alarm übersprungen und nichts berechnet.
Registriert einen HTTPS-Endpunkt. Die URL muss auf eine öffentliche Adresse auflösen. Lassen Sie events weg oder übergeben Sie ["*"], um jeden Ereignistyp zu empfangen. Das Signaturgeheimnis wird nur in dieser Antwort zurückgegeben.
Beispielanfrage
curl -X POST "https://domscan.net/v1/webhooks" \
-H "X-API-Key: $DOMSCAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/domscan",
"events": ["domain.expiring_30", "domain.available", "domain.dns_changed"]
}'
Beispielantwort
{
"endpoint": {
"id": "whe_3f1c0a9b8e7d6c5b4a39281706f5e4d3",
"url": "https://hooks.example.com/domscan",
"events": ["domain.available", "domain.expiring_30", "domain.dns_changed"],
"status": "active",
"secret_hint": "9c2e"
},
"secret": "whsec_..."
}
Antwortfelder
| Feld | Typ |
|---|---|
endpoint |
object |
endpoint.id |
string |
endpoint.url |
string |
endpoint.description |
string | null |
endpoint.events[] |
string[] |
endpoint.status |
string |
endpoint.disabled_reason |
string | null |
endpoint.consecutive_failures |
integer |
endpoint.secret_hint |
string |
endpoint.previous_secret_expires_at |
string | null |
endpoint.secret_rotated_at |
string | null |
endpoint.last_success_at |
string | null |
endpoint.last_failure_at |
string | null |
endpoint.last_error |
string | null |
endpoint.created_at |
string |
endpoint.updated_at |
string |
endpoint.disabled_at |
string | null |
secret |
string |
Listet Ihre Endpunkte mit Status, abonnierten Ereignissen, Fehleranzahl und den letzten vier Zeichen des Geheimnisses auf, zusammen mit den verfügbaren Ereignistypen und der Zustellungsrichtlinie.
Antwortfelder
| Feld | Typ |
|---|---|
endpoints[] |
object[] |
endpoints[] |
object |
endpoints[].id |
string |
endpoints[].url |
string |
endpoints[].description |
string | null |
endpoints[].events[] |
string[] |
endpoints[].status |
string |
endpoints[].disabled_reason |
string | null |
endpoints[].consecutive_failures |
integer |
endpoints[].secret_hint |
string |
endpoints[].previous_secret_expires_at |
string | null |
endpoints[].secret_rotated_at |
string | null |
endpoints[].last_success_at |
string | null |
endpoints[].last_failure_at |
string | null |
endpoints[].last_error |
string | null |
endpoints[].created_at |
string |
endpoints[].updated_at |
string |
endpoints[].disabled_at |
string | null |
available_events[] |
string[] |
all_events |
string |
test_event |
string |
policy |
object |
policy.secret_rotation_grace_seconds |
integer |
policy.secret_rotation_credits |
integer |
policy.credits_per_delivered_alert |
integer |
policy.test_event_credits |
integer |
policy.job_event_credits |
integer |
policy.failed_deliveries_charged |
boolean |
policy.max_endpoints |
integer |
policy.max_attempts |
integer |
policy.disable_after_consecutive_failures |
integer |
policy.signature_tolerance_seconds |
integer |
Beispielantwort
{
"endpoints": [
{
"id": "example-id",
"url": "https://example.com",
"events": [
"example"
],
"status": "active",
"secret_hint": "example",
"created_at": "2026-08-27T12:00:00Z",
"description": "example",
"disabled_reason": "customer",
"consecutive_failures": 1,
"previous_secret_expires_at": "2026-08-27T12:00:00Z",
"secret_rotated_at": "2026-08-27T12:00:00Z",
"last_success_at": "2026-08-27T12:00:00Z",
"last_failure_at": "2026-08-27T12:00:00Z",
"last_error": "example",
"updated_at": "2026-08-27T12:00:00Z",
"disabled_at": "2026-08-27T12:00:00Z"
}
],
"available_events": [
"domain.available"
],
"policy": {
"credits_per_delivered_alert": 2,
"test_event_credits": 0,
"failed_deliveries_charged": false,
"max_endpoints": 1,
"max_attempts": 1,
"disable_after_consecutive_failures": 1,
"signature_tolerance_seconds": 1,
"secret_rotation_grace_seconds": 86400,
"secret_rotation_credits": 0,
"job_event_credits": 0
},
"all_events": "*",
"test_event": "webhook.test"
}
Pausiert oder aktiviert einen Endpunkt, ändert seine Ereignisse oder bearbeitet seine Beschreibung. Beim Aktivieren eines Endpunkts wird seine Fehleranzahl zurückgesetzt.
{ "enabled": true, "events": ["*"] }
Antwortfelder
| Feld | Typ |
|---|---|
endpoint |
object |
endpoint.id |
string |
endpoint.url |
string |
endpoint.description |
string | null |
endpoint.events[] |
string[] |
endpoint.status |
string |
endpoint.disabled_reason |
string | null |
endpoint.consecutive_failures |
integer |
endpoint.secret_hint |
string |
endpoint.previous_secret_expires_at |
string | null |
endpoint.secret_rotated_at |
string | null |
endpoint.last_success_at |
string | null |
endpoint.last_failure_at |
string | null |
endpoint.last_error |
string | null |
endpoint.created_at |
string |
endpoint.updated_at |
string |
endpoint.disabled_at |
string | null |
Beispielantwort
{
"endpoint": {
"id": "example-id",
"url": "https://example.com",
"events": [
"example"
],
"status": "active",
"secret_hint": "example",
"created_at": "2026-08-27T12:00:00Z",
"description": "example",
"disabled_reason": "customer",
"consecutive_failures": 1,
"previous_secret_expires_at": "2026-08-27T12:00:00Z",
"secret_rotated_at": "2026-08-27T12:00:00Z",
"last_success_at": "2026-08-27T12:00:00Z",
"last_failure_at": "2026-08-27T12:00:00Z",
"last_error": "example",
"updated_at": "2026-08-27T12:00:00Z",
"disabled_at": "2026-08-27T12:00:00Z"
}
}
Löscht einen Endpunkt. Ausstehende Zustellungen werden abgebrochen und reservierte Credits erstattet.
Antwortfelder
| Feld | Typ |
|---|---|
id |
string |
deleted |
boolean |
Beispielantwort
{
"id": "example-id",
"deleted": true
}
Sendet ein kostenloses Ereignis webhook.test und gibt das Ergebnis zurück. Testereignisse werden nicht wiederholt und zählen nicht für die automatische Pausierung.
Antwortfelder
| Feld | Typ |
|---|---|
delivery |
object |
delivery.id |
string |
delivery.endpoint_id |
string |
delivery.event_id |
string |
delivery.event_type |
string |
delivery.status |
string |
delivery.attempts |
integer |
delivery.next_attempt_at |
string | null |
delivery.last_attempt_at |
string | null |
delivery.response_status |
integer | null |
delivery.last_error |
string | null |
delivery.credits_charged |
integer |
delivery.refunded |
boolean |
delivery.created_at |
string |
delivery.delivered_at |
string | null |
delivered |
boolean |
Beispielantwort
{
"delivery": {
"id": "example-id",
"endpoint_id": "example",
"event_id": "example",
"event_type": "domain",
"status": "pending",
"attempts": 1,
"next_attempt_at": "2026-08-27T12:00:00Z",
"last_attempt_at": "2026-08-27T12:00:00Z",
"response_status": 1,
"last_error": "example",
"credits_charged": 1,
"refunded": false,
"created_at": "2026-08-27T12:00:00Z",
"delivered_at": "2026-08-27T12:00:00Z"
},
"delivered": false
}
Ersetzt das Signaturgeheimnis eines Endpunkts, auch eines pausierten. Das neue Geheimnis wird nur in dieser Antwort zurückgegeben. In den nächsten 24 Stunden wird jede Zustellung mit dem neuen und dem vorherigen Geheimnis signiert. Die Rotation ist kostenlos.
Beispielanfrage
curl -X POST "https://domscan.net/v1/webhooks/whe_3f1c0a9b8e7d6c5b4a39281706f5e4d3/rotate-secret" \
-H "X-API-Key: $DOMSCAN_API_KEY"
Beispielantwort
{
"endpoint": {
"id": "whe_3f1c0a9b8e7d6c5b4a39281706f5e4d3",
"status": "active",
"secret_hint": "4b7a",
"previous_secret_expires_at": "2026-10-11T12:00:00.000Z"
},
"secret": "whsec_...",
"previous_secret_expires_at": "2026-10-11T12:00:00.000Z",
"grace_period_seconds": 86400
}
Antwortfelder
| Feld | Typ |
|---|---|
endpoint |
object |
endpoint.id |
string |
endpoint.url |
string |
endpoint.description |
string | null |
endpoint.events[] |
string[] |
endpoint.status |
string |
endpoint.disabled_reason |
string | null |
endpoint.consecutive_failures |
integer |
endpoint.secret_hint |
string |
endpoint.previous_secret_expires_at |
string | null |
endpoint.secret_rotated_at |
string | null |
endpoint.last_success_at |
string | null |
endpoint.last_failure_at |
string | null |
endpoint.last_error |
string | null |
endpoint.created_at |
string |
endpoint.updated_at |
string |
endpoint.disabled_at |
string | null |
secret |
string |
previous_secret_expires_at |
string |
grace_period_seconds |
integer |
Abfrageparameter
| Parameter | Typ | Beschreibung |
|---|---|---|
| limit | integer | Anzahl der zurückzugebenden Zustellungen, von 1 bis 100. Standard: 50. |
Listet aktuelle Zustellungen mit Status, Versuchen, HTTP-Antwort, berechneten Credits und Erstattungen auf. Zustellungsprotokolle werden 30 Tage lang aufbewahrt.
Antwortfelder
| Feld | Typ |
|---|---|
endpoint_id |
string |
deliveries[] |
object[] |
deliveries[] |
object |
deliveries[].id |
string |
deliveries[].endpoint_id |
string |
deliveries[].event_id |
string |
deliveries[].event_type |
string |
deliveries[].status |
string |
deliveries[].attempts |
integer |
deliveries[].next_attempt_at |
string | null |
deliveries[].last_attempt_at |
string | null |
deliveries[].response_status |
integer | null |
deliveries[].last_error |
string | null |
deliveries[].credits_charged |
integer |
deliveries[].refunded |
boolean |
deliveries[].created_at |
string |
deliveries[].delivered_at |
string | null |
Beispielantwort
{
"endpoint_id": "example",
"deliveries": [
{
"id": "example-id",
"endpoint_id": "example",
"event_id": "example",
"event_type": "domain",
"status": "pending",
"attempts": 1,
"next_attempt_at": "2026-08-27T12:00:00Z",
"last_attempt_at": "2026-08-27T12:00:00Z",
"response_status": 1,
"last_error": "example",
"credits_charged": 1,
"refunded": false,
"created_at": "2026-08-27T12:00:00Z",
"delivered_at": "2026-08-27T12:00:00Z"
}
]
}
Anfrageformat
Jeder Alarm ist eine POST-Anfrage mit JSON-Body. Das Feld id bleibt für ein Ereignis gleich und wird in X-DomScan-Event-Id wiederholt, sodass Sie bereits verarbeitete Wiederholungen ignorieren können.
POST /domscan HTTP/1.1
Content-Type: application/json
X-DomScan-Event: domain.expiring_30
X-DomScan-Event-Id: evt_6f1d2c3b4a5948e7b6c5d4e3f2a1b0c9
X-DomScan-Timestamp: 1791633600
X-DomScan-Signature: sha256=...
{
"id": "evt_6f1d2c3b4a5948e7b6c5d4e3f2a1b0c9",
"type": "domain.expiring_30",
"created": "2026-10-10T12:00:00.000Z",
"data": {
"domain": "acme.io",
"previous_status": "registered",
"current_status": "expiring_soon",
"expiry_date": "2026-11-09T00:00:00Z",
"days_until_expiry": 30,
"checked_at": "2026-10-10T12:00:00.000Z"
}
}
Signaturen prüfen
Berechnen Sie mit dem Geheimnis Ihres Endpunkts einen HMAC-SHA256 aus dem Wert von X-DomScan-Timestamp, einem Punkt und dem unveränderten Anfrage-Body. Vergleichen Sie das Ergebnis in konstanter Zeit mit X-DomScan-Signature und weisen Sie Anfragen zurück, deren Zeitstempel älter als 5 Minuten ist.
Das folgende Beispiel prüft jede Signatur im Header und funktioniert daher auch während einer Rotation des Geheimnisses weiter.
import crypto from 'node:crypto';
// rawBody: the request body exactly as received, before JSON parsing.
function verifyDomScanWebhook(rawBody, headers, secret) {
const timestamp = headers['x-domscan-timestamp'];
const header = headers['x-domscan-signature'] || '';
if (!/^\d{10}$/.test(timestamp || '')) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = Buffer.from('sha256=' + crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + rawBody)
.digest('hex'));
// One entry normally; two during a secret rotation (new secret first).
return header.split(',').some((entry) => {
const candidate = Buffer.from(entry.trim());
return candidate.length === expected.length &&
crypto.timingSafeEqual(candidate, expected);
});
}
Signaturgeheimnis rotieren
Während der 24-stündigen Übergangsfrist nach einer Rotation enthält X-DomScan-Signature zwei durch ein Komma getrennte Signaturen, das neue Geheimnis zuerst, wie unten gezeigt. Akzeptieren Sie eine Anfrage, wenn ein Eintrag zu einem Geheimnis passt, dem Sie vertrauen, setzen Sie das neue Geheimnis ein und vertrauen Sie dann dem alten nicht mehr. Wenn Sie während der Übergangsfrist erneut rotieren, wird das ältere vorherige Geheimnis sofort außer Kraft gesetzt.
X-DomScan-Signature: sha256=<new>,sha256=<previous>
Wiederholungen und automatische Pausierung
Geben Sie innerhalb von 8 Sekunden einen beliebigen 2xx-Status zurück, um einen Alarm zu bestätigen. Weiterleitungen, andere Statuscodes und Zeitüberschreitungen werden mit exponentiellem Backoff wiederholt (1, 4, 16, 64 und 256 Minuten), insgesamt bis zu 6 Versuche. Nach 15 aufeinanderfolgenden fehlgeschlagenen Versuchen wird der Endpunkt pausiert; aktivieren Sie ihn per PATCH oder in den Monitor-Einstellungen wieder.
Wird ein Endpunkt nach wiederholten Fehlern pausiert, erhält der Inhaber des Endpunkts eine E-Mail mit dem Host des Endpunkts, dem letzten Fehler und einem Link zu den Monitor-Einstellungen. Beheben Sie das Problem am Endpunkt und aktivieren Sie ihn dann wieder in den Monitor-Einstellungen oder mit PATCH und enabled auf true. Beim Aktivieren wird der Fehlerzähler auf null zurückgesetzt.
Alarm-Abonnements der Beobachtungsliste
Abonnieren Sie für ein beobachtetes Element die gewünschten Alarme. Jedes Abonnement beobachtet einen Hostnamen, eine TLD oder eine Markendomain, und Sie wählen, welche Ereignisse Sie erhalten. Die Ereignisse gehen an Ihre signierten Webhook-Endpunkte und an Ihre Alarme in der App.
| Typ | Ereignisse | Wann es ausgelöst wird |
|---|---|---|
ssl | ssl.expiring ssl.expired ssl.changed | ssl.expiring, wenn das von einem Hostnamen ausgelieferte Zertifikat innerhalb von ssl_expiring_days abläuft (30, 14, 7 oder 1, Standard 14), einmal pro Zertifikat und Schwellenwert. ssl.expired einmal pro abgelaufenem Zertifikat. ssl.changed, wenn bei zwei aufeinanderfolgenden Prüfungen ein neuer Zertifikat-Fingerprint gesehen wird; die Payload gibt an, ob sich der Aussteller geändert hat. |
price | price.dropped | Wenn der Registrierungs- oder Verlängerungspreis einer TLD, bei einem Registrar oder beim günstigsten, seit dem letzten Alarm um mindestens drop_percent vom höchsten Preis fällt oder target_price oder weniger erreicht. Die Preise stammen aus dem täglichen Preis-Snapshot, und jeder Snapshot wird einmal ausgewertet. |
dns | dns.changed | Wenn ein beobachteter Eintragstyp (A, AAAA, MX, NS, TXT oder CNAME) eines beliebigen Hostnamens bei zwei aufeinanderfolgenden bestätigten Abfragen dieselbe neue Antwort liefert. |
typosquat | typosquat.detected | Wenn eine ähnliche Domain zur Markendomain neu registriert wird, bestätigt durch eine maßgebliche Registrierungsabfrage. Der erste vollständige Durchlauf über die ähnlichen Domains legt die Ausgangsbasis fest und löst keinen Alarm aus. |
Nur eindeutige Belege lösen ein Ereignis aus. Ein fehlgeschlagener TLS-Handshake, eine DNS-Abfrage, die fehlschlägt oder in ein Timeout läuft, ein fehlender Preis und eine blockierte oder ratenbegrenzte Abfrage gelten als unbekannt: Sie ändern nichts und lösen nie einen Alarm oder eine Abbuchung aus. Die erste bestätigte Prüfung eines Abonnements legt dessen Ausgangsbasis fest.
Die Prüfungen laufen automatisch: Zertifikate alle 12 Stunden, DNS-Einträge stündlich (mit einer Bestätigungsprüfung 15 Minuten nach der ersten Erkennung einer Änderung), Preise alle 2 Stunden gegen den täglichen Snapshot und ähnliche Domains in Batches zu 30 mit einem vollständigen Durchlauf pro Tag. Nach einer unbekannten Prüfung erfolgt der nächste Versuch früher.
Das Anlegen von Abonnements und das Ausführen von Prüfungen ist kostenlos. Jeder an einen Webhook-Endpunkt zugestellte Alarm mit 2xx-Antwort kostet 2 Credits, wie jeder andere Monitoring-Alarm. Fehlgeschlagene Zustellungen werden erstattet, und ein Konto kann bis zu 100 Abonnements haben, davon 20 für ähnliche Domains.
Legt ein Abonnement an. type bestimmt, welche Felder gelten: domain für ssl, dns und typosquat; tld, registrar, price_type, drop_percent und target_price für price. Felder, die nicht zum Typ passen, werden abgelehnt.
Anfragetext
| Parameter | Typ | Beschreibung |
|---|---|---|
| type | string | ssl, price, dns oder typosquat. Erforderlich. |
| domain | string | Zu beobachtender Hostname für ssl und dns oder die Markendomain für typosquat. |
| tld | string | Zu beobachtende TLD für price, zum Beispiel com. |
| registrar | string | Registrar-ID für price. Weglassen, um den günstigsten Registrar zu beobachten. |
| events | string[] | Zu empfangende Ereignisse. Standardmäßig alle Ereignisse des Typs. |
| ssl_expiring_days | integer | Tage vor Ablauf für ssl.expiring: 30, 14, 7 oder 1. Standard 14. |
| price_type | string | registration (Standard) oder renewal. |
| drop_percent | number | Alarm bei einem Rückgang um mindestens diesen Prozentsatz, 1 bis 95. |
| target_price | number | Alarm, wenn der Preis in USD diesen Betrag oder weniger erreicht. Ein Preis-Abonnement benötigt drop_percent, target_price oder beides. |
| record_types | string[] | Zu beobachtende Eintragstypen für dns. Standardmäßig A, AAAA, MX, NS, TXT und CNAME. |
Beispielanfrage
curl -X POST "https://domscan.net/v1/watchlist/alerts" \
-H "X-API-Key: $DOMSCAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "price",
"tld": "com",
"registrar": "porkbun",
"price_type": "renewal",
"drop_percent": 10,
"target_price": 9.5
}'
Beispielantwort
{
"subscription": {
"id": "mas_8c1f0e2d3b4a59687766554433221100",
"type": "price",
"target": "com",
"registrar": "porkbun",
"events": ["price.dropped"],
"status": "active",
"price_type": "renewal",
"drop_percent": 10,
"target_price": 9.5,
"currency": "USD",
"observed": null,
"last_check_status": null,
"next_check_at": "2026-10-10T12:00:00.000Z"
}
}
Antwortfelder
| Feld | Typ |
|---|---|
subscription |
object |
subscription.id |
string |
subscription.type |
string |
subscription.target |
string |
subscription.registrar |
string | null |
subscription.events[] |
string[] |
subscription.status |
string |
subscription.ssl_expiring_days |
integer | null |
subscription.price_type |
string | null |
subscription.drop_percent |
number | null |
subscription.target_price |
number | null |
subscription.currency |
string | null |
subscription.record_types[] |
string[] |
subscription.observed |
object | null |
subscription.last_check_at |
string | null |
subscription.last_check_status |
string | null |
subscription.last_error |
string | null |
subscription.next_check_at |
string | null |
subscription.created_at |
string |
subscription.updated_at |
string |
Listet Ihre Abonnements mit den neuesten bestätigten Belegen und dem Prüfstatus, den von jedem Typ unterstützten Ereignissen, dem Prüfplan und dem Alarmpreis auf.
Antwortfelder
| Feld | Typ |
|---|---|
subscriptions[] |
object[] |
subscriptions[] |
object |
subscriptions[].id |
string |
subscriptions[].type |
string |
subscriptions[].target |
string |
subscriptions[].registrar |
string | null |
subscriptions[].events[] |
string[] |
subscriptions[].status |
string |
subscriptions[].ssl_expiring_days |
integer | null |
subscriptions[].price_type |
string | null |
subscriptions[].drop_percent |
number | null |
subscriptions[].target_price |
number | null |
subscriptions[].currency |
string | null |
subscriptions[].record_types[] |
string[] |
subscriptions[].observed |
object | null |
subscriptions[].last_check_at |
string | null |
subscriptions[].last_check_status |
string | null |
subscriptions[].last_error |
string | null |
subscriptions[].next_check_at |
string | null |
subscriptions[].created_at |
string |
subscriptions[].updated_at |
string |
total |
integer |
available_types |
object |
available_types.ssl[] |
string[] |
available_types.price[] |
string[] |
available_types.dns[] |
string[] |
available_types.typosquat[] |
string[] |
policy |
object |
policy.credits_per_delivered_alert |
integer |
policy.check_credits |
integer |
policy.unknown_checks_charged |
boolean |
policy.max_subscriptions |
integer |
policy.max_typosquat_subscriptions |
integer |
policy.ssl_expiring_days[] |
integer[] |
policy.default_ssl_expiring_days |
integer |
policy.record_types[] |
string[] |
policy.price_types[] |
string[] |
policy.check_interval_minutes |
object |
policy.confirmation_checks |
object |
Beispielantwort
{
"subscriptions": [
{
"id": "example-id",
"type": "ssl",
"target": "example",
"registrar": "example",
"events": [
"ssl.expiring"
],
"status": "active",
"ssl_expiring_days": 30,
"price_type": "registration",
"drop_percent": 0.5,
"target_price": 0.5,
"currency": "USD",
"record_types": [
"A"
],
"observed": {},
"last_check_at": "2026-08-27T12:00:00Z",
"last_check_status": "baseline",
"last_error": "example",
"next_check_at": "2026-08-27T12:00:00Z",
"created_at": "2026-08-27T12:00:00Z",
"updated_at": "2026-08-27T12:00:00Z"
}
],
"total": 1,
"available_types": {
"ssl": [
"ssl.expiring"
],
"price": [
"price.dropped"
],
"dns": [
"dns.changed"
],
"typosquat": [
"typosquat.detected"
]
},
"policy": {
"credits_per_delivered_alert": 2,
"check_credits": 0,
"unknown_checks_charged": false,
"max_subscriptions": 1,
"check_interval_minutes": {},
"max_typosquat_subscriptions": 1,
"ssl_expiring_days": [
1
],
"default_ssl_expiring_days": 1,
"record_types": [
"A"
],
"price_types": [
"registration"
],
"confirmation_checks": {}
}
}
Ruft ein Abonnement mit den neuesten bestätigten Belegen und seinen 20 jüngsten Ereignissen ab.
Antwortfelder
| Feld | Typ |
|---|---|
subscription |
object |
subscription.id |
string |
subscription.type |
string |
subscription.target |
string |
subscription.registrar |
string | null |
subscription.events[] |
string[] |
subscription.status |
string |
subscription.ssl_expiring_days |
integer | null |
subscription.price_type |
string | null |
subscription.drop_percent |
number | null |
subscription.target_price |
number | null |
subscription.currency |
string | null |
subscription.record_types[] |
string[] |
subscription.observed |
object | null |
subscription.last_check_at |
string | null |
subscription.last_check_status |
string | null |
subscription.last_error |
string | null |
subscription.next_check_at |
string | null |
subscription.created_at |
string |
subscription.updated_at |
string |
events[] |
object[] |
events[] |
object |
events[].id |
string |
events[].event_type |
string |
events[].detected_at |
string |
events[].published_at |
string | null |
events[].data |
object |
Beispielantwort
{
"subscription": {
"id": "example-id",
"type": "ssl",
"target": "example",
"registrar": "example",
"events": [
"ssl.expiring"
],
"status": "active",
"ssl_expiring_days": 30,
"price_type": "registration",
"drop_percent": 0.5,
"target_price": 0.5,
"currency": "USD",
"record_types": [
"A"
],
"observed": {},
"last_check_at": "2026-08-27T12:00:00Z",
"last_check_status": "baseline",
"last_error": "example",
"next_check_at": "2026-08-27T12:00:00Z",
"created_at": "2026-08-27T12:00:00Z",
"updated_at": "2026-08-27T12:00:00Z"
},
"events": [
{
"id": "example-id",
"event_type": "ssl.expiring",
"detected_at": "2026-08-27T12:00:00Z",
"published_at": "2026-08-27T12:00:00Z",
"data": {}
}
]
}
Pausiert oder setzt ein Abonnement mit enabled fort oder ändert dessen events, ssl_expiring_days, drop_percent, target_price oder record_types. Ein neuer Zielpreis löst erst bei einer späteren Preisbewegung einen Alarm aus.
{ "enabled": false }
Antwortfelder
| Feld | Typ |
|---|---|
subscription |
object |
subscription.id |
string |
subscription.type |
string |
subscription.target |
string |
subscription.registrar |
string | null |
subscription.events[] |
string[] |
subscription.status |
string |
subscription.ssl_expiring_days |
integer | null |
subscription.price_type |
string | null |
subscription.drop_percent |
number | null |
subscription.target_price |
number | null |
subscription.currency |
string | null |
subscription.record_types[] |
string[] |
subscription.observed |
object | null |
subscription.last_check_at |
string | null |
subscription.last_check_status |
string | null |
subscription.last_error |
string | null |
subscription.next_check_at |
string | null |
subscription.created_at |
string |
subscription.updated_at |
string |
Beispielantwort
{
"subscription": {
"id": "example-id",
"type": "ssl",
"target": "example",
"registrar": "example",
"events": [
"ssl.expiring"
],
"status": "active",
"ssl_expiring_days": 30,
"price_type": "registration",
"drop_percent": 0.5,
"target_price": 0.5,
"currency": "USD",
"record_types": [
"A"
],
"observed": {},
"last_check_at": "2026-08-27T12:00:00Z",
"last_check_status": "baseline",
"last_error": "example",
"next_check_at": "2026-08-27T12:00:00Z",
"created_at": "2026-08-27T12:00:00Z",
"updated_at": "2026-08-27T12:00:00Z"
}
}
Löscht ein Abonnement. Noch nicht gesendete Ereignisse werden verworfen und nie berechnet.
Antwortfelder
| Feld | Typ |
|---|---|
id |
string |
deleted |
boolean |
Beispielantwort
{
"id": "example-id",
"deleted": true
}
Beispiel für ein dns.changed-Ereignis
{
"id": "evt_2b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e",
"type": "dns.changed",
"created": "2026-10-10T12:15:00.000Z",
"data": {
"domain": "partner-shop.example",
"changes": [
{
"record_type": "MX",
"before": ["10 mx1.mail.example"],
"after": ["10 mx.other-mail.example"],
"added": ["10 mx.other-mail.example"],
"removed": ["10 mx1.mail.example"],
"first_seen_at": "2026-10-10T12:00:00.000Z"
}
],
"confirmed_checks": 2,
"confirmed_at": "2026-10-10T12:15:00.000Z",
"subscription_id": "mas_8c1f0e2d3b4a59687766554433221100"
}
}