Outbound : Besoins agrégés

Endpoint pull (SmartWatt expose, le BSP vient tirer). Pour chaque site et date cible, SmartWatt publie un Besoins_Agreges.

Version courante du contrat : v0.2

Direction SmartWatt → opérateur de marché (BSP). Modèle d’intégration pull : SmartWatt expose un endpoint HTTPS sur lequel vous venez récupérer le Besoins_Agreges publié pour un couple (site_id, target_date). SmartWatt ne pousse jamais le fichier chez vous, c’est vous qui appelez.

Endpoint

GET /api/v0.5/energy-programs/besoins-agreges?site_id=<PRM>&target_date=<YYYY-MM-DD>
Host: api.smartwatt.fr
Authorization: Bearer <OUTBOUND_TOKEN>
Accept: application/json
ParamètreTypeDescription
site_idstring (PRM Enedis)identifiant du site. Ex: PRM12345678901234
target_dateYYYY-MM-DDjournée cible. Ex: 2026-06-13

Les deux paramètres sont obligatoires. Le serveur retourne le dernier Besoins_Agreges publié pour ce couple (s’il y a eu plusieurs révisions, c’est emitted_at DESC LIMIT 1 côté SmartWatt).

Cadence de publication

SmartWatt publie quotidiennement à J-1 08:00 Europe/Paris, plus une republication hebdomadaire vendredi 08:00 Europe/Paris pour le weekend. Pour ne pas tirer un fichier obsolète, attendez ~08:30 Europe/Paris pour la première tentative de la journée.

Pour le polling intra-journée (révisions), utilisez les en-têtes de cache (cf. plus bas) : vous payez seulement le coût d’un HEAD sémantique tant que rien n’a changé.

Authentification

Cert client mTLS + token Bearer scopé outbound:besoins-agreges, les deux obligatoires. Le token se génère depuis votre espace dashboard. Voir Authentification pour le détail (cert client, génération du token, rotation).

Un token sans le scope outbound:besoins-agreges reçoit 403 SCOPE_DENIED.

Réponse

Succès : 200 OK

HTTP/1.1 200 OK
Content-Type: application/json
ETag: W/"id-1842-7d3e1f2a"
Last-Modified: Thu, 12 Jun 2026 06:00:00 GMT
Cache-Control: private, max-age=60, must-revalidate

Ordre des champs préservé :

{
  "schema_version": "v0.2",
  "type": "besoins_agreges",
  "emitted_by": "SmartWatt",
  "emitted_at": "2026-06-12T06:00:00Z",
  "target_date": "2026-06-13",
  "coverage_start_utc": "2026-06-12T22:00:00Z",
  "coverage_end_utc": "2026-06-14T00:00:00Z",
  "slot_duration_secs": 900,
  "sites": [
    {
      "site_id": "PRM12345678901234",
      "site_name": "SiteDemo",
      "jalons_besoin": [
        {
          "debut_utc": "2026-06-12T22:00:00Z",
          "deadline_utc": "2026-06-13T03:00:00Z",
          "valeur_kwh": 180,
          "puissance_kW": 36
        }
      ],
      "puissance_disponible": [
        { "debut_utc": "2026-06-12T22:00:00Z", "fin_utc": "2026-06-12T22:15:00Z", "p_max_kw": 120 }
      ]
    }
  ]
}

Pas encore publié : 404 Not Found

Si SmartWatt n’a pas (encore) publié pour ce (site_id, target_date), vous recevez 404 avec :

{
  "type": "https://api.smartwatt.fr/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "no Besoins_Agreges published for this (site_id, target_date)"
}

Réessayez plus tard (cf. cadence). Pas de retry plus fréquent que toutes les 5 minutes recommandé.

Erreurs

CodeCas
400site_id ou target_date manquant ou mal formé (target_date doit être YYYY-MM-DD)
401header Authorization: Bearer absent ou token invalide / expiré / révoqué
403token valide mais scope outbound:besoins-agreges absent, ou entreprise suspendue
404pas de publication pour ce couple, réessayez plus tard
503base de données indisponible (transitoire, retry après quelques secondes)

Cache HTTP

Le serveur émet un ETag faible et un Last-Modified. Utilisez-les pour éviter de re-télécharger un fichier identique :

GET /api/v0.5/energy-programs/besoins-agreges?site_id=PRM12345678901234&target_date=2026-06-13
Authorization: Bearer <OUTBOUND_TOKEN>
If-None-Match: W/"id-1842-7d3e1f2a"

Si rien n’a changé depuis l’ETag fourni, le serveur répond 304 Not Modified sans body :

HTTP/1.1 304 Not Modified
ETag: W/"id-1842-7d3e1f2a"
Last-Modified: Thu, 12 Jun 2026 06:00:00 GMT

Alternative : If-Modified-Since (header standard HTTP/1.1), fonctionne pareil mais à la résolution seconde.

Recommandation : conservez le dernier ETag par (site_id, target_date) et présentez-le aux requêtes suivantes. Côté réseau, un 304 est ~quelques centaines d’octets contre plusieurs kilo-octets pour le 200 + body complet.

Idempotence et révisions

Une republication SmartWatt (= correction intra-journée) émet un emitted_at plus récent et un nouvel ETag. Le target_date reste le même. Conséquence côté votre SI :

  • la clé de stockage côté vous = (site_id, target_date) : la dernière révision écrase la précédente
  • pour audit, conservez le emitted_at reçu : il prouve quel snapshot vous avez consommé

Exemple curl

curl -i \
  -H "Authorization: Bearer $OUTBOUND_TOKEN" \
  "https://api.smartwatt.fr/api/v0.5/energy-programs/besoins-agreges?site_id=PRM12345678901234&target_date=2026-06-13"

Avec ETag :

curl -i \
  -H "Authorization: Bearer $OUTBOUND_TOKEN" \
  -H "If-None-Match: W/\"id-1842-7d3e1f2a\"" \
  "https://api.smartwatt.fr/api/v0.5/energy-programs/besoins-agreges?site_id=PRM12345678901234&target_date=2026-06-13"

Fallback console web

Si votre intégration API est indisponible, le dernier Besoins_Agreges publié reste accessible via la console web SmartWatt (login dashboard, page « Besoins agrégés »). C’est un fallback opérationnel, pas un canal de production : privilégiez l’API.