Pourquoi cette nouvelle version v0 ?#
Notre API actuelle app.switchgrid.tech/enedis/v2/* présente quelques problèmes / limitations :
- elle est spécifique à Enedis. Nous avons depuis intégré GRDF et Strasbourg Électricité Réseaux. Nous prévoyons de supporter d'autres sources de données à l'avenir.
- elle ne supporte pas le versioning.
Versioning et headers HTTP#
Les clients devront déclarer quelle version de l'API ils souhaitent utiliser dans le header x-api-version. Voir le Guide pour plus de détails.
Changements#
16 septembre 2026 — GET /ask?status=EXPIRED est désormais accepté#
EXPIRED est documenté comme statut d'un Ask, mais le filtre status de GET/ask le refusait avec une 400 : c'est un statut dérivé, que nous calculons à la lecture, et le filtre ne connaissait que les statuts stockés.
Il l'accepte maintenant, à l'inclusion comme à l'exclusion :
GET /ask?status=EXPIRED # les consentements arrivés à échéance
GET /ask?status=ACCEPTED,!EXPIRED # ceux qui sont encore valides
GET /ask?status=CREATED,EXPIRED # l'un ou l'autre
EXPIRED et ACCEPTED se recouvrent volontairement : un consentement expiré reste ACCEPTED en base, seule sa date de fin est passée. status=ACCEPTED continue donc de renvoyer les Asks expirés — c'est le comportement actuel, et nous ne le changeons pas pour ne casser personne. Pour les seuls consentements encore actifs, demandez ACCEPTED,!EXPIRED.
15 septembre 2026 — le délai de signature d'un Ask est documenté#
Un Ask doit être signé dans les 2 mois qui suivent sa création. C'est le cas depuis juillet 2026, ce n'était simplement pas écrit. Passé ce délai, consentCollectionDetails.userUrl n'accepte plus de signature et invite le signataire à vous redemander un mandat : il vous faut alors créer un nouvel Ask. Le détail est dans le guide.
Ce délai est indépendant de consentDuration, et le statut de l'Ask ne change pas quand il est dépassé : un Ask jamais signé reste en PENDING_USER_ACTION. EXPIRED ne concerne que les Asks déjà signés arrivés au terme de leur consentDuration.
14 septembre 2026 — un Ask révoqué avant signature est désormais renvoyé, avec un signer à null#
POST/ask/{askId}/revoke n'a pas de prérequis : vous pouvez révoquer un Ask qui attend encore sa signature, pour l'annuler. Un tel Ask n'a jamais eu de signataire — et nos endpoints de lecture ne s'y attendaient pas. GET/ask le retirait silencieusement de la liste (returnedItemsCount revenait inférieur à totalCount, sans indiquer quel Ask manquait), et GET/ask/{askId} répondait une 500.
Les deux renvoient maintenant l'Ask, avec status: "REVOKED" et signer: null.
GET/ask/{askId}/proof sur un de ces Asks répond une 404 au lieu d'une 500 : rien n'a été signé, il n'y a donc pas de preuve à servir.
signer est désormais nullable lorsque status vaut REVOKED. Il reste non-null pour ACCEPTED et EXPIRED, qui impliquent tous deux que l'Ask a été signé. Un client qui valide strictement la réponse (schéma, types générés depuis une version antérieure de la spécification OpenAPI) doit régénérer ses types, et lire signer sur un Ask REVOKED avec prudence : il vaut null exactement quand acceptedAt vaut null.
8 septembre 2026 — courbe de charge : l'activation de la collecte est de nouveau systématique, et l'erreur le dit#
Le 10 juin 2026, Enedis a retiré le motif qui disait explicitement qu'un point n'avait aucun service de collecte de courbe de charge souscrit :
La demande ne peut aboutir : aucun service souscrit de courbe de charge n'est présent pour la période demandée
Ce cas est depuis renvoyé sous deux motifs génériques — le plus souvent « Absence de données de mesure », parfois « L'état contractuel du point ne permet pas de traiter cette demande » — qui couvrent aussi les points sans mesure sur la période. Le volume d'échecs n'a pas bougé, seul le libellé a changé.
Trois conséquences côté API, à partir d'aujourd'hui :
- L'activation de la collecte redevient systématique. Quand un de ces motifs tombe sur une demande
R63/LOADCURVE, nous vérifions auprès d'Enedis si la collecte est souscrite sur le point ; si elle ne l'est pas, nous en demandons l'activation — que la requête ait ou non l'optionenedisRetryAfterLoadcurveActivation. Vos prochaines commandes sur ces points peuvent alors aboutir. - Un message explicite remplace le motif générique dans ce cas précis.
errorMessagedevient « La collecte de courbe de charge n'était pas souscrite sur ce point… », avec lereasonCodeENEDIS_CCDC_AUCUN_SERVICE_SOUSCRIT— celui d'avant juin 2026. Quand la collecte est souscrite, rien ne change : le motif d'Enedis vous est restitué tel quel. enedisRetryAfterLoadcurveActivationpeut être activé par défaut sur votre workspace. Demandez-le nous : la requête attend alors l'activation et rejoue la demande toute seule, au prix d'unPENDINGd'environ une heure (parfois une dizaine) au lieu d'un échec en moins de deux minutes. Une commande qui envoie le champ explicitement garde toujours la main,falsecompris.
Aucun champ n'est ajouté ni supprimé. Si vous testez errorMessage par égalité de chaîne sur « Absence de données de mesure » pour détecter une courbe non activée, basculez sur reasonCode === "ENEDIS_CCDC_AUCUN_SERVICE_SOUSCRIT".
7 septembre 2026 — extraction de factures : nouveau moteur de lecture, et un champ error par fichier#
POST/integration/enedis/search_contracts_from_invoices lit désormais les factures avec un algorithme d'extraction amélioré, le même que celui de notre extraction de prix. Concrètement, le nom du titulaire et l'adresse du point de livraison sont extraits plus proprement — sans civilité, sans nom de résidence, de bâtiment ni de numéro d'appartement, et en distinguant le lieu de consommation de l'adresse de facturation lorsque la facture donne les deux. Ce sont ces deux valeurs qui sont comparées au réseau de distribution : mieux les lire, c'est trouver le contrat plus souvent.
Cette version corrige aussi un défaut qui rendait l'endpoint inexploitable : une vérification d'autorisation interne, prévue pour nos outils d'administration, s'appliquait à tous les appels et faisait échouer l'extraction. L'échec était silencieux — la réponse était un 200 avec des tableaux vides.
Chaque entrée de resultsByFile porte désormais un champ error :
error: null: la facture a été lue. Des tableauxcontractsetothersvides veulent alors vraiment dire « nous avons lu cette facture et aucun contrat ne correspond » ;error: "<message>": nous n'avons pas réussi à lire le fichier. Le message distingue les deux cas qui vous concernent : le fichier ne contient rien de lisible (envoyez un meilleur scan), ou la lecture a échoué de notre côté (réessayez).
Le champ est ajouté à la réponse, aucun champ existant ne change. Un client qui valide la réponse de façon stricte (schéma, types générés depuis une version antérieure de la spécification OpenAPI) doit régénérer ses types.
28 août 2026 — rate-limits sur la restitution de données#
Les endpoints qui restituent une courbe de charge — GET/integration/enedis/request/{requestId}/data et leurs équivalents de l'ancienne API enedis-v2 — sont désormais soumis à une rate-limit par projet : 5 appels par seconde, et 120 par minute. Les deux fenêtres sont glissantes et le budget est commun à toutes ces routes.
C'est l'appel le plus coûteux de l'API : une rafale soutenue depuis un seul projet allonge les temps de réponse pour tout le monde. Le plafond est volontairement placé au-dessus de ce que consomme notre intégration la plus active, il ne devrait donc se déclencher que sur une boucle de retry ou un export massivement parallélisé.
Au-delà, l'appel est rejeté avec un statut 429 Too Many Requests sans lire la donnée, et sans consommer de budget : dès que la fenêtre glisse, l'appel suivant passe. Réessayez avec un backoff exponentiel.
La limite déjà en place sur GET/integration/enedis/search_contract (2 appels par seconde et par projet) est désormais documentée elle aussi.
Ces limites sont configurables projet par projet : si votre usage légitime les dépasse, contactez-nous. Voir Rate-limits de l'API pour le détail.
27 août 2026 — points de livraison hors GRDF et statut NOT_VERIFIABLE#
Les réseaux de distribution de gaz qui ne sont pas exploités par GRDF — les entreprises locales de distribution (ELD) comme Régaz-Bordeaux ou R-GDS — numérotent leurs points de livraison à leur façon, et ces formats ne sont pour la plupart documentés nulle part. Jusqu'ici nous refusions ces identifiants avec une erreur 400 : il était impossible d'inclure un tel compteur dans un mandat.
Désormais :
- POST
/askaccepte, pour un contrat_energyType: gas, undeliveryPointIddont nous ne connaissons pas le format (32 caractères maximum) lorsque l'adresse indique que le réseau n'est pas exploité par GRDF. Sur une adresse desservie par GRDF, undeliveryPointIdqui n'est pas un PCE valide (14 chiffres, ouGIsuivi de 6 chiffres) reste refusé avec une erreur 400 ; - un contrat dont le réseau est exploité par un distributeur auquel nous ne sommes pas intégrés prend le nouveau statut
NOT_VERIFIABLE: nous n'avons interrogé personne, donc nous ne pouvons ni le confirmer ni l'infirmer. Il figure sur le mandat, qui reste signable, mais aucune donnée ne pourra être récupérée pour ce point de livraison. SonstatusTextl'explicite ; - un contrat
NOT_VALID— un distributeur auquel nous sommes intégrés a répondu que le point de livraison n'existe pas, ou que le titulaire ne correspond pas — continue, lui, de rendre l'AskentierNOT_VALID.
Ce changement peut casser une intégration existante : il ajoute une valeur à l'énumération du status des contrats, et il rompt deux hypothèses que votre code fait peut-être aujourd'hui. Les trois points ci-dessous détaillent lesquelles.
1. Une nouvelle valeur apparaît dans l'énumération du status des contrats. Les réponses de GET/ask/{askId} peuvent désormais contenir NOT_VERIFIABLE. Un client qui valide cette énumération de façon stricte — schéma de validation, types générés depuis une version antérieure de la spécification OpenAPI, switch exhaustif — échouera au décodage sur une valeur qu'il ne connaît pas.
2. Un Ask peut être PENDING_USER_ACTION alors que tous ses contrats ne sont pas VALID. Si votre code déduit l'état des compteurs de celui du mandat — « le mandat est signable, donc tous les contrats sont valides », ou « un contrat n'est pas valide, donc l'Ask sera NOT_VALID » — cette hypothèse n'est plus vraie. Après signature, un contrat NOT_VERIFIABLE ne donnera jamais lieu à une livraison de données : vérifiez le statut de chaque contrat plutôt que celui de l'Ask.
3. Un deliveryPointId gaz mal formé ne provoque plus systématiquement une erreur 400. Si vous vous appuyiez sur cette 400 pour valider une saisie utilisateur, un identifiant erroné sur une adresse hors GRDF crée maintenant un Ask — avec un contrat NOT_VERIFIABLE — au lieu d'être rejeté.