Referencia para desarrolladores

Lista de seguimiento de dominios

API de DomScan: Monitoriza dominios por expiración y cambios de disponibilidad. Recibe alertas cuando dominios registrados estén disponibles.

Lista de seguimiento de dominios

Monitoriza dominios por expiración y cambios de disponibilidad. Recibe alertas cuando dominios registrados estén disponibles.

Monitor

Inicia sesión con Google para acceder a tu lista de seguimiento de dominios personalizada con alertas por correo electrónico, webhooks y más.

Reciba notificaciones por correo electrónico, Telegram, Slack, Discord o Webhook.

GET /v1/watchlist

Obtiene todos los dominios en tu lista de seguimiento.

Paginado: envía limit (de 1 a 100) y devuelve next_cursor como cursor. Las respuestas incluyen has_more y next_cursor. Sin limit se devuelve la lista completa. Consulta la paginación.

Respuesta de ejemplo

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

Campos de respuesta

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

Añade un dominio a tu lista de seguimiento.

Cuerpo de la solicitud

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

Campos de respuesta

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

Respuesta de ejemplo

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

Eliminar de lista de seguimiento

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

Campos de respuesta

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

Respuesta de ejemplo

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

Caducan pronto

Paginado: envía limit (de 1 a 100) y devuelve next_cursor como cursor. Las respuestas incluyen has_more y next_cursor. Sin limit se devuelve la lista completa. Consulta la paginación.

Respuesta de ejemplo

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

Campos de respuesta

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

Disponible

Paginado: envía limit (de 1 a 100) y devuelve next_cursor como cursor. Las respuestas incluyen has_more y next_cursor. Sin limit se devuelve la lista completa. Consulta la paginación.

Respuesta de ejemplo

{
                "available_domains": [
                {
                "domain": "startupdrop.ai",
                "status": "available",
                "last_checked": "2026-04-14T08:30:00Z",
                "check_count": 18
                }
                ],
                "total": 1,
                "message": "¡Estos dominios de tu lista de vigilancia ya están disponibles para registrar!"
                }

Campos de respuesta

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

Webhooks de alertas

Recibe alertas de monitorización como solicitudes POST JSON firmadas en tus propios endpoints HTTPS. Gestiona los endpoints con una clave de API o desde los ajustes de Monitor con la sesión iniciada.

Tipos de evento

MonitorEventos
Disponibilidad, caducidad y estado de la lista de seguimientodomain.available domain.expiring_30 domain.expiring_14 domain.expiring_7 domain.expiring_1 domain.status_change
Monitorización de cambios de dominiodomain.dns_changed domain.certificate_changed domain.registration_changed domain.hosting_changed domain.technology_changed domain.email_security_changed
Monitorización de marca (nuevos registros similares)brand.threat_detected
Suscripciones de alerta de la lista de seguimiento (certificados, precios, registros DNS, dominios similares)ssl.expiring ssl.expired ssl.changed price.dropped dns.changed typosquat.detected
Trabajos asíncronos (gratis, solo para trabajos creados con notify_webhook)job.completed job.failed job.cancelled
Evento de prueba (gratuito)webhook.test

Lee la guía de la API de alertas webhook

Precios

Cada alerta entregada a un endpoint con una respuesta 2xx cuesta 2 créditos. Los créditos se reservan justo antes del primer intento y se reembolsan si la entrega falla, se cancela o se elimina el endpoint. Los eventos de prueba son gratuitos. Si el saldo es insuficiente, la alerta se omite y no se cobra nada.

POST /v1/webhooks

Registra un endpoint HTTPS. La URL debe resolverse a una dirección pública. Omite events, o envía ["*"], para recibir todos los tipos de evento. El secreto de firma se devuelve únicamente en esta respuesta.

Solicitud de ejemplo

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

Respuesta de ejemplo

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

Campos de respuesta

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

Lista tus endpoints con su estado, los eventos suscritos, el recuento de fallos y los últimos cuatro caracteres del secreto, junto con los tipos de evento disponibles y la política de entrega.

