Riferimento per sviluppatori

Watchlist Dominio

API DomScan: Monitora i domini per modifiche di scadenza e disponibilità. Ricevi avvisi quando i domini registrati diventano disponibili.

Watchlist Dominio

Monitora i domini per modifiche di scadenza e disponibilità. Ricevi avvisi quando i domini registrati diventano disponibili.

Monitoraggio

Accedi con Google per accedere al tuo elenco di vigilanza dei domini personalizzato con avvisi email, webhook e altri.

Ricevi notifiche tramite e-mail, Telegram, Slack, Discord o Webhook.

GET /v1/watchlist

Ottieni tutti i domini nella tua watchlist.

Paginato: invia limit (da 1 a 100) e passa next_cursor come cursor. Le risposte includono has_more e next_cursor. Senza limit viene restituita l'intera lista. Vedi la paginazione.

Risposta di esempio

{
                "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"
                }

Campi della risposta

Campo Tipo
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
POST /v1/watchlist

Aggiungi un dominio alla tua watchlist.

Corpo della richiesta

{
                "domain": "mydomain.com",
                "notify_email": "[email protected]"
                }

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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
}
DELETE /v1/watchlist?domain=mydomain.com

Rimuovi dalla lista di controllo

curl -X DELETE -H "X-API-Key: your-api-key" "https://domscan.net/v1/watchlist?domain=mydomain.com"

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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
}
GET /v1/watchlist/expiring?days=30

In scadenza a breve

Paginato: invia limit (da 1 a 100) e passa next_cursor come cursor. Le risposte includono has_more e next_cursor. Senza limit viene restituita l'intera lista. Vedi la paginazione.

Risposta di esempio

{
                "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
                }

Campi della risposta

Campo Tipo
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
GET /v1/watchlist/available

Disponibile

Paginato: invia limit (da 1 a 100) e passa next_cursor come cursor. Le risposte includono has_more e next_cursor. Senza limit viene restituita l'intera lista. Vedi la paginazione.

Risposta di esempio

{
                "available_domains": [
                {
                "domain": "startupdrop.ai",
                "status": "available",
                "last_checked": "2026-04-14T08:30:00Z",
                "check_count": 18
                }
                ],
                "total": 1,
                "message": "Questi domini dalla tua watchlist sono ora disponibili per la registrazione!"
                }

Campi della risposta

Campo Tipo
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

Webhook per gli avvisi

Ricevi gli avvisi di monitoraggio come richieste POST JSON firmate sui tuoi endpoint HTTPS. Gestisci gli endpoint con una chiave API oppure dalle impostazioni di Monitoraggio dopo aver effettuato l’accesso.

Tipi di evento

MonitoraggioEventi
Disponibilità, scadenza e stato della watchlistdomain.available domain.expiring_30 domain.expiring_14 domain.expiring_7 domain.expiring_1 domain.status_change
Monitoraggio delle modifiche dei dominidomain.dns_changed domain.certificate_changed domain.registration_changed domain.hosting_changed domain.technology_changed domain.email_security_changed
Monitoraggio del brand (nuove registrazioni simili)brand.threat_detected
Sottoscrizioni di avviso della lista di monitoraggio (certificati, prezzi, record DNS, domini simili)ssl.expiring ssl.expired ssl.changed price.dropped dns.changed typosquat.detected
Job asincroni (gratuiti, solo per i job creati con notify_webhook)job.completed job.failed job.cancelled
Evento di test (gratuito)webhook.test

Leggi la guida all'API degli avvisi webhook

Prezzi

Ogni avviso consegnato a un endpoint con una risposta 2xx costa 2 crediti. I crediti vengono riservati subito prima del primo tentativo e rimborsati se la consegna non riesce, viene annullata o l’endpoint viene eliminato. Gli eventi di test sono gratuiti. Se il saldo è insufficiente, l’avviso viene saltato e non viene addebitato nulla.

POST /v1/webhooks

Registra un endpoint HTTPS. L’URL deve risolversi in un indirizzo pubblico. Ometti events, oppure passa ["*"], per ricevere ogni tipo di evento. Il segreto di firma viene restituito solo in questa risposta.

Richiesta di esempio

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"]
  }'

Risposta di esempio

{
  "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_..."
}

Campi della risposta

Campo Tipo
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
GET /v1/webhooks

Elenca i tuoi endpoint con stato, eventi sottoscritti, numero di errori e ultimi quattro caratteri del segreto, insieme ai tipi di evento disponibili e alla policy di consegna.

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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"
}
PATCH /v1/webhooks/:webhook_id

Metti in pausa o riattiva un endpoint, cambia i suoi eventi o modifica la descrizione. Riattivare un endpoint azzera il suo contatore di errori.

