Environments
We provide multiple environments, each with unique data access policies, and live/mocked vendors.
Environments are isolated from each other. Client credentials are tied to a specific environment and cannot be reused across environments.
Copy linkProduction
Features the latest stable software, live vendors, and strict data access controls.
Name | URL |
---|---|
API | https://enode-api.production.enode.io |
OAuth Authorization | https://oauth.production.enode.io/oauth2/auth |
OAuth Token | https://oauth.production.enode.io/oauth2/token |
Link UI | https://link.production.enode.io |
Copy linkSandbox
Includes the latest stable software and mocked vendors/vehicles/chargers.
Name | URL |
---|---|
API | https://enode-api.sandbox.enode.io |
OAuth Authorization | https://oauth.sandbox.enode.io/oauth2/auth |
OAuth Token | https://oauth.sandbox.enode.io/oauth2/token |
Link UI | https://link.sandbox.enode.io |
Authentication
The Enode API uses OAuth 2.0 client access tokens for authenticating server requests.
Copy linkAPI credentials
Enode API access begins with a client and its corresponding client ID and client secret. Clients organize data, are separate, and relate to a specific environmentAPI.
API credentials are used to obtain an access tokenAPI for accessing the entire APIAPI
Key | Description |
---|---|
Client ID | The identifier for your client, referred to as the client_id . |
Client secret | The secret for your client, referred to as the client_secret . |
Copy linkGetting an access token
The access token authorizes client access to all data and functionality. Obtain it via the OAuth 2.0 client credentials grant using the API credentialsAPI and the relevant OAuth URLsAPI for your client's environment.
Token request example
curl https://oauth.{YOUR_CLIENT_ENVIRONMENT}.enode.io/oauth2/token \
-X POST \
-u {YOUR_CLIENT_ID}:{YOUR_CLIENT_SECRET} \
-d "grant_type=client_credentials"
After requesting the token URL, you'll receive an access token in the response. Cache this token on your server until it expires and needs refreshingAPI. Keep the access token secret.
Token response example
{
"access_token": "{YOUR_ACCESS_TOKEN}",
"expires_in": 3599,
"scope": "",
"token_type": "bearer"
}
Copy linkRefreshing access tokens
Access tokens expire hourly, indicated by the expires_in
key in the response. When expired, obtain a new tokenAPI.
Copy linkAccessing the API with the access token
Authenticate all API requests using a bearer authentication header. This header accesses client-wide endpoints (service healthAPI, tariffsAPI, user managementAPI, and webhooksAPI).
Type | Value |
---|---|
Header | Authorization: Bearer {YOUR_ACCESS_TOKEN} |
Client resource request example
curl https://enode-api.{YOUR_CLIENT_ENVIRONMENT}.enode.io/health/ready \
-H "Authorization: Bearer {YOUR_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
Response times
Enode resources like Schedules and Locations have response times of <200ms
. However, vehicle interactions involve various delays and timing characteristics.
Understanding the range of possible timings without diving into vendor-specific causes, helps you account for these factors in your UX design.
Copy linkAPI GET requests
Copy linkGet Vehicle
Get Vehicles
and List Vehicles
are fast operations since all data is prefetched by Enode and shared from a cache.
On API versions prior to 2023-08-01
it is possible to request a synchronous update where data is fetched directly from the vendor. Such requests have longer response times, sometimes 30 seconds or more, depending on the characteristics of the underlying vendor APIs. From 2023-08-01
onwards this has been replaced by the refresh hintAPI mechanism.
Copy linkLink User
The Login
step usually takes <2 seconds
, but can rarely take up to 30 seconds
due to background negotiations, retries, and initial vehicle data fetching.
The final Accept
step experiences similar delays as List Vehicles
.
Copy linkCharging commands
Charging commands show significant timing variability among vendors. Initiating the action is instant, but the updated charging state typically takes 20 seconds to appear, with a maximum delay of 30 minutes.
Command implementation | Typical delay |
---|---|
native | 3-15 seconds |
synthetic A | 3-30 seconds |
synthetic B | 5-15 minutes |
Copy linkWebhooks
Webhooks usually involve polling and dynamically adjust the polling rate based on different situations to provide prompt updates without overloading the vehicle.
The maximum baseline delay between a real-world change (e.g., a vehicle being plugged in) and the resulting webhook notification is 7 minutes
.
Vehicle context | Maximum delay |
---|---|
default | 7 minutes |
charging | 2 minutes |
smartcharge PLAN:* | 2 minutes |
sleeping | 20 minutes |
For faster updates during a short period, call Get Vehicle
. It returns synchronous data from the vehicle and triggers a webhook if anything changes.
For example, when a user expects updates while using your app, you might poll Get Vehicle
every 15 seconds temporarily.
Errors and problems
Copy linkOAuth Authorization Request
Upon completing the Enode Link authorization process, the user will be redirected to your configured redirect URI. If an issue occurs, query parameters error
and error_description
will be set as described in Section 4.1.2.1 of the OAuth 2.0 specification:
Error | Error description |
---|---|
invalid_request | The request has a missing or invalid parameter, duplicate parameters, or is malformed. |
unauthorized_client | The client isn't authorized to request an authorization code with this method. |
access_denied | The resource owner or authorization server denied the request. |
unsupported_response_type | The authorization server doesn't support obtaining an authorization code with this method. |
invalid_scope | The requested scope is invalid, unknown, or malformed. |
server_error | The authorization server encountered an unexpected condition that prevented it from fulfilling the request. |
temporarily_unavailable | The authorization server is temporarily unable to handle the request due to overloading or maintenance. |
Sample
https://website.example/oauth_callback?state=e0a86fe5&error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.
Copy linkErrors when accessing a User's resources
When using an access_token
to access a user's resources, you may encounter the following 4XX range HTTP Status Codes:
HTTP Status Code | Explanation |
---|---|
400 Bad Request | The request payload failed schema validation or parsing |
401 Unauthorized | Missing or invalid authentication details |
403 Forbidden | Authentication succeeded, but the user lacks access to the resource |
404 Not Found | Requested resource doesn't exist |
405 Method Not Allowed | Vendor unavailability prevented request completion |
408 Request Timeout | Vendor timeout prevented request completion |
409 Conflict | Vendor rejection prevented request completion |
424 Failed Dependency | Failed vendor requests prevented request completion |
429 Too Many Requests | Vendor rate limiting prevented request completion |
In all cases, an RFC7807 Problem Details body is returned to aid in debugging.
Sample
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://docs.enode.io/problems/bad-request",
"title": "Payload validation failed",
"detail": "\"authorizationRequest.scope\" is required",
}
Copy linkProblems
Title | Description |
---|---|
Bad request | Some part of the request was malformed. See associated detail message for more information. |
Enode Controlled Entity | This entity is currently managed by Smart Charging or Schedules and cannot accept manual commands. Either disable the feature controlling the target, or force charging to start through our External Start APIAPI. |
Entity Not Found | The requested entity was not found on the user's account. |
Failed Auth Challenge | The code the User entered in response to a login challenge was not correct. |
Forbidden | The current context is not allowed to access the requested resource. |
Not Found | The requested entity was not found on the user's account. If requesting vendor entities, ensure you're using the top level |
Permanently Invalid Credentials | The User's vendor credentials have become invalid. The User needs to relink their account. |
Server Error | A critical error has ocurred. An employee has been alerted and will work to remedy the situation |
Should Not Disturb | Making a call to the vendor would negatively impact the vendor resource. For example, a Kia vehicle's 12V battery has reached a critical state and we cannot send further requests. |
Timeout | A request timed out. If this problem was returned by a route that tried to communicate with vendor APIs, remove the fields query parameter to fetch the Enode hosted cache. This cache is updated every 10 minutes. |
Unauthorized | The request contained an invalid or expired token. |
Validation Error | The response we prepared failed to pass outgoing validation. An employee has been alerted and will work to remedy the situation. |
Vendor Not Yet Reached | This error is returned when a request for entity state fails on an entity where |
Vendor Rate Limited | Enode has sent too many requests to a vendor. |
Vendor Rejected | An action sent to a vendor was rejected. This typically happens when too many commands are sent in a short period of time. |
Unauthorized | The request contained an invalid or expired token. |
Vendor Unavailable | We were able to reach the vendor's server but were unable to make direct contact with the requested resource. For example, a Tesla vehicle was sleeping and we were unable to wake it. |
Versioning
Versioning
Enode's REST API is versioned. A dated version is released when breaking changes occur, while new features and bug fixes (additive changes) are available in all supported API versions.
You can view all available versions and updates in the changelog.
API clients are pinned to the latest API version upon creation, affecting all API requests and webhook events. API responses include an Enode-Version
header, and webhook events have a version
field.
You can override the API version on a specific request by sending an Enode-Version
in the request header.
Breaking changes
Breaking changes will be released as a new version. When a new version is released, the previous version is supported for six months before deactivation. Enode staff will notify you in advance. Each API version comes with a migration guide explaining changes and upgrade suggestions.
We consider the following breaking changes
- Changing a request’s authorization or authentication requirements
- Adding a new required input parameter
- Changing input validation
- Removing an HTTP route or method
- Removing or renaming a response parameter
- Adding a new case to a response field documented as an enum.
All other additive changes are considered backwards compatible.
Deprecation
Deprecated
means that a particular feature, endpoint, or field is marked for removal in a future version of the API. When something is marked as deprecated, it's a signal for you to update your application to use alternative features or methods we provide. While the deprecated item will continue to work in the current version, it will be removed in a future version of the API. When we deprecate an item, we will mark it as deprecated through all the previous versions. Once a version without the item is released, the deprecated feature, endpoint, or field will still be supported in the previous version for six months. After six months, using the deprecated item will return an error. Enode staff will notify you before any item is removed.
Pagination
Enode endpoints returning collections of a specific type of resource, such as GET /vehicles
, will return a paginated response. Each response will consist of a subset of the resources, called a page. To retrieve the entire collection, subsequent pages need to be fetched.
Each response includes two properties: data
and pagination
. The data
property contains the records of the current page and the pagination
property contains cursors that can be used to fetch additional pages. These cursors, before
and after
, are unique identifiers for specific records in the dataset that help you keep track of your position and navigate through the pages.
Copy linkQuerying a paginated API endpoint
When querying a paginated endpoint, you may provide the following pagination query parameters:
Pagination query parameter example
{
"pageSize": 50,
"before": "MjAyMy0wNy0xOFQxMDowODowMi4zNzNa",
"after": "MjAyMy0wNi0xNlQwOTowMzowMS4yNjJa"
}
All of these pagination query parameters are optional. If pageSize
is not provided, the default page size of 50 is used. If neither before
nor after
are provided, the returned page will contain the first set of resources in the collection.
The before
and after
parameters are mutually exclusive. If both are supplied, the API will return an error.
Responses from most paginated endpoints are sorted in descending order according to when the resource was created. Hence, for a request like GET /vehicles
, the most recently linked vehicles appear on the first page.
Copy linkHow to navigate through paginated API responses
The pagination
property in a paginated response typically looks like this:
Pagination property example
"pagination": {
"before": "MjAyMy0wNy0xOFQxMDowODowMi4zNzNa",
"after": "MjAyMy0wNi0xNlQwOTowMzowMS4yNjJa"
}
The pagination
property provides the cursors required to fetch the next and previous pages of resources:
before
contains the cursor to be used to fetch the previous page.after
contains the cursor to be used to fetch the next page.
One or both cursors may be null
instead of a string. This occurs when:
- You are on the first page. There are no preceding resources, so
before
will now benull
as otherwise it would point to an empty page. - You are on the last page. There are no subsequent resources, so
after
will now benull
as otherwise it would point to an empty page. - The entire collection fits on the first page. There are no preceding or subsequent resources, so both
before
andafter
are null.
Copy linkFull example response
Example paginated response
{
"data": [
{
"id": "0",
"vendor": "TESLA",
...
"isReachable": true
},
...
{
"id": "49",
"vendor": "TESLA",
...
"isReachable": true
}
],
"pagination": {
"before": null,
"after": "MjAyMy0wNy0xOFQxMDowNDowMi4zNzNa"
}
}
In this example, the data array includes the resource records for the current page. The pagination object provides the cursors for navigating to adjacent pages.
Batteries
The Battery
object represents a residential energy storage unit, like a Tesla Powerwall or Enphase IQ. It offers detailed insights into the battery's operation and allows you to instruct the battery on handling its stored energy.
Get Battery
BetaGET /batteries/{batteryId}
Request
Path parameters
The ID of the battery you are looking up
Response
200Attributes
Unique identifier for the battery object
One of TESLA or ENPHASE
ID of the location the battery is currently positioned at (if any).
The last time Enode successfully communicated with the vendor or when the battery was initially linked. An ISO8601 UTC timestamp.
Whether live data from the battery is currently reachable from Enode's perspective. This 'reachability' may refer to reading from a cache operated by the battery's cloud service if that service has determined that its cache is valid.
Descriptive information about the battery
Battery's GPS coordinates
A collection of descriptors that describe the capabilities of this specific battery
Sample
{
"id": "string",
"vendor": "TESLA",
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"chargeState": {
"status": "CHARGING",
"batteryCapacity": 0,
"batteryLevel": 0,
"chargeRate": 0,
"lastUpdated": "string"
},
"config": {
"operationMode": "IMPORT_FOCUS",
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "Tesla",
"model": "Powerwall",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"exportFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"importFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"timeOfUse": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"selfReliance": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
List User Batteries
BetaGET /users/{userId}/batteries
Returns a paginated list of batteries for the given userId.
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of batteries
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "TESLA",
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"chargeState": {
"status": "CHARGING",
"batteryCapacity": 0,
"batteryLevel": 0,
"chargeRate": 0,
"lastUpdated": "string"
},
"config": {
"operationMode": "IMPORT_FOCUS",
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "Tesla",
"model": "Powerwall",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"exportFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"importFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"timeOfUse": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"selfReliance": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Set Operation Mode for Battery
BetaPOST /batteries/{batteryId}/operation-mode
Request an operationMode
change for a battery. This request will retry until the battery's operationMode matches the expected value. Note that this request will complete before any commands are sent to the battery. Only one action can be active for a specific target id at a time. If a new action is created, the previous action will be automatically cancelled and transitioned to the CANCELLED
state. Track transitions via the user:vendor-action:updated
webhook event or the Battery Get ActionAPI.
Request
Path parameters
The ID of the battery you are looking up
Attributes
Desired operation mode of the battery.
IMPORT_FOCUS
: Prioritizes charging the battery. Draws power from the grid and any excess solar for charging.EXPORT_FOCUS
: Prioritizes discharging energy stored in the battery back to the grid.TIME_OF_USE
: Maximizes energy cost savings in accordance with a user-defined utility rate plan. Energy may be consumed from solar, battery, or grid sources, depending on the current prices and your user's settings in the OEM app. Energy may be exported to the grid from solar or battery sources, depending on current prices and your user's settings in the OEM app.SELF_RELIANCE
: Minimizes reliance on the grid. Consumes own energy from solar or battery before importing from grid. Energy may be exported to the grid from solar, depending on excess solar and your user's settings in the OEM app.
One of IMPORT_FOCUS, EXPORT_FOCUS, TIME_OF_USE, or SELF_RELIANCE
Sample
{
"operationMode": "IMPORT_FOCUS"
}
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the battery which this action is controlling.
One of battery
Target battery operation mode
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "battery",
"targetState": {
"operationMode": "IMPORT_FOCUS"
}
}
Other responses
Response 400
A precondition check failed, that is unlikely to change within 30 minutes. This occurs if the battery cannot perform the action.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Refresh battery data
BetaPOST /batteries/{batteryId}/refresh-hint
Use this endpoint to initiate an expedited data refresh for the specified battery.
Note: The Enode platform keeps data automatically up-to-date and detects changes in the OEM APIs within seconds to a few minutes. We change the refresh interval dynamically based on a number of heuristics. This ensures we find the best trade-off between the stability of the connection to the OEM and freshness of the data.
This method overrides most of our heuristics and should therefore be used with caution. You may use it when you have a strong reason to believe the data might be stale.
Request
Path parameters
The ID of the battery you are looking up
Response
204Refresh hint registered successfully.
Other responses
Response 404
The specified battery was not found.
Get Operation Mode Action
BetaGET /batteries/actions/{vendorActionId}
Returns the current state of the requested action.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the battery which this action is controlling.
One of battery
Target battery operation mode
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "battery",
"targetState": {
"operationMode": "IMPORT_FOCUS"
}
}
Other responses
Response 404
Action not found.
Cancel Battery Action
BetaPOST /batteries/actions/{vendorActionId}/cancel
Cancels a pending battery action, halting any further attempts by Enode to execute it.
Note: This only updates the action's status to CANCELLED
within Enode and does not reflect a change in the vendor's cloud. Thus any pending action in the vendor's cloud might still be executed.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the battery which this action is controlling.
One of battery
Target battery operation mode
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "battery",
"targetState": {
"operationMode": "IMPORT_FOCUS"
}
}
Other responses
Response 404
Action not found.
Response 409
Action already in a resolved state.
Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the battery which this action is controlling.
One of battery
Target battery operation mode
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "battery",
"targetState": {
"operationMode": "IMPORT_FOCUS"
}
}
List Batteries
BetaGET /batteries
Returns a paginated list of all Batteries.
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of batteries
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "TESLA",
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"chargeState": {
"status": "CHARGING",
"batteryCapacity": 0,
"batteryLevel": 0,
"chargeRate": 0,
"lastUpdated": "string"
},
"config": {
"operationMode": "IMPORT_FOCUS",
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "Tesla",
"model": "Powerwall",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"exportFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"importFocus": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"timeOfUse": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"selfReliance": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Chargers
EV Chargers provide charging data and can be controlled through the Control Charger endpointAPI and through Schedules
List Chargers
GET /chargers
Returns a paginated list of all Chargers.
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of chargers
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "2211e263-0362-4235-83f4-887bdf3ee414",
"vendor": "ZAPTEC",
"lastSeen": "2023-03-21T21:08:27.596Z",
"isReachable": true,
"locationId": "2211e263-d6d4-d6d4-d6d4-dbdd77ec82b6",
"chargeState": {
"isPluggedIn": true,
"isCharging": true,
"powerDeliveryState": "PLUGGED_IN:CHARGING",
"chargeRate": 6.939,
"lastUpdated": "2023-03-21T16:39:20.000Z",
"maxCurrent": 16
},
"information": {
"brand": "Zaptec",
"model": "ZAPTEC PRO",
"year": null
},
"capabilities": {
"information": {
"interventionIds": [],
"isCapable": true
},
"chargeState": {
"interventionIds": [],
"isCapable": true
},
"startCharging": {
"interventionIds": [],
"isCapable": true
},
"stopCharging": {
"interventionIds": [],
"isCapable": true
},
"setMaxCurrent": {
"interventionIds": [
"dbdd77ec82b6-d6d4-d6d4-d6d4-dbdd77ec82b6"
],
"isCapable": false
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List User Chargers
GET /users/{userId}/chargers
Returns a paginated list of chargers for the given userId.
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of chargers
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "2211e263-0362-4235-83f4-887bdf3ee414",
"vendor": "ZAPTEC",
"lastSeen": "2023-03-21T21:08:27.596Z",
"isReachable": true,
"locationId": "2211e263-d6d4-d6d4-d6d4-dbdd77ec82b6",
"chargeState": {
"isPluggedIn": true,
"isCharging": true,
"powerDeliveryState": "PLUGGED_IN:CHARGING",
"chargeRate": 6.939,
"lastUpdated": "2023-03-21T16:39:20.000Z",
"maxCurrent": 16
},
"information": {
"brand": "Zaptec",
"model": "ZAPTEC PRO",
"year": null
},
"capabilities": {
"information": {
"interventionIds": [],
"isCapable": true
},
"chargeState": {
"interventionIds": [],
"isCapable": true
},
"startCharging": {
"interventionIds": [],
"isCapable": true
},
"stopCharging": {
"interventionIds": [],
"isCapable": true
},
"setMaxCurrent": {
"interventionIds": [
"dbdd77ec82b6-d6d4-d6d4-d6d4-dbdd77ec82b6"
],
"isCapable": false
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Get Charge Action
GET /chargers/actions/{vendorActionId}
Returns the current state of the requested action.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the chargeable entity asset (Vehicle or Charger) which this action is controlling.
One of vehicle or charger
One of START or STOP
Information about why was this action not executed successfully.
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "vehicle",
"kind": "START",
"failureReason": {
"type": "NO_RESPONSE",
"detail": "The chargeable device remained unreachable."
}
}
Other responses
Response 404
Action not found.
Cancel Charger Action
POST /chargers/actions/{vendorActionId}/cancel
Cancels a pending charger action, halting any further attempts by Enode to execute it.
Note: This only updates the action's status to CANCELLED
within Enode and does not reflect a change in the vendor's cloud. Thus any pending action in the vendor's cloud might still be executed.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the chargeable entity asset (Vehicle or Charger) which this action is controlling.
One of vehicle or charger
One of START or STOP
Information about why was this action not executed successfully.
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "vehicle",
"kind": "START",
"failureReason": {
"type": "NO_RESPONSE",
"detail": "The chargeable device remained unreachable."
}
}
Other responses
Response 404
Action not found.
Response 409
Action already in a resolved state.
Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the chargeable entity asset (Vehicle or Charger) which this action is controlling.
One of vehicle or charger
One of START or STOP
Information about why was this action not executed successfully.
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "vehicle",
"kind": "START",
"failureReason": {
"type": "NO_RESPONSE",
"detail": "The chargeable device remained unreachable."
}
}
Get Charger
GET /chargers/{chargerId}
Request
Path parameters
ID of the Charger.
Response
200Attributes
Charger ID
One of ZAPTEC, EASEE, WALLBOX, EO, CHARGEAMPS, or EVBOX
The last time Enode successfully communicated with the vendor or when the charger was initially linked. An ISO8601 UTC timestamp.
Whether live data from the charger is currently reachable from Enode's perspective. This 'reachability' may refer to reading from a cache operated by the charger's cloud service if that service has determined that its cache is valid.
ID of the location the charger is currently positioned at (if any).
Descriptive information about the Charger
A collection of descriptors that describe the capabilities of this specific charger
Sample
{
"id": "2211e263-0362-4235-83f4-887bdf3ee414",
"vendor": "ZAPTEC",
"lastSeen": "2023-03-21T21:08:27.596Z",
"isReachable": true,
"locationId": "2211e263-d6d4-d6d4-d6d4-dbdd77ec82b6",
"chargeState": {
"isPluggedIn": true,
"isCharging": true,
"powerDeliveryState": "PLUGGED_IN:CHARGING",
"chargeRate": 6.939,
"lastUpdated": "2023-03-21T16:39:20.000Z",
"maxCurrent": 16
},
"information": {
"brand": "Zaptec",
"model": "ZAPTEC PRO",
"year": null
},
"capabilities": {
"information": {
"interventionIds": [],
"isCapable": true
},
"chargeState": {
"interventionIds": [],
"isCapable": true
},
"startCharging": {
"interventionIds": [],
"isCapable": true
},
"stopCharging": {
"interventionIds": [],
"isCapable": true
},
"setMaxCurrent": {
"interventionIds": [
"dbdd77ec82b6-d6d4-d6d4-d6d4-dbdd77ec82b6"
],
"isCapable": false
}
}
}
Update Charger
BetaPUT /chargers/{chargerId}
Update the locationId
field on an Charger device.
Request
Path parameters
ID of the Charger.
Attributes
Sample
{
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
Response
200Attributes
Charger ID
One of ZAPTEC, EASEE, WALLBOX, EO, CHARGEAMPS, or EVBOX
The last time Enode successfully communicated with the vendor or when the charger was initially linked. An ISO8601 UTC timestamp.
Whether live data from the charger is currently reachable from Enode's perspective. This 'reachability' may refer to reading from a cache operated by the charger's cloud service if that service has determined that its cache is valid.
ID of the location the charger is currently positioned at (if any).
Descriptive information about the Charger
A collection of descriptors that describe the capabilities of this specific charger
Sample
{
"id": "2211e263-0362-4235-83f4-887bdf3ee414",
"vendor": "ZAPTEC",
"lastSeen": "2023-03-21T21:08:27.596Z",
"isReachable": true,
"locationId": "2211e263-d6d4-d6d4-d6d4-dbdd77ec82b6",
"chargeState": {
"isPluggedIn": true,
"isCharging": true,
"powerDeliveryState": "PLUGGED_IN:CHARGING",
"chargeRate": 6.939,
"lastUpdated": "2023-03-21T16:39:20.000Z",
"maxCurrent": 16
},
"information": {
"brand": "Zaptec",
"model": "ZAPTEC PRO",
"year": null
},
"capabilities": {
"information": {
"interventionIds": [],
"isCapable": true
},
"chargeState": {
"interventionIds": [],
"isCapable": true
},
"startCharging": {
"interventionIds": [],
"isCapable": true
},
"stopCharging": {
"interventionIds": [],
"isCapable": true
},
"setMaxCurrent": {
"interventionIds": [
"dbdd77ec82b6-d6d4-d6d4-d6d4-dbdd77ec82b6"
],
"isCapable": false
}
}
}
Control Charging
POST /chargers/{chargerId}/charging
Register a request for a charger to start or stop charging. We retry sending the command until the charger's powerDeliveryState
field transitions to the expected state. Note that this API request will complete before any commands are sent to the charger. There can only be one vendor action active for any one target id at a time. If a new action is created, the old action will transition into the CANCELLED
state. You may react to transitions by listening for the user:vendor-action:updated
webhook event or by polling the charger action endpointAPI.
This endpoint returns an error with status code 422 if the charger is controlled by a schedule. To restore user control, either disable the schedule or use our Smart Override APIAPI to temporarily enable charging.
Request
Path parameters
ID of the Charger.
Attributes
Charging action to perform
One of START or STOP
Sample
{
"action": "START"
}
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the chargeable entity asset (Vehicle or Charger) which this action is controlling.
One of vehicle or charger
One of START or STOP
Information about why was this action not executed successfully.
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "vehicle",
"kind": "START",
"failureReason": {
"type": "NO_RESPONSE",
"detail": "The chargeable device remained unreachable."
}
}
Other responses
Response 400
A precondition check failed, that is unlikely to change within 30 minutes. This occurs if the charger cannot perform the action, is fully charged, or is already in the desired state.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Response 422
Charger controlled by a Schedule
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Refresh Charger data
POST /chargers/{chargerId}/refresh-hint
Use this endpoint to initiate an expedited data refresh for the specified charger.
Note: The Enode platform keeps data automatically up-to-date and detects changes in the OEM APIs within seconds to a few minutes. We change the refresh interval dynamically based on a number of heuristics. This ensures we find the best trade-off between the stability of the connection to the OEM and freshness of the data.
This method overrides most of our heuristics and should therefore be used with caution. You may use it when you have a strong reason to believe the data might be stale.
Request
Path parameters
ID of the Charger.
Response
204Refresh hint registered successfully.
Other responses
Response 404
The specified charger was not found.
Set Max Current
POST /chargers/{chargerId}/max-current
Register a request for a change of the maxCurrent
field on a charger. We retry sending the command until the charger's maxCurrent
field transitions to the expected value. Note that this request will complete before any commands are sent to the charger. There can only be one vendor action active for any one target id at a time. If a new action is created, the old action transitions to the CANCELLED
state. You may react to transitions by listening for the user:vendor-action:updated
webhook event or polling Charger Get ActionAPI.
Request
Path parameters
ID of the Charger.
Attributes
Desired max current in ampere
Sample
{
"maxCurrent": 20
}
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the charger which this action is controlling.
One of charger
Target maximum current for charger
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "charger",
"targetState": {
"maxCurrent": 20
}
}
Other responses
Response 400
A precondition check failed, that is unlikely to change within 30 minutes. This occurs if the charger cannot perform the action.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Create Smart Override
POST /chargers/{chargerId}/smart-override
Overrides an active smart feature by forcing the charger to start charging. This feature is meant to be used in situations where the user wants to charge immediately without disabling other smart features. The override remains active until the charger stops charging, or until the Delete Smart OverrideAPI endpoint is called. When the override ends, the overriden smart feature will regain control of the charger. This endpoint should not be used for standard charge control, use the Control ChargingAPI endpoint instead.
Request
Path parameters
ID of the Charger.
Response
200Attributes
ISO8601 UTC timestamp at which the smart override was created.
ISO8601 UTC timestamp at which the smart override was ended. If null, the smart override is still active.
One of vehicle or charger
ID of the asset (Vehicle or Charger) to which this smart override applies.
The ID of Vendor Action responsible for starting charging on the target. Use the Vehicle Get ActionAPI or the Charger Get ActionAPI endpoints to monitor action results.
ID of the User
Sample
{
"createdAt": "2020-04-07T17:04:26Z",
"endedAt": "string",
"targetType": "vehicle",
"targetId": "string",
"vendorActionId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string",
"vendor": "AUDI"
}
End Smart Override
DELETE /chargers/{chargerId}/smart-override
Ends any active Smart Override for the charger specified by chargerId
. If previously configured, Schedules or Smart Charging will resume control over the target charger. Note that this does not mean the charger will stop charging, only that it will return to the state expected by the active Schedule or Smart Charging Plan.
Request
Path parameters
ID of the Charger.
Response
200Attributes
ISO8601 UTC timestamp at which the smart override was created.
ISO8601 UTC timestamp at which the smart override was ended. If null, the smart override is still active.
One of vehicle or charger
ID of the asset (Vehicle or Charger) to which this smart override applies.
The ID of Vendor Action responsible for starting charging on the target. Use the Vehicle Get ActionAPI or the Charger Get ActionAPI endpoints to monitor action results.
ID of the User
Sample
{
"createdAt": "2020-04-07T17:04:26Z",
"endedAt": "string",
"targetType": "vehicle",
"targetId": "string",
"vendorActionId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string",
"vendor": "AUDI"
}
Other responses
Response 404
No Smart Override Exists
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Get Smart charging policy
BetaGET /chargers/{chargerId}/smart-charging-policy
Get the configured smart charging policy for this charger.
Request
Path parameters
ID of the Charger.
Response
200Attributes
When enabled, this charger's charging status may be controlled by Smart Charging
The HH:MM
deadline for the cycle. If a timezone is set on the charging location at which the smart charging occurs, the deadline is interpreted in that timezone, otherwise UTC is used.
The HH:MM
charging duration for each cycle.
Sample
{
"isEnabled": false,
"deadline": "07:00",
"chargingDuration": "07:00"
}
Update Smart charging policy
BetaPUT /chargers/{chargerId}/smart-charging-policy
Update the configured smart charging policy for this charger.
Request
Path parameters
ID of the Charger.
Attributes
When enabled, this charger's charging status may be controlled by Smart Charging
The HH:MM
deadline for the cycle. If a timezone is set on the charging location at which the smart charging occurs, the deadline is interpreted in that timezone, otherwise UTC is used.
The HH:MM
charging duration for each cycle.
Sample
{
"isEnabled": false,
"deadline": "07:00",
"chargingDuration": "07:00"
}
Response
200Attributes
When enabled, this charger's charging status may be controlled by Smart Charging
The HH:MM
deadline for the cycle. If a timezone is set on the charging location at which the smart charging occurs, the deadline is interpreted in that timezone, otherwise UTC is used.
The HH:MM
charging duration for each cycle.
Sample
{
"isEnabled": false,
"deadline": "07:00",
"chargingDuration": "07:00"
}
Get Smart charging status
BetaGET /chargers/{chargerId}/smart-charging-status
Get the current smart charging status for this charger
Request
Path parameters
ID of the Charger.
Response
200Attributes
Charger ID
User ID
An enum value that describes the current smart charging state of the charger. Every charger is in exactly one state, at all times
One of DISABLED, CHARGER_NOT_REACHABLE, VEHICLE_NOT_PLUGGED_IN, CHARGING_PAUSED, CHARGING, or AWAITING_PRICES
Charging intervals for this cycle
Sample
{
"chargerId": "string",
"userId": "string",
"state": "DISABLED",
"chargingIntervals": [
{
"status": "IN_PROGRESS",
"startTime": "2023-03-21T21:08:27.596Z",
"endTime": "2023-03-21T21:08:27.596Z"
}
]
}
HVAC
HVAC units (heaters, heat pumps, air conditioning, thermostats, etc.) are controlled by altering the mode & target setpoints. This can be done directly using the Set Permanent HoldAPI endpoint, Return to ScheduleAPI, or via Schedules.
List HVAC units
GET /hvacs
Paginated list of HVAC units
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
List of paginated HVAC units
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"vendor": "ADAX",
"lastSeen": "2020-04-07T17:04:26.000Z",
"isReachable": true,
"isActive": true,
"currentTemperature": 20.8,
"consumptionRate": 1.8,
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"information": {
"brand": "ADAX",
"model": "Neo Wi-Fi Skirting",
"displayName": "Bedroom Panel Heater",
"groupName": "Bedroom",
"category": "HEATING"
},
"capabilities": {
"capableModes": [
"HEAT",
"COOL",
"OFF"
],
"capableHoldTypes": [
"PERMANENT"
],
"coolSetpointRange": {
"min": 15,
"max": 25
},
"heatSetpointRange": {
"min": 15,
"max": 25
},
"setpointDifferenceRange": {
"min": 15,
"max": 25
}
},
"thermostatState": {
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"lastUpdated": "2020-04-07T17:04:26.000Z"
},
"temperatureState": {
"currentTemperature": 20.8,
"isActive": true,
"lastUpdated": "2020-04-07T17:03:26.000Z"
},
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List User HVAC units
GET /users/{userId}/hvacs
Paginated list of HVAC units for the given User
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
List of paginated HVAC units
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"vendor": "ADAX",
"lastSeen": "2020-04-07T17:04:26.000Z",
"isReachable": true,
"isActive": true,
"currentTemperature": 20.8,
"consumptionRate": 1.8,
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"information": {
"brand": "ADAX",
"model": "Neo Wi-Fi Skirting",
"displayName": "Bedroom Panel Heater",
"groupName": "Bedroom",
"category": "HEATING"
},
"capabilities": {
"capableModes": [
"HEAT",
"COOL",
"OFF"
],
"capableHoldTypes": [
"PERMANENT"
],
"coolSetpointRange": {
"min": 15,
"max": 25
},
"heatSetpointRange": {
"min": 15,
"max": 25
},
"setpointDifferenceRange": {
"min": 15,
"max": 25
}
},
"thermostatState": {
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"lastUpdated": "2020-04-07T17:04:26.000Z"
},
"temperatureState": {
"currentTemperature": 20.8,
"isActive": true,
"lastUpdated": "2020-04-07T17:03:26.000Z"
},
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Get HVAC unit Smart Policy
BetaGET /hvacs/{hvacId}/smart-policy
Get HVAC unit smart policy
Request
Path parameters
ID of the HVAC unit.
Response
200Attributes
When enabled, this HVAC unit is under smart control.
Sample
{
"isEnabled": false
}
Update HVAC unit Smart Policy
BetaPUT /hvacs/{hvacId}/smart-policy
Updates the smart policy for an HVAC unit
Request
Path parameters
ID of the HVAC unit.
Attributes
When enabled, this HVAC unit is under smart control.
Sample
{
"isEnabled": false
}
Response
200Attributes
When enabled, this HVAC unit is under smart control.
Sample
{
"isEnabled": false
}
Get Smart HVAC unit Status
BetaGET /hvacs/{hvacId}/smart-status
Get the status of a smart HVAC unit
Request
Path parameters
ID of the HVAC unit.
Response
200Attributes
ID of the HVAC unit.
ID of the user who owns the HVAC unit.
Sample
{
"hvacId": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"userId": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"intervals": [
{
"from": "10:00",
"to": "11:00",
"heatSetpoint": 20
}
]
}
Set Location for an HVAC unit
PUT /hvacs/{hvacId}
Update the locationId
field on an HVAC unit.
Request
Path parameters
ID of the HVAC unit.
Attributes
Sample
{
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
Response
200Attributes
HVAC device ID
One of TADO, MILL, ADAX, ECOBEE, SENSIBO, HONEYWELL, RESIDEO, MITSUBISHI, or MICROMATIC
The last time Enode successfully communicated with the vendor or when the HVAC unit was initially linked. An ISO8601 UTC timestamp.
Whether live data from the HVAC unit is currently reachable from Enode's perspective. It can happen that this 'reachability' refers to reading from a cache operated by the vendor's cloud service, if that service has determined that its cache is valid.
The current rate of energy consumption in kW. An inactive HVAC will have a consumption rate of 0. This value is currently experimental and is typically estimated with a large margin of error.
Descriptive information about the HVAC unit
An object describing valid states for this HVAC device.
An object grouping the latest temperature information. Values are identical to top-level fields and include a freshness indicator.
An object grouping the latest thermostat state. Values are identical to top-level fields and include a freshness indicator.
Replaced by thermostatState.mode
. The HVAC's mode.
One of OFF, AUTO, COOL, or HEAT
Replaced by thermostatState.heatSetpoint
. If mode allows, heat when currentTemperature
falls below this point.
Replaced by thermostatState.coolSetpoint
. If mode allows, cool when currentTemperature
rises above this point.
Replaced by thermostatState.holdType
. The duration the setpoints and mode are expected to be held. If SCHEDULED
, the device is being controlled by an OEM schedule configured on the device.
One of PERMANENT or SCHEDULED
Replaced by temperatureState.isActive
. Whether the HVAC unit is actively heating or cooling.
Replaced by temperatureState.currentTemperature
. Current air temperature reported by device in degrees Celsius.
ID of the location the HVAC unit is housed at (if any)
Sample
{
"id": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"vendor": "ADAX",
"lastSeen": "2020-04-07T17:04:26.000Z",
"isReachable": true,
"isActive": true,
"currentTemperature": 20.8,
"consumptionRate": 1.8,
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"information": {
"brand": "ADAX",
"model": "Neo Wi-Fi Skirting",
"displayName": "Bedroom Panel Heater",
"groupName": "Bedroom",
"category": "HEATING"
},
"capabilities": {
"capableModes": [
"HEAT",
"COOL",
"OFF"
],
"capableHoldTypes": [
"PERMANENT"
],
"coolSetpointRange": {
"min": 15,
"max": 25
},
"heatSetpointRange": {
"min": 15,
"max": 25
},
"setpointDifferenceRange": {
"min": 15,
"max": 25
}
},
"thermostatState": {
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"lastUpdated": "2020-04-07T17:04:26.000Z"
},
"temperatureState": {
"currentTemperature": 20.8,
"isActive": true,
"lastUpdated": "2020-04-07T17:03:26.000Z"
},
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe"
}
Get HVAC Unit
GET /hvacs/{hvacId}
Request
Path parameters
ID of the HVAC unit.
Response
200Attributes
HVAC device ID
One of TADO, MILL, ADAX, ECOBEE, SENSIBO, HONEYWELL, RESIDEO, MITSUBISHI, or MICROMATIC
The last time Enode successfully communicated with the vendor or when the HVAC unit was initially linked. An ISO8601 UTC timestamp.
Whether live data from the HVAC unit is currently reachable from Enode's perspective. It can happen that this 'reachability' refers to reading from a cache operated by the vendor's cloud service, if that service has determined that its cache is valid.
The current rate of energy consumption in kW. An inactive HVAC will have a consumption rate of 0. This value is currently experimental and is typically estimated with a large margin of error.
Descriptive information about the HVAC unit
An object describing valid states for this HVAC device.
An object grouping the latest temperature information. Values are identical to top-level fields and include a freshness indicator.
An object grouping the latest thermostat state. Values are identical to top-level fields and include a freshness indicator.
Replaced by thermostatState.mode
. The HVAC's mode.
One of OFF, AUTO, COOL, or HEAT
Replaced by thermostatState.heatSetpoint
. If mode allows, heat when currentTemperature
falls below this point.
Replaced by thermostatState.coolSetpoint
. If mode allows, cool when currentTemperature
rises above this point.
Replaced by thermostatState.holdType
. The duration the setpoints and mode are expected to be held. If SCHEDULED
, the device is being controlled by an OEM schedule configured on the device.
One of PERMANENT or SCHEDULED
Replaced by temperatureState.isActive
. Whether the HVAC unit is actively heating or cooling.
Replaced by temperatureState.currentTemperature
. Current air temperature reported by device in degrees Celsius.
ID of the location the HVAC unit is housed at (if any)
Sample
{
"id": "8f39fa8d-8f10-4984-a319-741dc23848c0",
"vendor": "ADAX",
"lastSeen": "2020-04-07T17:04:26.000Z",
"isReachable": true,
"isActive": true,
"currentTemperature": 20.8,
"consumptionRate": 1.8,
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"information": {
"brand": "ADAX",
"model": "Neo Wi-Fi Skirting",
"displayName": "Bedroom Panel Heater",
"groupName": "Bedroom",
"category": "HEATING"
},
"capabilities": {
"capableModes": [
"HEAT",
"COOL",
"OFF"
],
"capableHoldTypes": [
"PERMANENT"
],
"coolSetpointRange": {
"min": 15,
"max": 25
},
"heatSetpointRange": {
"min": 15,
"max": 25
},
"setpointDifferenceRange": {
"min": 15,
"max": 25
}
},
"thermostatState": {
"mode": "HEAT",
"heatSetpoint": 22,
"coolSetpoint": 24,
"holdType": "PERMANENT",
"lastUpdated": "2020-04-07T17:04:26.000Z"
},
"temperatureState": {
"currentTemperature": 20.8,
"isActive": true,
"lastUpdated": "2020-04-07T17:03:26.000Z"
},
"locationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe"
}
Get Action
GET /hvacs/actions/{vendorActionId}
Returns the current state of the requested action.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the entity asset (HVAC) which this action is controlling.
One of hvac
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "hvac",
"target": {
"coolSetpoint": 0,
"mode": "COOL",
"holdType": "PERMANENT"
}
}
Other responses
Response 404
Action not found.
Cancel HVAC Action
POST /hvacs/actions/{vendorActionId}/cancel
Cancels a pending HVAC action, halting any further attempts by Enode to execute it.
Note: This only updates the action's status to CANCELLED
within Enode and does not reflect a change in the vendor's cloud. Thus any pending action in the vendor's cloud might still be executed.
Request
Path parameters
ID of the Action.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the entity asset (HVAC) which this action is controlling.
One of hvac
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "hvac",
"target": {
"coolSetpoint": 0,
"mode": "COOL",
"holdType": "PERMANENT"
}
}
Other responses
Response 404
Action not found.
Response 409
Action already in a resolved state.
Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the entity asset (HVAC) which this action is controlling.
One of hvac
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "hvac",
"target": {
"coolSetpoint": 0,
"mode": "COOL",
"holdType": "PERMANENT"
}
}
Set HVAC unit to follow device schedule
POST /hvacs/{hvacId}/follow-schedule
Tell an HVAC unit to follow the schedule set on the device. Only available if SCHEDULED
is present in the target's capabilities.capableHoldType
. This endpoint can be used to cancel permanent holds. We retry sending the command until the HVAC unit's fields transition to the expected values. Note that this request will complete before any commands are sent to the HVAC unit. You may react to transitions by listening for the user:vendor-action:updated
webhook event or polling the HVAC action endpointAPI.
Request
Path parameters
ID of the HVAC unit.
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the entity asset (HVAC) which this action is controlling.
One of hvac
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "hvac",
"target": {
"holdType": "SCHEDULED"
}
}
Other responses
Response 400
A precondition check failed, and it is unlikely to change within the next 30 minutes. This occurs if the HVAC unit cannot perform the action.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Response 422
HVAC unit controlled by an Enode Schedule
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Refresh HVAC unit data
POST /hvacs/{hvacId}/refresh-hint
Use this endpoint to initiate an expedited data refresh for the specified HVAC unit.
Note: The Enode platform keeps data automatically up-to-date and detects changes in the OEM APIs within seconds to a few minutes. We change the refresh interval dynamically based on a number of heuristics. This ensures we find the best trade-off between the stability of the connection to the OEM and freshness of the data.
This method overrides most of our heuristics and should therefore be used with caution. You may use it when you have a strong reason to believe the data might be stale.
Request
Path parameters
ID of the HVAC unit.
Response
204Refresh hint registered successfully.
Other responses
Response 404
The specified hvac was not found.
Set HVAC unit Mode as Permanent Hold
POST /hvacs/{hvacId}/permanent-hold
Tell an HVAC unit to enter a permanent hold. Only available if PERMANENT
is present in the target's capabilities.capableHoldType
. We retry sending the command until the HVAC unit's target
field transition to the expected value. Note that this request will complete before any commands are sent to the HVAC unit. You may react to transitions by listening for the user:vendor-action:updated
webhook event or polling the HVAC action endpointAPI.
Request
Path parameters
ID of the HVAC unit.
Attributes
One of COOL
Sample
{
"coolSetpoint": 0,
"mode": "COOL"
}
Response
200Attributes
The ID of the action.
ISO8601 UTC timestamp
ISO8601 UTC timestamp
ISO8601 UTC timestamp at which the action transitioned to a non-pending state. If this value is set, then we are no longer sending commands to the target.
The real-time status of a vendor action executed on an energy asset.
PENDING
: The initial state. Enode is actively sending commands and monitoring the asset for changes.CONFIRMED
: Successful transition of the asset to the desired state.FAILED
: The asset did not respond to the action within 30 minutes. Enode has ceased sending additional commands.CANCELLED
: A required precondition was not met during the 30 minutes period or another action targeted the same asset, overriding this one.
One of PENDING, CONFIRMED, FAILED, or CANCELLED
ID of the entity asset (HVAC) which this action is controlling.
One of hvac
Sample
{
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"createdAt": "2020-04-07T17:04:26Z",
"updatedAt": "2020-04-07T17:04:26Z",
"completedAt": "string",
"state": "PENDING",
"targetId": "string",
"targetType": "hvac",
"target": {
"coolSetpoint": 0,
"mode": "COOL",
"holdType": "PERMANENT"
}
}
Other responses
Response 400
A precondition check failed, that is unlikely to change within 30 minutes. This occurs if the HVAC unit cannot perform the action or the setpoints are invalid.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Response 422
HVAC unit controlled by an Enode Schedule
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Interventions
Endpoints that return information about interventions. More information and examples are available in the Interventions guide.
List Interventions
GET /interventions
Returns a list of all known interventions.
The language
parameter can be used to specify the language of the resolution title and description.
Request
Query parameters
Preferred BCP47 language code - Request translation for the specified language. Falls back to en-US
if not provided.
One of en-US, en-GB, de-DE, fr-FR, es-ES, pt-PT, nl-NL, nb-NO, sv-SE, da-DK, fi-FI, or ro-RO
Response
200Attributes
Machine-friendly representation of the OEM's name.
One of AUDI, BMW, HONDA, HYUNDAI, JAGUAR, LANDROVER, KIA, MERCEDES, MINI, NISSAN, PEUGEOT, PORSCHE, RENAULT, SEAT, SKODA, TESLA, VOLKSWAGEN, VOLVO, FORD, OPEL, DS, TOYOTA, CITROEN, CUPRA, VAUXHALL, FIAT, RIVIAN, NIO, CHEVROLET, or GMC
Type of device this intervention relates to.
One of vehicle, charger, hvac, inverter, battery, or meter
A formatted and properly cased OEM brand name, suitable for reading by humans. May contain special characters.
One of Audi, BMW, Honda, Hyundai, Jaguar, Land Rover, Kia, Mercedes, MINI, Nissan, Peugeot, Porsche, Renault, SEAT, ŠKODA, Tesla, Volkswagen, Volvo, Ford, Opel, DS, Toyota, Citroën, Cupra, Vauxhall, Fiat, Rivian, Nio, Chevrolet, or GMC
ISO 8601 timestamp of when the intervention was introduced.
The domain the intervention is related to. i.e. Is the intervention related to the vendor service account or a setting on the device.
One of Account or Device
Sample
[
{
"id": "9d90a9ad-9b24-4ce0-94e9-e888b1b877f4",
"vendor": "AUDI",
"vendorType": "vehicle",
"brand": "Audi",
"introducedAt": "2023-03-16T00:00:00",
"domain": "Account",
"resolution": {
"title": "Accept the Audi terms and conditions",
"description": "To gain access to your vehicle's telemetry data, it's necessary to accept Audi's terms and conditions. Follow these steps to proceed:<br><br>1. Open the **myAudi app** on your phone<br>2. Follow the prompts to accept Audi's terms and conditions",
"access": "Remote",
"agent": "User"
}
}
]
Get Intervention
GET /interventions/{interventionId}
Returns a single intervention.
The language
parameter can be used to specify the language of the resolution title and description.
Request
Path parameters
ID of the intervention.
Query parameters
Preferred BCP47 language code - Request translation for the specified language. Falls back to en-US
if not provided.
One of en-US, en-GB, de-DE, fr-FR, es-ES, pt-PT, nl-NL, nb-NO, sv-SE, da-DK, fi-FI, or ro-RO
Response
200Attributes
Machine-friendly representation of the OEM's name.
One of AUDI, BMW, HONDA, HYUNDAI, JAGUAR, LANDROVER, KIA, MERCEDES, MINI, NISSAN, PEUGEOT, PORSCHE, RENAULT, SEAT, SKODA, TESLA, VOLKSWAGEN, VOLVO, FORD, OPEL, DS, TOYOTA, CITROEN, CUPRA, VAUXHALL, FIAT, RIVIAN, NIO, CHEVROLET, or GMC
Type of device this intervention relates to.
One of vehicle, charger, hvac, inverter, battery, or meter
A formatted and properly cased OEM brand name, suitable for reading by humans. May contain special characters.
One of Audi, BMW, Honda, Hyundai, Jaguar, Land Rover, Kia, Mercedes, MINI, Nissan, Peugeot, Porsche, Renault, SEAT, ŠKODA, Tesla, Volkswagen, Volvo, Ford, Opel, DS, Toyota, Citroën, Cupra, Vauxhall, Fiat, Rivian, Nio, Chevrolet, or GMC
ISO 8601 timestamp of when the intervention was introduced.
The domain the intervention is related to. i.e. Is the intervention related to the vendor service account or a setting on the device.
One of Account or Device
Sample
{
"id": "9d90a9ad-9b24-4ce0-94e9-e888b1b877f4",
"vendor": "AUDI",
"vendorType": "vehicle",
"brand": "Audi",
"introducedAt": "2023-03-16T00:00:00",
"domain": "Account",
"resolution": {
"title": "Accept the Audi terms and conditions",
"description": "To gain access to your vehicle's telemetry data, it's necessary to accept Audi's terms and conditions. Follow these steps to proceed:<br><br>1. Open the **myAudi app** on your phone<br>2. Follow the prompts to accept Audi's terms and conditions",
"access": "Remote",
"agent": "User"
}
}
Other responses
Response 404
Intervention not found.
Locations
A user creates locations to denote locations where they pay for the power used to charge their vehicle, heat their home, etc. Smart Charging is active at these locations only.
List Locations
GET /locations
Returns a paginated list of all Locations.
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of locations
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List User Locations
GET /users/{userId}/locations
Returns a paginated list of Locations for the given user.
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of locations
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Create Location
POST /users/{userId}/locations
Create a Location for a User.
Request
Path parameters
ID of the User.
Attributes
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo"
}
Response
200Attributes
The ID of the Location.
User ID the location belongs to
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
Get Location
GET /locations/{locationId}
Fetch a Location.
Request
Path parameters
ID of the Location.
Response
200Attributes
The ID of the Location.
User ID the location belongs to
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
Delete Location
DELETE /locations/{locationId}
Delete a Location.
Request
Path parameters
ID of the Location.
Response
200Attributes
The ID of the Location.
User ID the location belongs to
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
Update Location
PUT /locations/{locationId}
Updates a location.
Request
Path parameters
ID of the Location.
Attributes
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo"
}
Response
200Attributes
The ID of the Location.
User ID the location belongs to
User-supplied name for the Location
Longitude in degrees
Latitude in degrees
An IANA TZ database timezone name. This value will be used to convert rules and deadlines for tariffs, smart charging, and schedules into local time. Defaults to UTC
.
Sample
{
"name": "Enode",
"latitude": 59.9173985,
"longitude": 10.7197486,
"timezoneName": "Europe/Oslo",
"id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"userId": "string"
}
Meters
The Meter
object represents a unit responsible for measuring energy usage. It provides detailed information about the meter itself and the energy consumption data it records.
Get Meter
BetaGET /meters/{meterId}
Request
Path parameters
The ID of the meter you are looking up
Response
200Attributes
Unique identifier for the meter object
One of ENPHASE or TESLA
The last time Enode successfully communicated with the vendor or when the meter was initially linked. An ISO8601 UTC timestamp.
Whether live data from the meter is currently reachable from Enode's perspective. This 'reachability' may refer to reading from a cache operated by the meter's cloud service if that service has determined that its cache is valid.
Descriptive information about the meter
Meter's GPS coordinates
The specific meter's capabilities for recording energy consumption and production data.
Sample
{
"id": "string",
"vendor": "ENPHASE",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"information": {
"brand": "Enphase",
"model": "Tesla Powerwall built-in meter",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"energyState": {
"power": 0,
"lastUpdated": "string"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"measuresConsumption": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"measuresProduction": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
Refresh meter data
BetaPOST /meters/{meterId}/refresh-hint
Use this endpoint to initiate an expedited data refresh for the specified meter.
Note: The Enode platform keeps data automatically up-to-date and detects changes in the OEM APIs within seconds to a few minutes. We change the refresh interval dynamically based on a number of heuristics. This ensures we find the best trade-off between the stability of the connection to the OEM and freshness of the data.
This method overrides most of our heuristics and should therefore be used with caution. You may use it when you have a strong reason to believe the data might be stale.
Request
Path parameters
The ID of the meter you are looking up
Response
204Refresh hint registered successfully.
Other responses
Response 404
The specified meter was not found.
List User Meters
BetaGET /users/{userId}/meters
Returns a paginated list of meters for the given userId.
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of meters
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "ENPHASE",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"information": {
"brand": "Enphase",
"model": "Tesla Powerwall built-in meter",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"energyState": {
"power": 0,
"lastUpdated": "string"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"measuresConsumption": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"measuresProduction": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List Meters
BetaGET /meters
Returns a paginated list of all Meters.
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of meters
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "ENPHASE",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"information": {
"brand": "Enphase",
"model": "Tesla Powerwall built-in meter",
"siteName": "Powerwall Home",
"installationDate": "2020-04-07T17:04:26Z"
},
"energyState": {
"power": 0,
"lastUpdated": "string"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"capabilities": {
"measuresConsumption": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"measuresProduction": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
}
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Schedules
Endpoints to manage schedules for Vehicles, Chargers and HVAC.
More information and examples are available in the Using Schedules guide.
List Schedules
GET /users/{userId}/schedules
Returns a list of Schedules registered to the User.
Request
Path parameters
ID of the User.
Response
200Attributes
Paginated list of schedules
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"id": "string"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Create Schedule
POST /users/{userId}/schedules
Request
Path parameters
ID of the User.
Attributes
Whether this Schedule should be attempting to control the target's charge state.
When no rule is active, the default charge state for the target.
Each rule sets a value for shouldCharge
, either true
or false
. All other properties of the rule are optional filters that limit the times to which this rule applies.
ID of the asset (Vehicle/Charger) to which this schedule applies
One of vehicle or charger
ID of the Location to which this schedule applies. The behavior of a null value differs based on the targetType
. For chargers, a null value is essentially ignored and the schedule is applied even if the charger isn't at a charging location. This is designed to prevent schedules from controlling vehicles at public chargers where the user doesn't pay for electricity.
Sample
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
Response
200Attributes
Whether this Schedule should be attempting to control the target's charge state.
When no rule is active, the default charge state for the target.
Each rule sets a value for shouldCharge
, either true
or false
. All other properties of the rule are optional filters that limit the times to which this rule applies.
ID of the asset (Vehicle/Charger) to which this schedule applies
One of vehicle or charger
ID of the Location to which this schedule applies. The behavior of a null value differs based on the targetType
. For chargers, a null value is essentially ignored and the schedule is applied even if the charger isn't at a charging location. This is designed to prevent schedules from controlling vehicles at public chargers where the user doesn't pay for electricity.
Sample
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"id": "string"
}
Get Schedule
GET /schedules/{scheduleId}
Request
Path parameters
ID of the Schedule.
Response
200Attributes
Whether this Schedule should be attempting to control the target's charge state.
When no rule is active, the default charge state for the target.
Each rule sets a value for shouldCharge
, either true
or false
. All other properties of the rule are optional filters that limit the times to which this rule applies.
ID of the asset (Vehicle/Charger) to which this schedule applies
One of vehicle or charger
ID of the Location to which this schedule applies. The behavior of a null value differs based on the targetType
. For chargers, a null value is essentially ignored and the schedule is applied even if the charger isn't at a charging location. This is designed to prevent schedules from controlling vehicles at public chargers where the user doesn't pay for electricity.
Sample
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"id": "string"
}
Update Schedule
PUT /schedules/{scheduleId}
Does a partial update of a schedule.
Request
Path parameters
ID of the Schedule.
Attributes
Whether this Schedule should be attempting to control the target's charge state.
When no rule is active, the default charge state for the target.
Each rule sets a value for shouldCharge
, either true
or false
. All other properties of the rule are optional filters that limit the times to which this rule applies.
ID of the asset (Vehicle/Charger) to which this schedule applies
One of vehicle or charger
ID of the Location to which this schedule applies. The behavior of a null value differs based on the targetType
. For chargers, a null value is essentially ignored and the schedule is applied even if the charger isn't at a charging location. This is designed to prevent schedules from controlling vehicles at public chargers where the user doesn't pay for electricity.
Sample
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
Response
200Attributes
Whether this Schedule should be attempting to control the target's charge state.
When no rule is active, the default charge state for the target.
Each rule sets a value for shouldCharge
, either true
or false
. All other properties of the rule are optional filters that limit the times to which this rule applies.
ID of the asset (Vehicle/Charger) to which this schedule applies
One of vehicle or charger
ID of the Location to which this schedule applies. The behavior of a null value differs based on the targetType
. For chargers, a null value is essentially ignored and the schedule is applied even if the charger isn't at a charging location. This is designed to prevent schedules from controlling vehicles at public chargers where the user doesn't pay for electricity.
Sample
{
"isEnabled": true,
"defaultShouldCharge": true,
"rules": [
{
"hourMinute": {
"from": "string",
"to": "string"
},
"fromTimestamp": "2020-04-07T17:04:26Z",
"toTimestamp": "2020-04-07T17:04:26Z",
"weekdays": [
0,
1,
2,
3,
4,
5
],
"shouldCharge": true
}
],
"targetId": "string",
"targetType": "vehicle",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"id": "string"
}
Delete Schedule
DELETE /schedules/{scheduleId}
Delete a Schedule
Request
Path parameters
ID of the Schedule.
Response
204No Content
Get Schedule Status
GET /schedules/{scheduleId}/status
Request
Path parameters
ID of the Schedule.
Response
200Attributes
ID of the schedule.
One of CHARGE
Time at which any value of the status last changed
An enum value that describes the current state of the Schedule
One of ALIGNED, MISALIGNED, PENDING, INACTIVE:OVERRIDDEN, INACTIVE:DISABLED, INACTIVE:AWAY, or INACTIVE:INCAPABLE
Whether the target is currently actually charging
Whether the target is currently expected to be charging
Collection of booleans that - when combined via AND operator - forms the isChargingExpected
value
List of upcoming transitions of the shouldCharge
or targetTemperature
value. A maximum of 2 items are returned.
This field is only populated after calling the vehicleAPI or chargerAPI smart override APIs. While this parameter is populated, the parent charge controller will remain in an overridden state and will not attempt to send actions to the target. The smart override remains in place until the target stops charging for any reason, or until the smart override is ended via the Delete vehicleAPI or chargerAPI smart override APIs.
Sample
{
"scheduleId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"scheduleType": "CHARGE",
"changedAt": "2020-04-07T17:04:26Z",
"state": "ALIGNED",
"isCharging": true,
"isChargingExpected": true,
"isChargingExpectedParts": {
"needsCharge": true,
"isPluggedIn": true,
"shouldCharge": true
},
"upcomingTransitions": [
{
"at": "2020-04-07T17:04:26Z",
"shouldCharge": true
}
],
"smartOverride": {
"createdAt": "2020-04-07T17:04:26Z",
"endedAt": "string",
"targetType": "vehicle",
"targetId": "string",
"vendorActionId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
}
Service Health
Endpoints that return information about the health of Enode and our integrations.
Check Available Charger Vendors
GET /health/chargers
Lists the available charger vendors. If you authenticate with a client or link token, we also include the activated vendors that your client has access to. Learn more about vendors requiring activation.
Response
200Attributes
Machine-friendly name of the Vendor
One of ZAPTEC, EASEE, WALLBOX, EO, CHARGEAMPS, or EVBOX
A formatted and properly cased vendor brand name, suitable for reading by humans.
One of Zaptec, Easee, Wallbox, EO, EVBox, or Charge Amps
The name of the first party service or app that the user normally logs into.
Ready-state of the Vendor. Currently always READY
.
One of READY, ELEVATED_ERROR_RATE, or OUTAGE
Sample
[
{
"vendor": "EASEE",
"displayName": "Easee",
"portalName": "Easee",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "WALLBOX",
"displayName": "Wallbox",
"portalName": "Wallbox",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "ZAPTEC",
"displayName": "Zaptec",
"portalName": "Zaptec",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "EO",
"displayName": "EO",
"portalName": "EO",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
}
]
Check Available Vehicle Vendors
GET /health/vehicles
Lists the available vehicle vendors. If you authenticate with a client or link token, we also include the activated vendors that your client has access to. Learn more about vendors requiring activation.
Response
200Attributes
Machine-friendly name of the Vendor
One of AUDI, BMW, HONDA, HYUNDAI, JAGUAR, LANDROVER, KIA, MERCEDES, MINI, NISSAN, PEUGEOT, PORSCHE, RENAULT, SEAT, SKODA, TESLA, VOLKSWAGEN, VOLVO, FORD, OPEL, DS, TOYOTA, CITROEN, CUPRA, VAUXHALL, FIAT, RIVIAN, NIO, CHEVROLET, or GMC
A formatted and properly cased vendor brand name, suitable for reading by humans.
One of Audi, BMW, Honda, Hyundai, Jaguar, Land Rover, Kia, Mercedes, MINI, Nissan, Peugeot, Porsche, Renault, SEAT, ŠKODA, Tesla, Volkswagen, Volvo, Ford, Opel, DS, Toyota, Citroën, Cupra, Vauxhall, Fiat, Rivian, Nio, Chevrolet, or GMC
The name of the first party service or app that the user normally logs into.
Ready-state of the Vendor. Currently always READY
.
One of READY, ELEVATED_ERROR_RATE, or OUTAGE
Sample
[
{
"vendor": "TESLA",
"displayName": "Tesla",
"portalName": "Tesla",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "BMW",
"displayName": "BMW",
"portalName": "My BMW",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "AUDI",
"displayName": "Audi",
"portalName": "myAudi",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
}
]
Check Available Inverter Vendors
GET /health/inverter
Lists the available inverter vendors. If you authenticate with a client or link token, we also include the activated vendors that your client has access to. Learn more about vendors requiring activation.
Response
200Attributes
Machine-friendly name of the Vendor
One of CSISolar, Deye, EMA, ENPHASE, FRONIUS, GOODWE, GROWATT, Hoymiles, HUAWEI, INVT, SMA, SOFAR, SOLAREDGE, SOLAX, SOLIS, SUNGROW, TESLA, or TSUN
A formatted and properly cased vendor brand name, suitable for reading by humans.
One of CSISolar, Deye, EMA, Enphase, Fronius, GoodWe, Growatt, Hoymiles, Huawei, INVT, SMA, Sofar, SolarEdge, Solax, Solis, Sungrow, Tesla, or TSUN
The name of the first party service or app that the user normally logs into.
Ready-state of the Vendor. Currently always READY
.
One of READY, ELEVATED_ERROR_RATE, or OUTAGE
Sample
[
{
"vendor": "SOLAREDGE",
"displayName": "SolarEdge",
"portalName": "Solar Edge",
"status": "READY",
"defaultRegion": "region-global-except-north-america"
},
{
"vendor": "SMA",
"displayName": "SMA",
"status": "READY",
"defaultRegion": "region-global-except-north-america",
"portalName": "SMA Energy"
},
{
"vendor": "SOLIS",
"displayName": "Solis",
"status": "READY",
"defaultRegion": "region-global-except-north-america",
"portalName": "Solis"
},
{
"vendor": "FRONIUS",
"displayName": "Fronius",
"status": "READY",
"defaultRegion": "region-global-except-north-america",
"portalName": "Fronius"
}
]
Check Available Hvac Vendors
GET /health/hvacs
Lists the available HVAC vendors. If you authenticate with a client or link token, we also include the activated vendors that your client has access to. Learn more about vendors requiring activation.
Response
200Attributes
Machine-friendly name of the Vendor
One of TADO, MILL, ADAX, ECOBEE, SENSIBO, HONEYWELL, RESIDEO, MITSUBISHI, or MICROMATIC
A formatted and properly cased vendor brand name, suitable for reading by humans.
One of Tado, Mill, ADAX, Ecobee, Sensibo, Honeywell TCC, Resideo, Mitsubishi, or Micro Matic
The name of the first party service or app that the user normally logs into.
Ready-state of the Vendor. Currently always READY
.
One of READY, ELEVATED_ERROR_RATE, or OUTAGE
Sample
[
{
"vendor": "MILL",
"displayName": "Mill",
"status": "READY",
"defaultRegion": "region-global-except-north-america",
"portalName": "Mill"
}
]
Check Service Readiness
GET /health/ready
Gets the combined health status of the service and all functionalities and dependencies.
Response
204All functionalities are operating nominally.
Other responses
Response 503
At least one functionality of the system is not operating nominally.
Solar inverters
Solar inverters can be queried for current production state
List Solar Inverters
GET /inverters
Response
200Attributes
Paginated list of solar inverters
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "CSISolar",
"chargingLocationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"productionState": {
"productionRate": 0,
"isProducing": true,
"totalLifetimeProduction": 100152.56,
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "CSISolar",
"model": "Sunny Boy",
"siteName": "Sunny Plant",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"timezone": "string"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List User Solar Inverters
GET /users/{userId}/inverters
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of solar inverters
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "CSISolar",
"chargingLocationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"productionState": {
"productionRate": 0,
"isProducing": true,
"totalLifetimeProduction": 100152.56,
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "CSISolar",
"model": "Sunny Boy",
"siteName": "Sunny Plant",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"timezone": "string"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Get Solar Inverter
GET /inverters/{inverterId}
Request
Path parameters
ID of the solar inverter
Response
200Attributes
Solar Inverter ID
One of CSISolar, Deye, EMA, ENPHASE, FRONIUS, GOODWE, GROWATT, Hoymiles, HUAWEI, INVT, SMA, SOFAR, SOLAREDGE, SOLAX, SOLIS, SUNGROW, TESLA, or TSUN
ID of the charging location the solar inverter is currently positioned at (if any).
The last time Enode received live data or when the solar inverter was initially linked. An ISO8601 UTC timestamp.
Whether live data from the solar inverter is currently reachable from Enode's perspective. This 'reachability' may refer to reading from a cache operated by the solar inverter's cloud service if that service has determined that its cache is valid.
Descriptive information about the solar inverter
Solar inverter's GPS coordinates
IANA timezone string
Sample
{
"id": "string",
"vendor": "CSISolar",
"chargingLocationId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"productionState": {
"productionRate": 0,
"isProducing": true,
"totalLifetimeProduction": 100152.56,
"lastUpdated": "string"
},
"information": {
"id": "string",
"brand": "CSISolar",
"model": "Sunny Boy",
"siteName": "Sunny Plant",
"installationDate": "2020-04-07T17:04:26Z"
},
"location": {
"longitude": 10.7197486,
"latitude": 59.9173985
},
"timezone": "string"
}
Refresh Inverter data
POST /inverters/{inverterId}/refresh-hint
Use this endpoint to initiate an expedited data refresh for the specified inverter.
Note: The Enode platform keeps data automatically up-to-date and detects changes in the OEM APIs within seconds to a few minutes. We change the refresh interval dynamically based on a number of heuristics. This ensures we find the best trade-off between the stability of the connection to the OEM and freshness of the data.
This method overrides most of our heuristics and should therefore be used with caution. You may use it when you have a strong reason to believe the data might be stale.
Request
Path parameters
ID of the solar inverter
Response
204Refresh hint registered successfully.
Other responses
Response 404
The specified inverter was not found.
Statistics
Endpoints returning timeseries data collected from any linked devices.
Get User Charging Statistics
GET /users/{userId}/statistics/charging
Returns statistics about power consumption and price in the form of a time series.
If Smart Charging has shifted the consumption, the 'non-smart' price fields will show what the consumption would have cost if it had happened at the default time. If smart charging has resulted in savings, the value is reported in the estimatedSavings
field. <CURRENCY>
is an ISO4217 Alpha-3 currency code that is determined by client-wide configuration or the currency code provided during price data ingestion (such as Tariffs).
Request
Path parameters
User ID
Query parameters
Earliest date to include in the response in ISO format. Example: 2021-03-21T00:25:43.511Z
Latest date to include in the response (defaults to current date/time) in ISO format. Example: 2021-03-21T00:25:43.511Z
Filter statistics to only include this location
Filter statistics to only include a specific entity. Hardware category of the entity must match the type
parameter.
Get statistics for this hardware type.
One of charger, vehicle, or hvac
Offset (in hours) from UTC of the timezone from which the statistics should be viewed. By default, all returned timestamps are in UTC, and period boundaries (day, week, month, year) used in the aggregation are calculated in UTC. Providing utcOffset
instead aligns these to the viewer's timezone so that the timestamps and period boundaries fall where the viewer expects them to. Positive, negative, and fractional values are valid.
The unit of time the data will be cut into before aggregate statistics are applied. Each entry in the response array corresponds to aggregated data of the time range specified.
One of QUARTER_HOUR, HALF_HOUR, HOUR, DAY, WEEK, MONTH, or YEAR
Response
200Attributes
Aggregate statistics for charge rate in kW
Total power consumption in kWh
Aggregate statistics for power price (<CURRENCY>
per kWh)
Total cost in <CURRENCY>
Aggregate statistics for power price (<CURRENCY>
per kWh), calculated as if charging had occurred uninterrupted without being delayed by Smart Charging
Total estimated savings in <CURRENCY>
, achieved by Smart Charging. If null
, no part of the time range was impacted by Smart Charging.
The start date of this sample
Sample
[
{
"kw": {
"min": 0,
"max": 78,
"mean": 61
},
"kwhSum": 120,
"price": {
"min": 13.8,
"max": 14.4,
"mean": 14.1
},
"nonSmartPrice": {
"min": 12.9,
"max": 16.7,
"mean": 14.8
},
"costSum": 3.14,
"estimatedSavings": 1.07,
"date": "2021-01-19T09:37:36.845Z"
}
]
Get User Statistics on Charging Sessions
GET /users/{userId}/statistics/charging/sessions
Returns statistics about power consumption and price binned by sessions.
Request
Path parameters
User ID
Query parameters
Earliest date to include in the response in ISO format. Example: 2021-03-21T00:25:43.511Z
Latest date to include in the response (defaults to current date/time) in ISO format. Example: 2021-03-21T00:25:43.511Z
Filter statistics to only include this location
Filter statistics to only include a specific entity. Hardware category of the entity must match the type
parameter.
Get statistics for this hardware type.
One of charger, vehicle, or hvac
Response
200Attributes
Aggregate statistics for charge rate in kW
Total power consumption in kWh
Aggregate statistics for power price (<CURRENCY>
per kWh)
Total cost in <CURRENCY>
ID of the asset (charger/hvac/vehicle) for this session.
Charging Location ID for this session.
Start time.
End time.
Aggregate statistics for power price (<CURRENCY>
per kWh), calculated as if charging had occurred uninterrupted without being delayed by Smart Charging
Total estimated savings in <CURRENCY>
, achieved by Smart Charging. If null
, the entire session was not a Smart Charging session.
Sample
[
{
"kw": {
"min": 0,
"max": 0,
"mean": 0
},
"kwhSum": 120,
"price": {
"min": 0,
"max": 0,
"mean": 0
},
"costSum": 3.14,
"id": "string",
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
"from": "2020-04-07T17:04:26Z",
"to": "2020-04-07T17:04:26Z",
"nonSmartPrice": {
"min": 0,
"max": 0,
"mean": 0
},
"estimatedSavings": 1.07
}
]
Get User Production Statistics
GET /users/{userId}/statistics/production
Returns statistics about power production and price in the form of a time series.
Request
Path parameters
User ID
Query parameters
Earliest date to include in the response in ISO format. Example: 2021-03-21T00:25:43.511Z
Latest date to include in the response (defaults to current date/time) in ISO format. Example: 2021-03-21T00:25:43.511Z
Filter statistics to only include this location
Filter statistics to only include a specific entity. Hardware category of the entity must match the type
parameter.
Get statistics for this hardware type.
One of inverter
The unit of time the data will be cut into before aggregate statistics are applied. Each entry in the response array corresponds to aggregated data of the time range specified.
One of QUARTER_HOUR, HALF_HOUR, HOUR, DAY, WEEK, MONTH, or YEAR
Offset (in hours) from UTC of the timezone from which the statistics should be viewed. By default, all returned timestamps are in UTC, and period boundaries (day, week, month, year) used in the aggregation are calculated in UTC. Providing utcOffset
instead aligns these to the viewer's timezone so that the timestamps and period boundaries fall where the viewer expects them to. Positive, negative, and fractional values are valid.
Response
200Attributes
Aggregate statistics for production rate in kW
Total power production in kWh
Aggregate statistics for power price (<CURRENCY>
per kWh)
Total earnings in <CURRENCY>
The start date of this sample
Sample
[
{
"kw": {
"min": 0,
"max": 78,
"mean": 61
},
"kwhSum": 120,
"price": {
"min": 13.8,
"max": 14.4,
"mean": 14.1
},
"earningsSum": 3.14,
"date": "2021-01-19T09:37:36.845Z"
}
]
Get Vendor Statistics For Inverters
BetaGET /users/{userId}/vendor-statistics
Returns statistics about power production for the given inverter in the form of a time series, collected from vendor APIs.
This endpoint is currently in alpha, undergoing active development. Please be aware that errors, inaccuracies, and breaking changes may occur without prior notice. For testing the endpoint or more information, contact our Product Manager Kristine at kristine@enode.io.
Since the statistics data provided by the vendors starts and ends at well defined offsets, the returned time series may start/end at an earlier/later time than requested. E.g. if hourly statistics are requested with startDate = 2023-06-17T09:30:00Z
, the returned time series will start at 2023-06-17T09:00:00Z
. Currently, we only support querying for 1 month of data.
Please note that currently, requests may take a long time to complete.
Request
Path parameters
User ID
Query parameters
The duration of each time bucket the returned time series is divided into. Each entry in the response array corresponds to aggregated data of the specified time range.
One of HOUR or DAY
The earliest date (UTC) to include in the response in ISO format. Cannot be greater than endDate. Example: 2021-03-21T02:00:00Z
The latest date (UTC) to include in the response in ISO format. Defaults to the current date/time. Example: 2021-03-21T05:00:00Z
ID of the Inverter.
Response
200Attributes
Contains information about power production statistics.
Sample
{
"production": {
"unit": "kWh",
"data": [
{
"date": "2024-01-19T09:00:00.000Z",
"value": 11.1
},
{
"date": "2024-01-19T10:00:00.000Z",
"value": 15.4
}
]
}
}
Tariffs
Endpoints used to submit pricing information to Enode.
Send Tariff information
PUT /tariffs/{tariffId}
Set a list of rates for a given tariffId
. If previous data exists for a given tariffId
, it will be overwritten. These tariffs are used in our Statistics and Smart Charging features.
Request
Path parameters
Attributes
Per-tariff unique interval name
Rate cost (decimal string)
Sample
[
{
"name": "PEAK",
"cost": "13.37"
},
{
"name": "OFF-PEAK",
"cost": "12.34"
}
]
Response
204Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Get Location Tariff for user
GET /locations/{locationId}/tariff
Get Tariff intervals for a given location for user.
Request
Path parameters
ID of the Location.
Response
200Attributes
Weekday to apply the named tariff. A weekday starts with 0 for Monday, and ends with 6 for Sunday. If not specified, named tariff is applied for entire week
One of 0, 1, 2, 3, 4, 5, or 6
Interval from time (inclusive, UTC)
Interval to time (exclusive, UTC)
Energy Provider Tariff ID
Rate name
Sample
[
{
"weekday": 0,
"fromHourMinute": "00:00",
"toHourMinute": "06:00",
"tariffId": "testing-tariff-a",
"tariffName": "OFF-PEAK"
},
{
"weekday": 0,
"fromHourMinute": "06:00",
"toHourMinute": "18:00",
"tariffId": "testing-tariff-a",
"tariffName": "PEAK"
}
]
Other responses
Response 400
Invalid tariffId or rate name, or incomplete interval series
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Response 404
Location not found
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Associate Location With Tariff for user
PUT /locations/{locationId}/tariff
Associates a tariff to a location and specifies time intervals for the tariff's rates at this location. Further requests will overwrite the existing intervals for the specified tariffId. Multiple tariffs can be associated with a Location. To disassociate a particular tariff, send a request with the tariffId and an empty tariffInterval list.
Request
Path parameters
ID of the Location.
Attributes
Energy Provider Tariff ID
List of time intervals at which to apply the specified tariff rates
Sample
{
"tariffId": "string",
"tariffIntervals": [
{
"name": "OFF-WEEKEND",
"weekdays": [
5,
6
],
"from": "00:00",
"to": "06:00"
},
{
"name": "PEAK-WEEKEND",
"weekdays": [
5,
6
],
"from": "06:00",
"to": "18:00"
},
{
"name": "OFF",
"weekdays": [
5,
6
],
"from": "18:00",
"to": "23:59"
},
{
"name": "PEAK",
"from": "00:00",
"to": "18:00"
}
]
}
Response
204Successful
Other responses
Response 400
Invalid tariffId, invalid rate name, or incomplete interval series.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Response 404
Location not found.
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
User Management
Endpoints used to link and unlink users or vendors.
List Users
GET /users
Returns a paginated list of all users.
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Paginated list of users.
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "ad84e742-0f46-4cf4-b0db-7d890f8f23f5",
"createdAt": "2020-04-07T17:04:26Z",
"scopes": [
"all"
]
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
Get User
GET /users/{userId}
Returns metadata about the given User ID, including a list of vendors for which the User has provided credentials.
Request
Path parameters
ID of the User.
Response
200Attributes
The user's ID.
Sample
{
"id": "123456789-ABc",
"linkedVendors": [
{
"vendor": "CSISolar",
"vendorType": "vehicle",
"isValid": true
}
]
}
Unlink User
DELETE /users/{userId}
Deletes a User and all of their data permanently and invalidates any associated sessions, authorization codes, and access/refresh tokens.
Request
Path parameters
ID of the User.
Response
204No Content
Disconnect Vendor
DELETE /users/{userId}/vendors/{vendor}
Disconnect a single Vendor from the User's account.
All stored data about their Vendor account will be deleted, and any vehicles that were provided by that Vendor will disappear from the system.
Request
Path parameters
ID of the User.
Vendor to be unlinked.
Response
204No Content
Disconnect Vendor Type
DELETE /users/{userId}/vendors/{vendor}/{vendorType}
Disconnect a specific vendor type from the User's account. Assets of this type from that Vendor will be removed. If no other types from that vendor remain, all its stored data will be deleted.
Request
Path parameters
ID of the User.
Vendor to be unlinked.
One of vehicle, charger, hvac, inverter, battery, or meter
Response
204No Content
Link User
POST /users/{userId}/link
Creates an Enode Link session attached to the provided User ID. If this User does not exist, it will be created. The returned linkState
gives the User short-lived (24hs) access to Enode Link. A URL for Enode Link for the user to initiate asset linking is also returned.
Request
Path parameters
ID of the User.
Attributes
Skip the vendor selection screen and present the credential input for a specific vendor immediately.
Sets the type of vendors available for connection in a Link UI session. If absent, this defaults to vehicle
.
One of vehicle, charger, hvac, inverter, battery, or meter
The scope(s) you wish to request access to when linking an asset.
A URI to redirect the user to after successfully linking an asset. A user may also arrive at the redirect URI if they exited Link UI by clicking the X or denying permissions. In these cases, an error
query param will be added to your redirect URI with the values of user closed session
or consent request denied
, respectively.
Sample
{
"vendor": "AUDI",
"vendorType": "vehicle",
"forceLanguage": "en",
"scopes": [
"offline_access",
"all"
],
"redirectUri": "myapp://integrations/enode"
}
Response
200Attributes
Sample
{
"linkState": "ZjE2MzMxMGFiYmU4MzcxOTU1ZmRjMTU5NGU2ZmE4YTU3NjViMzIwY2YzNG",
"linkUrl": "https://link.production.enode.io?link_state=YzIwZThhYjYtMjMzMi00ZTAyLTg0OTYtYzdjOTlhZTY3Zjc3QDI2YzI1MDExLTdhYTctNGE2NS1iNjBmLTZmMzc5NmRhODUyMDowNDViYjFiYmE0M2Y5NDU5YTc5OTgxZmEyYTg1NmI4YzhkOGU4YjgyNmNmMzQzZmFmMGNhZTlmNDBjMmZmOTgy&requested_scope=vehicle%3Alocation%20vehicle%3Aodometer&redirect_uri=myapp%3A%2F%2Fintegrations%2Fenode"
}
Other responses
Response 403
Connections limit reached for this clients
Attributes
Sample
{
"type": "https://docs.enode.io/problems/validation-error",
"title": "Invalid Request",
"detail": "\"action\" must be one of [START, STOP]"
}
Deauthorize User
DELETE /users/{userId}/authorization
Deletes the User's stored vendor authorizations and credentials, invalidates any associated sessions, authorization codes, and access/refresh tokens.
All other User data is retained, and if the User is sent through the Link User flow in the future, their account will be just as they left it.
No webhook events will be generated for a deauthorized user.
Request
Path parameters
ID of the User.
Response
204No Content
Vehicles
EVs provide charge, location, and odometer data. Vehicles can be controlled either directly using the Control ChargingAPI endpoint, or through Smart Charging and Schedules.
List Vehicles
GET /vehicles
Returns a paginated list of all available Vehicles
Request
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",
"vendor": "AUDI",
"lastSeen": "2020-04-07T17:04:26Z",
"isReachable": true,
"information": {
"vin": "string",
"brand": "string",
"model": "Model S P85",
"year": 2020
},
"chargeState": {
"batteryLevel": 0,
"range": 0,
"isPluggedIn": true,
"isCharging": true,
"isFullyCharged": true,
"batteryCapacity": 0,
"chargeLimit": 0,
"chargeRate": 0,
"chargeTimeRemaining": 0,
"lastUpdated": "string",
"powerDeliveryState": "UNPLUGGED"
},
"smartChargingPolicy": {
"isEnabled": false,
"deadline": "07:00",
"minimumChargeLimit": 0
},
"location": {
"longitude": 0,
"latitude": 0,
"lastUpdated": "string"
},
"odometer": {
"distance": 0,
"lastUpdated": "string"
},
"capabilities": {
"information": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"chargeState": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"location": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"odometer": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"startCharging": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"stopCharging": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
},
"smartCharging": {
"isCapable": true,
"interventionIds": [
"4eaeb363-296d-4ccc-a973-7805e6f400bd"
]
}
},
"locationId": "4eaeb363-296d-4ccc-a973-7805e6f400bd"
}
],
"pagination": {
"after": "string",
"before": "string"
}
}
List User Vehicles
GET /users/{userId}/vehicles
Paginated list of user vehicles.
Request
Path parameters
ID of the User.
Query parameters
Number of records to return per page
Encoded cursor used to fetch previous page. Should be set to the corresponding before
value found in the pagination.before
property of a paginated response. Cannot be used together with after
.
Encoded cursor used to fetch next page. Should be set to the corresponding after
value found in the pagination.after
property of a paginated response. Cannot be set together with before
.
Response
200Attributes
Cursors to the pages before and after current page.
Sample
{
"data": [
{
"id": "string",