- Home
- Supporto
- API telelettura
API telelettura
Il tuo software legge da enerdata i contatori, le curve di carico al quarto d'ora e i registri mensili 1.8.0 e 2.8.0 già acquisiti, con i filtri che servono. Sola lettura, in JSON o CSV. Le chiamate all'API non consumano crediti.
Come si inizia
Dalla chiave alla prima sincronizzazione.
L'API legge gli stessi dati che vedi in enerdata, nelle pagine Contatori e Letture. Non chiama i contatori: le letture le fa enerdata, con le sue programmazioni e le tue richieste.
- 01Chiedi l'attivazione
Attiviamo l'API sulla tua istanza e ti mandiamo la chiave. La chiave è una sola per istanza e legge tutti i contatori.
- 02Prova la chiave
Chiama
GET /status: risponde con il numero di contatori che la chiave legge. - 03Scarica i contatori
Con
GET /metershai l'elenco, con l'id di ogni contatore da usare nelle letture. - 04Scarica le letture, poi solo le nuove
La prima volta chiedi il periodo che ti serve. Dopo, ogni giorno o ogni ora, chiedi solo quello che è stato letto dall'ultima volta con
read_since.
Accesso
Un indirizzo, una chiave.
Tratta la chiave come una password: la vedi una volta sola, quando la creiamo. Se la perdi o pensi che qualcuno la conosca, te ne diamo una nuova e quella di prima smette subito di funzionare.
- Indirizzo
https://app.enerdata.it/api/v1- Chiave
- In ogni chiamata, nell'intestazione
Authorization: Bearer <chiave>. La chiave comincia coned_e dice a quale istanza appartiene. - Chiamate
- Solo
GET: l'API legge e non cambia niente. Al massimo 60 chiamate al minuto. - Formato
- JSON in UTF-8. Con
format=csvle stesse righe in CSV: virgola come separatore, punto per i decimali, una riga di intestazione. - Date e ore
- Ora italiana, senza fuso:
2026-11-05T09:30. GiorniAAAA-MM-GG, mesiAAAA-MM. - Energia
- In kWh. La curva è già moltiplicata per il fattore K del contatore, i registri danno la lettura del contatore e i kWh del mese calcolati con il K.
- Errori
- Codice HTTP e un JSON
{"error": "..."}con il motivo, in inglese, per i log.
Prova della chiave
/statusRisponde se la chiave funziona, con il numero di contatori che legge. Serve a provare il collegamento e la chiave prima di tutto il resto.
Chiamata
curl https://app.enerdata.it/api/v1/status \ -H "Authorization: Bearer ed_demo1_XXXXXXXXXXXXXXXXXXXXXXXX"
Risposta
{"ok": true, "meters": 42}
Contatori
/meters/meters/{id}L'elenco dei contatori dell'istanza, con i loro dati e lo stato dell'ultima lettura. /meters/{id} dà un contatore solo. Senza filtri, tutti.
| Parametro | Cosa fa |
|---|---|
q | Cerca nell'impianto, nel modello, nella matricola e nel telefono. |
model | Solo un modello, come in enerdata: EMH - LZQJ-XC. |
reachability | reachable, unreachable o never_read. |
curve_mode | daily, monthly o none. |
meter | Uno o più id, separati da virgola. |
size, offset | Contatori per pagina, da 1 a 500 (100 se manca), e quanti saltarne (0 se manca): vedi Pagine. |
format | json (se manca) o csv. |
Risposta
{"meters": [
{"id": 47597436551038921,
"plant": "Impianto Rossi 1",
"model": "EMH - LZQJ-XC",
"serial": "10008139",
"phone": "3465113516",
"k": 400.0,
"register_fed": "2.8.0",
"curve_mode": "daily",
"monthly_totals": true,
"reachability": "reachable",
"status": "Ok",
"last_read_at": "2026-11-05T00:31"}
],
"offset": 0, "size": 100, "total": 42}
| Campo | Cosa contiene |
|---|---|
id | L'id del contatore in enerdata: non cambia mai. |
k | Il fattore K, il moltiplicatore delle letture. |
register_fed | Il registro dell'energia immessa, 1.8.0 o 2.8.0. L'altro è quella prelevata. null finché enerdata non l'ha riconosciuto. |
curve_mode | La lettura automatica della curva: daily ogni giorno, monthly il primo del mese, null solo a richiesta. |
monthly_totals | I registri del mese chiuso, letti il primo del mese. |
reachability, status | Com'è andata l'ultima lettura: raggiungibile, non raggiungibile o mai letto, e lo stato come lo mostra enerdata (Ok, Non raggiungibile, Segnale debole...). |
last_read_at | Quando il contatore è stato letto l'ultima volta. |
Curva di carico
/readings/loadsLa curva al quarto d'ora, un elemento per contatore e giorno: i 96 quarti d'ora con i kWh immessi e prelevati, il totale del giorno e l'ora della lettura. I giorni senza dati non ci sono.
Un quarto d'ora porta l'ora del suo inizio: 00:00 è il quarto dalle 00:00 alle 00:15, come in Esporta di enerdata. Un quarto non letto vale null. Nei giorni del cambio d'ora i quarti restano 96, nell'ora italiana.
| Parametro | Cosa fa |
|---|---|
from | Il primo giorno, AAAA-MM-GG. Obbligatorio. |
to | L'ultimo giorno, compreso. Se manca, solo from. |
meter | Uno o più id, separati da virgola. Se manca, tutti i contatori. |
read_since | Solo i giorni letti da quest'ora in poi: vedi Solo i dati nuovi. |
size, offset | Giorni per pagina, da 1 a 366 (31 se manca), e quanti saltarne. |
format | json o csv. In CSV una riga per quarto d'ora: meter_id, date, start, kwh_fed, kwh_drawn, register_fed, read_at. |
Chiamata
curl "https://app.enerdata.it/api/v1/readings/loads?meter=47597436551038921&from=2026-11-01&to=2026-11-04" \ -H "Authorization: Bearer ed_demo1_XXXXXXXXXXXXXXXXXXXXXXXX"
Risposta
{"loads": [
{"meter_id": 47597436551038921,
"date": "2026-11-01",
"register_fed": "2.8.0",
"read_at": "2026-11-02T00:31",
"kwh_fed": 812.4,
"kwh_drawn": 3.2,
"quarters": [
{"start": "2026-11-01T00:00", "kwh_fed": 0.0, "kwh_drawn": 0.04},
{"start": "2026-11-01T00:15", "kwh_fed": 0.0, "kwh_drawn": 0.04},
... 96 quarti, fino alle 23:45
]}
],
"offset": 0, "size": 31, "total": 4}
| Campo | Cosa contiene |
|---|---|
register_fed | Il registro dell'energia immessa. Se il contatore non ce l'ha ancora, il canale con più energia. |
kwh_fed, kwh_drawn | I kWh immessi e prelevati, del giorno e di ogni quarto d'ora. |
read_at | Quando il giorno è stato letto l'ultima volta. null se la lettura si è interrotta a metà: enerdata lo rilegge, e il giorno torna con i dati completi e la nuova ora. |
Registri mensili
/readings/totalsLe letture dei registri 1.8.0 e 2.8.0, un elemento per contatore e mese, e i kWh del mese: la lettura del mese meno quella del mese prima, per il fattore K. Il mese in corso ha la lettura fatta finora, e closed a false.
| Parametro | Cosa fa |
|---|---|
from | Il primo mese, AAAA-MM. Obbligatorio. |
to | L'ultimo mese, compreso. Se manca, il mese in corso. |
meter, read_since | Come per la curva. |
size, offset | Mesi per pagina, da 1 a 1000 (120 se manca), e quanti saltarne. |
format | json o csv, una riga per contatore e mese. |
Risposta
{"totals": [
{"meter_id": 47597436551038921,
"month": "2026-10",
"closed": true,
"register_fed": "2.8.0",
"reading_1_8_0": 10.5,
"reading_2_8_0": 1100.0,
"k": 400.0,
"kwh_fed": 40000.0,
"kwh_drawn": 200.0,
"read_at": "2026-11-01T00:11"}
],
"offset": 0, "size": 120, "total": 1}
| Campo | Cosa contiene |
|---|---|
reading_1_8_0, reading_2_8_0 | Le letture dei registri come le dà il contatore, senza K. |
kwh_fed, kwh_drawn | I kWh immessi e prelevati nel mese. null se manca la lettura del mese prima, o se il registro dell'immessa non è ancora riconosciuto. |
read_at | Quando il mese è stato letto. |
Pagine e dati nuovi
Si scarica a pagine, poi solo quello che è cambiato.
Ogni risposta dà al massimo size elementi, saltando i primi offset, e in total quanti sono in tutto con quei filtri. Per la pagina dopo rifai la stessa chiamata con offset aumentato di size, finché offset arriva a total. In CSV il totale arriva nell'intestazione X-Total-Count, e per la curva conta i giorni, non le righe dei quarti d'ora. Gli elementi sono in ordine di contatore, poi di giorno o di mese.
Per tenere il tuo software allineato non serve riscaricare tutto. Salva il read_at più recente che hai ricevuto e alla volta dopo passalo come read_since: arrivano solo i giorni e i mesi letti da allora, compresi quelli riletti. Salva le righe per contatore e giorno (o mese), sovrascrivendo quelle che hai già.
Esempio in Python, solo libreria standard
import json import urllib.parse import urllib.request BASE = "https://app.enerdata.it/api/v1" KEY = "ed_demo1_XXXXXXXXXXXXXXXXXXXXXXXX" # la tua chiave def get(path, **params): query = urllib.parse.urlencode({k: v for k, v in params.items() if v}) req = urllib.request.Request(f"{BASE}{path}?{query}", headers={"Authorization": "Bearer " + KEY}) with urllib.request.urlopen(req, timeout=60) as r: return json.load(r) # la curva letta dall'ultima volta, pagina per pagina since = load_last_read_at() # es. "2026-11-04T00:31" offset, newest = 0, since while True: page = get("/readings/loads", **{"from": "2026-01-01", "to": "2026-12-31", "read_since": since, "size": 100, "offset": offset}) for day in page["loads"]: save_day(day) # per meter_id e date: sovrascrivi newest = max(newest or "", day["read_at"] or "") offset += page["size"] if offset >= page["total"]: break save_last_read_at(newest)
Le funzioni load_last_read_at, save_day e save_last_read_at sono quelle del tuo software.
Errori
Il codice dice cosa fare.
Con 401 e 403 non insistere: la chiamata non andrà finché non cambia la chiave o la situazione dell'istanza. Con 429 aspetta i secondi di Retry-After.
| Codice | Quando |
|---|---|
200 | Tutto bene. |
400 | Un parametro non va: una data scritta male, to prima di from, un size o un offset fuori dai valori. |
401 | Chiave mancante, sbagliata o revocata. |
403 | API non attiva sulla tua istanza, oppure istanza sospesa. |
404 | Il contatore non c'è, oppure l'indirizzo non esiste. |
405 | Una chiamata diversa da GET. |
429 | Più di 60 chiamate al minuto. |
5xx | Un errore nostro: riprova dopo qualche minuto, e se continua scrivici. |
Attivazione
Come si attiva.
Le chiamate all'API non consumano crediti: sono un altro modo di prendere i dati che enerdata ha già letto, come Esporta. Per attivarla sulla tua istanza scrivici: ti mandiamo la chiave.