Introduction

Bienvenue sur la documentation de l'API Pro Capfile. Cette interface REST permet d'interroger les données brutes de soutirage (consommation) et d'injection (production) d'un point de livraison.

Aucune information tarifaire n'est renvoyée par cette API (pas de prix, d'abonnement ni de puissance souscrite) : elle expose les données techniques et énergétiques brutes du compteur, à charge pour l'intégrateur d'appliquer sa propre logique métier.

Démo interactive. Pour tester l'API directement depuis votre navigateur (connexion, quotas, compteurs, graphique de courbe de charge, webhook), consultez la page de démonstration.
Référence OpenAPI. La description formelle de l'API (OpenAPI 3) est disponible en openapi.json, utilisable pour générer un client dans votre langage, et consultable dans Swagger UI avec essai des appels en direct (« Try it out », clé API à saisir via « Authorize »).

Toutes les réponses sont en JSON et partagent la même enveloppe { success, code, message, data }. En cas d'erreur, le statut HTTP de la réponse reprend la valeur de code (voir codes d'erreur).


Base URL : https://api.capfile.com/pro/v1.1/

Authentification

Deux modes d'authentification sont disponibles selon l'action effectuée :

  • Basic Auth : Obligatoire pour la gestion de la clé. Format Authorization: Basic Base64(login:password).
  • API Key Auth : Recommandé pour l'accès aux données. En-tête : x-api-key: VOTRE_CLE_API.

Gestion de la Clé API

Endpoints accessibles uniquement via Basic Auth.

GET /api_key

Récupère la clé API active associée à votre compte.

{
  "success": true,
  "code": 200,
  "message": "Clé API",
  "data": {
    "api_key": "TamxBsK9hTjszezcSy4sdfsdfsdfqRmYUFo"
  }
}
GET /api_key/renew

Révoque la clé actuelle et en génère une nouvelle immédiatement.

{
  "success": true,
  "code": 200,
  "message": "Clé API renouvelée",
  "data": {
    "api_key": "anQBz1brst89eymswVCqhk29mpKqnb7n"
  }
}

Compteurs

Récupère la liste de tous les compteurs accessibles avec la clé API fournie, y compris les compteurs partagés par d'autres utilisateurs Capfile.

Cet endpoint requiert l'authentification par API Key (x-api-key).

GET /meters
Exemple d'URL complète :
https://api.capfile.com/pro/v1.1/meters

Réponse JSON

{
  "success": true,
  "code": 200,
  "message": "OK",
  "data": [
    {
      "prm": "12345678901234",
      "name": "Maison principale"
    },
    {
      "prm": "98765432109876",
      "name": "Appartement voisin",
      "shared": true
    }
  ]
}
Champs de réponse
  • prm : Identifiant du point de livraison (14 chiffres).
  • name : Nom du site associé au compteur.
  • shared : Présent et à true uniquement si le compteur appartient à un autre utilisateur Capfile et vous a été partagé. Ce champ est absent pour vos propres compteurs.
Compteurs partagés

Un même compte peut avoir accès à des compteurs appartenant à d'autres utilisateurs Capfile. Pour ces compteurs (shared: true), l'accès aux endpoints /info, /index et /loadcurve dépend des options de partage définies par le propriétaire du compteur.

Infos Compteur

Récupère les informations techniques brutes d'un PRM : segments contractuels en service, informations techniques (ITC), et grandeurs physiques disponibles en soutirage et en injection. Aucune donnée tarifaire n'est renvoyée par cet endpoint.

Cet endpoint requiert l'authentification par API Key (x-api-key).

GET /data/{PRM}/info
Exemple d'URL complète :
https://api.capfile.com/pro/v1.1/data/12345678901234/info

Réponse JSON (extrait, "itc" tronqué)

