> For the complete documentation index see https://domscan.net/llms.txt. Markdown versions of every docs page are available by appending .md to the page URL.

Source: https://domscan.net/fr/docs/response-format

# Format de réponse

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

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

```bash
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.

```bash
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ètre | Endpoints | Équivaut à |
| --- | --- | --- |
| `prefer_cache` | `/v1/status`, `/v1/subdomains` | `max_age=2592000` |
| `skip_cache` | `/v1/status`, `/v1/tech`, `/v1/categorize`, `/v1/identity-assets`, `/v1/identity-resolution`, `/v1/url-intelligence`, `/v1/agent-readiness`, `/v1/robots` | `max_age=0` |
| `cache_skip` | `/v1/status` | `max_age=0` |
| `cache-skip` | `/v1/status` | `max_age=0` |
| `options.prefer_cache (body)` | `/v1/status/bulk` | `max_age=2592000` |
| `prefer_cache (body)` | `/v1/status/bulk` | `max_age=2592000` |
| `options.skip_cache (body)` | `/v1/status/bulk` | `max_age=0` |
| `options.cache_skip (body)` | `/v1/status/bulk` | `max_age=0` |
| `options.cache-skip (body)` | `/v1/status/bulk` | `max_age=0` |
| `refresh` | `/v1/ssl/deep-scan` | `max_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`.

| Endpoint | Taille de page par défaut | Limite maximale |
| --- | --- | --- |
| `GET /v1/whois/history` | 50 | 100 |
| `GET /v1/dns/history` | 100 | 1000 |
| `GET /v1/subdomains` | 500 | 2000 |
| `GET /v1/certificates` | 100 | 1000 |
| `GET /v1/watchlist` | Liste complète | 100 |
| `GET /v1/watchlist/expiring` | Liste complète | 100 |
| `GET /v1/watchlist/available` | Liste complète | 100 |
| `GET /v1/brand-monitor` | Liste complète | 100 |
| `GET /v1/email/blacklist` | 1000 | 10000 |

#### Exemple

```bash
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.

```json
{
  "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é.
