Aller au contenu principal

API HTTP

L'API HTTP convient aux appareils qui ne peuvent pas maintenir une connexion ouverte, aux réseaux qui n'autorisent que du HTTPS ordinaire et à la mise en route du firmware : contrairement à MQTT, chaque requête répond en vous indiquant ce que la plateforme a fait de chacun des relevés que vous avez envoyés.

URL de base

https://api.sensocan.com/api/v1

Authentification

Chaque requête transporte le jeton d'accès (access token) de l'appareil sous forme de jeton Bearer :

Authorization: Bearer {DEVICE_ACCESS_TOKEN}

Obtenez le jeton depuis Détails de l'appareilAfficher le jeton. Le jeton appartient à un seul appareil, et l'URL à laquelle vous envoyez vos relevés doit porter l'UUID de ce même appareil.

Détails de l'appareil après un appui sur Afficher le jeton : la boîte de dialogue du jeton de l'appareil est ouverte, le jeton d'accès y est visible avec son bouton de copie, pour que le lecteur voie d'où vient le jeton Bearer.
Détails de l'appareil après un appui sur Afficher le jeton : la boîte de dialogue du jeton de l'appareil est ouverte, le jeton d'accès y est visible avec son bouton de copie, pour que le lecteur voie d'où vient le jeton Bearer.
Régénérer le jeton bloque l'appareil

L'action de régénération, dans la même boîte de dialogue, émet un nouveau jeton et invalide l'ancien dans le même geste. Chaque appareil qui utilise l'ancien jeton commence à recevoir des 401 tant que vous n'y avez pas flashé le nouveau.

En-têtes

En-têteValeurObligatoire
AuthorizationBearer {DEVICE_ACCESS_TOKEN}Oui
Content-Typeapplication/jsonOui
Acceptapplication/jsonRecommandé — sans lui, la réponse de limite de requêtes revient en HTML et non en JSON

Points de terminaison (endpoints)

1. Un relevé pour un capteur

POST /devices/{device_uuid}/sensors/{sensor}/readings

{sensor} est soit le slug du capteur (son identifiant court), soit son UUID : les deux figurent sur la page du capteur.

{
"data": {
"value": 25.5,
"timestamp": "2026-09-03T10:00:00Z"
},
"battery_voltage": 3.7
}
ChampTypeObligatoireNotes
dataobjetOuiExactement un relevé. Pour en envoyer plusieurs, le point de terminaison par lot
data.valuenombreOuiLes valeurs non numériques sont rejetées
data.timestampchaîne ISO 8601NonPar défaut, l'heure d'arrivée de la requête
battery_voltagenombre (volts), de 0 à 100NonSe place à côté de data, pas à l'intérieur

Toute autre clé placée dans data est conservée en métadonnées avec le relevé : voir les règles de charge utile communes.

2. Plusieurs relevés pour un capteur

POST /devices/{device_uuid}/sensors/{sensor}/readings/bulk
{
"data": [
{ "value": 22.1, "timestamp": "2026-09-03T09:00:00Z" },
{ "value": 22.4, "timestamp": "2026-09-03T09:15:00Z" },
{ "value": 22.8, "timestamp": "2026-09-03T09:30:00Z" }
],
"battery_voltage": 3.6
}

data doit être un tableau comportant au moins une entrée. Chaque entrée suit les mêmes règles que data ci-dessus.

3. Des relevés pour plusieurs capteurs

POST /devices/{device_uuid}/readings
{
"data": [
{
"sensor_slug": "temp_01",
"value": 25.5,
"timestamp": "2026-09-03T10:00:00Z"
},
{ "sensor_uuid": "7a8b9c0d-1234-5678-90ab-cdef12345678", "value": 60.2 },
{ "sensor_slug": "door_01", "value": 1 }
],
"battery_voltage": 3.7
}

