// docs / rest api
API REST
Authentifié par le porteur JSON API pour l'automatisation de l'analyse, l'état de l'analyse et les résultats. Les analyses passives sont disponibles via REST ; les analyses actives ne sont disponibles pour les forfaits payants qu'une fois le domaine vérifié et explicitement autorisé dans le tableau de bord.
Authentification
Chaque requête doit porter un bearer token dans l'en-tête Authorization. Les tokens sont créés depuis Compte → Tokens API ; le texte en clair t'est montré exactement une fois à la création. Révoquer un token renvoie 401 au prochain appel.
curl -H "Authorization: Bearer fxv_..." \
https://fixvibe.app/api/v1/scansFormat du token : fxv_ suivi de 43 caractères base64url. Stocké au repos comme hash SHA-256 ; le texte en clair n'est jamais persisté côté serveur.
Limites de débit
Deux fenêtres sur chaque requête authentifiée : rafale de 10 req/sec et régime stable de 60 req/min, toutes deux indexées sur le hash bearer. L'application des quotas (plafonds mensuels de scans) s'ajoute par-dessus ; consulte Quotas et limites.
Pagination
Les endpoints de liste (/api/v1/scans, /api/v1/findings) utilisent une pagination par curseur basée sur (created_at, id) en ordre décroissant. Passe ?cursor=<next_cursor> pour récupérer la page suivante. Le curseur reste correct malgré les écritures concurrentes (pas de dérive OFFSET).
Formats d'erreur
Chaque erreur est un objet JSON avec au moins une clé error.
{ "error": "invalid_token" } // 401
{ "error": "forbidden" } // 403
{ "error": "not_found" } // 404
{ "error": "quota_exceeded", "quota": {...} } // 429
{ "error": "rate_limited", "retry_after_seconds": 47 } // 429
{ "error": "invalid_input", "issues": [...] } // 400Endpoints
Démarrer un scan
/api/v1/scansMet en file d'attente une analyse passive par défaut. Pour les domaines vérifiés avec autorisation active, les forfaits payants peuvent demander le mode actif. Renvoie immédiatement avec un identifiant d'analyse en file d'attente ; interrogez GET /api/v1/scans/[scanId] jusqu'à status === "completed".
curl -X POST https://fixvibe.app/api/v1/scans \
-H "Authorization: Bearer fxv_..." \
-H "content-type: application/json" \
-d '{"target":"https://staging.example.com"}'// réponse 200
{
"id": "8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4d",
"status": "queued",
"target": "https://staging.example.com",
"mode": "passive"
}Lister tes scans
/api/v1/scansRenvoie les scans de l'organisation liée au token appelant, les plus récents d'abord. Pagine avec ?cursor=. Limite par défaut 50, maximum 100.
curl -H "Authorization: Bearer fxv_..." \
"https://fixvibe.app/api/v1/scans?limit=25"// réponse 200
{
"scans": [
{
"id": "8f1c4e2a-...",
"target_url": "https://staging.example.com",
"target_hostname": "staging.example.com",
"mode": "passive",
"status": "completed",
"started_at": "2026-05-07T14:00:00Z",
"completed_at": "2026-05-07T14:00:23Z",
"findings_count": { "critical": 1, "high": 3, "medium": 7, "low": 2, "info": 4 },
"triggered_by": "api",
"created_at": "2026-05-07T14:00:00Z"
}
],
"next_cursor": "2026-05-07T14:00:00Z:8f1c4e2a-..."
}Récupérer un scan
/api/v1/scans/{scanId}Renvoie l'enveloppe du scan + un résumé de sévérité par catégorie par défaut. Passe ?include_findings=true pour obtenir le rapport complet (volumineux pour les scans bruyants ; préfère l'endpoint findings avec filtres).
curl -H "Authorization: Bearer fxv_..." \
https://fixvibe.app/api/v1/scans/8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4dLister les constats
/api/v1/findingsListe filtrable de constats sur tous les scans de l'organisation appelante. Filtres : severity=critical,high, check_id=secrets.patterns, since=2026-04-01T00:00:00Z. Paginée par curseur.
curl -H "Authorization: Bearer fxv_..." \
"https://fixvibe.app/api/v1/findings?severity=critical,high&limit=50"// réponse 200
{
"findings": [
{
"id": "...",
"scan_id": "...",
"check_id": "secrets.js-bundle-sweep",
"severity": "critical",
"title": "Supabase service role key exposed in JS bundle",
"description": "...",
"evidence": { ... },
"remediation": "...",
"cwe_id": "CWE-798",
"created_at": "2026-05-07T14:00:23Z"
}
],
"next_cursor": null
}Spécification OpenAPI
Spécification lisible par machine sur /docs/api/openapi (text/yaml). Dépose-la dans ton générateur de code préféré (openapi-typescript, openapi-python-client ou n'importe quelle chaîne d'outils OpenAPI 3.1) pour obtenir des clients typés.