{ "enabled": true, "events": ["*"] }

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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"
  }
}
DELETE /v1/webhooks/:webhook_id

Elimina un endpoint. Le consegne in sospeso vengono annullate e gli eventuali crediti riservati vengono rimborsati.

Campi della risposta

Campo Tipo
id string
deleted boolean

Risposta di esempio

{
  "id": "example-id",
  "deleted": true
}
POST /v1/webhooks/:webhook_id/test

Invia un evento webhook.test gratuito e restituisce il risultato. Gli eventi di test non vengono ritentati e non contano ai fini della pausa automatica.

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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
}
POST /v1/webhooks/:webhook_id/rotate-secret

Sostituisce il segreto di firma di un endpoint, anche se è in pausa. Il nuovo segreto viene restituito solo in questa risposta. Per le 24 ore successive, ogni consegna è firmata sia con il nuovo segreto sia con quello precedente. La rotazione è gratuita.

Richiesta di esempio

curl -X POST "https://domscan.net/v1/webhooks/whe_3f1c0a9b8e7d6c5b4a39281706f5e4d3/rotate-secret" \
  -H "X-API-Key: $DOMSCAN_API_KEY"

Risposta di esempio

{
  "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
}

Campi della risposta

Campo Tipo
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
GET /v1/webhooks/:webhook_id/deliveries

Parametri di query

ParametroTipoDescrizione
limit integer Numero di consegne da restituire, da 1 a 100. Predefinito 50.

Elenca le consegne recenti con stato, tentativi, risposta HTTP, crediti addebitati e rimborsi. I record delle consegne vengono conservati per 30 giorni.

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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"
    }
  ]
}

Formato della richiesta

Ogni avviso è una richiesta POST con un corpo JSON. Il campo id resta invariato per un evento ed è ripetuto in X-DomScan-Event-Id, così puoi ignorare i nuovi tentativi già elaborati.

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"
  }
}

Verifica delle firme

Calcola un HMAC-SHA256 del valore di X-DomScan-Timestamp, un punto e il corpo grezzo della richiesta, usando il segreto del tuo endpoint. Confronta il risultato con X-DomScan-Signature in tempo costante e rifiuta le richieste con un timestamp più vecchio di 5 minuti.

L'esempio sotto verifica ogni firma presente nell'intestazione, quindi continua a funzionare anche durante la rotazione di un segreto.

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);
  });
}

Ruotare un segreto di firma

Durante il periodo di tolleranza di 24 ore dopo una rotazione, X-DomScan-Signature contiene due firme separate da una virgola, con il nuovo segreto per primo, come mostrato sotto. Accetta una richiesta quando una qualsiasi voce corrisponde a un segreto di cui ti fidi, distribuisci il nuovo segreto e poi smetti di fidarti del vecchio. Ruotando di nuovo durante il periodo di tolleranza, il segreto precedente più vecchio viene ritirato subito.

X-DomScan-Signature: sha256=<new>,sha256=<previous>

Nuovi tentativi e pausa automatica

Restituisci qualsiasi stato 2xx entro 8 secondi per confermare un avviso. Reindirizzamenti, altri codici di stato e timeout vengono ritentati con backoff esponenziale (1, 4, 16, 64 e 256 minuti), fino a 6 tentativi in totale. Dopo 15 tentativi consecutivi non riusciti l’endpoint viene messo in pausa; riattivalo con PATCH o dalle impostazioni di Monitoraggio.

Quando un endpoint viene messo in pausa dopo errori ripetuti, il proprietario dell'endpoint riceve un'e-mail con l'host dell'endpoint, l'ultimo errore e un link alle impostazioni di Monitor. Correggi l'endpoint, poi riattivalo dalle impostazioni di Monitor o con PATCH e enabled impostato su true. La riattivazione azzera il conteggio degli errori.

Sottoscrizioni di avviso della lista di monitoraggio

Sottoscrivi un elemento monitorato agli avvisi che desideri. Ogni sottoscrizione monitora un hostname, un TLD o un dominio di marchio, e tu scegli quali eventi ricevere. Gli eventi vengono inviati ai tuoi endpoint webhook firmati e ai tuoi avvisi nell'app.

