Rapports SEO

L'application SEO (seo.inklura.fr) rassemble des données de plusieurs sources et les assemble en rapports. Côté développeur, la génération de rapport tient en un endpoint POST et, pour la génération en arrière-plan, un flux de progression SSE.

Sources de données

Source Utilisée pour
Données de moteur de recherche Positions dans les résultats, volumes et idées de mots-clés.
Google Analytics 4 et Google Search Console Trafic et statistiques de recherche.
Robot d'exploration Audits on-page de votre site.
Note

Pour Google Analytics 4 et Google Search Console, vous connectez un compte Google puis choisissez, pour chaque site, les propriétés Search Console et GA4 que l'application SEO doit lire.

Générer un rapport

POST /api/seo/reports
Content-Type: application/json

{ "websiteId": "<id>", "async": true }

La requête est authentifiée par le cookie de session de l'application SEO et réservée aux comptes de l'agence. Le comportement dépend de async.

Statut Cas
401 Pas de session : { "error": "unauthorized" }.
403 Session valide, mais compte qui n'est pas un compte de l'agence (par exemple un compte client du portail).
400 websiteId absent ou corps illisible : { "error": "websiteId requis" }.
404 Site inconnu : { "error": "Site introuvable" }.

async: true

Le rapport est mis en file et généré en arrière-plan. La réponse arrive immédiatement :

202 Accepted

{ "jobId": "<id>", "status": "pending" }

Suivez ensuite le job avec le flux de progression ci-dessous. C'est le mode qu'utilise la console. Le job passe par les statuts pending, running, puis completed ou failed ; il peut rester pending un moment avant que la génération ne commence.

Sans async (par défaut)

Le rapport est généré pendant la requête, enregistré, puis renvoyé dans la réponse :

200 OK

{
  "id": "<id>",
  "title": "...",
  "clientName": "...",
  "healthScore": 72,
  "healthGrade": null,
  "summary": "...",
  "metrics": "{...}"
}

healthGrade vaut toujours null (aucune note en lettre n'est calculée) et metrics est une chaîne JSON à décoder. La requête doit tenir dans une limite de moins de 30 secondes : réservez ce mode aux petits rapports et utilisez async: true pour tout ce qui est plus lourd.

Suivre la progression (SSE)

GET /api/seo/reports/stream?jobId=<id>

La réponse est de type text/event-stream, authentifiée par le cookie de session (sans session valide d'un compte de l'agence, la requête est redirigée au lieu d'ouvrir le flux). Le flux consulte le job environ toutes les 1,5 seconde et envoie une trame event: status à chaque changement de statut (des pings en commentaire entre-temps) :

event: status
data: {"status":"completed","reportId":"<id>","error":null}

Il se ferme quand le job est completed ou failed, ou de lui-même au bout de 24 secondes environ. Il fixe retry: 2000 : un client EventSource se reconnecte donc automatiquement et continue de suivre le job jusqu'à la fin. Une requête sans jobId reçoit une trame event: error puis la fermeture du flux. Pour un jobId inconnu, le flux n'envoie que des pings jusqu'à sa fermeture.

const es = new EventSource(`/api/seo/reports/stream?jobId=${jobId}`);
es.addEventListener("status", (e) => {
  const job = JSON.parse(e.data); // { status, reportId, error }
  if (job.status === "completed" || job.status === "failed") es.close();
});

E-mails programmés

En plus des rapports à la demande, la page « Emails programmés » de l'application permet de programmer l'envoi de rapports par e-mail, chaque semaine ou chaque mois.

Autres routes

L'application SEO expose d'autres routes sous /api/seo/*, dont :

/api/seo/audit
/api/seo/keywords
/api/seo/onpage
/api/seo/traffic
/api/seo/websites
/api/seo/geo
/api/seo/research

Pour automatiser, appuyez-vous sur la génération de rapport décrite plus haut.

Voir aussi