Développeurs · REST JSON

API Développeur Astrina

Une API REST JSON pour vos statistiques de trafic, avis, évaluations, intelligence téléphonique, 32 utilitaires exécutables et connexion sociale. Authentification par clé simple, généreux niveau gratuit.

20Sections de référence API
18réseaux sociaux
6réseaux publicitaires

Authentification & quota

Chaque requête nécessite votre clé API. Obtenez-en une sur votre Tableau de bord API. Passez-le dans un en-tête de requête — les clés ne sont jamais acceptées dans l'URL, donc elles ne peuvent pas fuir dans les journaux du serveur, les proxys ou les en-têtes Referer :

curl https://astrina.io/api/v1/rating?site=example.com \
     -H "X-Api-Key: ak_your_key_here"

# or:  Authorization: Bearer ak_your_key_here

Votre quota quotidien est inclus dans votre plan : Gratuit 100/jour, Pro 5 000/jour, Business 25 000/jour, Business Plus 100 000/jour — mettez à niveau votre plan pour une limite plus élevée. Chaque réponse reflète votre quota. Les erreurs renvoient un champ "erreur" avec le bon statut : 401 (mauvaise clé), 429 (quota), 400/422 (mauvais paramètres), 403/404 (pas le vôtre / non trouvé). Les réponses sont ouvertes CORS et noindex.

API sociale

Une API REST pour publier, planifier, mesurer et envoyer des messages sur chaque réseau que vous connectez — 18 réseaux sociaux et 6 réseaux publicitaires, un modèle d'authentification, une forme de requête.

Réseaux pris en charge (18): X (Twitter), Instagram, Facebook, Threads, LinkedIn, TikTok, YouTube, Pinterest, Reddit, Snapchat, Google Business, VK, Odnoklassniki, Telegram, WhatsApp, Discord, Mastodon, Bluesky. Réseaux publicitaires: Meta Ads, Google Ads, TikTok Ads, LinkedIn Ads, Pinterest Ads, X Ads.

Authentification par clé identique à tout ce qui précède (en-tête uniquement), limité à social. Connecter des canaux sur votre Tableau de bord social. La publication est asynchrone : /publish renvoie le post avec chaque cible en file d'attente ; le travailleur livre dans la minute et un webhook se déclenche lorsqu'il arrive.

GET/api/v1/social/channels Chaque réseau, ses capacités et ceux que vous avez connectés. Appelez ceci en premier.
GET/api/v1/social/accounts Les canaux que vous avez connectés — les ids /publish cibles.
POST/api/v1/social/publish Publiez ou planifiez un post sur un ou plusieurs canaux.
ParamDescription
textCorps du post (obligatoire sauf si un média est fourni)
channels"tous", ou une liste d'identifiants de canaux depuis /accounts
mediaTableau de {url,type,alt} (optionnel)
scheduled_atTemps ISO-8601 ; omettre ou passé = publier maintenant
idempotency_keyVotre identifiant pour le post — une nouvelle tentative avec la même clé renvoie le premier, jamais de double publication
overridesRemplacements de corps par canal, indexés par identifiant de canal
POST /api/v1/social/publish
Authorization: Bearer <your API key>
Content-Type: application/json

{ "text": "We just shipped 🚀", "channels": "all",
  "idempotency_key": "launch-42" }

{ "ok": true, "post": {
    "id": 1841, "status": "publishing", "text": "We just shipped 🚀",
    "targets": [
      { "channel_id": 12, "provider": "telegram", "status": "queued", "url": null },
      { "channel_id": 31, "provider": "mastodon", "status": "queued", "url": null } ] },
  "quota": { "used": 3, "limit": 25000 } }
GET/api/v1/social/post Un post et le résultat de livraison de chaque cible (?id=…), ou la liste récente.
GET/api/v1/social/analytics Abonnés, impressions, portée et engagement — une série de canaux ou un regroupement de comptes. Instantanés, jamais d'estimations.
GETPOST/api/v1/social/messages Lisez un fil de DM, ou envoyez un message direct sur un canal qui le supporte.
GET/api/v1/social/comments Commentaires capturés sur vos posts publiés.
GETPOST/api/v1/social/ads Listez et créez des campagnes publicitaires sur les six réseaux publicitaires.
GETPOSTDELETE/api/v1/social/webhooks Soyez informé lorsqu'un post est publié ou qu'un commentaire/DM/mention arrive.

Événements: post.published, post.partial, post.failed, comment.received, dm.received, mention.received. Un hook générique est signé avec X-Astrina-Signature: sha256=hmac(timestamp.body, secret).

Analytics

GET/api/v1/stats Analytics de trafic pour un site que vous possédez.
ParamDescription
siteIdentifiant de site ou domaine que vous possédez (obligatoire)
period24h · 7d (par défaut) · 30d · 90d
reportsummary (par défaut) · timeseries · pages · sources · countries · devices
limitLignes pour les rapports détaillés (1–100, par défaut 20)
GET /api/v1/stats?site=example.com&period=30d

{
  "site": "example.com", "site_id": 4, "period": "30d",
  "summary": {
    "visitors": 18204, "pageviews": 54881, "visits": 24310,
    "pages_per_visit": 2.26, "online_now": 7
  },
  "top_sources":   [{ "source": "google.com", "visitors": 9021 }, …],
  "top_countries": [{ "country": "US", "visitors": 7440 }, …],
  "quota": { "used": 12, "limit": 100 }
}

Conversions

POST/api/v1/conversion Enregistrez une conversion depuis votre serveur, afin que les revenus qui ne touchent jamais le navigateur soient toujours attribués.
ParamDescription
siteIdentifiant de site ou domaine que vous possédez (obligatoire)
kindlead · qualified · deal · sale · recurring · refund · churn
valueMontant, dans la devise ci-dessous. Négatif pour un remboursement.
currencyCode à trois lettres, USD par défaut
uidIdentifiant de visiteur du script de suivi. Optionnel — voir la note ci-dessous.
external_idVotre propre identifiant pour l'enregistrement, utilisé pour éviter le double comptage d'une nouvelle tentative
POST /api/v1/conversion
Authorization: Bearer <your API key>

site=example.com&kind=sale&value=249.00&currency=USD&uid=v_8f3c…&external_id=order-1042

{ "recorded": true, "id": 5512, "kind": "sale" }

Une conversion sans uid est enregistrée, pas rejetée : une vente conclue par téléphone est toujours un revenu. Elle compte dans les totaux et est rapportée comme non attribuée plutôt que d'être assignée à un canal auquel elle ne peut pas être retracée.

Minifier

POST/api/v1/minify Minifiez HTML, CSS ou JS et récupérez les octets compressés. S'exécute sur nos serveurs (pas de jetons IA) ; facturé par demande en fonction de la taille d'entrée.
ParamDescription
kindhtml · css · js — requis (via ?kind=, le nom de fichier téléchargé, ou Content-Type)
corpsLa source à minifier : le corps de la requête brute, un multipart file, ou JSON {"kind":"…","data":"…"}
POST /api/v1/minify?kind=css
X-Api-Key: ak_your_key_here

