{"openapi":"3.0.3","info":{"title":"legifrance.dev API","version":"1.0.0","description":"API REST exposant le droit français EN VIGUEUR (Code général des impôts d'abord) en JSON, avec versioning par article et requêtes « en vigueur à une date » (asOf). Source : Légifrance — Etalab 2.0. Service indépendant, non affilié à la DILA."},"servers":[{"url":"https://api.legifrance.dev","description":"Production"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"responses":{"RateLimited":{"description":"Trop de requêtes par minute (rate-limit dépassé)","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Secondes avant retry"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds du prochain reset"}}},"QuotaExceeded":{"description":"Quota mensuel atteint (upgrade requis)"},"Unauthorized":{"description":"En-tête X-API-Key manquant ou clé invalide"},"NotFound":{"description":"Ressource introuvable"},"InvalidRequest":{"description":"Paramètre manquant ou invalide"}}},"paths":{"/v1/article/{num}":{"get":{"summary":"Article de loi à une date (asOf)","description":"Récupère l'unique version de l'article (code + numéro) EN VIGUEUR à la date `asOf` (défaut : aujourd'hui). C'est la valeur ajoutée de legifrance.dev : la bonne version à la bonne date.","parameters":[{"name":"num","in":"path","required":true,"schema":{"type":"string"},"description":"Numéro d'article (ex : 777, '150-0 B')"},{"name":"code","in":"query","schema":{"type":"string","default":"CGI"},"description":"Code (défaut : CGI)"},{"name":"asOf","in":"query","schema":{"type":"string","format":"date"},"description":"Date YYYY-MM-DD ; défaut : aujourd'hui"}],"responses":{"200":{"description":"OK — {legiarti_id, code, num, etat, date_debut, date_fin, asOf, version_label, plan_classement, texte, texte_html, url, source}"},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/article":{"get":{"summary":"Recherche plein-texte (FTS5) sur les articles en vigueur","description":"Recherche plein-texte stemmée français, restreinte aux versions en vigueur à la date `asOf` (défaut : aujourd'hui). Retourne extrait avec balises <mark> et score BM25.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200},"description":"Requête FTS5"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"maximum":10000}},{"name":"code","in":"query","schema":{"type":"string","example":"CGI"},"description":"Filtre par code"},{"name":"asOf","in":"query","schema":{"type":"string","format":"date"},"description":"Versions en vigueur à cette date"}],"responses":{"200":{"description":"OK — {total, limit, offset, asOf, results[], source}"},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/article/semantic":{"post":{"summary":"Recherche sémantique (Mistral embeddings + Vectorize)","description":"Recherche par sens (vecteurs cosinus 1024 dims), restreinte aux versions en vigueur à la date `asOf` (post-filtre). À utiliser pour les questions en langage naturel. Réservé aux tiers avec accès sémantique.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","minLength":2,"maxLength":500},"topK":{"type":"integer","default":5,"maximum":20},"code":{"type":"string","example":"CGI"},"asOf":{"type":"string","format":"date"}}}}}},"responses":{"200":{"description":"OK — {asOf, results: [{legiarti_id, code, num, etat, date_debut, date_fin, url, score}], source}"},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/health":{"get":{"summary":"Health check (public)","security":[],"responses":{"200":{"description":"OK — {status, timestamp, service, version, source}"}}}},"/v1/stats":{"get":{"summary":"Statistiques publiques (public)","security":[],"responses":{"200":{"description":"OK — {total_versions, versions_en_vigueur, codes[], source}"}}}},"/v1/status":{"get":{"summary":"Status détaillé des bindings (D1/KV/R2/Vectorize)","description":"Endpoint diagnostic pour monitoring externe (UptimeRobot, etc.). Renvoie 503 si un binding est dégradé.","security":[],"responses":{"200":{"description":"Tous bindings opérationnels"},"503":{"description":"Au moins un binding dégradé — voir checks.{d1,kv,r2,vectorize}.ok"}}}}}}