Documentation API

Une ressource en entrée, un signal structuré en sortie.

NicheObserver accepte un domaine, une hostname, une origin ou une URL HTTP(S), puis renvoie un snapshot CrUX mensuel avec le périmètre de la ressource, le Domain reach ajusté, le reach direct de la meilleure origin, l’historique depuis octobre 2022 et les parts d’audience estimées par pays.

Le contrat fait foi. Le contrat lisible par machine est décrit dans l’OpenAPI et la documentation API. Cette page explique la sémantique nécessaire à une intégration sûre. Une clé bearer doit rester côté serveur ; ne l’embarquez jamais dans du code navigateur.
Une API gratuite pour vos outils. Utilisez nos scores gratuitement dans votre outil public en mentionnant NicheObserver à côté des scores. Le lien vers notre site reste facultatif. Exemple : Source: NicheObserver Reach. Voir les conditions d’utilisation.

01 · Démarrage

Interroger une ressource

La route canonique est GET /v1/domain?resource=…. L’authentification utilise Authorization: Bearer. La ressource est normalisée par le data plane Rust et sa Public Suffix List embarquée ; Laravel vérifie la forme et le quota, mais n’applique pas un second parseur.

curl --get 'https://api.nicheobserver.com/v1/domain' \
  --data-urlencode 'resource=https://www.example.co.uk/articles?id=42#intro' \
  -H 'Authorization: Bearer ro_live_<public_id>_<secret>'

Une ressource valide absente du snapshot courant produit une réponse métier avec found: false. Elle arrive en HTTP 404 avec le corps complet, pas un objet d’erreur : un client qui traite tout 404 comme un échec jettera la réponse la plus fréquente lors du scoring de listes froides. Ce n’est ni une entrée mal formée, qui renvoie 400 avec une clé error, ni une panne upstream. Cela consomme une unité.

02 · Ressources

Domaine, hostname, origin ou URL

Envoyez la ressource dont vous disposez. NicheObserver calcule le domaine enregistrable et expose la résolution effectuée :

EntréePérimètreCe qui est interrogé
example.comdomainLe domaine enregistré et ses origins observées.
www.example.co.ukdomainLe domaine enregistrable example.co.uk.
https://app.example.comoriginL’origin exacte scheme + host + port, avec son domaine parent.
https://example.com/path?q=1originL’origin ; chemin, query et fragment ne changent pas l’identité CrUX.

Les credentials, adresses IP, schémas non HTTP(S) et suffixes publics seuls sont refusés. Les IDN sont convertis vers la forme normalisée rendue dans lookup. Un lookup domaine expose la best_origin et jusqu’à dix origins ; un lookup origin filtre la liste sur l’origin demandée tout en conservant le contexte du domaine.

03 · Batch

Jusqu’à 1 000 ressources par requête

Utilisez POST /v1/domains:lookup avec la propriété publique resources. Chaque entrée coûte un token de débit et, sur les plans plafonnés, un lookup quotidien, y compris les doublons et les chaînes que Rust classera ensuite comme invalides. Le batch entier est refusé si le débit pondéré ou le quota plafonné restant ne suffit pas ; il n’y a pas d’admission partielle.

curl -X POST 'https://api.nicheobserver.com/v1/domains:lookup' \
  -H 'Authorization: Bearer ro_live_<public_id>_<secret>' \
  -H 'Content-Type: application/json' \
  -d '{"resources":["example.com","https://app.example.com/login","www.example.co.uk"]}'

Une réponse 200 correspond à un batch traité et conserve les statuts par entrée : found, not_found, invalid et duplicate. Chaque résultat garde les champs du lookup, dont snapshot_month, reach_score, adjusted_reach_score, reach_score_model, popularity_rank_bucket, history, best_market et best_origin.

04 · Origins

Paginer volontairement la liste d’origins

Le lookup principal renvoie la meilleure origin et au plus dix origins. Pour la liste bornée complète, appelez GET /v1/domain/{resource}/origins. Une page contient par défaut 1 000 entrées et au maximum 5 000. Chaque page coûte une unité.

curl --get 'https://api.nicheobserver.com/v1/domain/example.com/origins' \
  --data-urlencode 'limit=1000' \
  --data-urlencode 'cursor=0' \
  -H 'Authorization: Bearer ro_live_<public_id>_<secret>'

Lisez next_cursor jusqu’à null. Le curseur est un offset dans un snapshot immuable, pas un identifiant permanent. Quand snapshot_month change, abandonnez-le et repartez de zéro. Une entrée origin ne renvoie que l’origin correspondante ; une entrée domaine renvoie la page des origins observées du domaine.