{
  "success": true,
  "code": 200,
  "message": "OK",
  "data": {
    "prm": "12345678901234",
    "name": "Maison principale",
    "segments": {
      "C5": {
        "segment": "C5",
        "etatContractuel": "En service",
        "etatContractuelCode": "SERVC"
      }
    },
    "itc": {
      "point": {
        "donneesGenerales": { "...": "..." },
        "situationContractuelle": { "...": "..." }
      }
    },
    "soutirage": {
      "grandeurs_physiques": {
        "EA": "Energie Active (Wh)"
      },
      "itc": { "...": "informations techniques spécifiques au flux de soutirage" }
    },
    "injection": {
      "grandeurs_physiques": {
        "EA": "Energie Active (Wh)"
      },
      "itc": { "...": "informations techniques spécifiques au flux d'injection" },
      "puissance_raccordement": 12.0
    }
  }
}
Champs racine
  • segments : Dictionnaire des segments contractuels connus pour ce PRM, avec leur état contractuel.
  • itc : Informations Techniques et Contractuelles du point de livraison. Structure riche et variable selon le compteur.
Structure soutirage / injection
  • grandeurs_physiques : Dictionnaire code → libellé des grandeurs physiques mesurées et disponibles pour ce flux (ex. EA = Energie Active). La liste dépend du compteur — voir la table des grandeurs physiques.
  • itc : Informations techniques spécifiques au flux (injection ou soutirage).
  • puissance_raccordement (injection uniquement) : Puissance de raccordement en kVA, 0 si non disponible.

Le bloc soutirage est absent si le PRM ne soutire pas ; le bloc injection est absent si le PRM n'injecte pas.

Données d'Index

Récupère l'historique des index quotidiens pour une grandeur physique donnée. Cet endpoint requiert l'authentification par API Key (x-api-key).

Même convention pour tous les compteurs, Linky ou télérelevés : la ligne datée D porte l'index relevé à la fin de la journée D (cadran_*) et l'énergie de la journée D (différence avec la veille). Un seul relevé par jour est retenu, le premier après minuit ; pour un compteur télérelevé il a lieu quelques minutes après minuit.

GET /data/{PRM}/index/{SENS}/{GP}
Exemple d'URL complète :
https://api.capfile.com/pro/v1.1/data/12345678901234/index/sou/EA?start_date=2024-01-01&end_date=2024-01-02
Paramètre SENS (obligatoire)

Définit le flux :

  • sou : Soutirage (consommation)
  • inj : Injection (production)
Paramètre GP — grandeur physique (obligatoire)

Code de la grandeur physique à récupérer (ex. EA, ER…). Les valeurs possibles dépendent du compteur : consultez le champ grandeurs_physiques renvoyé par /data/{PRM}/info pour ce PRM, dans le bloc soutirage ou injection correspondant. Une valeur non disponible pour ce compteur renvoie une erreur 400.

Différence vs Réel

Les champs sont doublés dans chaque ligne de data :

  • NOM_CADRAN : Différence par rapport à la veille (valeur "journalière"), dans l'unité de la grandeur physique (ex. Wh pour EA).
  • cadran_NOM_CADRAN : Index cumulé lu sur le compteur à minuit.

Réponse JSON

{
  "success": true,
  "code": 200,
  "message": "OK",
  "data": {
    "head": {
      "prm": "12345678901234",
      "type": "index",
      "sens": "sou",
      "grandeur_physique": "EA",
      "start_date": "2026-03-04",
      "end_date": "2026-03-11"
    },
    "data": [
      {
        "date": "2026-03-04",
        "BASE": "11593",
        "Total": "11593",
        "cadran_BASE": "17539897",
        "cadran_Total": "17539897"
      },
      {
        "date": "2026-03-05",
        "BASE": "11021",
        "Total": "11021",
        "cadran_BASE": "17550918",
        "cadran_Total": "17550918"
      }
    ]
  }
}

Le nombre et le nom des champs (autres que date et Total) dépendent des cadrans réellement utilisés par le compteur pour la grandeur physique demandée.

Courbe de Charge

Données précises au pas défini par le compteur (énergie active uniquement). Unité : Wh (numérique). Chaque point est horodaté à la fin de son intervalle, en heure légale française avec décalage explicite (voir Horodatage ci-dessous).

