API

Référence API

Endpoints, événements SSE et structures de données pour intégrer Pharone dans vos outils.

L'API Pharone vous permet de lancer des audits programmatiquement, de suivre leur progression en temps réel via SSE, et de récupérer les résultats complets. Elle est construite avec FastAPI et tourne sur http://localhost:8000 en développement.

Base URL

Développement : http://localhost:8000
Production    : https://[votre-backend-déployé]

Endpoints

POST /api/audit

Lance un audit sur une URL. Retourne immédiatement un audit_id — le traitement se fait en arrière-plan.

Body :

{ "url": "https://www.example.com" }

Réponse 202 :

{ "audit_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }

Erreur 422 (URL invalide ou SSRF bloquée) :

{
  "detail": [
    { "loc": ["body", "url"], "msg": "URL invalide ou accès refusé", "type": "value_error" }
  ]
}

Exemple :

curl -X POST http://localhost:8000/api/audit \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.example.com"}'

GET /api/audit/{id}/stream

Ouvre un flux Server-Sent Events pour suivre la progression de l'audit en temps réel. Reconnectable — si le client se déconnecte, il reçoit un événement sync à la reconnexion qui rejoue l'état complet.

Headers de réponse :

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Événements SSE :

ÉvénementQuandDonnées
syncConnexion / reconnexionÉtat complet (phase, agents, scores, pages)
crawl_startDébut du crawl{ url, audit_id }
crawl_doneFin du crawl{ pages_count, sitemap_found, robots_found, llms_txt_found, business_type, site_alerts[] }
agent_startDébut d'un agent{ agent_id }
agent_doneFin d'un agent{ agent_id, score, checks[], tokens_used }
completeAudit terminé{ audit_id, overall_score, pages_audited, agents{}, total_issues, total_tokens }
errorErreur fatale{ message, audit_id }

Structure de l'événement sync :

{
  "type": "sync",
  "data": {
    "phase": "agents",
    "agents_completed": ["technical", "on_page"],
    "agents_pending": ["content", "schema", "performance", "images", "ai_readiness", "sitemap"],
    "agents_scores": { "technical": 72, "on_page": 65 },
    "pages_crawled": 8,
    "pages_total": 10
  }
}

Exemple JavaScript :

const source = new EventSource(`/api/audit/${auditId}/stream`);

source.addEventListener('agent_done', (e) => {
  const { agent_id, score } = JSON.parse(e.data);
  console.log(`${agent_id}: ${score}/100`);
});

source.addEventListener('complete', (e) => {
  const result = JSON.parse(e.data);
  console.log(`Score global: ${result.overall_score}/100`);
  source.close();
});

GET /api/audit/{id}

Récupère le résultat complet d'un audit terminé.

Réponse 200 :

{
  "audit_id": "a1b2c3d4-...",
  "url": "https://www.example.com",
  "started_at": "2026-03-01T14:32:00Z",
  "finished_at": "2026-03-01T14:34:15Z",
  "overall_score": 68,
  "status": "complete",
  "agents": {
    "technical": {
      "agent_id": "technical",
      "score": 72,
      "issues": [
        {
          "priority": "high",
          "title": "Balise canonical absente sur 3 pages",
          "detail": "Les pages /about, /services et /contact n'ont pas de balise canonical.",
          "recommendation": "Ajouter <link rel=\"canonical\" href=\"[url-canonique]\"> dans le <head> de chaque page.",
          "affected_urls": ["/about", "/services", "/contact"]
        }
      ],
      "checks": [
        {
          "name": "robots.txt accessible",
          "status": "pass",
          "detail": "Fichier présent et valide à https://www.example.com/robots.txt"
        }
      ],
      "tokens_used": 1240
    }
  },
  "progress": {
    "phase": "complete",
    "agents_completed": ["technical", "content", "on_page", "schema", "performance", "images", "ai_readiness", "sitemap"],
    "agents_pending": [],
    "pages_crawled": 10,
    "pages_total": 10
  }
}

Erreur 404 : audit introuvable.


GET /api/audits

Récupère la liste de tous les audits (plus récents en premier).

Réponse 200 :

[
  {
    "audit_id": "a1b2c3d4-...",
    "url": "https://www.example.com",
    "started_at": "2026-03-01T14:32:00Z",
    "finished_at": "2026-03-01T14:34:15Z",
    "overall_score": 68,
    "status": "complete"
  }
]

POST /api/audit/{id}/retry/{agent_id}

Relance un agent spécifique sans répéter le crawl. Utile quand un agent a échoué (timeout, erreur réseau).

agent_id valides : technical, content, on_page, schema, performance, images, ai_readiness, sitemap

Réponse 202 :

{ "status": "retrying", "agent_id": "technical" }

Après cette requête, reconnectez-vous au stream SSE pour suivre la progression.

Exemple :

curl -X POST http://localhost:8000/api/audit/a1b2c3d4/retry/technical

DELETE /api/audit/{id}

Supprime un audit de la base de données.

Réponse : 204 No Content


GET /health

Vérifie l'état du serveur et de la base de données.

Réponse 200 :

{ "status": "ok", "db": "ok" }

Structures de données

AuditStatus

ValeurSignification
runningAudit en cours
completeAudit terminé avec succès
errorAudit terminé avec une erreur fatale

IssuePriority

ValeurCouleurDescription
critical🔴 RougeBloque l'indexation ou cause une pénalité
high🟠 OrangeImpact significatif sur le classement
medium🟡 JauneOpportunité d'optimisation
low⚪ GrisAmélioration mineure

CheckStatus

ValeurSignification
passVérification réussie
failProblème détecté
warnAvertissement
infoInformation (pas d'impact direct)

BusinessType

Détecté automatiquement pendant le crawl pour adapter les recommandations :

ValeurSignification
localCommerce local, artisan, restaurant
saasApplication SaaS, logiciel
ecommerceBoutique en ligne
publisherBlog, média, site éditorial
agencyAgence, cabinet de conseil
otherAutre

Codes d'erreur HTTP

CodeSignification
202Audit lancé en arrière-plan
204Suppression réussie
404Audit introuvable
422Validation échouée (URL invalide, SSRF bloquée)
500Erreur serveur interne

Limites et plans

PlanAudits/moisPages/auditRétention
Starter101007 jours
GrowthIllimité50030 jours
ProIllimité2 000Illimité

En développement local, MAX_PAGES est réglé à 10 dans .env. Changez-le à 50 avant de déployer en production.


Intégration complète — exemple Node.js

async function runAudit(url) {
  // 1. Lancer l'audit
  const res = await fetch('http://localhost:8000/api/audit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ url }),
  });
  const { audit_id } = await res.json();

  // 2. Suivre la progression
  await new Promise((resolve, reject) => {
    const source = new EventSource(`http://localhost:8000/api/audit/${audit_id}/stream`);

    source.addEventListener('agent_done', (e) => {
      const { agent_id, score } = JSON.parse(e.data);
      console.log(`✓ ${agent_id}: ${score}/100`);
    });

    source.addEventListener('complete', (e) => {
      source.close();
      resolve(JSON.parse(e.data));
    });

    source.addEventListener('error', (e) => {
      source.close();
      reject(new Error(e.data ? JSON.parse(e.data).message : 'Erreur inconnue'));
    });
  });

  // 3. Récupérer le résultat complet
  const report = await fetch(`http://localhost:8000/api/audit/${audit_id}`);
  return report.json();
}

// Usage
const result = await runAudit('https://www.example.com');
console.log(`Score global : ${result.overall_score}/100`);