Format de réponse

Toutes les réponses sont au format JSON. Chaque résultat de domaine contient ces champs communs :

  • domain - Nom de domaine complet
  • available - Statut de disponibilité booléen
  • source - "rdap" ou "cache"
  • checked_at - Horodatage ISO 8601
  • error - Présent si une erreur s'est produite

Métadonnées de réponse

Chaque réponse de l’API inclut un ID de requête et une valeur de fraîcheur. Lorsqu’ils sont disponibles, les en-têtes de réponse indiquent également les crédits demandés, débités, remboursés et restants, ainsi que votre offre de limite de débit, la limite, la capacité restante et la politique. Une valeur de fraîcheur unknown signifie que la fraîcheur n’a pas pu être établie pour cette réponse. Cela ne signifie pas que les données sont à jour.

Sélection des champs et réponses compactes

Ajoutez fields ou compact à la query string de n'importe quelle requête GET ou POST pour recevoir une réponse JSON plus légère. Les deux sont facultatifs. Pour les requêtes POST, ils se placent dans la query string, pas dans le corps. Aucun des deux ne modifie le coût en crédits.

Sélectionner des champs

fields accepte des chemins à points séparés par des virgules, comme fields=domain,classification.status,records.data. Lorsqu'un chemin traverse une liste, il s'applique à chaque élément. Les éléments conservent leur position, et un élément sans aucun champ sélectionné devient {}. Une valeur nulle le long d'un chemin est conservée telle quelle.

Envoyez jusqu'à 50 chemins, chacun comportant jusqu'à 6 segments de 1 à 64 lettres, chiffres ou tirets bas. Toute autre valeur renvoie 400 INVALID_PARAMETER avant l'exécution de la requête, donc rien n'est facturé.

Les chemins sans correspondance dans la réponse sont omis et listés dans l'en-tête de réponse X-Fields-Ignored, jusqu'à 20 chemins.

Réponses compactes

compact=true supprime uniquement les éléments suivants, et seulement au niveau racine de la réponse :

  • Dans l'objet meta : served_by et les clés de durée duration_ms, query_time_ms, total_ms, total_time_ms, latency_ms, generation_ms et check_duration_ms. L'objet meta lui-même est supprimé lorsqu'il ne contient plus rien d'autre.
  • warnings, caveats, notes et errors lorsque ce sont des listes vides.
  • request_id lorsqu'il reprend l'en-tête X-Request-Id.

Les champs de données, classification, les objets imbriqués et les éléments de liste ne sont jamais supprimés. Lorsque les deux paramètres sont envoyés, compact s'applique en premier et fields ensuite.

Seules les réponses JSON réussies sont remodelées. Les réponses d'erreur, les réponses CSV, texte et en streaming, ainsi que les estimations dry_run sont renvoyées telles quelles. Les réponses remodelées sont envoyées sans indentation.

Avec une Idempotency-Key, fields et compact font partie de la requête. Une nouvelle tentative avec les mêmes valeurs renvoie la réponse remodelée enregistrée. Réutiliser la clé avec des valeurs différentes renvoie 422 IDEMPOTENCY_KEY_REUSED.

Les outils MCP acceptent les mêmes arguments facultatifs fields et compact. Les chemins sans correspondance sont listés dans _meta.fields_ignored du résultat de l'outil.

Exemple

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/dns?domain=google.com&type=TXT&fields=domain,status,records.data,records.ttl,owner&compact=true"

X-Fields-Ignored: owner

{
  "domain": "google.com",
  "records": [
    {
      "data": "v=spf1 include:_spf.google.com ~all",
      "ttl": 300
    },
    {
      "data": "google-site-verification=abc123",
      "ttl": 300
    }
  ],
  "status": "success"
}

Clés snake_case (naming)

La plupart des clés de réponse sont déjà en snake_case, mais quelques endpoints renvoient certaines clés en camelCase, comme registrarName dans les résultats de prix, tldTier dans les facteurs de valorisation et eventDate dans les événements RDAP. Ajoutez naming=snake à la chaîne de requête, ou envoyez l'en-tête DomScan-Naming: snake, pour recevoir toutes ces clés en snake_case. Sans cela, les réponses conservent leurs clés actuelles.

Une clé ne change que si elle commence par une lettre minuscule, ne contient que des lettres et des chiffres et comporte au moins une majuscule. Chaque nouveau mot reçoit un tiret bas et la clé passe en minuscules. Les acronymes restent groupés, y compris IPv4 et les pluriels comme IPs : registrarName devient registrar_name, secureDNS devient secure_dns, ipv4Address devient ipv4_address et nameserverIPs devient nameserver_ips.

Les clés qui sont des données et non des noms de champ conservent leur orthographe exacte, par exemple les types d'enregistrement DNS comme A et MX, les notes comme A+, les noms de domaine, les noms d'en-têtes et les noms de technologies. Les valeurs ne sont jamais modifiées, et les objets et listes imbriqués sont convertis à tous les niveaux.