Chaque entrée désigne son propre capteur avec sensor_slug ou sensor_uuid ; l'un des deux est obligatoire. Utilisez ce point de terminaison pour un appareil qui porte plusieurs capteurs : trois requêtes distinctes font trois fois le même travail.

Ce que la réponse vous apprend

Une requête qui a fait passer au moins un relevé répond 202 Accepted :

{
"message": "Readings accepted and queued for rule chain processing.",
"accepted": 3,
"duplicates": 0,
"rejected": {},
"sensor": "temp_01"
}
ChampSignification
acceptedLes relevés remis à la chaîne de règles
duplicatesLes relevés reconnus comme la répétition d'un envoi antérieur. Comptés comme un succès : rejouer un tampon est sans risque
rejectedLes motifs d'écartement rencontrés, avec leur nombre. Vide ({}) quand rien n'a été écarté
sensorL'identifiant que vous avez mis dans l'URL, renvoyé tel quel. Seulement sur les deux points de terminaison à capteur unique

Un succès partiel reste un 202 : cinq relevés envoyés, trois acceptés et deux rejetés, vous valent un 202 accompagné du détail. Lisez les nombres, et ne prenez pas le code de statut à lui seul pour la preuve que tout est arrivé.

Accepté veut dire mis en file, pas enregistré

Un relevé accepté est remis à la chaîne de règles qui s'applique à ce capteur, et c'est cette chaîne qui décide de son sort, y compris de son enregistrement. Une chaîne dépourvue d'étape d'enregistrement produit exactement cela : des réponses 202 impeccables et aucune donnée nulle part dans l'interface. Chaque compte démarre avec une Chaîne de règles par défaut qui enregistre ; si vous avez construit la vôtre, vérifiez-la dans Gestion → Chaînes de règles.

Les motifs de rejet

Les clés qui peuvent apparaître dans rejected :

CléCe que cela signifieComment y remédier
dropped_unknown_sensorL'identifiant ne correspondait à aucun capteur de cet appareilComparez-le au slug et à l'UUID affichés sur la page du capteur. La correspondance est exacte et sensible à la casse
dropped_missing_identifierUne entrée du lot n'avait ni sensor_slug ni sensor_uuidDonnez l'un des deux à chaque entrée
dropped_missing_valueUn relevé n'avait pas de valueEnvoyez value sur chaque relevé ; pour un échantillon raté, n'envoyez pas null, omettez-le
dropped_invalid_shapeLa structure de data ne correspondait pas au point de terminaisonEnvoyez un objet au point de terminaison unitaire et un tableau aux deux autres
dropped_future_timestampUn horodatage restait en avance sur l'heure du serveur après correction d'horlogeEnvoyez un horodatage ISO 8601, ou omettez-le et laissez l'heure d'arrivée faire foi
dropped_duplicateLa même valeur pour le même capteur est revenue dans la fenêtre de suppression des doublonsRien à corriger. Signalé dans duplicates, jamais dans rejected

Erreurs

CodeCorpsCause et remède
401{"message":"Device authentication token required.","error":"missing_token"}Pas d'en-tête Authorization, ou pas sous la forme Bearer …
401{"message":"Invalid device authentication token.","error":"invalid_token"}Le jeton n'appartient pas à l'appareil désigné dans l'URL, ou il a été régénéré
404{"message":"Device not found.","error":"device_not_found"}Le {device_uuid} de l'URL ne désigne aucun appareil. Recopiez-le depuis Détails de l'appareil
404{"message":"No reading matched a sensor on this device.","error":"sensor_not_found","sensors":["temp_01"]}Rien dans la charge utile (payload) ne visait un capteur réel. sensors liste les identifiants restés sans correspondance
422{"message":"Validation failed.","errors":{"data.value":["The sensor value is required."]}}Le corps de la requête est mal formé. errors nomme le champ fautif
422{"message":"No readings were accepted.","error":"no_readings_accepted","rejected":{"dropped_missing_value":2}}Le corps était valide mais tous les relevés ont été écartés. rejected en dit la raison
429{"message":"Too Many Attempts."}Limite de requêtes atteinte. Temporisez, puis réessayez : voir ci-dessous

