Inbound : Programme de soutirage
Endpoint inbound (opérateur de marché → SmartWatt). L'opérateur POST son programme de soutirage quotidien pour un ou plusieurs sites SmartWatt.
Cette version est le contrat qui fait foi.
Version courante du contrat : v0.2
Direction Opérateur de marché → SmartWatt. Vous transmettez chaque jour un programme de soutirage J+1 par site, à la maille 15 minutes en kWh.
Endpoint
POST /api/v0.5/energy-programs/programme-soutirage
Host: api.smartwatt.fr
Authorization: Bearer <INBOUND_TOKEN>
Content-Type: application/json
Le payload est l’enveloppe Programme_Soutirage (1 ou plusieurs sites, créneaux 15 min en kWh). Une instruction est persistée par site listé dans sites[].
Idempotence : envoyer deux fois le même couple (target_date, emitted_at, site_id) produit le même instruction_id côté SmartWatt et écrase l’instruction précédente.
Cadence d’envoi
Quotidien à J 12:30 Europe/Paris pour la journée J+1.
Authentification
Cert client mTLS + token Bearer scopé inbound:programme-soutirage, les deux obligatoires. Le token vous est fourni par SmartWatt. Voir Authentification pour le détail (cert client, rotation).
Un token sans le scope inbound:programme-soutirage reçoit 403 SCOPE_DENIED.
Format du payload
Une enveloppe contenant 1 ou plusieurs sites, chacun avec sa série de créneaux 15 minutes en kWh :
{
"schema_version": "v0.2",
"type": "programme_soutirage",
"emitted_by": "OperateurDeMarche",
"emitted_at": "2026-05-04T10:10:08Z",
"target_date": "2026-05-05",
"slot_duration_secs": 900,
"sites": [
{
"site_id": "PRM12345678901234",
"site_name": "SiteDemo",
"energie_programmee": [
{
"debut_utc": "2026-05-04T22:00:00Z",
"fin_utc": "2026-05-04T22:15:00Z",
"energie_kwh": 0
},
{
"debut_utc": "2026-05-04T22:45:00Z",
"fin_utc": "2026-05-04T23:00:00Z",
"energie_kwh": 20
},
{
"debut_utc": "2026-05-04T23:00:00Z",
"fin_utc": "2026-05-04T23:15:00Z",
"energie_kwh": 45
}
]
}
]
}
Champs
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
schema_version | string | oui | Version du schéma payload. Une seule valeur est acceptée : celle affichée en haut de page. |
type | string | oui | Toujours "programme_soutirage". |
emitted_by | string | non | Identifiant de l’émetteur, repris tel quel dans l’audit. |
emitted_at | ISO 8601 UTC | oui | Horodatage d’émission du fichier. Sert à dériver l’instruction_id. |
target_date | YYYY-MM-DD | oui | Jour cible (J+1 par convention). |
slot_duration_secs | int | oui | Durée d’un créneau. Standard : 900 (15 min). Doit être strictement positif. |
sites[].site_id | string | oui | PRM Enedis : PRM + 14 chiffres (ex PRM12345678901234). Doit exister côté SmartWatt. |
sites[].site_name | string | non | Libellé lisible du site. Informatif, sans effet sur le traitement. |
sites[].energie_programmee[] | array | oui | Liste contiguë d’au moins un créneau. energie_kwh = 0 = effacement. |
schema_version : valeur exacte exigée
La validation compare schema_version à la version en vigueur par égalité stricte. Un champ
absent est refusé (is required), et une valeur périmée ou mal formée l’est aussi : "0.2" sans
le préfixe v échoue au même titre qu’une version antérieure. Les deux cas renvoient un 400
INVALID_PROGRAMME_SOUTIRAGE_REQUEST dont les details portent le motif sur la clé
schema_version.
Conséquence à anticiper : lors d’une montée de version du contrat, la nouvelle valeur devient la seule acceptée. Surveillez le sélecteur en haut de page et la communication de mise en service.
Sémantique
energie_kwh > 0= consommation cible (surconsommation).energie_kwh = 0= effacement (pas de charge sur ce créneau).- Créneau absent = pas de contrainte.
- Créneaux 15 min alignés sur
HH:00,HH:15,HH:30,HH:45. - Référentiel temporel : ISO 8601 UTC, suffixe
Z.
Conversion énergie → puissance
SmartWatt convertit côté SmartWatt :
power_kw = energie_kwh / (slot_duration_secs / 3600)
Pour des créneaux 15 min : power_kw = energie_kwh × 4. SmartWatt applique cette puissance comme plancher sur le créneau : la consigne doit être atteinte au minimum, l’overshoot n’est pas crédité.
Réponse
Succès : 202 Accepted
{
"status": "received",
"count": 1,
"instructions": [
{
"instruction_id": "ProgrammeSoutirage-2026-05-05-rev-20260504T101008Z-PRM12345678901234",
"site_id": "PRM12345678901234",
"periods_count": 96
}
],
"message": "instructions persisted, will be applied at next solver cycle"
}
L’instruction_id est dérivé côté SmartWatt, l’expéditeur ne le fournit pas. Il se termine toujours par le site_id de l’instruction, y compris pour un envoi mono-site : deux envois pour deux sites dans la même seconde reçoivent deux identifiants distincts.
Erreurs
| Code | error.code | Cas typiques |
|---|---|---|
400 | INVALID_PROGRAMME_SOUTIRAGE_REQUEST | schema_version manquant ou périmé, type ≠ programme_soutirage, target_date mal formé, créneaux non contigus, énergie négative, alignement slot incorrect |
400 | UNKNOWN_FIELD | le payload porte un champ que le contrat en vigueur ne prévoit pas. Aucun champ hors contrat n’est toléré, y compris un champ d’une version ultérieure |
400 | INVALID_DATETIME | horodatage non parsable (emitted_at, debut_utc, fin_utc) |
400 | INVALID_JSON_TYPE | champ présent mais du mauvais type JSON (chaîne là où un nombre est attendu, etc.) |
400 | INVALID_JSON | corps illisible, ou plusieurs valeurs JSON à la suite dans un même corps |
400 | SITE_NOT_FOUND | un site_id du payload n’existe pas côté SmartWatt. Cas le plus fréquent au premier envoi : vérifiez le PRM auprès de votre contact SmartWatt |
401 | header Authorization: Bearer absent ou token invalide / expiré / révoqué | |
403 | SCOPE_DENIED ou MTLS_REQUIRED | scope inbound:programme-soutirage absent, cert client mTLS absent, ou subject ne matche pas |
500 | DB_ERROR | erreur de persistance côté SmartWatt. Rejouez l’envoi ; si l’erreur persiste, signalez-la |
500 | NO_INTEGRATOR_CTX | contexte d’intégrateur absent : anomalie de configuration côté SmartWatt, à signaler (rien à corriger dans votre payload) |
503 | NO_STORE | base de données indisponible (transitoire, retry après quelques secondes) |
Seul INVALID_PROGRAMME_SOUTIRAGE_REQUEST renseigne error.details champ par champ. Les erreurs de
décodage (UNKNOWN_FIELD, INVALID_DATETIME, INVALID_JSON_TYPE) surviennent avant la
validation métier : elles s’arrêtent au premier problème rencontré et reportent le message du
décodeur, sans liste exhaustive des champs en faute.
Le détail des champs en faute est renvoyé dans error.details (chemin JSON pointer → message) :
{
"error": {
"code": "INVALID_PROGRAMME_SOUTIRAGE_REQUEST",
"message": "ProgrammeSoutirage request validation failed",
"details": {
"sites[0].energie_programmee[3].debut_utc": "must be aligned to 900s boundary"
}
}
}
Exemple curl
curl -X POST https://api.smartwatt.fr/api/v0.5/energy-programs/programme-soutirage \
--cert /path/to/bsp-client.crt \
--key /path/to/bsp-client.key \
-H "Authorization: Bearer $INBOUND_TOKEN" \
-H "Content-Type: application/json" \
-d @Programme_Soutirage_2026-05-05.json