Si un objet possède déjà le nom en snake_case, par exemple à la fois fooBar et foo_bar, foo_bar garde sa valeur et fooBar garde son nom d'origine, de sorte que rien n'est perdu. L'ordre des clés ne change pas.

Le paramètre de requête l'emporte sur l'en-tête, donc naming=default désactive l'activation par en-tête pour une seule requête. Les valeurs acceptées sont snake et default. Toute autre valeur renvoie 400 INVALID_PARAMETER avant l'exécution de la requête, donc rien n'est facturé. Les réponses incluent Vary: DomScan-Naming.

naming s'exécute avant compact et fields : écrivez donc les chemins de fields en snake_case, par exemple fields=factors.tld_tier. Les réponses d'erreur sont déjà en snake_case et ne changent jamais, et le coût en crédits reste le même.

Avec une Idempotency-Key, le choix de nommage fait partie de la requête, qu'il provienne du paramètre ou de l'en-tête, de sorte qu'une nouvelle tentative renvoie les mêmes clés.

Les outils MCP acceptent le même argument facultatif naming. Les appels MCP ne lisent pas l'en-tête.

curl -H "X-API-Key: $DOMSCAN_API_KEY" -H "DomScan-Naming: snake" "https://domscan.net/v1/value?domain=example.com&fields=domain,factors.tld_tier,factors.has_hyphens"

{
  "domain": "example.com",
  "factors": {
    "tld_tier": "premium",
    "has_hyphens": false
  }
}

Contrôle de fraîcheur (max_age)

Les endpoints qui peuvent répondre à partir de données vérifiées récemment acceptent max_age, un nombre entier de secondes de 0 à 2592000 (30 jours). Les données plus anciennes que max_age sont revérifiées avant d'être renvoyées, et max_age=0 vérifie toujours à nouveau. Sans max_age, chaque endpoint conserve son comportement habituel.

Chaque réponse réussie de ces endpoints inclut un cache_age_s de premier niveau : l'âge en secondes des données utilisées, ou 0 si elles ont été vérifiées à nouveau. La même valeur est envoyée dans l'en-tête de réponse X-Cache-Age. Lorsqu'une réponse contient plusieurs éléments, comme une vérification de disponibilité de plusieurs domaines, il s'agit de l'âge de l'élément le plus ancien, et les éléments gardent leur propre cache_age_s lorsqu'ils en avaient déjà un.

max_age ne modifie jamais la façon dont un résultat est classé. Un résultat qui n'a pas pu être confirmé reste unknown quelle que soit sa fraîcheur, et des données récentes ne sont jamais présentées comme présentes ou absentes sauf si la vérification d'origine l'a confirmé.

max_age ne modifie pas le coût d'une requête. Une vérification récente et une réponse issue de données récentes coûtent le même nombre de crédits.

Sur /v1/status et /v1/status/bulk, les vérifications forcées (max_age=0) sont limitées par client afin de protéger les registres. Au-delà de cette limite, la requête reçoit une réponse comme si max_age n'avait pas été envoyé, et cache_age_s indique l'âge de ce que vous avez reçu. Un max_age qui n'est pas un nombre entier de 0 à 2592000 renvoie 400 INVALID_PARAMETER avant l'exécution de la requête, donc rien n'est facturé.

Endpoints qui acceptent max_age : GET /v1/status, POST /v1/status/bulk, GET /v1/subdomains, GET /v1/certificates, GET /v1/tech, GET /v1/categorize, GET /v1/identity-assets, GET /v1/identity-resolution, GET /v1/url-intelligence, GET /v1/agent-readiness, GET /v1/robots, GET /v1/ssl/deep-scan

Anciens paramètres de cache

Ces paramètres continuent de fonctionner et sont désormais des alias obsolètes de max_age. Si vous envoyez aussi max_age, c'est max_age qui l'emporte.

ParamètreEndpointsÉquivaut à
prefer_cache/v1/status, /v1/subdomainsmax_age=2592000
skip_cache/v1/status, /v1/tech, /v1/categorize, /v1/identity-assets, /v1/identity-resolution, /v1/url-intelligence, /v1/agent-readiness, /v1/robotsmax_age=0
cache_skip/v1/statusmax_age=0
cache-skip/v1/statusmax_age=0
options.prefer_cache (body)/v1/status/bulkmax_age=2592000
prefer_cache (body)/v1/status/bulkmax_age=2592000
options.skip_cache (body)/v1/status/bulkmax_age=0
options.cache_skip (body)/v1/status/bulkmax_age=0
options.cache-skip (body)/v1/status/bulkmax_age=0
refresh/v1/ssl/deep-scanmax_age=0

Sur /v1/subdomains, prefer_cache conserve aussi son comportement cache seul : lorsque rien n'est encore stocké, la requête renvoie 202 sans facturation et lance la recherche en arrière-plan.