05 · Authentification

Créer, stocker et faire tourner les clés

Connectez-vous gratuitement via Google ou une adresse email vérifiée, puis créez une clé sur la page développeurs de forme ro_live_<public_id>_<secret>. Le secret possède au moins 256 bits d’entropie, n’est affiché qu’une fois et ne peut pas être récupéré. Stockez-le dans un gestionnaire de secrets côté serveur.

  1. Donnez une clé distincte à chaque intégration ; les clés partagent les limites du compte.
  2. Créez la clé de remplacement avant de révoquer l’ancienne.
  3. Déployez le remplacement et vérifiez un appel sans coût à /v1/stats.
  4. Révoquez l’ancienne clé. Une clé révoquée ne peut pas être réactivée.

Seul le header bearer est accepté. Les query strings, cookies, bundles navigateur et extensions ne doivent jamais contenir un secret. /v1/stats exige aussi une clé et ne consomme aucune unité de lookup.

06 · Limites

Quotas, headers et erreurs stables

Les limites sont partagées par toutes les clés du compte. Un batch de N ressources consomme N tokens de débit et, sur un plan plafonné, N lookups quotidiens. Free n’a aucun plafond journalier et autorise 5 analyses par seconde. Sur les plans plafonnés, le compteur journalier se réinitialise à 00:00:00 UTC sans report.

PlanLookups/jourLookups/sBatchClés
FreeIllimités51 0001
Builder100 000251 0002
Scale1 000 000501 0005
UnlimitedIllimités1001 0001 000

Les réponses authentifiées incluent les headers de tokens RateLimit-*, X-Quota-Policy et X-Request-Id. Les plans plafonnés reçoivent aussi X-Quota-Limit, X-Quota-Remaining et X-Quota-Reset ; Free et Unlimited omettent ces trois valeurs numériques. Programmez sur le code machine error, pas sur le message anglais.

HTTPCodeSignificationUnités
400invalid_jsonJSON ou forme de requête invalide.0
401invalid_api_keyClé absente, inconnue ou révoquée.0
413batch_too_largePlus de 1 000 entrées ou corps de plus de 512 Kio.0
429rate_limited / daily_quota_exceededRéessayer après le délai indiqué.0
503/504dependency_unavailable / upstream_timeoutPanne technique ; une erreur upstream observée est remboursée.0 net

Un lookup métier avec found:false coûte une unité. Il partage le statut 404 avec une route inexistante et s’en distingue par son corps : une réponse métier porte lookup, domain et found, jamais de clé error. Une requête invalide arrêtée avant admission ne coûte rien.

07 · Exemples clients

curl, PHP, JavaScript et Python

Ces exemples s’exécutent côté serveur. Placez NICHEOBSERVER_API_KEY dans l’environnement du processus ou un gestionnaire de secrets, jamais dans un fichier versionné.

PHP

$ch = curl_init('https://api.nicheobserver.com/v1/domain?resource=' . rawurlencode('example.com'));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NICHEOBSERVER_API_KEY')],
]);
$lookup = json_decode(curl_exec($ch), true, 512, JSON_THROW_ON_ERROR);
curl_close($ch);

JavaScript (Node.js)

const resource = encodeURIComponent('https://app.example.com/login');
const response = await fetch(`https://api.nicheobserver.com/v1/domain?resource=${resource}`, {
  headers: { Authorization: `Bearer ${process.env.NICHEOBSERVER_API_KEY}` },
});
if (!response.ok) throw new Error((await response.json()).error);
const lookup = await response.json();

Python

import os
import requests

response = requests.get(
    "https://api.nicheobserver.com/v1/domain",
    params={"resource": "example.com"},
    headers={"Authorization": f"Bearer {os.environ['NICHEOBSERVER_API_KEY']}"},
    timeout=10,
)
response.raise_for_status()
lookup = response.json()

Historique mensuel et parts par pays

Les recherches de domaines et les résultats par lot incluent l’historique depuis octobre 2022 : 47 mois jusqu’à août 2026. Chaque publication prolonge cet historique. Les points sont ordonnés du plus ancien au plus récent ; une observation absente est représentée par observed: false. Le site affiche 24 mois par défaut ; un compte gratuit déverrouille les mois précédents.

