{"openapi":"3.1.0","info":{"title":"VigiCité — API de transparence démocratique","description":"VigiCité croise les données publiques françaises (HATVP, marchés publics, Journal Officiel, data.gouv.fr) pour produire des fiches de cohérence factuelles sur les élus et les flux financiers publics.\n\n**Principes** :\n- Uniquement des données issues de sources publiques légales\n- Scores de cohérence, pas de jugements\n- Méthodologie transparente et reproductible\n- Licence AGPL-3.0 (open source)\n\n**Avertissement** : Ces données sont issues exclusivement de sources publiques. Les scores mesurent la cohérence des données, pas l'intégrité des personnes.","termsOfService":"https://vigicite.org/mentions-legales","contact":{"name":"VigiCité","url":"https://vigicite.org/","email":"contact@vigicite.org"},"license":{"name":"AGPL-3.0","url":"https://www.gnu.org/licenses/agpl-3.0.html"},"version":"0.3.0"},"paths":{"/api/v1/elus":{"get":{"tags":["API publique v1"],"summary":"Lister les élus","description":"Liste paginée des élus avec leur score composite. Filtrable par département et par recherche textuelle.","operationId":"list_elus_api_v1_elus_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Numéro de page (commence à 1)","default":1,"title":"Page"},"description":"Numéro de page (commence à 1)"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Nombre de résultats par page","default":50,"title":"Per Page"},"description":"Nombre de résultats par page"},{"name":"departement","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Code département (ex: 13, 75, 2A)","title":"Departement"},"description":"Code département (ex: 13, 75, 2A)"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2},{"type":"null"}],"description":"Recherche sur nom, prénom ou fonction","title":"Q"},"description":"Recherche sur nom, prénom ou fonction"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EluListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/elus/bulk":{"get":{"tags":["API publique v1","Bulk"],"summary":"Récupérer plusieurs élus","description":"Retourne les fiches complètes de plusieurs élus en une seule requête. Maximum 50 IDs par appel.","operationId":"bulk_elus_api_v1_elus_bulk_get","parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string","description":"IDs séparés par des virgules (ex: 1,2,3). Max 50.","title":"Ids"},"description":"IDs séparés par des virgules (ex: 1,2,3). Max 50."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EluBulkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/departement/{code}/elus":{"get":{"tags":["API publique v1","Bulk"],"summary":"Élus d'un département","description":"Liste paginée de tous les élus d'un département avec leur score composite.","operationId":"departement_elus_api_v1_departement__code__elus_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Numéro de page","default":1,"title":"Page"},"description":"Numéro de page"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Résultats par page","default":50,"title":"Per Page"},"description":"Résultats par page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartementElusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/elus/{elu_id}":{"get":{"tags":["API publique v1"],"summary":"Fiche complète d'un élu","description":"Retourne toutes les informations publiques d'un élu : identité, scores, déclarations HATVP, participations et relations croisées.","operationId":"get_elu_api_v1_elus__elu_id__get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EluDetail"}}}},"404":{"description":"Élu non trouvé"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/elus/{elu_id}/scores":{"get":{"tags":["API publique v1"],"summary":"Scores d'un élu","description":"Retourne les scores de cohérence sur chaque dimension pour un élu donné. Chaque score est accompagné de ses facteurs et sources.","operationId":"get_elu_scores_api_v1_elus__elu_id__scores_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScoreResponse"},"title":"Response Get Elu Scores Api V1 Elus  Elu Id  Scores Get"}}}},"404":{"description":"Élu non trouvé"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/entreprises/{siren}":{"get":{"tags":["API publique v1"],"summary":"Profil d'une entreprise","description":"Retourne le profil d'une entreprise identifiée par son SIREN : marchés publics remportés, élus déclarant des participations, répartition géographique.","operationId":"get_entreprise_api_v1_entreprises__siren__get","parameters":[{"name":"siren","in":"path","required":true,"schema":{"type":"string","title":"Siren"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntrepriseResponse"}}}},"404":{"description":"Entreprise non trouvée"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search":{"get":{"tags":["API publique v1"],"summary":"Recherche multi-entités","description":"Recherche transversale sur les élus et les entreprises. Retourne les résultats les plus pertinents avec leur type et score.","operationId":"search_api_v1_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"description":"Terme de recherche (minimum 2 caractères)","title":"Q"},"description":"Terme de recherche (minimum 2 caractères)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Nombre maximum de résultats","default":20,"title":"Limit"},"description":"Nombre maximum de résultats"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"tags":["API publique v1"],"summary":"Statistiques globales","description":"Compteurs globaux de la base de données VigiCité.","operationId":"stats_api_v1_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}},"/api/v1/health":{"get":{"tags":["API publique v1"],"summary":"État de santé de l'API","description":"Vérifie la connectivité à la base de données et retourne des métriques.","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v2/elu/{elu_id}/narrative":{"get":{"tags":["API publique v2"],"summary":"Get Elu Narrative","description":"Narratif factuel complet d'un élu.\n\nRetourne les phrases factuelles, les croisements détectés,\nles indicateurs et le résumé partageable.","operationId":"get_elu_narrative_api_v2_elu__elu_id__narrative_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Elu Narrative Api V2 Elu  Elu Id  Narrative Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/departement/{code}/resume":{"get":{"tags":["API publique v2"],"summary":"Get Departement Resume","description":"Résumé factuel d'un département.\n\nRetourne les statistiques, top élus, top entreprises,\ncroisements significatifs et résumé en 3 phrases.","operationId":"get_departement_resume_api_v2_departement__code__resume_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Departement Resume Api V2 Departement  Code  Resume Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/croisements/top":{"get":{"tags":["API publique v2"],"summary":"Get Top Croisements","description":"Croisements les plus significatifs (participation déclarée + marchés publics).\n\nRetourne les liens élu↔entreprise↔marchés triés par montant total décroissant.\n\nCache server-side : TTL 5 min, clé (departement, limit). En cold la requête\ncoûte 8-11s (8 JOIN sur 116K marchés × 4K relations) — en hit <100ms.","operationId":"get_top_croisements_api_v2_croisements_top_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"default":20,"title":"Limit"}},{"name":"departement","in":"query","required":false,"schema":{"type":"string","title":"Departement"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Top Croisements Api V2 Croisements Top Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/_cache/stats":{"get":{"tags":["API publique v2"],"summary":"Cache Stats","description":"Statistiques du cache server-side (observabilité C4 2026-05-27).\n\nRetourne hits, misses, taux, taille actuelle. robots.txt bloque /api/ →\nendpoint non indexé. Utilisé pour diagnostic perf.","operationId":"cache_stats_api_v2__cache_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Cache Stats Api V2  Cache Stats Get"}}}}}}},"/api/v2/search":{"get":{"tags":["API publique v2"],"summary":"Search V2","description":"Recherche unifiée élus + entreprises.\n\nRetourne des résultats mixtes triés par pertinence.","operationId":"search_v2_api_v2_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search V2 Api V2 Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Page Index","description":"Page d'accueil avec top croisements, stats et liste paginée des élus.","operationId":"page_index__get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/partials/elus":{"get":{"summary":"Partials Elu List","description":"Fragment HTML paginé de la liste des élus (pour HTMX hx-get).","operationId":"partials_elu_list_partials_elus_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Per Page"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":0,"default":"","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/fiche/{dept}/{slug}":{"get":{"summary":"Page Fiche Slug","description":"Fiche d'un élu via URL propre /fiche/{dept}/{slug}.","operationId":"page_fiche_slug_fiche__dept___slug__get","parameters":[{"name":"dept","in":"path","required":true,"schema":{"type":"string","title":"Dept"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/fiche/{identifier}":{"get":{"summary":"Page Fiche","description":"Fiche par ID numérique OU par slug seul.\n\n- /fiche/123        → ID numérique, redirige vers /fiche/{dept}/{slug} si dispo\n- /fiche/jean-dupont → slug seul, redirige vers /fiche/{dept}/{slug} si dispo","operationId":"page_fiche_fiche__identifier__get","parameters":[{"name":"identifier","in":"path","required":true,"schema":{"type":"string","title":"Identifier"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/departement/{code}":{"get":{"summary":"Page Departement","description":"Page département — vue locale des données publiques enrichies.","operationId":"page_departement_departement__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/{elu_id}/graphe.json":{"get":{"summary":"Api Elu Graphe","description":"Données du graphe de relations d'un élu pour la visualisation D3.js.","operationId":"api_elu_graphe_api_elus__elu_id__graphe_json_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Elu Graphe Api Elus  Elu Id  Graphe Json Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/departements/{code}/graphe.json":{"get":{"summary":"Api Departement Graphe","description":"Données du graphe départemental multi-élu pour la visualisation D3.js.","operationId":"api_departement_graphe_api_departements__code__graphe_json_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Departement Graphe Api Departements  Code  Graphe Json Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og-image/{elu_id}.png":{"get":{"summary":"Og Image","description":"Image Open Graph 1200x630 pour le partage social d'une fiche elu.","operationId":"og_image_og_image__elu_id__png_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/og-image/article/{slug}.png":{"get":{"summary":"Og Image Article","description":"Image Open Graph 1200x630 pour le partage social d'un article de blog.","operationId":"og_image_article_og_image_article__slug__png_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/entreprise/{siren}":{"get":{"summary":"Page Entreprise","description":"Profil d'une entreprise : marchés, élus déclarants, géographie.","operationId":"page_entreprise_entreprise__siren__get","parameters":[{"name":"siren","in":"path","required":true,"schema":{"type":"string","title":"Siren"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/entreprises/{siren}":{"get":{"summary":"Api Entreprise","description":"Profil complet d'une entreprise en JSON.","operationId":"api_entreprise_api_entreprises__siren__get","parameters":[{"name":"siren","in":"path","required":true,"schema":{"type":"string","title":"Siren"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Entreprise Api Entreprises  Siren  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/recherche":{"get":{"summary":"Page Recherche","description":"Page de recherche dédiée avec filtres.","operationId":"page_recherche_recherche_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/glossaire":{"get":{"summary":"Page Glossaire","description":"Page glossaire des termes techniques.","operationId":"page_glossaire_glossaire_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/comment-lire-une-fiche":{"get":{"summary":"Page Comment Lire","description":"Guide pas-à-pas pour décoder une fiche élu en 5 minutes.","operationId":"page_comment_lire_comment_lire_une_fiche_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/par-ou-commencer":{"get":{"summary":"Page Par Ou Commencer","description":"Page d'entrée par profil : citoyen / journaliste / chercheur / élu.","operationId":"page_par_ou_commencer_par_ou_commencer_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/white-paper":{"get":{"summary":"Page White Paper","description":"Landing page du white paper méthodologique (citable, dépôt HAL-ready).","operationId":"page_white_paper_white_paper_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/qualite-editoriale":{"get":{"summary":"Page Qualite Editoriale","description":"Page publique de transparence sur la qualité éditoriale du blog.\n\nAffiche en temps réel les stats du team_validator : nombre d'articles\nOK / avec warnings / bloqués, répartition par expert et par code.","operationId":"page_qualite_editoriale_qualite_editoriale_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/cas-qualifies":{"get":{"summary":"Page Cas Qualifies","description":"Tableau de bord : croisements qualifiés au-dessus d'un seuil.\n\nFiltre le bruit (mandats ès qualités, actions cotées banales, fonds standardisés)\npour ne présenter que les cas qui justifient une investigation.","operationId":"page_cas_qualifies_cas_qualifies_get","parameters":[{"name":"departement","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"}},{"name":"min_score","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":20,"default":60,"title":"Min Score"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/participations/override":{"post":{"summary":"Admin Set Override","description":"Endpoint admin protégé : enregistrer un override manuel sur un SIREN.\n\nPermet de corriger les faux positifs / vrais signaux confirmés. Le classifier\nrespecte ces overrides à chaque run, créant un système auto-améliorant.\n\nArgs:\n    secret: VIGICITE_SECRET_KEY pour authentification\n    siren: SIREN de l'entité concernée\n    categorie: catégorie forcée (parapublic/cotee/fonds/engagement/qualified) ou vide\n    score: score forcé 0-100 ou None\n    note: commentaire libre pour mémoire (raison de l'override)","operationId":"admin_set_override_api_admin_participations_override_post","parameters":[{"name":"secret","in":"query","required":true,"schema":{"type":"string","title":"Secret"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_set_override_api_admin_participations_override_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Set Override Api Admin Participations Override Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/participations/overrides":{"get":{"summary":"Admin List Overrides","description":"Liste tous les overrides actifs.","operationId":"admin_list_overrides_api_admin_participations_overrides_get","parameters":[{"name":"secret","in":"query","required":true,"schema":{"type":"string","title":"Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Overrides Api Admin Participations Overrides Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/classifier/runs":{"get":{"summary":"Admin Classifier Runs","description":"Historique des runs du classifier (antifragilité : monitor évolution).","operationId":"admin_classifier_runs_api_admin_classifier_runs_get","parameters":[{"name":"secret","in":"query","required":true,"schema":{"type":"string","title":"Secret"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Classifier Runs Api Admin Classifier Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rss/cas-qualifies.xml":{"get":{"summary":"Rss Cas Qualifies","description":"Flux RSS des 50 derniers cas qualifiés (score >= 60).\n\nCible : journalistes / ONG qui veulent une veille temps réel.\nMise à jour à chaque recalcul du classifier (idéalement quotidien post-collecte).","operationId":"rss_cas_qualifies_rss_cas_qualifies_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v2/cas-qualifies":{"get":{"summary":"Api Cas Qualifies","description":"API publique : export des cas qualifiés en JSON ou CSV pour journalistes/ONG.","operationId":"api_cas_qualifies_api_v2_cas_qualifies_get","parameters":[{"name":"departement","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"}},{"name":"min_score","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":20,"default":60,"title":"Min Score"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|csv)$","default":"json","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/soutenir":{"get":{"summary":"Page Soutenir","description":"Page de soutien : dons en Monero, transparence finances.","operationId":"page_soutenir_soutenir_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/evolutions":{"get":{"summary":"Page Evolutions","description":"Évolutions des scores sur 30 jours (signal éditorial pur).","operationId":"page_evolutions_evolutions_get","parameters":[{"name":"min_delta","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":5,"title":"Min Delta"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/case-groups":{"get":{"summary":"Api Case Groups","description":"Dossiers groupés : entités où plusieurs élus pointent.\n\nUn dossier = une entité privée + des élus d'une même collectivité qui y\ndéclarent un mandat ou des parts. Signal structurel.","operationId":"api_case_groups_api_v2_case_groups_get","parameters":[{"name":"departement","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"}},{"name":"min_elus","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":2,"title":"Min Elus"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|csv)$","default":"json","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/dataset-weekly.csv":{"get":{"summary":"Api Dataset Weekly","description":"Export hebdo CSV anonymisé (hash SHA-256 des IDs élus) prêt pour data.gouv.fr.\n\nCible : déposer manuellement sur data.gouv.fr en tant que dataset public AGPL.\nAnonymisation : les noms réels sont préservés (c'est l'objet même de VigiCité),\nmais les IDs internes sont hashés pour empêcher la réidentification croisée\navec d'autres datasets non publics.","operationId":"api_dataset_weekly_api_v2_dataset_weekly_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/methodologie":{"get":{"summary":"Page Methodologie","description":"Page méthodologie.","operationId":"page_methodologie_methodologie_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/mentions-legales":{"get":{"summary":"Page Mentions Legales","description":"Mentions légales.","operationId":"page_mentions_legales_mentions_legales_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/a-propos":{"get":{"summary":"Page A Propos","description":"Page à propos.","operationId":"page_a_propos_a_propos_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/resilience":{"get":{"summary":"Page Resilience","description":"Page résilience — accès alternatifs.","operationId":"page_resilience_resilience_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/presse":{"get":{"summary":"Page Presse","description":"Kit presse.","operationId":"page_presse_presse_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/documentation":{"get":{"summary":"Page Api Documentation","description":"Page de documentation de l'API publique.","operationId":"page_api_documentation_api_documentation_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/widget/{elu_id}":{"get":{"summary":"Page Widget","description":"Widget intégrable (iframe) pour un élu.","operationId":"page_widget_widget__elu_id__get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/embed/commune/{cp}":{"get":{"summary":"Page Embed Commune","description":"Widget « Ma commune » embeddable iframe.\n\nÀ partir d'un code postal, redirige vers les stats du département.\nPermet aux PQR (presse quotidienne régionale) d'intégrer un mini-tableau\n« transparence dans votre département » sur leur site.\n\nSnippet à coller :\n    <iframe src=\"https://vigicite.org/embed/commune/13011\"\n            width=\"340\" height=\"320\" frameborder=\"0\"\n            style=\"border: 1px solid #e5e7eb; border-radius: 6px\"></iframe>","operationId":"page_embed_commune_embed_commune__cp__get","parameters":[{"name":"cp","in":"path","required":true,"schema":{"type":"string","title":"Cp"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/blog":{"get":{"summary":"Page Blog","description":"Index du blog — articles auto-générés quotidiennement.","operationId":"page_blog_blog_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},{"name":"dept","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dept"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/blog/{slug}":{"get":{"summary":"Page Blog Article","description":"Article de blog individuel.\n\nSi article archived (cleanup SEO 2026-05-27 — analyse_departement) :\nredirect 301 vers /departement/{code} pour préserver l'autorité PageRank\naccumulée. Sinon 404 standard.","operationId":"page_blog_article_blog__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/subscribe":{"post":{"summary":"Api Newsletter Subscribe","description":"Inscription à la newsletter (double opt-in).","operationId":"api_newsletter_subscribe_api_newsletter_subscribe_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_api_newsletter_subscribe_api_newsletter_subscribe_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Newsletter Subscribe Api Newsletter Subscribe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/confirm/{token}":{"get":{"summary":"Api Newsletter Confirm","description":"Confirme l'inscription newsletter via le token.","operationId":"api_newsletter_confirm_api_newsletter_confirm__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/unsubscribe/{token}":{"get":{"summary":"Api Newsletter Unsubscribe","description":"Désabonnement en 1 clic via le token.","operationId":"api_newsletter_unsubscribe_api_newsletter_unsubscribe__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/autocomplete":{"get":{"summary":"Autocomplete Elus","description":"Autocomplete JSON minimal pour datalist / dropdown (comparateur 2026-05-27).\n\nRetourne {\"results\": [{\"id\", \"label\", \"fonction\", \"departement\"}, ...]}.\nLéger : pas de score, pas de HTML — destiné aux suggestions live des formulaires.","operationId":"autocomplete_elus_api_elus_autocomplete_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":0,"default":"","title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":25,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Autocomplete Elus Api Elus Autocomplete Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/search":{"get":{"summary":"Search Elus","description":"Recherche d'élus et entreprises (retourne du HTML pour HTMX).","operationId":"search_elus_api_elus_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":0,"default":"","title":"Q"}},{"name":"dept","in":"query","required":false,"schema":{"type":"string","default":"","title":"Dept"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/{elu_id}":{"get":{"summary":"Api Elu","description":"Fiche complète d'un élu en JSON.","operationId":"api_elu_api_elus__elu_id__get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Elu Api Elus  Elu Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/{elu_id}/export.json":{"get":{"summary":"Export Elu Json","description":"Export JSON complet d'un élu (scores, déclarations, participations, relations).","operationId":"export_elu_json_api_elus__elu_id__export_json_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Export Elu Json Api Elus  Elu Id  Export Json Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/elus/{elu_id}/export.csv":{"get":{"summary":"Export Elu Csv","description":"Export CSV d'un élu (ligne aplatie avec scores).","operationId":"export_elu_csv_api_elus__elu_id__export_csv_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/elus.csv":{"get":{"summary":"Export Bulk Csv","description":"Export CSV bulk de tous les élus avec scores composites.","operationId":"export_bulk_csv_api_export_elus_csv_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"default":1000,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/csv":{"get":{"summary":"Export Csv Alias","description":"Alias /api/export/csv → /api/export/elus.csv.","operationId":"export_csv_alias_api_export_csv_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"default":1000,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/json":{"get":{"summary":"Export Json Alias","description":"Export JSON d'un élu via query param.","operationId":"export_json_alias_api_export_json_get","parameters":[{"name":"elu_id","in":"query","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Export Json Alias Api Export Json Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/dataset":{"get":{"summary":"Export Anonymised Dataset","description":"Export CSV anonymisé pour analyse statistique reproductible.\n\nContient les scores, métadonnées (département, type mandat),\net compteurs — sans noms ni identifiants réels.","operationId":"export_anonymised_dataset_api_export_dataset_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"default":10000,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/departement/{code}.csv":{"get":{"summary":"Export Departement Csv","description":"Export CSV des élus d'un département avec scores.","operationId":"export_departement_csv_api_export_departement__code__csv_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"default":10000,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/dictionnaire.json":{"get":{"summary":"Export Data Dictionary Json","description":"Dictionnaire de données — description de tous les champs exportés.","operationId":"export_data_dictionary_json_api_export_dictionnaire_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response Export Data Dictionary Json Api Export Dictionnaire Json Get"}}}}}}},"/api/export/dictionnaire.csv":{"get":{"summary":"Export Data Dictionary Csv","description":"Dictionnaire de données au format CSV.","operationId":"export_data_dictionary_csv_api_export_dictionnaire_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/export/methodologie.pdf":{"get":{"summary":"Export Methodologie Pdf","description":"PDF de la methodologie de scoring VigiCite.","operationId":"export_methodologie_pdf_api_export_methodologie_pdf_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/elus/{elu_id}/reponse":{"post":{"summary":"Api Submit Reponse","description":"Droit de réponse d'un élu avec vérification email.","operationId":"api_submit_reponse_api_elus__elu_id__reponse_post","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_api_submit_reponse_api_elus__elu_id__reponse_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reponse/verify":{"get":{"summary":"Api Verify Reponse","description":"Vérifie un droit de réponse via token email.","operationId":"api_verify_reponse_api_reponse_verify_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Verify Reponse Api Reponse Verify Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/alertes":{"get":{"summary":"Page Alertes","description":"Page des alertes de veille avec filtres.","operationId":"page_alertes_alertes_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","title":"Type"}},{"name":"severite","in":"query","required":false,"schema":{"type":"string","title":"Severite"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alertes":{"get":{"summary":"Api Alertes","description":"Liste des alertes en JSON, filtrable par type et sévérité.","operationId":"api_alertes_api_alertes_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","title":"Type"}},{"name":"severite","in":"query","required":false,"schema":{"type":"string","title":"Severite"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api Alertes Api Alertes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alertes/feed":{"get":{"summary":"Api Alertes Feed","description":"Feed JSON des alertes, compatible Zapier/IFTTT/n8n.","operationId":"api_alertes_feed_api_alertes_feed_get","parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string","description":"ISO datetime — alertes après cette date","title":"Since"},"description":"ISO datetime — alertes après cette date"},{"name":"departement","in":"query","required":false,"schema":{"type":"string","title":"Departement"}},{"name":"severite","in":"query","required":false,"schema":{"type":"string","description":"Sévérité minimale : info, attention, alerte","title":"Severite"},"description":"Sévérité minimale : info, attention, alerte"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Alertes Feed Api Alertes Feed Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/briefs":{"get":{"summary":"Page Briefs","description":"Page listant les briefs éditoriaux.","operationId":"page_briefs_briefs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/brief/{brief_id}":{"get":{"summary":"Page Brief","description":"Affiche un brief sous forme d'article.","operationId":"page_brief_brief__brief_id__get","parameters":[{"name":"brief_id","in":"path","required":true,"schema":{"type":"integer","title":"Brief Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/briefs":{"get":{"summary":"Api Briefs","description":"Liste des briefs en JSON.","operationId":"api_briefs_api_briefs_get","parameters":[{"name":"statut","in":"query","required":false,"schema":{"type":"string","title":"Statut"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api Briefs Api Briefs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/briefs/{brief_id}/statut":{"post":{"summary":"Api Changer Statut","description":"Change le statut d'un brief (workflow éditorial — protégé par secret).\n\nEndpoint admin : nécessite le ``VIGICITE_SECRET_KEY`` en query param.\nSans cette protection, n'importe qui pourrait publier ou retirer des briefs.","operationId":"api_changer_statut_api_briefs__brief_id__statut_post","parameters":[{"name":"brief_id","in":"path","required":true,"schema":{"type":"integer","title":"Brief Id"}},{"name":"secret","in":"query","required":true,"schema":{"type":"string","title":"Secret"}}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_api_changer_statut_api_briefs__brief_id__statut_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Changer Statut Api Briefs  Brief Id  Statut Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comparer":{"get":{"summary":"Page Comparer","description":"Comparateur de deux élus côte-à-côte.\n\nPré-remplissage : si `a` est fourni seul (depuis un CTA fiche élu type\n/comparer?a=44), on charge l'élu A et le template propose un seul champ\npour saisir le 2e élu. Évite à l'utilisateur de retaper le 1er nom.","operationId":"page_comparer_comparer_get","parameters":[{"name":"a","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"A"}},{"name":"b","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"B"}},{"name":"q_a","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q A"}},{"name":"q_b","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q B"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rss.xml":{"get":{"summary":"Flux Rss","description":"Flux RSS des briefs publiés.","operationId":"flux_rss_rss_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/rss/alertes.xml":{"get":{"summary":"Flux Rss Alertes","description":"Flux RSS de toutes les alertes de veille.","operationId":"flux_rss_alertes_rss_alertes_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/rss/alertes/{code}.xml":{"get":{"summary":"Flux Rss Alertes Dept","description":"Flux RSS des alertes pour un département.","operationId":"flux_rss_alertes_dept_rss_alertes__code__xml_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rss/{code}.xml":{"get":{"summary":"Flux Rss Departement","description":"Flux RSS par département.","operationId":"flux_rss_departement_rss__code__xml_get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sitemap.xml":{"get":{"summary":"Sitemap","description":"Sitemap INDEX qui pointe vers les sub-sitemaps.","operationId":"sitemap_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/sitemap-{kind}.xml":{"get":{"summary":"Sub Sitemap","description":"Sub-sitemap dédié : static / departements / blog / elus / entreprises.","operationId":"sub_sitemap_sitemap__kind__xml_get","parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/robots.txt":{"get":{"summary":"Robots","description":"robots.txt pour les moteurs de recherche.","operationId":"robots_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/vigicite-indexnow-key.txt":{"get":{"summary":"Indexnow Key","description":"Fichier de vérification IndexNow legacy (Yandex).","operationId":"indexnow_key_vigicite_indexnow_key_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/9ce0af9924def3db0888b90548201925.txt":{"get":{"summary":"Indexnow Key Hex","description":"Fichier de vérification IndexNow (Bing/Yandex).","operationId":"indexnow_key_hex_9ce0af9924def3db0888b90548201925_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/elus/{elu_id}/full":{"get":{"summary":"Api Elu Full","description":"Dump complet d'un élu en un seul appel (journalistes).","operationId":"api_elu_full_api_v1_elus__elu_id__full_get","parameters":[{"name":"elu_id","in":"path","required":true,"schema":{"type":"integer","title":"Elu Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Elu Full Api V1 Elus  Elu Id  Full Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats":{"get":{"summary":"Api Stats","description":"Statistiques générales de la base de données.","operationId":"api_stats_api_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Stats Api Stats Get"}}}}}}},"/api/departements":{"get":{"summary":"Api Departements","description":"Liste des départements avec nombre de marchés et d'élus.","operationId":"api_departements_api_departements_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response Api Departements Api Departements Get"}}}}}}},"/api/elus":{"get":{"summary":"Api Elus List","description":"Liste paginée des élus, filtrable par département.","operationId":"api_elus_list_api_elus_get","parameters":[{"name":"departement","in":"query","required":false,"schema":{"type":"string","title":"Departement"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Elus List Api Elus Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"summary":"Api Health","description":"Health check minimal — O(1), utilisé par Docker HEALTHCHECK.\n\nDoit rester ultra-rapide pour éviter les restart loops sous charge.\nPour les métriques détaillées : /api/health/metrics ou /api/v1/stats.","operationId":"api_health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Health Api Health Get"}}}}}}},"/api/health/metrics":{"get":{"summary":"Api Health Metrics","description":"Health check avec métriques DB (lent — full COUNT(*) sur les tables).","operationId":"api_health_metrics_api_health_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Health Metrics Api Health Metrics Get"}}}}}}},"/api/freshness":{"get":{"summary":"Api Freshness","description":"État de fraîcheur des données et du scheduler de veille.","operationId":"api_freshness_api_freshness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Freshness Api Freshness Get"}}}}}}},"/api/collecte/trigger":{"post":{"summary":"Api Trigger Collecte","description":"Déclenche une collecte manuellement (protégé par secret).\n\n- mode=full : pipeline complet (4 phases, ~3h)\n- mode=quick : sources indépendantes seulement (~30min)\n\nLe pipeline tourne dans un process séparé pour ne pas bloquer l'API.","operationId":"api_trigger_collecte_api_collecte_trigger_post","parameters":[{"name":"mode","in":"query","required":false,"schema":{"type":"string","pattern":"^(full|quick)$","default":"full","title":"Mode"}},{"name":"secret","in":"query","required":true,"schema":{"type":"string","title":"Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Trigger Collecte Api Collecte Trigger Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard":{"get":{"summary":"Page Dashboard","description":"Tableau de bord avec vue d'ensemble des données.","operationId":"page_dashboard_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"Body_admin_set_override_api_admin_participations_override_post":{"properties":{"siren":{"type":"string","title":"Siren"},"categorie":{"type":"string","title":"Categorie","default":""},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"note":{"type":"string","title":"Note","default":""}},"type":"object","required":["siren"],"title":"Body_admin_set_override_api_admin_participations_override_post"},"Body_api_changer_statut_api_briefs__brief_id__statut_post":{"properties":{"nouveau_statut":{"type":"string","title":"Nouveau Statut","default":""},"revue_par":{"type":"string","title":"Revue Par","default":""},"commentaire":{"type":"string","title":"Commentaire","default":""}},"type":"object","title":"Body_api_changer_statut_api_briefs__brief_id__statut_post"},"Body_api_newsletter_subscribe_api_newsletter_subscribe_post":{"properties":{"email":{"type":"string","title":"Email"},"departement":{"type":"string","title":"Departement","default":""}},"type":"object","required":["email"],"title":"Body_api_newsletter_subscribe_api_newsletter_subscribe_post"},"Body_api_submit_reponse_api_elus__elu_id__reponse_post":{"properties":{"email":{"type":"string","title":"Email","default":""},"message":{"type":"string","title":"Message","default":""}},"type":"object","title":"Body_api_submit_reponse_api_elus__elu_id__reponse_post"},"DeclarationResponse":{"properties":{"type_document":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type Document"},"date_publication":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Publication"},"statut_publication":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Statut Publication"}},"type":"object","title":"DeclarationResponse","description":"Déclaration HATVP."},"DepartementElusResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EluSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","minimum":1.0,"title":"Page"},"per_page":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Per Page"},"departement":{"type":"string","title":"Departement"}},"type":"object","required":["items","total","page","per_page","departement"],"title":"DepartementElusResponse","description":"Liste paginée des élus d'un département."},"DepartementMarchesResponse":{"properties":{"departement":{"type":"string","title":"Departement"},"nb":{"type":"integer","title":"Nb"},"total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total"},"montant_fmt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Montant Fmt"}},"type":"object","required":["departement","nb"],"title":"DepartementMarchesResponse","description":"Répartition géographique des marchés."},"EluBulkResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EluDetail"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"EluBulkResponse","description":"Réponse pour la requête bulk d'élus par IDs."},"EluDeclarantResponse":{"properties":{"elu_id":{"type":"integer","title":"Elu Id"},"prenom":{"type":"string","title":"Prenom"},"nom":{"type":"string","title":"Nom"},"fonction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fonction"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"capital_detenu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capital Detenu"},"activite":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activite"}},"type":"object","required":["elu_id","prenom","nom"],"title":"EluDeclarantResponse","description":"Élu déclarant une participation dans une entreprise."},"EluDetail":{"properties":{"id":{"type":"integer","title":"Id"},"civilite":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Civilite"},"prenom":{"type":"string","title":"Prenom"},"nom":{"type":"string","title":"Nom"},"classement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Classement"},"fonction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fonction"},"type_mandat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type Mandat"},"departement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"scores":{"items":{"$ref":"#/components/schemas/ScoreResponse"},"type":"array","title":"Scores","description":"Scores sur chaque dimension"},"declarations":{"items":{"$ref":"#/components/schemas/DeclarationResponse"},"type":"array","title":"Declarations"},"participations":{"items":{"$ref":"#/components/schemas/ParticipationResponse"},"type":"array","title":"Participations"},"relations":{"additionalProperties":{"items":{"$ref":"#/components/schemas/RelationResponse"},"type":"array"},"type":"object","title":"Relations"}},"type":"object","required":["id","prenom","nom"],"title":"EluDetail","description":"Fiche complète d'un élu avec ses scores et déclarations."},"EluListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EluSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","minimum":1.0,"title":"Page"},"per_page":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Per Page"}},"type":"object","required":["items","total","page","per_page"],"title":"EluListResponse","description":"Liste paginée d'élus.","examples":[{"items":[{"departement":"13","fonction":"Maire de Marseille","id":1,"nom":"DUPONT","prenom":"Jean","score_composite":65.0,"slug":"dupont-jean"}],"page":1,"per_page":50,"total":1}]},"EluSummary":{"properties":{"id":{"type":"integer","title":"Id"},"prenom":{"type":"string","title":"Prenom"},"nom":{"type":"string","title":"Nom"},"fonction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fonction"},"departement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"score_composite":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Composite","description":"Score composite (0-100), null si non calculé"}},"type":"object","required":["id","prenom","nom"],"title":"EluSummary","description":"Résumé d'un élu pour les listes."},"EntrepriseResponse":{"properties":{"siren":{"type":"string","title":"Siren"},"nom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nom"},"dirigeants":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Dirigeants"},"adresse":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Adresse"},"elus_declarants":{"items":{"$ref":"#/components/schemas/EluDeclarantResponse"},"type":"array","title":"Elus Declarants"},"marches":{"items":{"$ref":"#/components/schemas/MarcheResponse"},"type":"array","title":"Marches"},"departements":{"items":{"$ref":"#/components/schemas/DepartementMarchesResponse"},"type":"array","title":"Departements"}},"type":"object","required":["siren"],"title":"EntrepriseResponse","description":"Profil d'une entreprise avec ses marchés et liens aux élus."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status","description":"'ok' ou 'error'"},"version":{"type":"string","title":"Version"},"db_size_mb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Db Size Mb"},"counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Counts"},"last_score_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Score At"}},"type":"object","required":["status","version"],"title":"HealthResponse","description":"État de santé de l'API.","examples":[{"counts":{"elus":15000,"entreprises":80000,"marches_publics":250000,"relations":120000,"scores":15000},"db_size_mb":42.5,"last_score_at":"2026-03-30T12:00:00","status":"ok","version":"0.1.0"}]},"MarcheResponse":{"properties":{"objet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Objet"},"montant":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Montant"},"montant_fmt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Montant Fmt"},"departement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departement"},"date_attribution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Attribution"}},"type":"object","title":"MarcheResponse","description":"Marché public attribué."},"ParticipationResponse":{"properties":{"type":{"type":"string","title":"Type"},"nom_societe":{"type":"string","title":"Nom Societe"},"siren_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Siren Match"},"match_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Score"},"capital_detenu":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capital Detenu"},"activite":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activite"},"nb_marches_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nb Marches Total"},"nb_marches_dept":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nb Marches Dept"}},"type":"object","required":["type","nom_societe"],"title":"ParticipationResponse","description":"Participation déclarée par un élu."},"RelationResponse":{"properties":{"relation_type":{"type":"string","title":"Relation Type"},"target_id":{"type":"string","title":"Target Id"},"entreprise_nom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entreprise Nom"},"nb_marches":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nb Marches"}},"type":"object","required":["relation_type","target_id"],"title":"RelationResponse","description":"Relation croisée entre un élu et une entité."},"ScoreResponse":{"properties":{"dimension":{"type":"string","title":"Dimension","description":"Dimension du score (composite, coherence, etc.)"},"label":{"type":"string","title":"Label","description":"Libellé lisible de la dimension"},"score":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Score","description":"Valeur du score entre 0 et 100"},"factors":{"items":{"type":"string"},"type":"array","title":"Factors","description":"Facteurs contributifs au score"},"sources":{"items":{"type":"string"},"type":"array","title":"Sources","description":"URLs des sources utilisées"},"methodology_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Methodology Version","description":"Version de la méthodologie de calcul"}},"type":"object","required":["dimension","label","score"],"title":"ScoreResponse","description":"Score de cohérence sur une dimension donnée.","examples":[{"dimension":"composite","factors":["Participation déclarée dans 2 entreprises attributaires"],"label":"Composite","methodology_version":"v2","score":72.5,"sources":["https://www.hatvp.fr/livraison/opendata/liste.csv"]}]},"SearchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/SearchResultItem"},"type":"array","title":"Results"},"total":{"type":"integer","title":"Total"},"query":{"type":"string","title":"Query"}},"type":"object","required":["results","total","query"],"title":"SearchResponse","description":"Résultats de recherche multi-entités."},"SearchResultItem":{"properties":{"type":{"type":"string","title":"Type","description":"Type de résultat : elu ou entreprise"},"id":{"type":"string","title":"Id","description":"Identifiant (id pour élu, siren pour entreprise)"},"nom":{"type":"string","title":"Nom"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail","description":"Fonction, département, ou autre info"},"score_composite":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Composite"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"}},"type":"object","required":["type","id","nom"],"title":"SearchResultItem","description":"Résultat de recherche individuel."},"StatsResponse":{"properties":{"elus":{"type":"integer","title":"Elus"},"declarations":{"type":"integer","title":"Declarations"},"marches_publics":{"type":"integer","title":"Marches Publics"},"entreprises":{"type":"integer","title":"Entreprises"},"relations":{"type":"integer","title":"Relations"},"alertes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Alertes"},"scores":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Scores"},"db_size_mb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Db Size Mb"}},"type":"object","required":["elus","declarations","marches_publics","entreprises","relations"],"title":"StatsResponse","description":"Statistiques globales de la base VigiCité."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"API publique v1","description":"Endpoints JSON stables pour l'accès programmatique aux données VigiCité. Tous les endpoints retournent du JSON avec des modèles Pydantic validés. Rate limit : 60 req/min anonyme, 600 req/min avec clé API."},{"name":"API publique v2 (bêta)","description":"Endpoints v2 en cours de stabilisation — l'interface peut évoluer. Retourne du JSON avec modèles Pydantic."},{"name":"Bulk","description":"Endpoints d'accès en lot : récupérer plusieurs élus, lister les élus d'un département. Idéal pour le data journalism."},{"name":"Pages HTML","description":"Interface web HTMX — pages HTML destinées aux navigateurs."},{"name":"Exports","description":"Export de données en CSV et JSON."},{"name":"Éditorial","description":"Pipeline éditorial — briefs, articles, flux RSS."},{"name":"SEO","description":"Sitemap, robots.txt, images Open Graph."}]}