GET /data/{PRM}/loadcurve/{SENS}
Exemple d'URL complète :
https://api.capfile.com/pro/v1.1/data/12345678901234/loadcurve/sou?start_date=2024-03-10&end_date=2024-03-11
Paramètre SENS (obligatoire)

Définit le flux :

  • sou : Soutirage (consommation)
  • inj : Injection (production)
Horodatage date_time

ISO 8601 avec décalage explicite : 2026-03-01T00:30:00+01:00. L'heure affichée est l'heure légale française (head.timezone = Europe/Paris), le décalage vaut +01:00 en hiver et +02:00 en été ; l'instant est donc exact et directement exploitable par tout parseur de dates (new Date(), DateTime, datetime.fromisoformat…).

  • Le point est horodaté à la fin de son intervalle de mesure (convention Enedis) : 2026-03-01T00:30:00+01:00 avec p = 30 couvre 00:00 → 00:30.
  • start_date / end_date sont des jours civils français.
  • Dernier dimanche de mars : la journée compte 23 heures de données (pas de point entre 02:00 et 02:59, heure inexistante).
  • Dernier dimanche d'octobre : la journée compte 24 heures de données pour 25 heures réelles ; les points 02:xx renvoyés sont ceux de l'heure d'hiver (+01:00).
Paramètre "p" (Le Pas)

Le champ p indique la durée de l'intervalle de mesure en minutes. Il est porté par chaque point et peut changer au cours de l'historique d'un même compteur (Enedis modifie le pas de collecte, ou comble certains jours à un pas plus grossier) : utilisez toujours le p du point, jamais une valeur supposée constante. Les valeurs possibles sont :

  • 5 minutes
  • 10 minutes
  • 15 minutes
  • 30 minutes
  • 60 minutes

Réponse JSON

{
  "success": true,
  "code": 200,
  "message": "OK",
  "data": {
    "head": {
      "prm": "04389580265458",
      "type": "loadcurve",
      "sens": "sou",
      "timezone": "Europe/Paris",
      "start_date": "2026-03-01",
      "end_date": "2026-03-11"
    },
    "data": [
      {
        "date_time": "2026-03-01T00:30:00+01:00",
        "p": 30,
        "Wh": 81
      },
      {
        "date_time": "2026-03-01T01:00:00+01:00",
        "p": 30,
        "Wh": 92
      },
      {
        "date_time": "2026-03-01T01:30:00+01:00",
        "p": 30,
        "Wh": 81
      }
    ]
  }
}

Gestion des Quotas

L'utilisation de l'API est encadrée par des quotas fixes basés sur le calendrier (et non glissants) :

  • Quotas quotidiens : Se réinitialisent chaque jour à 00:00.
  • Quotas hebdomadaires : Basés sur la semaine calendaire, du Lundi au Dimanche.
  • Quotas mensuels : Basés sur le mois calendaire en cours.

Le dépassement de l'une de ces limites entraîne une erreur 429. Les compteurs sont remis à zéro au début de chaque nouvelle période (jour, lundi ou 1er du mois).

GET /quotas

Consulte vos quotas autorisés, votre consommation actuelle et le nombre d'appels restants sur chaque période. Cet endpoint requiert l'authentification par API Key (x-api-key) et n'est pas soumis lui-même au décompte des quotas.

Exemple d'URL complète :
https://api.capfile.com/pro/v1.1/quotas

Réponse JSON

{
  "success": true,
  "code": 200,
  "message": "Usage et quotas",
  "data": {
    "quotas": {
      "day": 5000,
      "week": 50000,
      "month": 300000
    },
    "usage": {
      "day": 120,
      "week": 890,
      "month": 3400
    },
    "remaining": {
      "day": 4880,
      "week": 49110,
      "month": 296600
    }
  }
}
Champs de réponse
  • quotas : Limites autorisées pour votre compte, par période.
  • usage : Nombre d'appels déjà effectués sur la période en cours (jour, semaine calendaire, mois calendaire).
  • remaining : Nombre d'appels restants avant d'atteindre chaque quota (jamais négatif).

Table des grandeurs physiques