Les outils MCP de ces endpoints acceptent le même argument facultatif max_age, et leurs résultats incluent cache_age_s.

Pagination (limit et cursor)

Les endpoints qui renvoient de longues listes acceptent limit et cursor, et chaque réponse inclut has_more et next_cursor. Pour obtenir la page suivante, répétez la requête avec cursor défini sur next_cursor. Sur la dernière page, has_more vaut false et next_cursor vaut null.

Sans limit, chaque endpoint renvoie le même nombre d'éléments qu'avant, donc les requêtes existantes ne changent pas. Vous pouvez modifier limit d'une page à l'autre.

Les curseurs sont opaques et signés. Un curseur ne fonctionne que pour le compte qui l'a reçu et pour la même requête, par exemple le même domaine et les mêmes filtres. Un curseur modifié, appartenant à un autre compte ou envoyé avec d'autres filtres renvoie 400 INVALID_CURSOR.

Les pages suivent un ordre stable : les éléments ajoutés ou supprimés entre deux requêtes ne sont ni répétés ni ignorés. Sur les endpoints d'historique, les champs de synthèse décrivent les éléments de la page courante.

Chaque page est une requête normale et coûte les crédits habituels de l'endpoint, exactement comme une requête avec limit auparavant. Les endpoints gratuits restent gratuits.

Les anciens paramètres continuent de fonctionner : offset sur /v1/email/blacklist, et le pagination.next_cursor numérique sur /v1/certificates.

EndpointTaille de page par défautLimite maximale
GET /v1/whois/history50100
GET /v1/dns/history1001000
GET /v1/subdomains5002000
GET /v1/certificates1001000
GET /v1/watchlistListe complète100
GET /v1/watchlist/expiringListe complète100
GET /v1/watchlist/availableListe complète100
GET /v1/brand-monitorListe complète100
GET /v1/email/blacklist100010000

Exemple

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/whois/history?domain=example.com&limit=20"

{
  "domain": "example.com",
  "snapshots": [
    "..."
  ],
  "has_more": true,
  "next_cursor": "eyJvIjoi..."
}

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/whois/history?domain=example.com&limit=20&cursor=eyJvIjoi..."

Statut de classification

Les endpoints qui indiquent si quelque chose existe (enregistrement de domaine, identifiants de réseaux sociaux, enregistrements DNS et d'authentification des e-mails, security.txt, robots.txt, sitemaps, en-têtes de sécurité, parking, enregistrements typosquat et certificats SSL) ajoutent un objet classification à côté de leurs champs existants. Les champs existants conservent leur nom et leur sens.

  • status - present, absent ou unknown. Present et absent ne sont renvoyés que lorsque la vérification a produit une preuve exacte et fiable.
  • reason - Renvoyé uniquement lorsque le statut est unknown. Explique pourquoi aucune réponse définitive n'a été possible.
  • evidence - L'origine de la réponse : source, method, observed_at et un detail facultatif tel que http_404 ou nxdomain.
  • checked_at - Le moment où DomScan a produit la classification. Pour les résultats en cache, evidence.observed_at est antérieur.

Motifs de unknown

  • blocked - La cible a refusé l'accès, par exemple avec HTTP 401, 403 ou un défi anti-bot.
  • rate_limited - La cible ou le registre nous a demandé de ralentir, par exemple avec HTTP 429.
  • timeout - La vérification ne s'est pas terminée dans le délai imparti.
  • ambiguous - Une réponse est arrivée mais elle ne prouvait ni la présence ni l'absence, par exemple un code de statut inattendu ou un enregistrement mal formé.
  • upstream_error - La source de données a échoué, par exemple une panne du serveur DNS ou une réponse HTTP 5xx.
  • unsupported - Cette vérification n'est pas disponible pour cette entrée, par exemple un TLD non pris en charge ou une plateforme sans vérificateur fiable.
{
  "classification": {
    "status": "unknown",
    "reason": "rate_limited",
    "evidence": {
      "source": "rdap",
      "method": "rdap_lookup",
      "observed_at": "2026-10-10T09:30:00.000Z",
      "detail": "http_429"
    },
    "checked_at": "2026-10-10T09:30:00.000Z"
  }
}
Une vérification bloquée, limitée, expirée ou échouée n'est jamais signalée comme absent. Considérez unknown comme « réessayez plus tard » et non comme « n'existe pas », et ne prenez jamais une absence pour la preuve qu'un nom peut être réclamé.

Scores et notes avec des vérifications inconnues

Les scores ne comptent jamais une vérification inconnue comme manquante. Le score de sécurité DNS et la note d'authentification des e-mails laissent de côté les vérifications inconnues, les signalent dans checks_unknown et définissent score_confidence sur partial. Lorsque toutes les vérifications sont inconnues, le score et la note valent null. La note et le score SSL valent null avec grade_reason défini sur certificate_not_retrieved lorsqu'aucun certificat n'a pu être lu, et le score de réputation signale un parking inconnu par null au lieu de non parqué.