.button{ color: #ffffff; margin: 0 0 0 0; }

{ "kind":"css", "in_bytes":42, "out_bytes":24, "saved_pct":43,
  "hash":"be6ca66f…", "output":".button{color:#fff;margin:0}" }

Auth : en-tête uniquement (X-Api-Key ou Bearer), portée minify. CSS et JS sont minifiés en toute sécurité — l'espacement calc() et JS ASI sont préservés ; HTML réduit les espaces tout en gardant <pre>, <textarea>, <script>, <style> et JSON-LD intacts. Suivez l'utilisation et les clés sur votre Tableau de bord Minify.

Originalité &amp; détection AI

POST/api/v1/originality Commencez une vérification : unicité du texte, texte écrit par AI, unicité de l'image ou image générée par AI. Renvoie un identifiant d'exécution immédiatement — le travail se fait sur un travailleur.
ParamDescription
kindtext-unique · ai-text · image-unique · ai-image — requis
textle texte à vérifier (modules de texte)
urllisez le texte — ou récupérez l'image — à partir de cette adresse à la place
imagechamp de fichier multipart (modules d'image) ; ou image_base64
POST /api/v1/originality
X-Api-Key: ak_your_key_here
kind=ai-text&text=In+today%27s+rapidly+evolving+digital+landscape…

{ "ok":true, "run":1042, "kind":"ai-text", "status":"queued",
  "poll":"https://astrina.io/api/v1/originality?run=1042",
  "units_charged":5, "balance_charged_usd":0,
  "checks_used_today":7, "checks_per_day":500 }

Auth : en-tête uniquement (X-Api-Key ou Bearer), portée originality. Pro et supérieur. Une tâche coûte un nombre fixe de requêtes API de votre quota quotidien — 10 pour l'unicité du texte, 5 pour le texte AI, 5 pour l'unicité de l'image, 3 pour l'image AI — car une tâche représente une douzaine de requêtes d'index, une douzaine de téléchargements de pages ou quelques centaines d'évaluations de modèles. Au-delà de l'allocation quotidienne de vérifications de votre plan, une tâche coûte également un prix fixe de votre solde, et la réponse indique exactement ce qui a été facturé.

GET/api/v1/originality?run=<id> Interrogez une exécution. Pendant qu'elle fonctionne, vous obtenez l'étape dans laquelle elle se trouve ; lorsqu'elle se termine, vous obtenez le rapport complet.
GET /api/v1/originality?run=1042
X-Api-Key: ak_your_key_here

{ "ok":true, "run":1042, "kind":"ai-text", "status":"running",
  "progress":75, "stage":"model", "stage_label":"Scoring every sentence against a language model" }

{ "ok":true, "status":"done", "score":88.4, "verdict":"ai", "confidence":71,
  "report":{ "per_sentence":[…], "features":{…}, "notes":[…] } }

L'interrogation coûte 1 requête. Un passage d'unicité de texte se termine généralement en 15 à 40 secondes ; interrogez toutes les 2 à 3 secondes. Chaque rapport porte sa confiance et les preuves qui le sous-tendent : pages correspondantes avec des fragments cités, ou les mesures produites par chaque signal. La détection est probabiliste — l'API ne renvoie jamais un verdict sans les chiffres dont il provient.

POST/api/v1/originality La couche de dé-AI, même porte : kind=deai-text réécrit un brouillon pour qu'il ne soit plus lu comme écrit par une machine ; kind=deai-image re-code une image générée pour que ses pixels se comportent comme une photographie.
POST /api/v1/originality
X-Api-Key: ak_your_key_here
kind=deai-text&text=In+today%27s+rapidly+evolving+digital+landscape…

{ "ok":true, "run":1043, "kind":"deai-text", "status":"queued", "units_charged":15 }

GET /api/v1/originality?run=1043
{ "status":"done", "score":41.2,
  "report":{ "before":93.0, "after":41.2, "target":70, "reached_target":true,
             "changes":["4 stock transition(s) removed","1 sentence pair(s) joined for rhythm"],
             "paid_pass":true, "text":"…the rewritten text…" } }

15 requêtes API pour une réécriture de texte, 6 pour un recodage d'image — une réécriture peut utiliser un appel de modèle, et le prix le couvre. Chaque tâche obtient UN passage déterministe gratuit et au maximum UNE réécriture de modèle payante : si cela n'est pas suffisant, la réponse le dit au lieu de dépenser à nouveau. Une tâche d'image répond avec un lien de téléchargement (conservé pendant 72 heures). Le réécrivain effectue des modifications qu'un éditeur défendrait — transitions standard coupées, rythme varié, mots surutilisés remplacés — et re-mesure avec le même détecteur. Il n'ajoute pas d'erreurs et n'invente pas de faits. Le re-codeur d'images refuse les fichiers portant un manifeste C2PA signé plutôt que de les supprimer, et écrit un crédit honnête « illustration assistée par IA » dans ce qu'il produit.

GET/api/v1/originality Le catalogue : ce que chaque vérification coûte en requêtes API et en argent, et combien de votre allocation reste aujourd'hui.

Avis & évaluations

GET/api/v1/reviews Derniers avis + note agrégée pour tout sujet.
ParamDescription
typesite · phone · email · address · org · shop
keyLa valeur du sujet (domaine, numéro, email, …)
GET /api/v1/reviews?type=site&key=example.com

{ "type": "site", "subject": "example.com", "rating": 4.3, "count": 87,
  "reviews": [{ "author": "Jane", "rating": 5, "body": "…", "date": "2026-07-01" }, …],
  "url": "https://astrina.io/reviews/site/example.com/" }
GET/api/v1/rating Résumé compact des évaluations + distribution des étoiles + URLs intégrées.
ParamDescription
siteRaccourci pour un site web par domaine
type + keyOu tout sujet par type + clé
GET /api/v1/rating?site=example.com

{ "type": "site", "subject": "example.com", "rating": 4.3, "count": 87,
  "distribution": { "1": 3, "2": 4, "3": 9, "4": 26, "5": 45 },
  "reviews_url": "https://astrina.io/reviews/site/example.com/",
  "widget_url":  "https://astrina.io/widget.php?type=site&key=example.com",
  "badge_url":   "https://astrina.io/badge.php?s=4" }

Intelligence téléphonique

GET/api/v1/phone Opérateur, type de ligne et risque de spam communautaire pour un numéro.
ParamDescription
numberNuméro de téléphone au format international, par ex. +14155550123
GET /api/v1/phone?number=+14155550123

{ "number": "+14155550123", "country": "United States", "iso": "US",
  "operator": "…", "line_type": "mobile",
  "risk": { "score": 12, "verdict": "low", "confidence": 0.6, "reports": 3, … },
  "url": "https://astrina.io/reviews/phone/+14155550123/" }

Vérification de la liste noire et du spam

GET/api/v1/blacklist Vérifiez si un téléphone, un e-mail, un domaine ou un site est sur la liste noire de spam / arnaque.
ParamDescription
valueLe téléphone, l'e-mail, le domaine ou l'URL à vérifier (type détecté automatiquement).
typeOptionnel — forcer l'un de phone · email · domain
GET /api/v1/[email protected]

{ "value": "[email protected]", "listed": true,
  "categories": ["disposable"],
  "matches": [
    { "type": "email_domain", "match": "mailinator.com",
      "category": "disposable", "source": "disposable-email-domains",
      "confidence": 90, "added": "2026-07-12 15:46:00" } ],
  "quota": { "used": 7, "limit": 100000 } }

Vérification AML Crypto

GET/api/v1/aml Vérifiez une adresse de portefeuille crypto contre les listes de sanctions et d'intelligence sur les menaces — chaîne détectée automatiquement, score de risque inclus.
ParamDescription
addressL'adresse du portefeuille à vérifier. Les formats BTC, EVM (0x…), TRON, Solana, TON, LTC, DOGE, XRP, XMR et BCH sont reconnus ; toute autre chaîne est recherchée telle quelle.
formatOptionnel — définissez sur csv pour recevoir CSV au lieu de JSON.
GET /api/v1/aml?address=TPPR7e8hGC57dexrE2jy1f94wtuGyVP6Dp

{ "address": "TPPR7e8hGC57dexrE2jy1f94wtuGyVP6Dp",
  "chain": "tron", "listed": true, "risk": 100, "level": "sanctioned",
  "categories": ["sanctioned"],
  "matches": [
    { "category": "sanctioned", "source": "US OFAC SDN sanctions list",
      "jurisdiction": "US", "risk": 100, "confidence": 88, "added": "2026-08-10" } ],
  "quota": { "used": 1, "limit": 100 } }

En masse : POSTez un tableau "adresses" (jusqu'à 50) pour vérifier plusieurs en un seul appel — une unité de quota chacune.

POST /api/v1/aml
{ "addresses": ["0x…", "bc1…", "T…"] }

{ "results": [ { "address": "0x…", "listed": false, "risk": 0, … } ], "count": 3 }

Chaque réponse contient les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining. Documentation complète, modèle de risque et tableaux en direct : astrina.io/aml/

Vérification de fuite de mot de passe

GET/api/v1/pwned Vérifiez si un mot de passe est apparu dans une violation de données — en utilisant la k-anonymité, de sorte que le mot de passe ne quitte jamais le client.

Hachez le mot de passe avec SHA-1 dans votre application, puis envoyez uniquement les 5 premiers caractères hexadécimaux de ce hachage. L'API renvoie chaque suffixe de hachage compromis qui partage le préfixe ; vous comparez localement. Le mot de passe en clair n'est jamais transmis.

ParamDescription
prefix5 premiers caractères hexadécimaux du hachage SHA-1 (recommandé — k-anonymité). Renvoie les suffixes correspondants avec les comptes de violations.
hashAlternative : le SHA-1 complet de 40 hex. Pratique, mais le hachage quitte le client — préférez le préfixe lorsque c'est possible.
GET /api/v1/pwned?prefix=5BAA6

{ "mode": "range", "prefix": "5BAA6", "returned": 1978,
  "suffixes": [
    { "suffix": "1E4C9B93F3F0682250B6CF8331B7EE68FD8", "count": 52372427 }, ... ],
  "quota": { "used": 22, "limit": 100000 } }

# convenience mode — send the whole SHA-1, get a direct verdict:
GET /api/v1/pwned?hash=5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8

{ "mode": "hash", "found": true, "count": 52372427,
  "note": "This password appears in known breaches - do not use it.",
  "quota": { "used": 23, "limit": 100000 } }

Source de données : Have I Been Pwned (Mots de passe compromis). Le même modèle de k-anonymité alimente l'outil de navigateur gratuit à /password-check/.

Utilitaires

Exécutez nos utilitaires côté serveur synchrones via l'API — 31 des 141. Les utilitaires réservés au navigateur et les crawls/renders en file d'attente ne sont pas exposés. Chaque utilitaire prend la même forme et renvoie la même enveloppe ; les portes de plan et les limites d'exécution quotidiennes sont identiques à celles du site web.

GET /api/v1/tool                         # le catalogue
GET /api/v1/tool?name=<key>&value=<input>  # exécuter un (value2 pour les utilitaires à deux entrées)     -H "X-Api-Key: ak_your_key_here"
ParamDescription
nameLa clé de l'utilitaire (voir chaque bloc ci-dessous).
valueL'entrée principale — une URL, un domaine, des URL séparées par des virgules/nouvelles lignes, ou du texte.
value2La deuxième entrée, uniquement pour les utilitaires qui comparent deux choses.

Erreurs : 404 utilitaire inconnu · 400 non exécutable par l'API · 403 plan requis · 429 limite quotidienne atteinte · 422 mauvaise entrée. Chacune renvoie un champ "erreur".

🔍 SEO (18)
GET/api/v1/tool?name=site-audit 🔍 Technique, vitesse et sécurité en un seul passage.
GET /api/v1/tool?name=site-audit&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "site-audit",
    "ms": 807,
    "result": {
        "summary": [
            {
                "label": "Overall",
                "value": "93/100",
                "state": "ok"
            },
            {
                "label": "SEO",
                "value": "90/100",
                "state": "ok"
            },
            {
                "label": "Performance",
                "value": "90/100",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Area",
            "What failed",
            "What to do"
        ],
        "rows": [
            {
                "a": "SEO",
                "b": "Headings in logical order",
                "c": "Nest headings sequentially (H1→H2→H3) without skipping levels.",
                "state": "bad"
            },
            {
                "a": "SEO",
                "b": "All images have alt",
                "c": "Add descriptive alt to every <img> (alt=\"\" only for decorative).",
                "state": "bad"
            },
            {
                "a": "SEO",
                "b": "Form inputs have labels",
                "c": "Pair every input with a <label for> or an aria-label.",
                "state": "warn"
            },
            "…"
        ],
        "notes": []
    }
}
GET/api/v1/tool?name=serp-preview 👁️ Comment le snippet apparaît dans les résultats de recherche.
GET /api/v1/tool?name=serp-preview&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "serp-preview",
    "ms": 127,
    "result": {
        "summary": [
            {
                "label": "Title length",
                "value": "53 chars",
                "state": "ok"
            },
            {
                "label": "Description length",
                "value": "163 chars",
                "state": "warn"
            },
            {
                "label": "Title truncated",
                "value": "no",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Part",
            "Value"
        ],
        "rows": [
            {
                "a": "Headline shown",
                "b": "Every site you look after, in one dashboard — Astrina",
                "state": ""
            },
            {
                "a": "Breadcrumb shown",
                "b": "astrina.io",
                "state": ""
            },
            {
                "a": "Snippet shown",
                "b": "Real traffic, daily SEO checks and reviews for your sites and your clients’ sites. One …",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Google cuts on pixel width, not character count, and rewrites titles on roughly a third…"
        ]
    }
}
GET/api/v1/tool?name=og-preview 📣 La carte affichée lorsque votre lien est partagé.
GET /api/v1/tool?name=og-preview&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "og-preview",
    "ms": 499,
    "result": {
        "summary": [
            {
                "label": "og:title",
                "value": "set",
                "state": "ok"
            },
            {
                "label": "og:description",
                "value": "set",
                "state": "ok"
            },
            {
                "label": "og:image",
                "value": "set",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Field",
            "Value"
        ],
        "rows": [
            {
                "a": "Card title",
                "b": "Every site you look after, in one dashboard — Astrina",
                "state": ""
            },
            {
                "a": "Card description",
                "b": "Real traffic, daily SEO checks and reviews for your sites and your clients’ sites. One …",
                "state": ""
            },
            {
                "a": "Card image",
                "b": "https://astrina.io/og.php",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "Facebook, X and LinkedIn each cache what they scraped. After fixing tags, re-scrape in …"
        ]
    }
}
GET/api/v1/tool?name=schema-validator 🧬 Valide les données structurées JSON-LD.
GET /api/v1/tool?name=schema-validator&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "schema-validator",
    "ms": 75,
    "result": {
        "summary": [
            {
                "label": "JSON-LD blocks",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "Types found",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "Invalid blocks",
                "value": "0",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Where",
            "Type",
            "Verdict"
        ],
        "rows": [
            {
                "a": "block 1",
                "b": "Organization",
                "c": "required properties present",
                "state": "ok"
            },
            {
                "a": "block 2",
                "b": "WebSite",
                "c": "required properties present",
                "state": "ok"
            }
        ],
        "notes": [
            "Valid markup is not the same as an eligible rich result. Google also applies content po…"
        ]
    }
}
GET/api/v1/tool?name=meta-tags 🏷️ Titres, descriptions et balises og avec longueurs.
GET /api/v1/tool?name=meta-tags&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "meta-tags",
    "ms": 164,
    "result": {
        "summary": [
            {
                "label": "Title length",
                "value": "53",
                "state": "ok"
            },
            {
                "label": "Description length",
                "value": "163",
                "state": "warn"
            },
            {
                "label": "H1 count",
                "value": "1",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Tag",
            "Value",
            "Length",
            "…"
        ],
        "rows": [
            {
                "a": "title",
                "b": "Every site you look after, in one dashboard — Astrina",
                "c": "53",
                "d": "Good length.",
                "state": "ok"
            },
            {
                "a": "meta description",
                "b": "Real traffic, daily SEO checks and reviews for your sites and your clients’ sites. One …",
                "c": "163",
                "d": "Long — the snippet is cut around 160 characters.",
                "state": "warn"
            },
            {
                "a": "canonical",
                "b": "https://astrina.io/",
                "c": "19",
                "d": "Declared.",
                "state": "ok"
            },
            "…"
        ],
        "notes": []
    }
}
GET/api/v1/tool?name=keyword-density 📊 Densité et fréquence des mots sur la page.
GET /api/v1/tool?name=keyword-density&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "keyword-density",
    "ms": 93,
    "result": {
        "summary": [
            {
                "label": "Words",
                "value": "1093",
                "state": "ok"
            },
            {
                "label": "Unique words",
                "value": "503",
                "state": ""
            },
            {
                "label": "Vocabulary richness",
                "value": "46.0%",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Kind",
            "Term",
            "Count",
            "…"
        ],
        "rows": [
            {
                "a": "single word",
                "b": "one",
                "c": "20",
                "d": "1.83%",
                "e": "title, H1, description",
                "state": "ok"
            },
            {
                "a": "single word",
                "b": "reviews",
                "c": "17",
                "d": "1.56%",
                "e": "description",
                "state": "ok"
            },
            {
                "a": "single word",
                "b": "listed",
                "c": "15",
                "d": "1.37%",
                "e": "body only",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Density is a diagnostic, not a target. No search engine has a threshold to hit — this i…"
        ]
    }
}
GET/api/v1/tool?name=redirects ↪️ Suit les chaînes 301/302 étape par étape.
GET /api/v1/tool?name=redirects&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "redirects",
    "ms": 1753,
    "result": {
        "summary": [
            {
                "label": "Final status",
                "value": "200",
                "state": "ok"
            },
            {
                "label": "Redirects followed",
                "value": "0",
                "state": "ok"
            },
            {
                "label": "Ends at",
                "value": "https://astrina.io/",
                "state": ""
            },
            "…"
        ],
        "cols": [
            "Address",
            "Hop",
            "Status",
            "…"
        ],
        "rows": [
            {
                "a": "as entered",
                "b": "1",
                "c": "200",
                "d": "https://astrina.io/",
                "e": "— final destination —",
                "state": "ok"
            },
            {
                "a": "http://astrina.io/",
                "b": "1",
                "c": "200",
                "d": "http://astrina.io/",
                "e": "— final destination —",
                "state": "ok"
            },
            {
                "a": "https://astrina.io/",
                "b": "1",
                "c": "200",
                "d": "https://astrina.io/",
                "e": "— final destination —",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "The http, https, www and apex forms of this address do not all end at the same URL. Sea…",
            "The page contains JavaScript that changes location. A crawler may or may not follow it,…",
            "Every hop above was requested and its answer read; nothing in the chain is guessed from…"
        ]
    }
}
GET/api/v1/tool?name=sitemap 🗺️ Valide le sitemap XML et son index.
GET /api/v1/tool?name=sitemap&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "sitemap",
    "ms": 2646,
    "result": {
        "summary": [
            {
                "label": "Type",
                "value": "sitemap index",
                "state": "ok"
            },
            {
                "label": "URLs found",
                "value": "5408",
                "state": "ok"
            },
            {
                "label": "Unique URLs",
                "value": "5405",
                "state": "warn"
            },
            "…"
        ],
        "cols": [
            "Child sitemap",
            "Status",
            "URLs",
            "…"
        ],
        "rows": [
            {
                "a": "https://astrina.io/sitemap-core.xml",
                "b": "200",
                "c": "534",
                "d": "59.9 KB",
                "state": "ok"
            },
            {
                "a": "https://astrina.io/sitemap-blog.xml",
                "b": "200",
                "c": "42",
                "d": "5.2 KB",
                "state": "ok"
            },
            {
                "a": "https://astrina.io/sitemap-catalog.xml",
                "b": "200",
                "c": "61",
                "d": "6.9 KB",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "Started from the sitemap declared in robots.txt: https://astrina.io/sitemap.xml",
            "3 URLs appear more than once.",
            "7 addresses were fetched, within your plan cap of 25."
        ]
    }
}
GET/api/v1/tool?name=html-validate ✅ Erreurs structurelles selon les règles W3C.
GET /api/v1/tool?name=html-validate&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "html-validate",
    "ms": 180,
    "result": {
        "summary": [
            {
                "label": "Errors",
                "value": "8",
                "state": "bad"
            },
            {
                "label": "Warnings",
                "value": "0",
                "state": "ok"
            },
            {
                "label": "Total findings",
                "value": "8",
                "state": "warn"
            },
            "…"
        ],
        "cols": [
            "Line",
            "Level",
            "Finding"
        ],
        "rows": [
            {
                "a": "314",
                "b": "error",
                "c": "htmlParseEntityRef: expecting ';'",
                "state": "bad"
            },
            {
                "a": "513",
                "b": "error",
                "c": "Unexpected end tag : svg",
                "state": "bad"
            },
            {
                "a": "514",
                "b": "error",
                "c": "Unexpected end tag : svg",
                "state": "bad"
            },
            "…"
        ],
        "notes": [
            "420 \"unknown element\" complaints were discarded. The parser behind this check knows the…",
            "This is a structural check — parse errors, duplicate ids, obsolete and required element…"
        ]
    }
}
GET/api/v1/tool?name=robots-txt 🤖 Analyse le fichier et le résout par crawler.
GET /api/v1/tool?name=robots-txt&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "robots-txt",
    "ms": 133,
    "result": {
        "summary": [
            {
                "label": "robots.txt",
                "value": "found",
                "state": "ok"
            },
            {
                "label": "Size",
                "value": "1.9 KB",
                "state": "ok"
            },
            {
                "label": "Groups",
                "value": "10",
                "state": ""
            },
            "…"
        ],
        "cols": [
            "Crawler",
            "This URL",
            "Deciding rule",
            "…"
        ],
        "rows": [
            {
                "a": "*",
                "b": "allowed",
                "c": "Allow: /",
                "d": "the * group",
                "state": "ok"
            },
            {
                "a": "Googlebot",
                "b": "allowed",
                "c": "Allow: /",
                "d": "the * group",
                "state": "ok"
            },
            {
                "a": "Bingbot",
                "b": "allowed",
                "c": "Allow: /",
                "d": "the * group",
                "state": "ok"
            },
            "…"
        ],
        "text": "# As a condition of accessing this website, you agree to abide by the following\n# conte…",
        "notes": [
            "At least one group carries Disallow: / — that blocks an entire crawler from the whole s…"
        ]
    }
}
GET/api/v1/tool?name=images-seo 🖼️ Texte alternatif, dimensions et formats.
GET /api/v1/tool?name=images-seo&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "images-seo",
    "ms": 1910,
    "result": {
        "summary": [
            {
                "label": "Images",
                "value": "7",
                "state": "ok"
            },
            {
                "label": "Missing alt",
                "value": "0",
                "state": "ok"
            },
            {
                "label": "Decorative (alt=\"\")",
                "value": "7",
                "state": ""
            },
            "…"
        ],
        "cols": [
            "Image",
            "Alt text",
            "Size",
            "…"
        ],
        "rows": [
            {
                "a": "https://astrina.io/shot.php?s=1",
                "b": "(empty)",
                "c": "46.6 KB",
                "d": "empty alt (decorative); no width/height — causes layout shift",
                "state": "warn"
            },
            {
                "a": "https://astrina.io/shot.php?s=4",
                "b": "(empty)",
                "c": "75.1 KB",
                "d": "empty alt (decorative); no width/height — causes layout shift",
                "state": "warn"
            },
            {
                "a": "https://astrina.io/shot.php?s=8",
                "b": "(empty)",
                "c": "68.1 KB",
                "d": "empty alt (decorative); no width/height — causes layout shift",
                "state": "warn"
            },
            "…"
        ],
        "notes": [
            "6 images declare no width and height. The browser cannot reserve space, so the page jum…",
            "None of the sampled images are WebP or AVIF. Converting usually removes a third of the …",
            "Optimizing the sampled images could save roughly 131 KB. Compress or convert them to We…",
            "…"
        ]
    }
}
GET/api/v1/tool?name=cms-detect 🧱 Identifie le CMS et la pile technologique.
GET /api/v1/tool?name=cms-detect&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "cms-detect",
    "ms": 135,
    "result": {
        "summary": [
            {
                "label": "CMS",
                "value": "Magento",
                "state": "ok"
            },
            {
                "label": "Signals found",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "Server",
                "value": "cloudflare",
                "state": ""
            },
            "…"
        ],
        "cols": [
            "Kind",
            "Name",
            "Evidence",
            "…"
        ],
        "rows": [
            {
                "a": "CMS",
                "b": "Magento",
                "c": "markup: mage/",
                "d": "strong",
                "state": "ok"
            },
            {
                "a": "CDN / Edge",
                "b": "Cloudflare",
                "c": "server: cloudflare",
                "d": "strong",
                "state": "ok"
            }
        ],
        "notes": [
            "This reads fingerprints, not an inventory. A strong match is reliable; a weak one is a …"
        ]
    }
}
GET/api/v1/tool?name=readability 📖 Difficulté du texte et métriques de lisibilité.
GET /api/v1/tool?name=readability&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "readability",
    "ms": 94,
    "result": {
        "summary": [
            {
                "label": "Reading ease",
                "value": "47.0 — difficult",
                "state": "warn"
            },
            {
                "label": "Grade level",
                "value": "12.6",
                "state": "warn"
            },
            {
                "label": "Gunning Fog",
                "value": "15.5",
                "state": "warn"
            },
            "…"
        ],
        "cols": [
            "Measure",
            "Value"
        ],
        "rows": [
            {
                "a": "Formula used",
                "b": "Flesch Reading Ease and Flesch–Kincaid grade",
                "state": ""
            },
            {
                "a": "Language detected",
                "b": "Latin script",
                "state": ""
            },
            {
                "a": "Syllables per word",
                "b": "1.60",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "10 sentences run past 25 words.",
            "These formulas count syllables and sentence lengths. They cannot tell whether the writi…"
        ]
    }
}
GET/api/v1/tool?name=hreflang 🌍 Marquage international, y compris les liens de retour.
GET /api/v1/tool?name=hreflang&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "hreflang",
    "ms": 907,
    "result": {
        "summary": [
            {
                "label": "hreflang tags",
                "value": "4",
                "state": "ok"
            },
            {
                "label": "Problems",
                "value": "0",
                "state": "ok"
            },
            {
                "label": "x-default",
                "value": "yes",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Code",
            "URL",
            "Links back",
            "…"
        ],
        "rows": [
            {
                "a": "en",
                "b": "https://astrina.io/",
                "c": "n/a",
                "d": "ok",
                "state": "ok"
            },
            {
                "a": "ru",
                "b": "https://astrina.io/ru/",
                "c": "yes",
                "d": "ok",
                "state": "ok"
            },
            {
                "a": "uk",
                "b": "https://astrina.io/uk/",
                "c": "yes",
                "d": "ok",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "Return links were checked on 2 alternates."
        ]
    }
}
GET/api/v1/tool?name=canonical 🔗 Quelle URL la page déclare comme originale.
GET /api/v1/tool?name=canonical&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "canonical",
    "ms": 75,
    "result": {
        "summary": [
            {
                "label": "Canonical",
                "value": "declared",
                "state": "ok"
            },
            {
                "label": "Self-referencing",
                "value": "yes",
                "state": "ok"
            },
            {
                "label": "Declarations found",
                "value": "1",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Field",
            "Value"
        ],
        "rows": [
            {
                "a": "Requested URL",
                "b": "https://astrina.io/",
                "state": ""
            },
            {
                "a": "URL after redirects",
                "b": "https://astrina.io/",
                "state": ""
            },
            {
                "a": "Canonical in HTML",
                "b": "https://astrina.io/",
                "state": ""
            },
            "…"
        ],
        "notes": []
    }
}
GET/api/v1/tool?name=http-status 📋 Codes HTTP en masse et redirections.
GET /api/v1/tool?name=http-status&value=https%3A%2F%2Fastrina.io%2F%0Ahttps%3A%2F%2Fastrina.io%2Fpricing{
    "ok": true,
    "utility": "http-status",
    "ms": 774,
    "result": {
        "summary": [
            {
                "label": "Checked",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "OK (2xx)",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "Redirected",
                "value": "0",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "URL",
            "Status",
            "Hops",
            "…"
        ],
        "rows": [
            {
                "a": "https://astrina.io/",
                "b": "200",
                "c": "0",
                "d": "same URL",
                "e": "97 ms",
                "state": "ok"
            },
            {
                "a": "https://astrina.io/pricing",
                "b": "200",
                "c": "0",
                "d": "same URL",
                "e": "62 ms",
                "state": "ok"
            }
        ],
        "notes": [
            "All 2 addresses were checked, within the cap of 25 for this run."
        ]
    }
}
GET/api/v1/tool?name=favicon ⭐ Chaque taille et format recherchés par un navigateur.
GET /api/v1/tool?name=favicon&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "favicon",
    "ms": 573,
    "result": {
        "summary": [
            {
                "label": "Icons declared",
                "value": "1",
                "state": ""
            },
            {
                "label": "Icons that load",
                "value": "1 / 2",
                "state": "ok"
            },
            {
                "label": "/favicon.ico",
                "value": "missing",
                "state": "warn"
            },
            "…"
        ],
        "cols": [
            "Relation",
            "URL",
            "Status",
            "…"
        ],
        "rows": [
            {
                "a": "icon",
                "b": "https://astrina.io/favicon.svg",
                "c": "200",
                "d": "unknown",
                "e": "396 B",
                "state": "ok"
            },
            {
                "a": "icon (browser fallback)",
                "b": "https://astrina.io/favicon.ico",
                "c": "404",
                "d": "unknown",
                "e": "2.8 KB",
                "state": "warn"
            }
        ],
        "notes": [
            "There is no /favicon.ico at the root. Browsers and feed readers still ask for it by def…",
            "No apple-touch-icon. iOS will screenshot the page instead when someone adds it to their…",
            "No web app manifest. Android uses it for the home-screen icon and the install prompt."
        ]
    }
}
🛡️ Sécurité (12)
GET/api/v1/tool?name=ssl 🔒 Certificat, chaîne et expiration.
GET /api/v1/tool?name=ssl&value=astrina.io{
    "ok": true,
    "utility": "ssl",
    "ms": 86,
    "result": {
        "summary": [
            {
                "label": "Certificate",
                "value": "valid and trusted",
                "state": "ok"
            },
            {
                "label": "Days left",
                "value": "75",
                "state": "ok"
            },
            {
                "label": "Hostname matches",
                "value": "yes",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Field",
            "Value"
        ],
        "rows": [
            {
                "a": "Common name",
                "b": "astrina.io",
                "state": ""
            },
            {
                "a": "Subject alternative names",
                "b": "astrina.io, *.astrina.io",
                "state": ""
            },
            {
                "a": "Issued by",
                "b": "WE1",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Read from a live TLS handshake to 172.67.166.83:443 with SNI for astrina.io."
        ]
    }
}
GET/api/v1/tool?name=security-headers 🛡️ HSTS, CSP, options de cadre, notés.
GET /api/v1/tool?name=security-headers&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "security-headers",
    "ms": 94,
    "result": {
        "summary": [
            {
                "label": "Grade",
                "value": "A",
                "state": "ok"
            },
            {
                "label": "Score",
                "value": "85/100",
                "state": "ok"
            },
            {
                "label": "HSTS",
                "value": "yes",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Header",
            "Value",
            "Verdict"
        ],
        "rows": [
            {
                "a": "Strict-Transport-Security",
                "b": "max-age=31536000; includeSubDomains",
                "c": "Set for 365 days.",
                "state": "ok"
            },
            {
                "a": "Content-Security-Policy",
                "b": "default-src 'self' https: data:; script-src 'self' 'unsafe-inline' https:; style-src 's…",
                "c": "Set. The CSP analyser tool checks whether it actually holds.",
                "state": "ok"
            },
            {
                "a": "X-Content-Type-Options",
                "b": "nosniff",
                "c": "Set correctly.",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "The grade weighs the headers that change what an attacker can do. It says nothing about…"
        ]
    }
}
GET/api/v1/tool?name=http-headers 📨 Chaque en-tête de réponse, expliqué.
GET /api/v1/tool?name=http-headers&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "http-headers",
    "ms": 88,
    "result": {
        "summary": [
            {
                "label": "Status",
                "value": "200",
                "state": "ok"
            },
            {
                "label": "Protocol",
                "value": "HTTP/2",
                "state": "ok"
            },
            {
                "label": "Headers",
                "value": "20",
                "state": ""
            },
            "…"
        ],
        "cols": [
            "Header",
            "Value",
            "What it does"
        ],
        "rows": [
            {
                "a": "alt-svc",
                "b": "h3=\":443\"; ma=86400",
                "c": "Advertises another protocol for this origin, usually HTTP/3.",
                "state": ""
            },
            {
                "a": "cache-control",
                "b": "no-store, no-cache, must-revalidate",
                "c": "How long, and by whom, this response may be cached.",
                "state": ""
            },
            {
                "a": "cf-cache-status",
                "b": "DYNAMIC",
                "c": "",
                "state": ""
            },
            "…"
        ],
        "text": "alt-svc: h3=\":443\"; ma=86400\ncache-control: no-store, no-cache, must-revalidate\ncf-cach…",
        "notes": [
            "Our fetcher keeps one value per header name, so if the server sent several Set-Cookie l…"
        ]
    }
}
GET/api/v1/tool?name=csp 🚧 Nomme les directives qui laissent une faille.
GET /api/v1/tool?name=csp&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "csp",
    "ms": 116,
    "result": {
        "summary": [
            {
                "label": "Policy",
                "value": "enforced",
                "state": "ok"
            },
            {
                "label": "Directives",
                "value": "7",
                "state": ""
            },
            {
                "label": "Serious holes",
                "value": "7",
                "state": "bad"
            },
            "…"
        ],
        "cols": [
            "Directive",
            "Sources",
            "Finding"
        ],
        "rows": [
            {
                "a": "default-src",
                "b": "'self' https: data:",
                "c": "data: in a script source is a known bypass; https: alone allows every https origin on t…",
                "state": "bad"
            },
            {
                "a": "script-src",
                "b": "'self' 'unsafe-inline' https:",
                "c": "'unsafe-inline' on scripts defeats the policy — this is the exact thing CSP exists to s…",
                "state": "bad"
            },
            {
                "a": "style-src",
                "b": "'self' 'unsafe-inline'",
                "c": "'unsafe-inline' — acceptable for styles, still worth removing",
                "state": "warn"
            },
            "…"
        ],
        "text": "default-src 'self' https: data:; script-src 'self' 'unsafe-inline' https:; style-src 's…",
        "notes": [
            "Nothing reports violations, so you will not learn what the policy blocked or nearly blo…",
            "This reads the policy as written. Whether it fits what the page actually loads can only…"
        ]
    }
}
GET/api/v1/tool?name=dns 🌐 A, AAAA, MX, NS, TXT, SOA et CAA.
GET /api/v1/tool?name=dns&value=astrina.io{
    "ok": true,
    "utility": "dns",
    "ms": 507,
    "result": {
        "summary": [
            {
                "label": "A",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "AAAA",
                "value": "2",
                "state": "ok"
            },
            {
                "label": "MX",
                "value": "1",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Type",
            "Name",
            "Value",
            "…"
        ],
        "rows": [
            {
                "a": "A",
                "b": "astrina.io",
                "c": "104.21.34.236",
                "d": "292s",
                "e": "",
                "state": ""
            },
            {
                "a": "A",
                "b": "astrina.io",
                "c": "172.67.166.83",
                "d": "292s",
                "e": "",
                "state": ""
            },
            {
                "a": "AAAA",
                "b": "astrina.io",
                "c": "2606:4700:3037::ac43:a653",
                "d": "296s",
                "e": "",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "No CAA record. Adding one names the certificate authorities allowed to issue for this d…",
            "Answered by this server's resolver. A record changed in the last few hours may not have…"
        ]
    }
}
GET/api/v1/tool?name=whois 📜 Registraire, dates et serveurs de noms.
GET /api/v1/tool?name=whois&value=astrina.io{
    "ok": true,
    "utility": "whois",
    "ms": 313,
    "result": {
        "summary": [
            {
                "label": "Domain",
                "value": "astrina.io",
                "state": "ok"
            },
            {
                "label": "Registrar",
                "value": "NameCheap, Inc.",
                "state": ""
            },
            {
                "label": "Expires",
                "value": "2027-07-09",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Field",
            "Value"
        ],
        "rows": [
            {
                "a": "Expires",
                "b": "2027-07-09 15:37 UTC",
                "state": ""
            },
            {
                "a": "Registered",
                "b": "2026-07-09 15:37 UTC",
                "state": ""
            },
            {
                "a": "Last changed",
                "b": "2026-07-14 15:37 UTC",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Read from the registry over RDAP, the protocol that replaced WHOIS. Registrant contact …"
        ]
    }
}
GET/api/v1/tool?name=email-auth ✉️ Enregistrements SPF, DKIM et DMARC.
GET /api/v1/tool?name=email-auth&value=astrina.io{
    "ok": true,
    "utility": "email-auth",
    "ms": 1954,
    "result": {
        "summary": [
            {
                "label": "SPF",
                "value": "present",
                "state": "ok"
            },
            {
                "label": "DKIM",
                "value": "1 selector(s)",
                "state": "ok"
            },
            {
                "label": "DMARC",
                "value": "p=none",
                "state": "warn"
            },
            "…"
        ],
        "cols": [
            "Mechanism",
            "Record",
            "Finding",
            "…"
        ],
        "rows": [
            {
                "a": "MX",
                "b": "mail.astrina.io",
                "c": "priority 10",
                "d": "",
                "state": "ok"
            },
            {
                "a": "SPF",
                "b": "v=spf1 a mx ip4:149.202.80.42 ~all",
                "c": "Ends in ~all (softfail) with about 2 lookups. Move to -all once you are confident the l…",
                "d": "2 lookups",
                "state": "ok"
            },
            {
                "a": "DMARC",
                "b": "v=DMARC1; p=none; rua=mailto:[email protected]; fo=1",
                "c": "p=none — monitoring only. It collects reports and blocks nothing, which is the right pl…",
                "d": "100%",
                "state": "warn"
            },
            "…"
        ],
        "notes": [
            "Move from p=none to p=quarantine once the reports show your legitimate senders passing.…",
            "All of this is read from public DNS. Nothing was sent to your mail servers and no messa…"
        ]
    }
}
GET/api/v1/tool?name=http2 ⚡ Quel protocole et compression sont utilisés.
GET /api/v1/tool?name=http2&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "http2",
    "ms": 122,
    "result": {
        "summary": [
            {
                "label": "Protocol",
                "value": "HTTP/2",
                "state": "ok"
            },
            {
                "label": "Compression",
                "value": "Zstandard",
                "state": "ok"
            },
            {
                "label": "HTTP/3",
                "value": "advertised",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Measure",
            "Value",
            "What it means"
        ],
        "rows": [
            {
                "a": "Negotiated protocol",
                "b": "HTTP/2",
                "c": "Multiplexed: many requests share one connection, so head-of-line blocking on the browse…",
                "state": "ok"
            },
            {
                "a": "Compression",
                "b": "Zstandard",
                "c": "Zstandard — fast and compact where the client supports it.",
                "state": "ok"
            },
            {
                "a": "Alt-Svc",
                "b": "h3=\":443\"; ma=86400",
                "c": "HTTP/3 is advertised, so browsers will move to QUIC after the first request.",
                "state": "ok"
            },
            "…"
        ],
        "notes": [
            "We ask for every encoding we can accept, so what is reported is what your server chose …"
        ]
    }
}
GET/api/v1/tool?name=ip-info 📍 Géolocalisation et réseau pour une adresse.
GET /api/v1/tool?name=ip-info&value=astrina.io{
    "ok": true,
    "utility": "ip-info",
    "ms": 2145,
    "result": {
        "summary": [
            {
                "label": "Host",
                "value": "astrina.io",
                "state": ""
            },
            {
                "label": "Addresses",
                "value": "4",
                "state": "ok"
            },
            {
                "label": "IPv6",
                "value": "yes",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Address",
            "Family",
            "Network",
            "…"
        ],
        "rows": [
            {
                "a": "104.21.34.236",
                "b": "IPv4",
                "c": "AS13335 — CLOUDFLARENET - Cloudflare, Inc., US",
                "d": "104.21.32.0/19",
                "e": "US",
                "f": "no reverse DNS",
                "state": "warn"
            },
            {
                "a": "172.67.166.83",
                "b": "IPv4",
                "c": "AS13335 — CLOUDFLARENET - Cloudflare, Inc., US",
                "d": "172.67.160.0/20",
                "e": "US",
                "f": "no reverse DNS",
                "state": "warn"
            },
            {
                "a": "2606:4700:3035::6815:22ec",
                "b": "IPv6",
                "c": "AS13335 — CLOUDFLARENET - Cloudflare, Inc., US",
                "d": "2606:4700:3035::/48",
                "e": "US",
                "f": "no reverse DNS",
                "state": "warn"
            },
            "…"
        ],
        "notes": [
            "4 addresses answer for this name. That is normal for a CDN or a load balancer.",
            "The country shown is the one recorded on the address allocation in the routing registry…",
            "No commercial geolocation database was consulted, so there is no city, no coordinate an…"
        ]
    }
}
GET/api/v1/tool?name=ports 🔌 Ports de service bien connus, vérifiés en toute sécurité.
GET /api/v1/tool?name=ports&value=https%3A%2F%2Fexample.com%2F{ "ok": true, "utility": "ports", "ms": 0, "result": { … } }
GET/api/v1/tool?name=cookies 🍪 Cookies et leurs indicateurs contre le RGPD.
GET /api/v1/tool?name=cookies&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "cookies",
    "ms": 103,
    "result": {
        "summary": [
            {
                "label": "Cookies in response",
                "value": "1",
                "state": "ok"
            },
            {
                "label": "Third-party trackers",
                "value": "0",
                "state": "ok"
            },
            {
                "label": "Consent mechanism",
                "value": "detected",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Name",
            "Value",
            "Secure",
            "…"
        ],
        "rows": [
            {
                "a": "astrsess",
                "b": "44c774bdb4b0b81bd429e64545acc9a7",
                "c": "yes",
                "d": "yes",
                "e": "lax",
                "f": "session",
                "g": "flags look right",
                "state": "ok"
            }
        ],
        "notes": [
            "Cookies set later by JavaScript, or after a login, are outside what a single anonymous …"
        ]
    }
}
GET/api/v1/tool?name=cors 🔓 Quelles origines votre point de terminaison autorise.
GET /api/v1/tool?name=cors&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "cors",
    "ms": 884,
    "result": {
        "summary": [
            {
                "label": "CORS enabled",
                "value": "no",
                "state": "ok"
            },
            {
                "label": "Allowed origin",
                "value": "same origin only",
                "state": "ok"
            },
            {
                "label": "Origin reflection",
                "value": "none",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Header or probe",
            "Value",
            "Meaning"
        ],
        "rows": [
            {
                "a": "Access-Control-Allow-Origin",
                "b": "— not sent —",
                "c": "No CORS headers on a request that carried no Origin. That is the ordinary case; what ma…",
                "state": "ok"
            },
            {
                "a": "Access-Control-Allow-Credentials",
                "b": "— not sent —",
                "c": "Credentials are not shared.",
                "state": "ok"
            },
            {
                "a": "Access-Control-Allow-Methods",
                "b": "— not sent —",
                "c": "Sent on preflight responses.",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Two forged origins were sent and neither was echoed back, so this endpoint does not bui…",
            "This is a GET carrying an Origin header, not a full preflight. An endpoint that answers…"
        ]
    }
}
🎨 CSS (1)
GET/api/v1/tool?name=palette-url 🌐 Les couleurs qu'un site utilise réellement.
GET /api/v1/tool?name=palette-url&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "palette-url",
    "ms": 578,
    "result": {
        "summary": [
            {
                "label": "Distinct colours",
                "value": "132",
                "state": "warn"
            },
            {
                "label": "Stylesheets read",
                "value": "2 / 2",
                "state": "ok"
            },
            {
                "label": "CSS custom properties",
                "value": "28",
                "state": "ok"
            },
            "…"
        ],
        "cols": [
            "Colour",
            "RGB",
            "Uses",
            "…"
        ],
        "rows": [
            {
                "a": "#ffffff",
                "b": "rgb(255, 255, 255)",
                "c": "40",
                "d": "near-white",
                "e": "contrast on white 1.0:1 · on black 21.0:1",
                "state": ""
            },
            {
                "a": "#000000",
                "b": "rgb(0, 0, 0)",
                "c": "27",
                "d": "near-black",
                "e": "contrast on white 21.0:1 · on black 1.0:1",
                "state": ""
            },
            {
                "a": "#5b5bd6",
                "b": "rgb(91, 91, 214)",
                "c": "20",
                "d": "brand or accent",
                "e": "contrast on white 5.4:1 · on black 3.9:1",
                "state": ""
            },
            "…"
        ],
        "notes": [
            "Over 60 distinct colours. That is usually several palettes layered by different people …",
            "Counts are how often a colour appears in the CSS, which is not the same as how much of …"
        ]
    }
}
{ } DevOps (1)
GET/api/v1/tool?name=php-version 🐘 Détectez la version PHP qu'un serveur révèle.
GET /api/v1/tool?name=php-version&value=https%3A%2F%2Fastrina.io%2F{
    "ok": true,
    "utility": "php-version",
    "ms": 74,
    "result": {
        "summary": [
            {
                "label": "PHP version",
                "value": "not disclosed",
                "state": "ok"
            },
            {
                "label": "Security support",
                "value": "unknown",
                "state": ""
            },
            {
                "label": "Version leaked",
                "value": "no",
                "state": "ok"
            }
        ],
        "cols": [
            "Field",
            "Value",
            "Verdict"
        ],
        "rows": [
            {
                "a": "PHP detected",
                "b": "no",
                "c": "Nothing in the response names PHP. The site may not use it, or it may simply be configu…",
                "state": "ok"
            },
            {
                "a": "Server header",
                "b": "cloudflare",
                "c": "No version published here.",
                "state": "ok"
            }
        ],
        "notes": [
            "This reads only what the server volunteers in its headers. Nothing is probed, and a sit…"
        ]
    }
}

Connexion avec Astrina (API Auth)

Ajoutez la connexion sociale à votre site avec une seule intégration. Astrina est le courtier de style OAuth2/OIDC ; vous enregistrez votre site une fois et réutilisez chaque fournisseur que vous activez.

GET /auth/authorize.phpEnvoyez l'utilisateur ici (ajoutez &provider=google pour ignorer le choix). Renvoie un code à votre redirect_uri.
POST /auth/token.phpÉchangez le code (côté serveur, avec votre secret client) contre l'identité : sub, fournisseur, email, nom, avatar.
GET /auth/providers.phpListe des fournisseurs actuellement activés, avec des URLs de connexion en profondeur prêtes.

SDK PHP prêt à l'emploi + guide complet : guide d'intégration · télécharger sdk.php

API d'optimisation d'image

Compressez et convertissez les images (JPEG, PNG, GIF, WebP, AVIF, SVG) — sans perte ou avec perte. Envoyez un fichier, une URL ou base64 ; récupérez l'image optimisée et son économie de taille.

POST /api/v1/imageCorps : image=@file, ou JSON {url} / {data:base64}. Options : lossy=1|0, format=keep|webp|avif|jpeg|png, qualité, redimensionner. Renvoie les octets d'entrée/sortie, saved_percent et une URL de téléchargement.
GET /api/v1/image?get=…Récupérez un résultat optimisé par son jeton — aucune clé nécessaire, passez l'URL directement à une balise image.

Plans payants uniquement ; mesuré par rapport à votre quota mensuel d'images. Interface web : Optimiseur d'Image

Points de terminaison que vous ne contactez pas

Deux familles existent sous /api/v1 qui ne sont pas pour votre code, listées ici afin que cette page soit la carte complète :

POST /api/v1/social/inboundLe récepteur de webhook du fournisseur (Meta / WhatsApp Cloud API). Il est appelé PAR le fournisseur, pas par vous : GET est la poignée de main d'abonnement, POST délivre des messages. Configurez-le dans Social.
/api/v1/node/…Le protocole de dispositif Pulsar — enregistrer, suivant, soumettre, battement de cœur et amis — parlé par l'agent de nœud, pas par une clé API. Il est documenté avec le reste du protocole sur le Page du protocole Pulsar.

Groupes de sites

GET/api/v1/groups Vos groupes de site et leurs membres — les identifiants de groupe que /api/v1/stats?group=… prend, sans extraire le tableau de bord.
GET /api/v1/groups
X-Api-Key: ak_your_key_here

{ "ok":true, "groups":[ { "id":4, "name":"Client sites", "sites":[ {"id":12,"domain":"example.com"} ] } ] }

Lecture seule ; les groupes sont modifiés dans Mes groupes de sites. Portée groups.

Aperçu de la promotion

GET/api/v1/promotion?site=… L'image de promotion de l'un de vos sites au format JSON : classements, géo, backlinks, audit et objectifs — les mêmes chiffres que ceux affichés par le hub de promotion.
ParamDescription
siteid de site ou domaine — doit appartenir au propriétaire de la clé
sectionsummary (default) · rankings · geo · backlinks · audit · goals

Un champ pour lequel la plateforme n'a pas de données revient à null — jamais une supposition. Portée promotion.

Données du réseau Pulsar

GET/api/v1/pulsar?site=… Surveillance distribuée pour un site que vous possédez, recueillie par des dispositifs indépendants : confirmation par moniteur depuis plusieurs points de vue, et latence par pays.
ParamDescription
siteid de site ou domaine (requis)
reportmonitors (default) · coverage

Chaque chiffre est un verdict de quorum provenant de dispositifs indépendants ; lorsque le réseau n'a pas encore décidé, la valeur est null plutôt que l'opinion d'un seul serveur. À propos du réseau.

Commentaires

GET/api/v1/comment?key=… Commentaires modérés sur site pour n'importe quelle page, par URL. Le même magasin que celui utilisé par le widget de commentaire intégré.
GET  /api/v1/comment?key=https://example.com/post
POST /api/v1/comment   key=https://example.com/post&author=Ann&body=Nice+one

Les corps sont stockés en texte brut (tags supprimés) — échapper lors du rendu. La modération et le widget vivent dans Commentaires.

Exportation d'intelligence sur les menaces

GET/api/v1/ti-export Exportation consciente des licences du corpus d'intelligence sur les menaces : seules les lignes sous licence redistribuable ou d'origine Astrina, chacune portant sa source pour attribution.

Double verrouillé : une clé valide ET le commutateur d'opérateur, qui est désactivé jusqu'à ce que les conditions commerciales soient convenues. Les flux sous licence restrictive ne sont jamais inclus, quel que soit le plan.

Ce que cette page répond

  • référence des points de terminaison de l'API
  • authentification et quotas de l'API
  • exemples de requêtes API
  • documentation de l'API REST JSON
  • comment obtenir une clé API
  • qu'est-ce que l'api astrina
  • comment l'api astrina fonctionne
  • l'api astrina expliqué
  • guide l'api astrina
  • comment commencer avec l'api astrina
  • avis sur l'api astrina
  • est-ce que l'api astrina en vaut la peine
  • tarification de l'api astrina
  • l'api astrina alternatives
  • l'api astrina pour les débutants
  • pourquoi l'api astrina
  • l'api astrina — ce que vous obtenez