TipoEventiQuando si attiva
sslssl.expiring ssl.expired ssl.changedssl.expiring quando il certificato servito da un hostname scade entro ssl_expiring_days (30, 14, 7 o 1, predefinito 14), una volta per certificato e soglia. ssl.expired una volta per ogni certificato scaduto. ssl.changed quando una nuova impronta del certificato viene rilevata in due controlli consecutivi; il payload indica se l'emittente è cambiato.
priceprice.droppedQuando il prezzo di registrazione o di rinnovo di un TLD, presso un registrar o presso il più economico, scende di almeno drop_percent rispetto al prezzo più alto dall'ultimo avviso, oppure raggiunge target_price o meno. I prezzi provengono dallo snapshot giornaliero dei prezzi, e ogni snapshot viene valutato una sola volta.
dnsdns.changedQuando un tipo di record monitorato (A, AAAA, MX, NS, TXT o CNAME) di qualsiasi hostname restituisce la stessa nuova risposta in due interrogazioni confermate consecutive.
typosquattyposquat.detectedQuando un dominio simile al dominio di marchio viene registrato per la prima volta, confermato da un'interrogazione di registrazione autorevole. Il primo passaggio completo sui domini simili stabilisce la base di riferimento e non genera avvisi.

Solo prove esatte attivano un evento. Un handshake TLS non riuscito, un'interrogazione DNS che fallisce o va in timeout, un prezzo mancante e un'interrogazione bloccata o limitata in frequenza sono sconosciuti: non cambiano nulla e non generano mai un avviso né un addebito. Il primo controllo confermato di una sottoscrizione stabilisce la sua base di riferimento.

I controlli vengono eseguiti automaticamente: certificati ogni 12 ore, record DNS ogni ora (con un controllo di conferma 15 minuti dopo la prima rilevazione di una modifica), prezzi ogni 2 ore rispetto allo snapshot giornaliero e domini simili in batch da 30 con un passaggio completo ogni giorno. Dopo un controllo sconosciuto, il tentativo successivo avviene prima.

Creare sottoscrizioni ed eseguire controlli è gratuito. Ogni avviso consegnato a un endpoint webhook con risposta 2xx costa 2 crediti, come ogni altro avviso di monitoraggio. Le consegne non riuscite vengono rimborsate e un account può avere fino a 100 sottoscrizioni, 20 delle quali per domini simili.

POST /v1/watchlist/alerts

Crea una sottoscrizione. type decide quali campi si applicano: domain per ssl, dns e typosquat; tld, registrar, price_type, drop_percent e target_price per price. I campi che non si applicano al tipo vengono rifiutati.

Corpo della richiesta

ParametroTipoDescrizione
typestringssl, price, dns o typosquat. Obbligatorio.
domainstringHostname da monitorare per ssl e dns, oppure il dominio di marchio per typosquat.
tldstringTLD da monitorare per price, ad esempio com.
registrarstringID del registrar per price. Omettilo per monitorare il registrar più economico.
eventsstring[]Eventi da ricevere. Per impostazione predefinita, tutti gli eventi del tipo.
ssl_expiring_daysintegerGiorni prima della scadenza per ssl.expiring: 30, 14, 7 o 1. Predefinito 14.
price_typestringregistration (predefinito) o renewal.
drop_percentnumberAvviso in caso di calo di almeno questa percentuale, da 1 a 95.
target_pricenumberAvviso quando il prezzo in USD raggiunge questo importo o meno. Una sottoscrizione di prezzo richiede drop_percent, target_price o entrambi.
record_typesstring[]Tipi di record da monitorare per dns. Per impostazione predefinita A, AAAA, MX, NS, TXT e CNAME.

Richiesta di esempio

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
  }'

Risposta di esempio

{
  "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"
  }
}

Campi della risposta

Campo Tipo
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
GET /v1/watchlist/alerts

Elenca le tue sottoscrizioni con le ultime prove confermate e lo stato dei controlli, gli eventi supportati da ciascun tipo, la pianificazione dei controlli e il prezzo dell'avviso.

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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": {}
  }
}
GET /v1/watchlist/alerts/:subscription_id

Recupera una sottoscrizione con le ultime prove confermate e i suoi 20 eventi più recenti.

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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": {}
    }
  ]
}
PATCH /v1/watchlist/alerts/:subscription_id

Mette in pausa o riprende una sottoscrizione con enabled, oppure ne modifica events, ssl_expiring_days, drop_percent, target_price o record_types. Un nuovo prezzo obiettivo genera un avviso solo in caso di una successiva variazione di prezzo.

{ "enabled": false }

Campi della risposta

Campo Tipo
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

Risposta di esempio

{
  "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"
  }
}
DELETE /v1/watchlist/alerts/:subscription_id

Elimina una sottoscrizione. Gli eventi che non ha ancora inviato vengono scartati e mai addebitati.

Campi della risposta

Campo Tipo
id string
deleted boolean

Risposta di esempio

{
  "id": "example-id",
  "deleted": true
}

Esempio di evento dns.changed

{
  "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"
  }
}