Les échecs de validation courants derrière un 422 Validation failed : data absent ou vide, value absent ou non numérique, timestamp qui n'est pas une date analysable, une entrée de lot sans sensor_slug ni sensor_uuid, battery_voltage hors de la plage de 0 à 100.

Limitation des requêtes

La limite est de 1000 requêtes par minute. Elle se compte par adresse source : plusieurs appareils derrière une même connexion internet se partagent donc le budget.

En-têtePrésent surSignification
X-RateLimit-LimitToute réponseLe plafond — 1000
X-RateLimit-RemainingToute réponseRequêtes restantes dans la fenêtre en cours
Retry-After429 seulementSecondes à attendre avant de réessayer
X-RateLimit-Reset429 seulementLe moment où la fenêtre se réinitialise

Respectez Retry-After au lieu de réessayer aussitôt, et temporisez de façon exponentielle si vous continuez à buter dessus. Si un appareil s'approche de la limite, regroupez ses capteurs dans une seule requête plutôt que d'envoyer une requête par capteur.

Exemple complet

curl -X POST \
https://api.sensocan.com/api/v1/devices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/readings \
-H "Authorization: Bearer your-device-access-token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"data": [
{ "sensor_slug": "temp_01", "value": 25.5 },
{ "sensor_slug": "humidity_01", "value": 60.2 }
],
"battery_voltage": 3.7
}'
{
"message": "Readings accepted and queued for rule chain processing.",
"accepted": 2,
"duplicates": 0,
"rejected": {}
}

Traiter les réponses dans le firmware

  • 202 — videz votre tampon de tout ce qui est compté dans accepted et duplicates. Un relevé passé dans rejected ne réussira pas davantage à la reprise : consignez-le plutôt que de le renvoyer indéfiniment.
  • 401 et 404 — c'est de la configuration, pas un incident passager. Cessez de réessayer et remontez le problème là où un opérateur le verra.
  • 422 — un problème de firmware. Consignez le corps de la réponse : il nomme le champ en cause.
  • 429 — attendez le nombre de secondes indiqué par Retry-After, puis réessayez.
  • 5xx ou pas de réponse — c'est passager. Temporisez de façon exponentielle et gardez les relevés en tampon ; les horodatages rendent le rattrapage exact, et une horloge en avance ne vous coûte rien.

Dépannage

Des réponses 202 mais aucune donnée nulle part. Ouvrez la page Détails de l'appareil. Le tableau des capteurs affiche pour chaque capteur sa Valeur actuelle et sa Dernière mise à jour.

Le tableau des capteurs sur Détails de l'appareil, avec au moins un capteur qui affiche une Valeur actuelle et un horodatage de Dernière mise à jour, et un capteur qui indique encore « Aucune donnée », pour que la différence se voie côte à côte.
Le tableau des capteurs sur Détails de l'appareil, avec au moins un capteur qui affiche une Valeur actuelle et un horodatage de Dernière mise à jour, et un capteur qui indique encore « Aucune donnée », pour que la différence se voie côte à côte.

Si Dernière connexion se met à jour alors que chaque capteur indique « Aucune donnée », c'est que la chaîne de règles ne les enregistre pas : vérifiez Gestion → Chaînes de règles. Si certains capteurs se mettent à jour et d'autres non, les identifiants des capteurs muets ne correspondent à aucun capteur de cet appareil, et le corps du 404 comme les compteurs de rejected vous le disaient déjà.

Tout renvoie 401. Vérifiez que le jeton n'a pas été régénéré et que l'UUID d'appareil présent dans l'URL est bien celui auquel ce jeton appartient. Un jeton qui fonctionne pour un appareil est rejeté sur un autre.

Les relevés mis en tampon reviennent en doublons. C'est la réponse attendue à un rejeu. Considérez-les comme transmis et faites avancer votre tampon.