country_shares décrit le mois du snapshot. Chaque point de history[] contient aussi son propre country_shares. Ce sont des parts d’audience estimées pour le domaine résolu, y compris lorsque la recherche porte sur une origin ou une URL. Elles sont distinctes de best_market, qui indique le signal géographique principal.

"country_shares": {
  "observed_countries": 6,
  "other_basis_points": 3300,
  "countries": [
    { "country": "BR", "basis_points": 4800 },
    { "country": "IN", "basis_points": 1400 },
    { "country": "US", "basis_points": 500 }
  ]
}

Cet exemple représente le Brésil à 48 %, l’Inde à 14 %, les États-Unis à 5 % et les autres pays à 33 %. Divisez basis_points par 100 pour obtenir un pourcentage. Jusqu’à cinq pays sont renvoyés, par part décroissante. Leurs points de base et other_basis_points totalisent 10 000 : ne ramenez pas les seuls pays affichés à 100 %. observed_countries compte les pays observés dans CrUX avant cette limite d’affichage. Les codes suivent ISO 3166-1 alpha-2, avec l’exception CLDR XK.

country_shares: null signifie qu’aucune estimation exploitable n’est disponible pour ce mois, et non une part nulle. Le modèle de parts par pays v3 est calibré sur Similarweb à partir du profil CrUX de chaque mois. Les estimations ne sont pas des comptages de visites analytics ; les mois anciens ne reprennent pas la répartition actuelle.

Schéma JSON des parts par pays

08 · Méthode

Buckets, marchés et fraîcheur mensuelle

Les buckets CrUX sont des plages

adjusted_reach_score est le signal principal du Domain reach, de 0 à 100. reach_score est l’ancre directe de la meilleure origin, calculée depuis le bucket source ; popularity_rank_bucket conserve cette tranche discrète à côté. Le score ajusté agrège l’empreinte observée et peut dépasser l’ancre directe, mais reste sous 100 sauf lorsque le score direct vaut 100. Aucun de ces champs ne donne une position exacte ni un nombre de visites. Un score de 0 signifie que la ressource n’a pas été observée ce mois-là.

Le marché principal est une classification

best_market est une classification CrUX prudente, distincte du bucket. Le hint public contient seulement le pays, la base et la confiance. Il ne distribue pas l’activité du domaine par pays ; une absence signifie non observé ou non résolu, et non une conclusion sur la ressource.

Fraîcheur

snapshot_month est le mois YYYYMM du snapshot immuable chargé. L’artefact courant représente le dernier mois et l’historique remonte à octobre 2022. Un point observed:false signifie qu’il n’existe pas d’enregistrement pour ce mois ; ce n’est ni une erreur ni une affirmation d’inactivité.

Les publications Astro et Rust sont préparées avec des mois cohérents. Affichez le mois d’observation avec un résultat stocké et recommencez la pagination origins lorsque le mois du snapshot change.

08 · Glossaire

Des termes stables

CrUX / Chrome UX Report
Dataset public Google sur l’expérience de vrais utilisateurs Chrome. Ce n’est pas un recensement universel du web.
Domaine enregistré
Domaine enregistrable calculé avec la Public Suffix List, par exemple example.co.uk.
Hostname
Hôte DNS tel que www.example.com, éventuellement rattaché à son domaine enregistrable.
Origin
Ensemble scheme + host + port, par exemple https://app.example.com.
Bucket
Plage ou étiquette discrète de la source. Un bucket n’est pas une position individuelle.
Marché principal
Classification pays prudente avec base et confiance explicites, pas une répartition d’activité.
Mois du snapshot
Mois YYYYMM représenté par l’artefact immuable chargé.
found, not_found, no_data
États de traitement. Une réponse réussie sans observation utile est distincte d’une entrée invalide ou d’une panne.

09 · Sources

Source publique, attribution et limites

La source est le Chrome UX Report de Google. Le guide BigQuery officiel documente les tables mensuelles, les origins et les datasets pays. La méthodologie détaille l’éligibilité, l’agrégation, le filtrage et le fuzzing. Le dataset BigQuery reste accessible directement à celles et ceux qui veulent interroger la donnée brute.

NicheObserver est une interface et une API indépendantes. Le produit n’est ni affilié, ni sponsorisé, ni approuvé par Google. « Chrome », « Google » et « Chrome UX Report » restent les marques de leurs propriétaires. Nous ne générons pas de fiche SEO indexable par domaine interrogé.

Statut juridique : brouillon pré-lancement. Les conditions/AUP et la confidentialité décrivent l’intention actuelle ; elles attendent les décisions sur l’entité, le paiement, le support et la rétention.