Codes utilisables pour le paramètre {GP} de l'endpoint /index. La disponibilité réelle par PRM est donnée par grandeurs_physiques dans /info.

Codes connus
  • EA : Energie Active (Wh)
  • ER : Energie Réactive (VARh)
  • ERI : Energie Réactive Inductive (VARh)
  • ERC : Energie Réactive Capacitive (VARh)
  • PMA : Puissance Maximale (VA)
  • TF : Temps de Fonctionnement (s)
  • DD : Durée de Dépassement (s)
  • DE : Dépassement Energétique (s)
  • DQ : Dépassement Quadratique (W)

Webhook : notification d'arrivée de données

Plutôt que d'interroger l'API en boucle, vous pouvez enregistrer une URL que Capfile appelle dès que de nouvelles données sont disponibles pour l'un des compteurs listés par /meters (vos compteurs et ceux partagés avec vous). La notification vous indique le compteur, le type de données et la période concernée : à vous ensuite d'aller chercher les données via /info, /index ou /loadcurve.

Les endpoints de configuration ci-dessous acceptent l'authentification par API Key ou Basic Auth et sont soumis aux quotas.

GET /webhook

Renvoie la configuration actuelle de votre webhook.

Réponse JSON

{
  "success": true,
  "code": 200,
  "message": "Configuration du webhook",
  "data": {
    "url": "https://www.monsite.fr/capfile/webhook",
    "secret": "3f9c…",
    "ssl_verify_peer": true,
    "ssl_verify_host": true,
    "configured": true
  }
}
Champs
  • url : URL appelée en POST à chaque notification.
  • secret : clé partagée servant à signer les notifications (voir Signature ci-dessous).
  • ssl_verify_peer / ssl_verify_host : vérification du certificat TLS de votre serveur (à laisser à true en production).
  • configured : true quand url et secret sont renseignés, c'est-à-dire quand les notifications sont actives.
POST /webhook

Enregistre ou modifie la configuration (PUT accepté). Corps JSON, tous les champs sont optionnels sauf url lors de la première configuration ; les champs absents conservent leur valeur.

{
  "url": "https://www.monsite.fr/capfile/webhook",
  "secret": "une-cle-secrete-de-16-caracteres-minimum",
  "ssl_verify_peer": true,
  "ssl_verify_host": true
}
Règles
  • url : absolue, en https (ou http), vers un hôte public. Les adresses locales ou privées sont refusées.
  • secret : 16 caractères minimum. S'il est omis à la première configuration, un secret aléatoire est généré et renvoyé dans la réponse.
  • La réponse contient la configuration enregistrée (même format que GET /webhook).
Erreurs
  • 400 : URL manquante ou invalide, secret trop court.
DELETE /webhook

Supprime la configuration et arrête les notifications (POST /webhook/delete accepté si votre client HTTP ne gère pas DELETE).

POST /webhook/test

Provoque immédiatement un appel de votre webhook avec une notification d'exemple, pour valider votre intégration. Le corps JSON est optionnel :

{
  "prm": "12345678901234",      // défaut : votre premier compteur
  "type": "loadcurve",          // info | index | loadcurve (défaut : loadcurve)
  "start_date": "2026-10-01",   // défaut : il y a 7 jours
  "end_date": "2026-10-07"      // défaut : aujourd'hui
}

La notification envoyée est identique à une notification réelle, avec en plus le champ "test": true. La réponse décrit le résultat de l'appel :

{
  "success": true,
  "code": 200,
  "message": "Webhook appelé",
  "data": {
    "status": "OK",
    "http_code": 200,
    "duration_ms": 143,
    "response": "…corps renvoyé par votre serveur (2000 premiers caractères)…",
    "payload": { "hook": "data_updated", "prm": "12345678901234", "name": "Bureau", "type": "loadcurve", "start_date": "2026-10-01", "end_date": "2026-10-07", "test": true },
    "signature": "a3c1…"
  }
}
Codes
  • 400 : webhook non configuré, type ou dates invalides, aucun compteur disponible.
  • 403 : PRM demandé non accessible depuis votre compte.
  • 502 : votre serveur n'a pas répondu en 2xx (success: false) ; status et response donnent le détail.

