{"openapi":"3.1.0","info":{"title":"Veton Public API","version":"1.0.0","summary":"Read-only access to your Veton charging sessions and chargers.","description":"Customer-facing, read-only (GET-only) API for pulling charging-session data. Authenticate with an API key (Bearer). A key sees only the chargers its owner can view sessions for; access is recomputed on every request. See docs/public-api-quickstart.md for a worked example and the incremental-sync recipe.","contact":{"name":"Veton","url":"https://veton.be"}},"servers":[{"url":"https://api.veton.be/public/v1","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"identity","description":"Who am I / what can this key see."},{"name":"chargers","description":"The chargers this key may read."},{"name":"sessions","description":"Charging sessions (the change feed + CSV export)."}],"paths":{"/whoami":{"get":{"tags":["identity"],"operationId":"whoami","summary":"Reflect the presented key's live identity and scope.","description":"Returns the key id, environment, whether raw RFID is exposed, the live charger scope, the CORS allow-list and whether the key is in rotation grace. Cheap way to confirm a key works and see exactly what it can read.","responses":{"200":{"description":"The presented key's identity and live scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoAmI"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers":{"get":{"tags":["chargers"],"operationId":"listChargers","summary":"List the chargers this key may read.","description":"Every charger in the key's live scope, ordered by name. Internal fields (VPN IP, machine id, address/geo, firmware, Odoo, smart/tariff config) are never returned.","responses":{"200":{"description":"The chargers in scope.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Charger"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers/{id}":{"get":{"tags":["chargers"],"operationId":"getCharger","summary":"Fetch one charger by id.","description":"Returns a single charger. An id outside the key's scope returns 404 (indistinguishable from a non-existent charger, so a key cannot enumerate the fleet).","parameters":[{"name":"id","in":"path","required":true,"description":"Charger UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The charger.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Charger"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers/{id}/live":{"get":{"tags":["chargers"],"operationId":"getChargerLive","summary":"Live per-charging-point telemetry.","description":"Real-time IEC state, per-phase current and power for each charging point on the charger, proxied live from the device. Requires the read_live capability on this charger; a key without it gets 404 (indistinguishable from a non-existent charger). Returns 502 when the charger is offline or unreachable, 501 when its software is too old to serve live telemetry.","parameters":[{"name":"id","in":"path","required":true,"description":"Charger UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Live telemetry snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveTelemetry"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/NotSupported"},"502":{"$ref":"#/components/responses/DeviceUnavailable"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers/{id}/settings":{"get":{"tags":["chargers"],"operationId":"getChargerSettings","summary":"Externally-visible charger settings (current values).","description":"The charger's charging-point, charging-limit/solar, safety-fallback and electrical-circuit settings with their current values and human labels, read live from the device. Network configuration, OCPP/billing configuration, and unrecognised device fields are never included. Requires the read_live capability; a key without it gets 404. Returns 502 when the charger is offline or unreachable, 501 when its software is too old.","parameters":[{"name":"id","in":"path","required":true,"description":"Charger UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The charger's externally-visible settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerSettings"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/NotSupported"},"502":{"$ref":"#/components/responses/DeviceUnavailable"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers/{id}/settings/{key}":{"put":{"tags":["chargers"],"operationId":"putChargerSetting","summary":"Change one externally-controllable charger setting.","description":"Writes a single allow-listed setting to the charger. Only a small set of load-management settings is writable (the per-charging-point charging currents, the solar current/fuse limits, and the charging mode); any other key returns 404, indistinguishable from a non-existent setting. Requires the control capability the setting maps to (control_load_mgmt, control_fuse, or control_charging_points) on this charger, recomputed live against the owner's permissions every request. Setting the charging mode to smart also enables smart charging and pushes a fresh price/forecast curve. Writing the same value the device already holds is a no-op (restart is not_needed). This whole endpoint is disabled (503 CONTROL_DISABLED) unless control is enabled on the deployment. Fuse-bearing values require a fuse limit to be configured on the charger and may not exceed it (422).","parameters":[{"name":"id","in":"path","required":true,"description":"Charger UUID.","schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"description":"Setting key, e.g. cp.maximum_charge_current or solar.mode.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingWrite"}}}},"responses":{"200":{"description":"The setting was applied (or already held the requested value).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingWriteResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/NotSupported"},"502":{"$ref":"#/components/responses/DeviceUnavailable"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/chargers/{id}/current-limit":{"put":{"tags":["chargers"],"operationId":"setChargerCurrentLimit","summary":"Set the live maximum charging current (external EMS setpoint).","description":"Sets a dynamic maximum charging current for the charger, for use by an external energy-management system. Unlike the settings endpoint this is a live setpoint with a watchdog: send it on a short loop (e.g. every watchdog_seconds/2) - if the charger stops hearing from you before watchdog_seconds elapse it falls back to its configured safe current, so a dead EMS can never pin the car. Requires the control_charging_current capability on this charger, recomputed live against the owner's permissions every request. amps is a whole number bounded by the charger's physical fuse limit (which must be configured); the charger additionally clamps to its installer maximum. This is NOT a no-op when unchanged - every call re-feeds the watchdog. If the charger is controlled by a LOCAL energy-management system (control ownership local_ems) the request is refused with 409 and nothing is written, so the web API never contends with the local controller. Disabled (503 CONTROL_DISABLED) unless control is enabled on the deployment.","parameters":[{"name":"id","in":"path","required":true,"description":"Charger UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentLimitWrite"}}}},"responses":{"200":{"description":"The setpoint was forwarded to the charger and the watchdog re-armed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentLimitResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/DeviceUnavailable"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/sessions":{"get":{"tags":["sessions"],"operationId":"listSessions","summary":"List charging sessions (keyset-paginated change feed, or CSV export).","description":"Returns a page of sessions ordered newest-first with an opaque cursor. For a durable change feed use order=updated_at together with updated_after (see the incremental-sync recipe in the quickstart) - sessions are back-filled and mutated after insert, so paging on started_at silently loses rows. Add format=csv to stream the same rows as a CSV attachment (subject to a stricter export rate limit).","parameters":[{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAfter"},{"$ref":"#/components/parameters/order"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/chargerId"},{"$ref":"#/components/parameters/format"}],"responses":{"200":{"description":"A page of sessions (JSON), or a CSV attachment when format=csv.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionPage"}},"text/csv":{"schema":{"type":"string","description":"One header row then one row per session. Columns: id, charger_id, charging_point_id, started_at, ended_at, energy_wh, start_meter_wh, end_meter_wh, is_complete, updated_at, and either rfid_tag_hash (default) or rfid_tag (only when the key has include_rfid). Leading formula characters are escaped against spreadsheet injection."}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/sessions/summary":{"get":{"tags":["sessions"],"operationId":"sessionsSummary","summary":"Aggregate session count and total energy over a window.","description":"Returns the number of sessions and the summed energy_wh for the filtered window. Accepts the same from/to/updated_after/charger_id filters as GET /sessions; pagination params are ignored.","parameters":[{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAfter"},{"$ref":"#/components/parameters/chargerId"}],"responses":{"200":{"description":"The aggregate over the filtered window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionSummary"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}},"/sessions/{id}":{"get":{"tags":["sessions"],"operationId":"getSession","summary":"Fetch one session by id.","description":"Returns a single session. An id outside the key's scope, or a malformed id, returns 404.","parameters":[{"name":"id","in":"path","required":true,"description":"Session UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Disabled"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","description":"Send your key as an Authorization: Bearer header. Keys look like vk_live_<keyId>_<secret>_<crc32>. The key must never travel in the query string (a ?api_key= param is rejected with 400)."}},"parameters":{"from":{"name":"from","in":"query","required":false,"description":"Lower bound (inclusive) on started_at, ISO-8601. The window (lower bound to upper bound or now) must not exceed 366 days.","schema":{"type":"string","format":"date-time"}},"to":{"name":"to","in":"query","required":false,"description":"Upper bound (inclusive) on started_at, ISO-8601.","schema":{"type":"string","format":"date-time"}},"updatedAfter":{"name":"updated_after","in":"query","required":false,"description":"Lower bound (inclusive) on updated_at, ISO-8601. Combine with order=updated_at for a durable change feed.","schema":{"type":"string","format":"date-time"}},"order":{"name":"order","in":"query","required":false,"description":"Sort/keyset column. started_at (default) for a chronological browse; updated_at for incremental sync.","schema":{"type":"string","enum":["started_at","updated_at"],"default":"started_at"}},"limit":{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 200 (default 50).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},"cursor":{"name":"cursor","in":"query","required":false,"description":"Opaque next_cursor from the previous page. Must match the order it was issued for; a forged or mismatched cursor returns 400.","schema":{"type":"string"}},"chargerId":{"name":"charger_id","in":"query","required":false,"description":"Restrict to one or more charger UUIDs (repeat the param). Ids outside the key's scope are silently dropped.","explode":true,"schema":{"type":"array","items":{"type":"string","format":"uuid"}}},"format":{"name":"format","in":"query","required":false,"description":"Set to csv to stream a CSV attachment instead of JSON. CSV is a query param, never a .csv path suffix.","schema":{"type":"string","enum":["csv"]}}},"responses":{"BadRequest":{"description":"A query parameter or cursor was invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"The API key was missing, malformed, unknown, expired, revoked, IP-denied, or its owner lost access. All of these return the identical opaque body (no enumeration oracle).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such resource in this key's scope. Returned for both out-of-scope and non-existent ids.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limit exceeded (per-key per-minute, per-key per-day, or the CSV-export limiter). Retry after the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Disabled":{"description":"The public API is not enabled on this deployment (the edge secret is unset), or the request did not arrive through the Veton edge.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotSupported":{"description":"The charger's software is too old to serve this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DeviceUnavailable":{"description":"The charger is offline, unreachable, or returned an error, so no live data could be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"The value was rejected by a device or safety constraint (e.g. it exceeds the charger's fuse limit, no fuse limit is configured, or the charger declined the change).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The request conflicts with the charger's current control ownership - the charger is controlled by a local energy-management system, or the charger declined an external current limit in its current mode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"The uniform error envelope for every non-2xx response.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code, e.g. VALIDATION_ERROR, INVALID_API_KEY, NOT_FOUND, RATE_LIMITED, PUBLIC_API_DISABLED."},"message":{"type":"string","description":"Human-readable description. Absent on some opaque responses."},"status":{"type":"integer","description":"The HTTP status code, mirrored in the body."}},"required":["code","status"]}},"required":["error"]},"WhoAmI":{"type":"object","properties":{"key_id":{"type":"string","description":"Public key id (the middle segment of the key). Safe to log."},"environment":{"type":"string","description":"Key environment, e.g. live."},"include_rfid":{"type":"boolean","description":"When true, sessions carry the raw rfid_tag; otherwise the household-salted rfid_tag_hash."},"charger_ids":{"type":"array","description":"The charger UUIDs this key may currently read (recomputed live).","items":{"type":"string","format":"uuid"}},"allowed_origins":{"type":"array","description":"Per-key CORS allow-list (defence-in-depth only, not an auth control).","items":{"type":"string"}},"rotation_grace":{"type":"boolean","description":"True while an old key is still accepted during rotation."}},"required":["key_id","environment","include_rfid","charger_ids","allowed_origins","rotation_grace"]},"Charger":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"serial":{"type":["string","null"]},"model":{"type":["string","null"]},"is_online":{"type":"boolean"},"last_seen_at":{"type":["string","null"],"format":"date-time"},"charging_point_count":{"type":"integer"},"charging_point_names":{"description":"Per-connector display names as stored on the charger, or null. Shape is charger-defined.","type":["object","null"]},"household_id":{"type":["string","null"]}},"required":["id","name","serial","model","is_online","last_seen_at","charging_point_count","charging_point_names","household_id"]},"Session":{"type":"object","description":"A charging session. Exactly one of rfid_tag_hash or rfid_tag is present, depending on the key's include_rfid flag; when the session has no tag the field is null.","properties":{"id":{"type":"string","format":"uuid"},"charger_id":{"type":"string","format":"uuid"},"charging_point_id":{"type":["string","null"],"description":"Connector/charging-point id within the charger."},"started_at":{"type":["string","null"],"format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"energy_wh":{"type":["integer","null"],"description":"Energy delivered this session, in watt-hours."},"start_meter_wh":{"type":["string","null"],"description":"Meter reading at session start, in watt-hours, as a decimal STRING (the value is a 64-bit integer that would overflow JSON number precision)."},"end_meter_wh":{"type":["string","null"],"description":"Meter reading at session end, in watt-hours, as a decimal STRING."},"is_complete":{"type":"boolean","description":"True once the session has ended (ended_at is set)."},"updated_at":{"type":["string","null"],"format":"date-time","description":"Last mutation time. Use with order=updated_at + updated_after for incremental sync."},"rfid_tag_hash":{"type":["string","null"],"description":"Household-salted, irreversible 16-hex HMAC of the RFID tag. Present unless the key has include_rfid. Stable per (tag, household) so you can group sessions by card without seeing the card."},"rfid_tag":{"type":["string","null"],"description":"Raw RFID/OCPP idTag. Present ONLY when the key has include_rfid (owner-only, audited)."}},"required":["id","charger_id","charging_point_id","started_at","ended_at","energy_wh","start_meter_wh","end_meter_wh","is_complete","updated_at"]},"SessionPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Session"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page, or null when there are no more rows. Pass it back as the cursor query param (keep the same order)."}},"required":["data","next_cursor"]},"SessionSummary":{"type":"object","properties":{"session_count":{"type":"integer"},"total_energy_wh":{"type":"integer","description":"Sum of energy_wh over the window (0 when no sessions)."},"from":{"type":["string","null"],"format":"date-time"},"to":{"type":["string","null"],"format":"date-time"}},"required":["session_count","total_energy_wh","from","to"]},"LiveChargingPoint":{"type":"object","description":"Live state of one charging point. All measured values may be null when the device has not reported them.","properties":{"charging_point_id":{"type":["integer","null"],"description":"Charging-point number within the charger."},"iec_state":{"type":["string","null"],"description":"IEC 61851 charging state (e.g. A, B1, B2, C2, E, F)."},"power_w":{"type":["number","null"],"description":"Instantaneous charging power, in watts."},"current_a":{"type":"object","description":"Per-phase measured current, in amps.","properties":{"l1":{"type":["number","null"]},"l2":{"type":["number","null"]},"l3":{"type":["number","null"]}},"required":["l1","l2","l3"]},"current_limit_a":{"type":["number","null"],"description":"Current limit applied to this charging point right now, in amps (null when the device does not report it)."},"charging":{"type":"boolean","description":"True when the charging point is actively delivering power."}},"required":["charging_point_id","iec_state","power_w","current_a","current_limit_a","charging"]},"LiveTelemetry":{"type":"object","properties":{"charger_id":{"type":"string","format":"uuid"},"is_online":{"type":"boolean","description":"Whether the charger is currently connected to Veton."},"updated_at":{"type":["string","null"],"format":"date-time","description":"When the charger was last seen online."},"charging_points":{"type":"array","items":{"$ref":"#/components/schemas/LiveChargingPoint"}}},"required":["charger_id","is_online","updated_at","charging_points"]},"SettingValue":{"type":"object","properties":{"instance_label":{"type":["string","null"],"description":"Human label for the instance this value belongs to (e.g. 'Charging point 1', 'Circuit 2'), or null for a single-instance setting."},"value":{"description":"The current value on the device. Type depends on the setting."}},"required":["instance_label","value"]},"ChargerSetting":{"type":"object","properties":{"key":{"type":"string","description":"Stable setting key (e.g. cp.maximum_charge_current)."},"label":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","description":"Value type: number, boolean, enum, string."},"unit":{"type":["string","null"],"description":"Unit of the value (e.g. A), or null."},"values":{"type":"array","items":{"$ref":"#/components/schemas/SettingValue"}}},"required":["key","label","description","type","unit","values"]},"ChargerSettingsGroup":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"ok":{"type":"boolean","description":"False when this group could not be read from the charger; its settings array is then empty."},"settings":{"type":"array","items":{"$ref":"#/components/schemas/ChargerSetting"}}},"required":["key","label","description","ok","settings"]},"ChargerSettings":{"type":"object","description":"Externally-visible charger settings. Network and OCPP/billing configuration and unrecognised device fields are deliberately omitted.","properties":{"charger_id":{"type":"string","format":"uuid"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/ChargerSettingsGroup"}}},"required":["charger_id","groups"]},"SettingWrite":{"type":"object","description":"The new value for a setting write. instance is required for per-charging-point / per-controller settings and forbidden otherwise.","properties":{"value":{"description":"The new value. Its type must match the setting (number, boolean, enum string). Numeric values must be whole numbers within the setting's range."},"instance":{"type":"string","description":"Charging-point or controller id for a per-instance setting. Omit for single-object settings (e.g. all solar.* keys)."}},"required":["value"]},"SettingWriteResult":{"type":"object","description":"The outcome of a setting write.","properties":{"key":{"type":"string","description":"The setting key that was written."},"instance":{"type":["string","null"],"description":"The instance written, or null for a single-object setting."},"old_value":{"description":"The value the device held before the write (null when not read, e.g. when switching to smart mode)."},"new_value":{"description":"The value now requested on the device."},"restart":{"description":"Which device agent was restarted to apply the change: an object {status, service}, null when no restart was needed, or the string not_needed when the value was already set (no device write)."}},"required":["key","instance","old_value","new_value","restart"]},"CurrentLimitWrite":{"type":"object","description":"A dynamic maximum-current setpoint with a safety watchdog.","properties":{"amps":{"type":"integer","minimum":6,"description":"The maximum charging current in amperes (whole number). Bounded by the charger's physical fuse limit; the charger also clamps to its installer maximum."},"watchdog_seconds":{"type":"integer","minimum":10,"maximum":3600,"description":"How long the charger honours this setpoint without hearing from you before it falls back to its configured safe current. Re-send the setpoint well within this window (e.g. every watchdog_seconds/2) to keep charging."}},"required":["amps","watchdog_seconds"]},"CurrentLimitResult":{"type":"object","description":"The outcome of a current-limit setpoint.","properties":{"amps":{"type":"integer","description":"The current limit now requested on the charger."},"watchdog_seconds":{"type":"integer","description":"The watchdog window now armed on the charger."},"applied":{"type":"boolean","description":"True when the charger accepted the setpoint."}},"required":["amps","watchdog_seconds","applied"]}}}}