Aller au contenu
NNextHop
API publique v1

Une API ouverte pour l'observatoire de la souveraineté.

Lecture seule, sans authentification, format JSON ou CSV. Spécification OpenAPI 3.0 disponible pour générer un client ou alimenter Postman.

Authentification

Aucune

Les endpoints v1 sont ouverts. Pas de clé API à fournir. Identification de l'appelant par IP source.

Limite de débit

60 requêtes / minute / IP

Au-delà, le serveur répond 429. Pour un volume supérieur, contactez contact@nexthop.fr.

Spécification

OpenAPI 3.0 YAML

Télécharger openapi.yaml ->

Endpoints

Six routes, lecture seule

Toutes les réponses JSON ont la forme { data, meta }. Les exports CSV/JSON utilisent un header Content-Disposition: attachment avec un nom de fichier daté.

GET/api/v1/providers

Liste de tous les fournisseurs, colonnes publiques, trié par nom.

Exemple curl

curl -s https://www.nexthop.fr/api/v1/providers

Réponse exemple

{
  "data": [
    {
      "id": 17,
      "name": "[A COMPLETER avec donnees reelles a la prochaine sync]",
      "slug": "[A COMPLETER]",
      "country_code": "[A COMPLETER]",
      "country": "[A COMPLETER]",
      "headquarters": "[A COMPLETER]",
      "employees": null,
      "founded_year": null,
      "ownership_holding": null,
      "website_url": "[A COMPLETER]",
      "sovereignty_score": 87,
      "sovereignty_status": "eu",
      "last_updated": "2026-05-23T08:12:00.000Z",
      "is_active": 1
    }
  ],
  "meta": {
    "count": 30,
    "generated_at": "2026-05-23T09:00:00.000Z"
  }
}
GET/api/v1/providers/{slug}

Détail d'un fournisseur, avec sous-objet criteria (6 critères de scoring).

Exemple curl

curl -s https://www.nexthop.fr/api/v1/providers/ovh

Réponse exemple

{
  "data": {
    "id": 17,
    "name": "[A COMPLETER]",
    "slug": "ovh",
    "country_code": "FR",
    "country": "France",
    "sovereignty_score": 87,
    "sovereignty_status": "eu",
    "criteria": {
      "juridique":      { "score": 20, "max": 20, "level": null, "label": null },
      "immunite":       { "score": 18, "max": 20, "level": null, "label": null },
      "technologie":    { "score": 12, "max": 15, "level": null, "label": null },
      "donnees":        { "score": 18, "max": 20, "level": null, "label": null },
      "certifications": { "score": 12, "max": 15, "level": null, "label": null },
      "ouverture":      { "score": 7,  "max": 10, "level": null, "label": null }
    },
    "last_updated": "2026-05-23T08:12:00.000Z"
  },
  "meta": { "generated_at": "2026-05-23T09:00:00.000Z" }
}
GET/api/v1/scores

Scores courants. Paramètres : ?sort=score|name &order=asc|desc.

Exemple curl

curl -s 'https://www.nexthop.fr/api/v1/scores?sort=score&order=desc'

Réponse exemple

{
  "data": [
    {
      "provider_id": 17,
      "provider_name": "[A COMPLETER]",
      "sovereignty_score": 87,
      "last_changed_at": "2026-05-20T14:32:11.000Z"
    }
  ],
  "meta": {
    "count": 30,
    "generated_at": "2026-05-23T09:00:00.000Z",
    "sort": "score",
    "order": "desc"
  }
}
GET/api/v1/export/providers.csv

Téléchargement CSV (UTF-8, header en première ligne).

Exemple curl

curl -OJ https://www.nexthop.fr/api/v1/export/providers.csv

Réponse exemple

id,name,slug,country_code,country,headquarters,employees,founded_year,ownership_holding,website_url,sovereignty_score,sovereignty_status,last_updated,is_active
17,[A COMPLETER],ovh,FR,France,Roubaix,,1999,,https://www.ovhcloud.com,87,eu,2026-05-23T08:12:00.000Z,1
GET/api/v1/export/providers.json

Téléchargement JSON (même payload que /providers, header Content-Disposition).

Exemple curl

curl -OJ https://www.nexthop.fr/api/v1/export/providers.json

Réponse exemple

(même schéma que /providers)
GET/api/v1/export/scores.csv

Téléchargement CSV scores actuels.

Exemple curl

curl -OJ https://www.nexthop.fr/api/v1/export/scores.csv

Réponse exemple

provider_id,provider_name,sovereignty_score,last_changed_at
17,[A COMPLETER],87,2026-05-20T14:32:11.000Z

Codes d'erreur

Format unifié

Une erreur réponds toujours avec le même schéma :

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Provider 'foo' not found"
  }
}
400 BAD_REQUESTParamètre invalide (slug vide, format de tri non reconnu).
404 NOT_FOUNDProvider slug introuvable.
429 RATE_LIMITEDPlus de 60 requêtes par minute depuis votre IP.
500 INTERNAL_ERRORErreur serveur. Notre monitoring est notifié automatiquement.

Webhooks

BETA

Notifications signées HMAC sur événements

Recevez une requête HTTP POST sur votre endpoint dès qu'un score évolue, qu'un fournisseur est ajouté ou qu'un snapshot est publié. Chaque livraison embarque une signature dans l'entête X-NextHop-Signature.

POST/api/v1/webhooks

Crée une souscription. Body JSON : { url, event_type, contact_email }. La réponse contient un secret 32-bytes (uniquement à la création).

Exemple curl

curl -X POST https://www.nexthop.fr/api/v1/webhooks \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-server.example.com/hook",
    "event_type": "score.changed",
    "contact_email": "you@example.com"
  }'
GET/api/v1/webhooks/events

Liste les types d'événements supportés avec un payload exemple pour chacun.

Exemple de payload (event score.changed)

{
  "event": "score.changed",
  "delivered_at": "2026-05-23T12:30:00.000Z",
  "data": {
    "provider_id": 17,
    "provider_slug": "ovh",
    "provider_name": "OVHcloud",
    "previous_score": 84,
    "new_score": 87,
    "changed_at": "2026-05-23T12:29:11.000Z"
  }
}

Vérification de signature

X-NextHop-Signature: sha256=<HMAC-SHA256 du body avec le secret>

# Node.js
const expected = 'sha256=' + crypto
  .createHmac('sha256', WEBHOOK_SECRET)
  .update(rawBody)
  .digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-nexthop-signature']))) {
  return res.status(401).end();
}

Beta : la livraison effective sera activée une fois le worker d'envoi en production. L'API de souscription est déjà disponible pour préparer l'intégration côté consommateur.