API Citadel v1
L’API est celle qu’utilisent la CLI et le serveur MCP. Elle permet d’intégrer Citadel dans vos propres outils : envoyer une archive ZIP, lancer l’analyse et récupérer le résultat en JSON.
Authentification
Créez un compte gratuit sur citadelscan.com, puis une clé d’API dans Console › CLI & IDE. Une clé agit en votre nom dans un espace ; elle n’est affichée qu’une fois et se révoque à tout moment.
curl https://citadelscan.com/api/v1/me \
-H "Authorization: Bearer cit_..."| Règle | Valeur |
|---|---|
| URL de base | https://citadelscan.com/api/v1 |
| Format | JSON, en UTF-8 |
| Limite | 300 requêtes par tranche de 10 minutes et par clé |
| Analyses par heure | Free 3, Builder 10, Pro 30, Agency 60 (en plus du quota mensuel : Free 10, Builder 60) |
| Analyses simultanées | Free et Builder 1, Pro 3, Agency 5 ; au-delà, réponse 429 avec un message clair |
| Erreurs | Code HTTP 4xx et corps { "error": "message lisible" } |
| Langue | Textes des failles dans la langue du compte |
GET /me
Vérifie la clé : compte, espace, offre et rôle.
{
"user": { "name": "Awa Mensah", "email": "awa@example.com" },
"workspace": { "name": "Studio Awa", "plan": "pro" },
"role": "owner",
"lang": "fr"
}POST /uploads
Prépare l’envoi d’une archive ZIP (50 Mo au plus). Le projet est retrouvé par son nom, ou créé : consent doit valoir true pour attester que vous pouvez analyser ce code.
{ "project": "my-app", "consent": true, "size": 482133 }{
"projectId": "2b91…",
"url": "https://…/uploads",
"fields": { "key": "archives/…/….zip", "Content-Type": "application/zip", "Policy": "…", "X-Amz-Signature": "…" },
"key": "archives/…/….zip"
}Envoyez ensuite l’archive en multipart/form-data vers url, avec tous les champs fields puis le fichier dans le champ file. L’URL est valable 10 minutes.
curl -X POST "$URL" \
-F key=… -F Content-Type=application/zip -F Policy=… -F X-Amz-Signature=… \
-F file=@app.zipPOST /scans
Lance l’analyse de l’archive envoyée. sha256 est l’empreinte hexadécimale du fichier ZIP : la même archive envoyée deux fois ne crée qu’une analyse (duplicate: true).
{ "projectId": "2b91…", "key": "archives/…/….zip", "sha256": "9f86d08…" }{ "scanId": "6f0c…", "duplicate": false }GET /scans/{id}
État et résultat d’une analyse. Interrogez toutes les 3 secondes environ jusqu’à un statut final : succeeded, partial (un moteur en échec), failed ou cancelled. grade, counts, coverage et findings ne sont présents qu’après une analyse réussie ; seules les failles ouvertes sont listées, les plus graves d’abord.
{
"id": "6f0c…",
"status": "succeeded",
"project": { "id": "2b91…", "name": "my-app" },
"reportUrl": "https://citadelscan.com/app/projects/2b91…/scans/6f0c…",
"steps": [
{ "key": "inspect", "label": "Sorting and checking: only useful files are kept", "state": "done", "detail": "412 files kept · 1 380 set aside" },
{ "key": "code", "label": "Reading the code: OWASP flaws", "state": "done", "detail": "2 issues" }
],
"error": null,
"grade": "C",
"counts": { "critical": 0, "high": 1, "medium": 1, "low": 0, "info": 0 },
"coverage": null,
"findings": [
{
"id": "a41e…",
"severity": "high",
"ruleId": "citadel.supabase.rls-disabled",
"category": "A01:2021",
"cwe": ["CWE-284"],
"title": "Row Level Security disabled on a table",
"description": "…",
"impact": "…",
"recommendation": "Enable RLS on the table and add one policy per role.",
"file": "supabase/migrations/0001_init.sql",
"line": 9,
"evidence": "alter table public.orders disable row level security;"
}
]
}coverage n’est pas nul quand une partie du code est dans un langage que Citadel ne lit pas encore : la note ne reflète alors qu’une partie des risques.
Le plan gratuit inclut 10 analyses par mois, CLI et MCP compris, sans carte bancaire.
Personne ne lit votre code : il est analysé automatiquement dans un environnement isolé, puis supprimé. Confidentialité du code