Clés d’API

Une clé permet à un script ou à un programme de chercher dans OwlyScan comme le fait votre IA.

Créer une clé

Dans l’application sur app.owlyscan.com, utilisez le lien Connecter votre IA de l’écran de recherche. Il ouvre la page Clés d’API et connexion IA. Créez-y votre clé.

  • Elle commence par owly_.
  • Elle s’affiche une seule fois, à sa création. Copiez-la à ce moment.
  • Gardez-la secrète : celui qui la détient cherche sur votre quota.
  • Vous pouvez la révoquer sur la même page.

Deux accès

Une clé Access fonctionne sur la route de recherche, sur les deux routes qui rouvrent une recherche passée, et sur le point d’accès MCP. Utilisez les routes depuis un script ou un programme, et le point d’accès MCP depuis une application d’IA : voir connecter votre IA pour l’URL et les deux outils.

Envoyer la clé

Envoyez la clé dans l’en-tête X-API-Key, ou comme jeton porteur dans Authorization. Une clé absente ou invalide reçoit un 401.

En-têtes
X-API-Key: owly_YOUR_KEY

# or, the same key as a bearer token:
Authorization: Bearer owly_YOUR_KEY

Toutes les autres routes demandent la session web de l’application. Une clé ne les ouvre pas.

Envoyez un POST avec un corps JSON à /api/search sur https://backend.owlyscan.com.

Recherche avec curl
curl -X POST https://backend.owlyscan.com/api/search \
  -H "X-API-Key: owly_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "acme.example"}'
  • query : votre recherche, écrite comme dans l’application. Syntaxe de recherche. Seuls les 20 premiers mots sont utilisés.
  • start_offset : facultatif, pour parcourir les résultats page par page. La valeur par défaut est 0. À partir de 500, la réponse est un 400 AccessLimit : voir le plafond ci-dessous.
  • max_hits : facultatif, la taille d’une page. Si vous l’omettez, vous recevez 200 résultats. Une page est réduite à ce qui reste sous le plafond, soit 500 moins start_offset, et jamais refusée. Les résultats sont regroupés : une page peut donc contenir moins de résultats que max_hits.

Le plafond de 500 résultats

  • Access affiche au plus 500 résultats d’une recherche. darknet.num_hits reste le vrai total.
  • Un start_offset de 500 ou plus répond 400 avec {"error":"AccessLimit","limit":500}, et rien n’est compté.

Ce qui revient

Des extraits seulement : ni document entier, ni adresse web, ni nom de fichier. Lisez la section darknet et ignorez les autres sections et les autres champs. Voici une réponse abrégée.

Une réponse abrégée
{
  "darknet": {
    "num_hits": 12,
    "hits": [
      {
        "level0": "ransomware",
        "date": "2025-03-14",
        "entry": {
          "visibility": "deidentified",
          "segments": [
            {"t": "text", "text": "Invoice sent to "},
            {"t": "label", "kind": "person", "n": 1},
            {"t": "text", "text": " at "},
            {"t": "label", "kind": "email", "n": 1},
            {"t": "text", "text": " for "},
            {"t": "term", "text": "acme.example"},
            {"t": "hidden", "w": 3}
          ]
        }
      }
    ],
    "entry": {
      "yours_on_page": 0,
      "likely_on_page": 0,
      "search_id": "0b7c2e4a-5f1d-4c3e-9a8b-1d2e3f4a5b6c",
      "shown_limit": 500,
      "preparing": 0
    }
  }
}
  • darknet.num_hits : le total dans l’index pour votre requête, pas le nombre de résultats de la page.
  • darknet.hits : la page. Chaque résultat a level0, le canal (par exemple ransomware), et date, au format AAAA-MM-JJ ou une chaîne vide.
  • entry.visibility indique ce que vous pouvez lire. yours est une correspondance de votre entreprise, lisible. deidentified est une correspondance d’une autre entreprise, dont les noms sont remplacés par des repères. fields est une correspondance d’une autre entreprise sans lien trouvé avec la vôtre : les noms de champs et vos termes de recherche, avec au plus un mot ordinaire de chaque côté, sont visibles ; toutes les autres valeurs sont masquées. hidden est masqué : seuls vos termes de recherche sont visibles. likely est une correspondance qui vous concerne probablement, sans certitude, ou qu’une recherche sur une marque liée à votre entreprise trouve : les noms d’organisations, de marques et de domaines sont en texte, tout autre nom ou numéro reste une étiquette, et les mots de passe et les empreintes sont des segments secret. Traitez toute valeur que vous ne connaissez pas comme hidden.
  • entry.segments est l’extrait en morceaux. Mettez-les bout à bout pour le reconstituer : text est du texte ordinaire, term est l’un de vos termes de recherche, label est une personne, une adresse e-mail ou un autre élément masqué, numéroté dans la page (kind et n), et hidden est un passage masqué (w n’est qu’une largeur d’affichage).
  • secret est un mot de passe ou une empreinte masqués, dans vos propres enregistrements. Un mot de passe a prefix, au plus ses deux premiers caractères (une chaîne vide quand aucun n’est montré), et length. Une empreinte a hash, son type comme MD5 ou null s’il est inconnu, et length, et pas de prefix.
  • Traitez tout type de segment que vous ne connaissez pas comme hidden.
  • darknet.entry.yours_on_page : facultatif, le nombre de correspondances de votre entreprise dans cette page.
  • darknet.entry.likely_on_page : le nombre de résultats likely sur cette page, 0 s’il n’y en a aucun.
  • darknet.entry.search_id : la référence de cette recherche, une chaîne. Elle sert à la rouvrir gratuitement : voir plus bas.
  • darknet.entry.shown_limit : le nombre de résultats qu’Access peut afficher pour une recherche, 500.
  • darknet.entry.preparing : le nombre de résultats de cette page encore en préparation.
  • entry.hidden : présent sur un résultat dont l’extrait n’est pas affiché. preparing signifie que l’extrait dépersonnalisé est en préparation. restricted signifie qu’il n’est pas affiché dans Access, et que cela ne changera pas.
  • Chaque résultat a aussi id et text : ignorez-les.