Campos de respuesta

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

Respuesta de ejemplo

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

Pausa o activa un endpoint, cambia sus eventos o edita su descripción. Al activar un endpoint se restablece su recuento de fallos.

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

Campos de respuesta

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

Respuesta de ejemplo

{
  "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. Las entregas pendientes se cancelan y los créditos reservados se reembolsan.

Campos de respuesta

Campo Tipo
id string
deleted boolean

Respuesta de ejemplo

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

Envía un evento webhook.test gratuito y devuelve el resultado. Los eventos de prueba no se reintentan y no cuentan para la pausa automática.

Campos de respuesta

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

Respuesta de ejemplo

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

Sustituye el secreto de firma de un endpoint, incluso si está pausado. El nuevo secreto solo se devuelve en esta respuesta. Durante las siguientes 24 horas, cada entrega se firma con el secreto nuevo y con el anterior. Rotar es gratis.

Solicitud de ejemplo

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

Respuesta de ejemplo

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

Campos de respuesta

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

Parámetros de consulta

ParámetroTipoDescripción
limit integer Número de entregas a devolver, de 1 a 100. Por defecto, 50.

Lista las entregas recientes con su estado, intentos, respuesta HTTP, créditos cobrados y reembolsos. Los registros de entrega se conservan durante 30 días.

Campos de respuesta

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

Respuesta de ejemplo

{
  "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 de la solicitud

Cada alerta es una solicitud POST con un cuerpo JSON. El campo id permanece igual para un evento y se repite en X-DomScan-Event-Id, así que puedes ignorar los reintentos que ya hayas procesado.

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

Verificar las firmas

Calcula un HMAC-SHA256 del valor de X-DomScan-Timestamp, un punto y el cuerpo sin procesar de la solicitud con el secreto de tu endpoint. Compara el resultado con X-DomScan-Signature en tiempo constante y rechaza las solicitudes cuya marca de tiempo tenga más de 5 minutos.

El ejemplo de abajo comprueba todas las firmas del encabezado, por lo que sigue funcionando durante una rotación de secreto.

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

Rotar un secreto de firma

Durante el periodo de gracia de 24 horas posterior a una rotación, X-DomScan-Signature contiene dos firmas separadas por una coma, con el secreto nuevo primero, como se muestra abajo. Acepta una solicitud cuando cualquiera de las entradas coincida con un secreto de confianza, despliega el nuevo secreto y deja de confiar en el antiguo. Si vuelves a rotar durante el periodo de gracia, el secreto anterior más antiguo se retira de inmediato.

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

Reintentos y pausa automática

Devuelve cualquier estado 2xx en un máximo de 8 segundos para confirmar una alerta. Las redirecciones, otros códigos de estado y los tiempos de espera agotados se reintentan con retroceso exponencial (1, 4, 16, 64 y 256 minutos), hasta 6 intentos en total. Tras 15 intentos fallidos consecutivos, el endpoint se pausa; vuelve a activarlo con PATCH o desde los ajustes de Monitor.

Cuando un endpoint se pausa tras fallos repetidos, su propietario recibe un correo con el host del endpoint, el último error y un enlace a los ajustes de Monitor. Corrige el endpoint y vuelve a activarlo desde los ajustes de Monitor o con PATCH y enabled en true. Al activarlo, el contador de fallos vuelve a cero.

Suscripciones de alerta de la lista de seguimiento

Suscribe un elemento vigilado a las alertas que quieras. Cada suscripción vigila un hostname, un TLD o un dominio de marca, y tú eliges qué eventos recibir. Los eventos se envían a tus endpoints de webhook firmados y a tus alertas dentro de la aplicación.

TipoEventosCuándo se activa
sslssl.expiring ssl.expired ssl.changedssl.expiring cuando el certificado que sirve un hostname caduca dentro de ssl_expiring_days (30, 14, 7 o 1, por defecto 14), una vez por certificado y umbral. ssl.expired una vez por cada certificado caducado. ssl.changed cuando se ve una nueva huella de certificado en dos comprobaciones consecutivas; el payload indica si ha cambiado el emisor.
priceprice.droppedCuando el precio de registro o renovación de un TLD, en un registrador concreto o en el más barato, baja al menos drop_percent respecto al precio más alto desde la última alerta, o alcanza target_price o menos. Los precios proceden de la instantánea diaria de precios, y cada instantánea se evalúa una sola vez.
dnsdns.changedCuando un tipo de registro vigilado (A, AAAA, MX, NS, TXT o CNAME) de cualquier hostname devuelve la misma respuesta nueva en dos consultas confirmadas consecutivas.
typosquattyposquat.detectedCuando se registra un nuevo dominio similar al dominio de marca, confirmado mediante una consulta de registro autorizada. La primera pasada completa sobre los dominios similares fija la referencia y no genera alerta.

Solo la evidencia exacta activa un evento. Un handshake TLS fallido, una consulta DNS que falla o agota el tiempo, un precio ausente y una consulta bloqueada o limitada por tasa son desconocidos: no cambian nada y nunca generan alerta ni cargo. La primera comprobación confirmada de una suscripción fija su referencia.

Las comprobaciones se ejecutan automáticamente: certificados cada 12 horas, registros DNS cada hora (con una comprobación de confirmación 15 minutos después de ver un cambio por primera vez), precios cada 2 horas frente a la instantánea diaria, y dominios similares en lotes de 30 con una pasada completa cada día. Tras una comprobación desconocida, el siguiente intento llega antes.

Crear suscripciones y ejecutar comprobaciones es gratis. Cada alerta entregada a un endpoint de webhook con respuesta 2xx cuesta 2 créditos, como cualquier otra alerta de monitorización. Las entregas fallidas se reembolsan, y una cuenta puede tener hasta 100 suscripciones, 20 de ellas para dominios similares.

POST /v1/watchlist/alerts

Crea una suscripción. type decide qué campos se aplican: domain para ssl, dns y typosquat; tld, registrar, price_type, drop_percent y target_price para price. Los campos que no corresponden al tipo se rechazan.

Cuerpo de la solicitud

ParámetroTipoDescripción
typestringssl, price, dns o typosquat. Obligatorio.
domainstringHostname a vigilar para ssl y dns, o el dominio de marca para typosquat.
tldstringTLD a vigilar para price, por ejemplo com.
registrarstringID del registrador para price. Omítelo para vigilar el registrador más barato.
eventsstring[]Eventos a recibir. Por defecto, todos los eventos del tipo.
ssl_expiring_daysintegerDías antes de la caducidad para ssl.expiring: 30, 14, 7 o 1. Por defecto 14.
price_typestringregistration (por defecto) o renewal.
drop_percentnumberAlerta ante una bajada de al menos este porcentaje, de 1 a 95.
target_pricenumberAlerta cuando el precio en USD alcanza esta cantidad o menos. Una suscripción de precio necesita drop_percent, target_price o ambos.
record_typesstring[]Tipos de registro a vigilar para dns. Por defecto A, AAAA, MX, NS, TXT y CNAME.

Solicitud de ejemplo

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

Respuesta de ejemplo

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

Campos de respuesta

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

Lista tus suscripciones con su última evidencia confirmada y el estado de las comprobaciones, los eventos que admite cada tipo, el calendario de comprobaciones y el precio de la alerta.

Campos de respuesta

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

Respuesta de ejemplo

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

Obtiene una suscripción con su última evidencia confirmada y sus 20 eventos más recientes.

Campos de respuesta

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

Respuesta de ejemplo

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

Pausa o reanuda una suscripción con enabled, o cambia sus events, ssl_expiring_days, drop_percent, target_price o record_types. Un nuevo precio objetivo solo genera alerta ante un movimiento de precio posterior.

{ "enabled": false }

Campos de respuesta

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

Respuesta de ejemplo

{
  "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 suscripción. Los eventos que aún no ha enviado se descartan y nunca se cobran.

Campos de respuesta

Campo Tipo
id string
deleted boolean

Respuesta de ejemplo

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

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