La notification reçue par votre serveur

Requête POST, en-tête Content-Type: application/json, corps JSON :

{
  "hook": "data_updated",
  "prm": "12345678901234",
  "name": "Bureau",
  "type": "loadcurve",
  "start_date": "2026-10-01",
  "end_date": "2026-10-07"
}
Champs
  • hook : type d'événement, toujours data_updated.
  • prm / name : compteur concerné (numéro de PRM et nom donné dans Capfile).
  • type : nature des données arrivées : info (caractéristiques techniques), index (index quotidiens) ou loadcurve (courbe de charge).
  • start_date / end_date : période couverte par les données reçues (absents pour info).
  • test : présent et à true uniquement pour les appels déclenchés par /webhook/test.
Livraison
  • Votre serveur doit répondre en 2xx dans les 10 secondes (5 s pour établir la connexion). Toute autre réponse est considérée comme un échec.
  • Pas de nouvelle tentative automatique : une notification manquée n'est pas renvoyée. Les données restent bien sûr disponibles via l'API.
  • Le sens (soutirage/injection) et les grandeurs physiques ne sont pas précisés : interrogez /index et /loadcurve pour les flux qui vous intéressent, avec la période indiquée.
  • Un même import peut générer plusieurs notifications (une par type de données).

Signature

Chaque notification porte un en-tête X-Signature contenant le HMAC-SHA256 (hexadécimal) du corps brut de la requête, calculé avec votre secret. Vérifiez-la avant tout traitement : c'est la garantie que la requête vient bien de Capfile et n'a pas été altérée.

<?php
// Réception d'une notification Capfile (exemple PHP)
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); exit; }

$secret   = 'votre-secret';                       // celui renvoyé par GET /webhook
$rawBody  = file_get_contents('php://input');     // corps brut, avant tout décodage
$expected = hash_hmac('sha256', $rawBody, $secret);
$received = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

if (!hash_equals($expected, $received)) { http_response_code(401); exit('Signature invalide'); }

$event = json_decode($rawBody, true);
if (!is_array($event) || ($event['hook'] ?? '') !== 'data_updated') { http_response_code(400); exit; }

http_response_code(200);   // répondre vite : le traitement lourd peut se faire ensuite
// … par exemple : mettre en file d'attente un appel à
//   GET /data/{$event['prm']}/{$event['type']}/… pour la période start_date → end_date

Codes d'erreur détaillés

En cas d'erreur, la réponse JSON a success: false et un code qui est aussi le statut HTTP de la réponse ; message précise la cause.

400 Bad Request

La requête contient des erreurs de syntaxe ou des paramètres manquants/invalides. Causes possibles :

  • PRM mal formé (doit faire exactement 14 chiffres).
  • {SENS} manquant ou différent de sou/inj.
  • {GP} manquant ou non disponible pour ce compteur (voir grandeurs_physiques dans /info).
  • Format de date invalide (le format attendu est YYYY-MM-DD) ou dates incohérentes.
  • Webhook : URL manquante ou invalide, secret trop court, webhook non configuré pour un test.

401 Unauthorized

Identifiants Basic Auth incorrects ou clé API x-api-key non reconnue.

403 Forbidden

Compte non pro, compteur non accessible depuis votre compte (ni à vous, ni partagé avec les droits nécessaires), ou période demandée au-delà de l'historique autorisé (3 ans pour /index, 1 an pour /loadcurve).

404 Not Found

Endpoint inconnu.

429 Too Many Requests

Un des quotas (journalier, hebdomadaire ou mensuel) a été atteint. L'en-tête Retry-After et le champ retry_after_seconds indiquent le délai avant le prochain appel possible.

502 Bad Gateway

/webhook/test uniquement : votre serveur n'a pas répondu en 2xx (ou pas répondu du tout) ; le détail est dans data.status et data.response.

500 Internal Server Error

Erreur inattendue côté Capfile. Réessayez plus tard ; si l'erreur persiste, contactez-nous avec l'URL appelée et l'heure de l'appel.