Résultats en préparation

Tant que darknet.entry.preparing est supérieur à 0, redemandez la même page par /page, qui est gratuit : voir plus bas. N’interrogez jamais /api/search pour cela. Toutes les 5 secondes suffisent. Arrêtez quand preparing atteint 0, ou après environ 2 minutes sans changement.

Vos propres enregistrements sont montrés tels quels, les autres avec les noms masqués, comme dans l’application. Dans vos enregistrements, les mots de passe et les empreintes (hash) sont masqués : on n’en voit que la longueur et au plus les deux premiers caractères. Confidentialité et données.

Quota

Une clé partage le compteur de la semaine avec l’application et votre IA. La même requête dans les 20 minutes qui suivent sa première recherche compte pour une seule de vos 100 recherches par semaine, quel que soit start_offset, et cette recherche est partagée avec l’application et votre IA. Passé ce délai de 20 minutes, la même requête compte de nouveau. Rouvrir une recherche passée ne compte jamais. Limites et quota.

Rouvrir une recherche passée

Deux routes rouvrent les recherches que vous avez faites au cours des 90 derniers jours. Aucune ne compte comme une recherche.

  • GET /api/entry/searches liste vos propres recherches, les plus récentes d’abord, au plus 100, aucune de plus de 90 jours, sans pagination. La réponse est {"searches":[{"id","query","created_at","total","person_query"}],"retention_days":90}.
  • POST /api/entry/searches/SEARCH_ID/page en rouvre une, avec l’id de la liste ou de darknet.entry.search_id. Le corps est facultatif : start_offset (0 par défaut) et max_hits (50 par défaut), avec le même plafond de 500.
Rouvrir une recherche avec curl
curl -X POST https://backend.owlyscan.com/api/entry/searches/0b7c2e4a-5f1d-4c3e-9a8b-1d2e3f4a5b6c/page \
  -H "X-API-Key: owly_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"start_offset": 0, "max_hits": 50}'

La réponse a la même forme qu’une réponse de recherche, plus darknet.entry.searched_at, au format ISO, en UTC. Les résultats sont ceux de cet instant : rien de ce qui a été indexé après n’apparaît. Pour voir les enregistrements plus récents, relancez la recherche, qui compte une fois les 20 minutes écoulées.

Erreurs

  • 401 : la clé est absente ou invalide.
  • 400 : la requête filtre sur un champ autre que le texte, la date ou level0. Cela ne coûte rien.
  • 400 AccessLimit avec limit : start_offset vaut 500 ou plus. Rien n’est compté.
  • 402 : l’abonnement n’est pas actif.
  • 404 SearchNotFound, sur /page : la recherche est inconnue, n’est pas la vôtre ou date de plus de 90 jours.
  • 429 avec resets_at : la limite de la semaine est atteinte. La réponse donne resets_at (UTC), used et limit, et un en-tête Retry-After en secondes.
  • 429 sans resets_at : trop de requêtes en peu de temps, sur n’importe quelle route. Patientez un instant puis réessayez.
  • 503 : temporaire. Réessayez après quelques secondes.

Applications d’IA connectées

La même page liste les applications d’IA que vous avez connectées, comme Claude, sous Applications d’IA connectées. Déconnecter est effectif immédiatement.