Consent flow in detail
After you create a meter, no data flows until you request consent and the grid operator (VNB) approves. This article documents the status values you can observe on a meter, how to poll while consent settles, and what external events can revoke an existing consent.
Meter status values
The status field on a meter reflects where consent stands:
status |
Meaning |
|---|---|
not_connected |
No consent has been requested, or the meter was disconnected. |
pending |
The request was sent to the VNB. We are waiting for the first response. |
processing |
The VNB acknowledged the request, but the customer still has to confirm in the VNB's portal. |
connected |
Consent is active. Data is flowing. |
failed |
The VNB rejected the request, or the customer did not confirm in time. Edit the meter and retry. |
disconnecting |
A revocation was sent. The VNB has not confirmed it yet. |
Only meters in connected deliver data. processing is normal: depending on the grid operator, the customer may have several days to confirm in the operator's portal.
Requesting consent
curl -X POST https://energiedaten.at/api/v1/smart-meters/«meter.id»/consent \
-H "Authorization: Bearer $API_TOKEN" \
-H "Energiedaten-Version: 2026-05-08" \
-H "Idempotency-Key: $(uuidgen)"
The call is asynchronous. The response confirms the consent message was sent. It does not mean consent has been granted. Poll the meter's status to track progress.
Polling pattern
Most consents settle within a few hours. Some VNBs respond within minutes; cases that require the customer to confirm in the operator's portal can take noticeably longer. Use a backoff:
import time, requests
def wait_for_consent(meter_id: str, token: str, timeout_hours: int = 2):
url = f"https://energiedaten.at/api/v1/smart-meters/{meter_id}"
headers = {"Authorization": f"Bearer {token}"}
terminal = {"connected", "failed"}
elapsed = 0
interval = 10 # first minute: every 10 seconds
while elapsed < timeout_hours * 3600:
meter = requests.get(url, headers=headers).json()["data"]
if meter["status"] in terminal:
return meter["status"]
time.sleep(interval)
elapsed += interval
if elapsed >= 60:
interval = 60
return "timeout"
async function waitForConsent(meterId, token, timeoutHours = 2) {
const url = `https://energiedaten.at/api/v1/smart-meters/${meterId}`;
const terminal = new Set(['connected', 'failed']);
let elapsed = 0;
let interval = 10_000;
while (elapsed < timeoutHours * 3_600_000) {
const res = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` } });
const { data: meter } = await res.json();
if (terminal.has(meter.status)) return meter.status;
await new Promise(r => setTimeout(r, interval));
elapsed += interval;
if (elapsed >= 60_000) interval = 60_000;
}
return 'timeout';
}
Recommended backoff: every 10 seconds for the first minute, then every 60 seconds for an hour, then once per hour. Polling faster only burns your rate limit; it will not make the VNB respond sooner.
External revocations
A connected meter can return to not_connected without action on your side:
- The customer revokes consent directly with the VNB.
- The VNB revokes consent, for example after a meter exchange or removal.
Watch for status transitions out of connected between polls. If your application depends on the data stream, treat any status other than connected as an interruption and surface it to whoever owns the meter on your side.
Webhooks (Phase 2)
Phase 2 will deliver consent.granted, consent.rejected, and consent.revoked webhooks. Once available, polling will no longer be necessary. You can subscribe under Integrations → Connections.