openapi: 3.2.0 info: description: "# Introduction\nWelcome to the Gravity Connect API documentation for Device Partners (typically Device OEMs). This developer guide outlines the API endpoints and integration capabilities that Device Partners need to implement to connect their distributed energy resource (DER) devices with a virtual power plant (VPP) platform or a DERMS solution. The Device Partner endpoints work in combination with [the VPP's Gravity Connect endpoints](./vp-api.html) to support device enrollment and real-time control.\n\nAfter building the endpoints described in this guide, Device Partners can add their products to the VPP's customers' programs. Utilities will use the VPP's platform and suite of device integrations to access real-time data and control smart devices as part of VPPs, demand response programs, and/or DER management programs.\n\nThis documentation is open-source, and we encourage all DERMS and VPP platforms to use this standard. Integrations built to the Gravity Connect API standard are not limited to use with one VPP platform.\n\n# About Gravity Connect\n\nGravity Connect is an open API specification developed by Virtual Peaker to simplify and accelerate the integration of distributed energy resource (DER) devices into utility demand response (DR) and DER management programs.\n\nGravity Connect offers several key benefits to Device Partners:\n* **Streamlined device integration:** Gravity Connect provides standardized endpoints and data models to enable quick, easy integration of your devices with VPP platforms.\n* **Accelerated time-to-value:** With simplified integrations via Gravity Connect, you can get your devices connected to DR programs faster, allowing utilities to control and access data from your devices sooner. This means faster time-to-value.\n* **Open and interoperable:** Gravity Connect uses modern API best practices and is openly published to facilitate integration. It is designed to be vendor-agnostic so your devices can integrate with any VPP or DERMS platform that implements the specification.\n* **Large ecosystem access:** VPP platforms that use Gravity Connect have relationships with dozens of utilities that run DR programs. Integrating via Gravity Connect gives your devices access to this large ecosystem of potential customers and programs.\n* **Standardized device control:** As VPPs launch advanced control software to improve utility event operations, Gravity Connect will continue to standardize control commands so that each improvement does not require modifications to each integration.\n\nGravity Connect simplifies and streamlines the process of integrating DER devices into utility programs by handling the complexity behind a standardized and interoperable API. By partnering with VPPs using a Gravity Connect integration, your devices can access a large ecosystem of utility customers and programs quickly and easily.\n\n## Articles About Gravity Connect\n* [API Showdown: Gravity Connect v. OpenADR](https://virtual-peaker.com/blog/gravity-connect-v-openadr/)\n* [How the Gravity Connect API Enhances OEMS & DERMS Integrations](https://virtual-peaker.com/blog/gravity-connect-api-oem-derms-integrations/)\n* [Virtual Peaker Launches Gravity Connect API](https://virtual-peaker.com/news/virtual-peaker-launches-gravity-connect-api/)\n\n## Interested in Getting Started with Gravity Connect?\nIf you're an OEM, utility, DERMS provider, or technology provider interested in learning more about integrating with Gravity Connect, our team is here to help.\n\nTo get started and discuss your use case, please reach out to our Gravity Connect support team at [gravity-connect@virtual-peaker.com](gravity-connect@virtual-peaker.com).\n\n# Changelog\nThis list tracks noteworthy changes to the API specification.\n\n* 2.0.6 - Revised the explanatory sections of the documentation.\n* 2.0.5 - Added Device Partner Driven Enrollment.\n* 2.0.4 - Updated power and energy signals in the TSTAT device-specific definition.\n* 2.0.3 - Updated the command and signals in the TSTAT device-specific definition.\n* 2.0.2 - Add `unsubscribe` from Device publishing as VP method of unenrollment. And, updated diagrams and and minor typo fixes.\n* 2.0.1 - Major updates to documentation including the `Energy Interval` endpoint.\n* 1.5.2 - Fixed using incorrect `baseUrl` to correct `vpBaseUrl` in VP Endpoints of Postman Collection.\n* 1.5.0 - Adding specification for EVSE device type with signals, settings, and commands.\n* 1.4.1 - Adding storage HVAC device type and FAQs. Clarifying startTime may be in past. Making deviceUids array optional when creating group.\n* 1.4.0 - Clarifying CTA modes (including swapping NORMAL in for RUN_NORMAL) and cta-op-modes.\n* 1.3.3 - Requiring country when houses are published to device partner. Specifying country field follows ISO 3166-1 alpha-2 (contrary to previous documentation which reference `USA` as a value).\n* 1.3.2 - Adding an optional array of devices when publishing houses.\n* 1.3.0 - Adding endpoint for individual devices to opt out of a group command.\n* 1.2.0 - Adding Publish houses for installation endpoint under a new pairing code based onboarding flow. Also clarifying pairing code structure and international addresses.\n* 1.1.0 - Adding Pairing Code Device Discovery as a proposal. Also clarifying that 1 program = 1 utility.\n* 1.0.1 - `invalidDevices` was listed under the request body for `Update group details`, but it was meant to be under the response. Fixed this.\n\n# Getting Started\n\n## Endpoint Architecture\nThe remainder of this guide describes the Device Partner endpoints, which are half of the integration. Meanwhile, the [VPP API](./vp-api.html) guide outlines the API endpoints hosted by the VPP for receiving data from the Device Partner's devices. The endpoints support standard integration operations, including publishing device signals, command statuses, and device enrollment events. In combination with the Device Partner endpoints, they allow a two-way flow of information that enables utilities to control and manage devices.\n\nThis data enables essential capabilities like:\n* Real-time device monitoring and analytics\n* Aggregation of fleet data across a utility\n* Execution of demand response events and commands\n* Accurate measurement and verification of event performance\n\nHaving a standardized set of endpoints for data intake simplifies integration significantly compared to custom development. Device Partners simply publish data in the documented format to stream it to the VPP's platform.\n\nLearn more about the data flows in the [Integration Overview](#section/Getting-Started/Device-Partner-Integration-Overview).\n\n## Glossary\n* **Device Partner**: The party working to integrate with the VPP. This may be an OEM or a company creating digital solutions for devices.\n* **Program**: An arrangement where a utility controls homeowners' devices in exchange for incentives such as rebates or gift cards. Multiple Device Partners typically participate in each program.\n* **PROGRAM_PUBLISH_KEY**: The identifier for a program, unique to each combination of program and Device Partner.\n* **PROGRAM_PUBLISH_SECRET**: The secret used as an input to HMAC for publishing program data to the VPP.\n* **DEVICE_PUBLISH_SECRET**: The secret used as an input to HMAC for publishing device data to the VPP.\n* **Signals and Settings**: The device telemetry and configuration data that is streamed to the VPP. See the [Device Type Specifications](#section/Device-Type-Specifications) for a specific list of the signals and settings required for each device type.\n* **VP_COMMAND_OBJECT**: A portion of the payload sent to the Device Partner when the VPP sends a command. For more information about the commands required for each device type, see the [Device Type Specifications](#section/Device-Type-Specifications). For details about the command request, see the [Send Command Endpoint](#operation/sendCommand).\n* **OAuth 2.0**: An open authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, such as for device onboarding. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account. Gravity Connect uses OAuth 2.0 for device enrollment and for all requests from the VPP to the Device Partner, such as commands.\n* **Webhook**: A method for apps to provide other applications with real-time information. When an event occurs, a HTPP POST callback is sent to the specified webhook URL endpoint. Gravity Connect uses webhooks for Device Partners to publish data updates instead of the VPP polling for data.\n\n## Building an Integration\n\nA new Device Partner typically integrates with a VPP's Gravity Connect API following this process:\n\n1. **Kickoff Meeting:** the VPP and the Device Partner discuss which device types and programs this integration will be used for initially, which affects which enrollment flows and data models will be implemented.\n2. **Onboarding:** the VPP provides the Device Partner with access to a development environment.\n4. **Implementation:** The Device Partner implements the required Gravity Connect endpoints based on the documentation and earlier discussions about the scope of the integration.\n5. **QA:** After the Device Partner has tested the integration, the VPP performs a final round of testing to validate the functionality and data flows.\n6. **Beta Launch:** The integration goes live for the first customer, and the Device Partner can begin enrolling devices into the utility program. These devices begin streaming data shortly after enrollment and are ready to participate in events. The VPP and the Device Partner monitor the first enrollments to ensure success.\n7. **Go Live:** After the integration has operated smoothly for a period of time, it becomes available to other customers and utility programs.\n\n## Postman Collection\nTo use Postman to interact with endpoints, download the [Postman Collection](./Gravity%20Connect%20API.postman_collection.json). After file opens hit Mac(command + s) or Windows(control + s) to save the file and download it to your computer.\n\n### Postman Setup\n1. Download the file linked [here](./Gravity%20Connect%20API.postman_collection.json).\n2. Open Postman and select `Import` near the top right of the left side panel menu.\n3. Select `Upload Files` and select the Postman Collection you downloaded earlier.\n4. Upon successful import it will create a collection Called `Gravity Connect API` with two main folders inside called `VP Endpoints` and `Device Partner Endpoints`.\n\n### Device Partner Endpoints\nThe collection uses Postman’s built in authentication handling to authenticate the request. Below are the steps to configure and request a new token, which will then be automatically included in subsequent requests.\n1. Select the `VP Endpoints` folder.\n2. Set the following:\n\t* Set `Type` to `OAuth2.0` and `Add auth dat to` to `Request Headers`.\n\t* Enter `Token Name` to what you want it to be called.\n\t* Set `Grant Type` to `Client Credentials`.\n\t* Use the `Client ID` and `Client Secret` you created within your application.\n\t* Set the `Access Token URL` to the auth endpoint for your application.\n\t* Set `Client Authentication` to `Send as Basic header`.\n\t* Leave any remaining fields to their default setting.\n3. Click `Get New Access Token` button.\n4. If all was successful it should pop up a confirmation the token was successfully created. Click use token and you are ready to begin accessing the endpoints.\n\n### Device Partner Endpoints (OAuth Onboarding)\nWe haven’t used the Postman collection for these endpoints yet, but we expect that using the Authorization Code flow will work something like:\n1. Select the `OAuth Onboarding` folder.\n2. Set the following:\n\t* Set `Type` to `OAuth2.0` and `Add auth dat to` to `Request Headers`.\n\t* Enter `Token Name` to what you want it to be called.\n\t* Set `Grant Type` to `Authorization Code`.\n\t* Use the `Client ID` and `Client Secret` you created within your application.\n\t* Set the scope to the scope that your application expects for our use case.\n\t* Set the `Access Token URL` and `Auth URL` to your urls.\n\t* Set the `Callback URL` to the VPP’s URL.\n\t* Set `Client Authentication` to `Send as Basic header`.\n\t* Leave any remaining fields to their default setting.\n3. Click `Get New Access Token` button.\n4. If all was successful it should pop up a confirmation the token was successfully created. Click use token and you are ready to begin accessing the endpoints.\n\n### Authentication for VPP Endpoints\nAttached to the VPP endpoints is a script that will automatically create an HMAC and set it as a variable that is then used to make the request. These scripts expect that you’ve properly set the PROGRAM_PUBLISH_KEY, PROGRAM_PUBLISH_SECRET, DEVICE_PUBLISH_SECRET.\n\nTo do this:\n1. Click on the root folder for the Gravity Connect API. Then select the tab `Variables`\n2. Find the variable and update the `CURRENT_VALUE`\n\n# Integration Flows\n\n![diagram of system connection](assets/diagrams/system-connection.png)\n[See larger image](assets/diagrams/system-connection.png)\n\n# Authentication\nGravity Connect uses the following authentication models:\n\n**Requests from the VPP to the Device Partner's endpoints**\n* These requests use OAuth 2.0 authentication. Please note that these OAuth credentials are required even if the homeowner enrollment flow is not OAuth-based. If the homeowner enrollment flow is OAuth-based, it can use separate credentials or it can re-use these.\n* The Device Partner provides:\n * `clientId`: A program-specific ID.\n * `clientSecret`: A program-specific secret.\n\n**Requests from the Device Partner to the VPP's endpoints**\n* These requests authenticate using a combination of the following credentials and HMAC authentication. The VPP provides:\n * `PROGRAM_PUBLISH_KEY`: The unique identifier for a utility program, provided when a program is set up.\n * `PROGRAM_PUBLISH_SECRET`: The secret key used to generate HMAC signatures when publishing program-level data, provided when a program is set up.\n * `DEVICE_PUBLISH_SECRET`: The secret key used to generate HMAC signatures when publishing device-level data, provided when each device is enrolled.\n* Find more detail about authenticating with the VPP's endpoints in the [VPP API Guide](./vp-api.html#section/Authentication).\n\n# Device Enrollment\nEach device will be added to a program using one of the following flows. After a device is added, the VPP will call the `/subscription` endpoint on the Device Partner's API to enable device data publishing and share the `DEVICE_PUBLISH_SECRET`.\n\nThe flows most suitable for device owners to enroll devices are:\n1. OAuth Device Discovery\n2. Pairing Code Device Discovery\n\nThe flows most suitable for installers or program managers to enroll devices are:\n1. Device Partner Driven Enrollment\n2. Pairing Code Device Discovery\n\n## Pairing Codes\n\nPairing codes are used in some enrollment flows to link device enrollments to homeowner enrollments to ensure accurate device association. The format is:\n\n- **2 alphanumeric characters** denoting the pairing code prefix representing the program (e.g., `A1`)\n- **5 random numeric characters** (e.g., `12345`)\n- **1 check digit** (Luhn algorithm, calculated from the 5 random numeric characters, e.g., `5`)\n\n**Example:** `A1123455`\n\n\n### How to Validate a Pairing Code\n1. Extract the first 2 alphanumeric characters to validate them against program pairing code prefix.\n2. Extract the 5 random numeric characters (characters 3–7).\n3. Calculate the Luhn check digit using the standard algorithm.\n4. Compare the calculated digit to the last digit (character 8).\n\nThe device partner can validate the pairing code to provide immediate feedback. The VPP's API can perform the same validation upon receipt of a pairing code.\n\n## OAuth Device Discovery (Preferred)\n[Diagram](https://d1byei05mtwnfj.cloudfront.net/apidocs/workflow/oauth-device-discovery.jpg)\n\nIn this flow, a device owner fills out an enrollment form hosted by the VPP, then logs in to their Device Partner account to grant the VPP permission to access and control their devices.\n\nThe OAuth device discovery flow works as follows:\n1. The device owner fills out an onboarding form on the VPP's site.\n2. At the end of the form, the device owner is redirected to the Device Partner's OAuth authorization page via a link.\n3. The user logs into the Device Partner's app and grants OAuth access permissions.\n4. The Device Partner app completes the OAuth authorization code flow, exchanging the code for an access token.\n5. Using the access token, the Device Partner calls their API to retrieve the user's devices.\n6. The Device Partner associates the devices with the correct VPP program in their backend and completes any other required internal onboarding logic.\n7. The Device Partner completes the OAuth callback to the VPP.\n8. The VPP discovers devices using the OAuth token provided.\n9. The VPP subscribes to devices for data publishing and provides a DEVICE_PUBLISH_SECRET.\n\nThe VPP creates a unique `client_id` for each utility program. This ID is passed in the OAuth link to associate devices with the correct program.\n\nWhen a customer onboards via the OAuth flow, we will direct them to a URL in the format below with:\n\n* Your domain substituted for example.com\n* Our domain substituted for gravity.example.com\n* The `client_id` of the program the user is onboarding to\n* A state generated by us to track the flow\n* The scopes required within your system\n* access_type=offline as per to indicate that a refresh token should be provided ([reference](https://developers.google.com/identity/protocols/oauth2/openid-connect#access-type-param))\n\n```\nhttps://example.com/oauth2/authorize?access_type=offline&response_type=code&redirect_uri=https%3A%2F%2Fgravity.example.com%2Foauth2%2Fcallback&client_id={}&state={}&scope={}\n```\n\n## Pairing Code Device Discovery - End User App\n[Diagram](https://d1byei05mtwnfj.cloudfront.net/apidocs/workflow/end-user-app.jpg)\n\nIn this flow, a device owner fills out an enrollment form hosted by the VPP, which then presents them with a pairing code. The device owner then informs the Device Partner of their pairing code, which the Device Partner sends to the VPP with information about the device owner's devices. The VPP uses the pairing code to match the devices to the correct enrollment form data.\n\nThe [pairing code](#section/Pairing-Codes) device discovery flow works as follows:\n1. The device owner fills out an onboarding form on the VPP's site.\n2. The form provides them with a pairing code and instructions to enter it in the Device Partner's app.\n3. The device owner enters the pairing code in the Device Partner's app, and the Device Partner publishes a device enrollment event to the VPP's API.\n 1. The publish event includes the pairing code, allowing the VPP to match the devices to the correct enrollment form data.\n 2. If multiple devices are enrolled for this device owner, the Device Partner sends multiple publish payloads with the same pairing code.\n4. The VPP subscribes to each device for data publishing and provides a `DEVICE_PUBLISH_SECRET`.\n\nEach utility program is assigned a different pairing code prefix that Device Partners can use to identify or confirm which program a device owner is joining.\n\n## Device Partner Driven Enrollment\n[![Device Partner Driven Enrollment Diagram](assets/diagrams/device-partner-driven-enrollment.png)](assets/diagrams/device-partner-driven-enrollment.png)\n\nDevice Partner Driven Enrollment is a flow that can be used when the Device Partner has enough information about both the devices and the site to form a complete record in the VPP platform. This includes data such as the device UID, the service address, and the device owner's contact information.\n\nThe Device Partner can use this flow to proactively enroll devices through the Device Partner's app/website, pre-enroll a device purchased directly from the Device Partner, and bulk enroll devices that are transferred to the VPP.\n\n1. The Device Partner publishes an enrollment message containing information about the site and each of the eligible devices. This enrollment message uses the program-specific credentials for the appropriate program.\n2. The VPP subscribes to the devices for data publishing and provides a `DEVICE_PUBLISH_SECRET` for each.\n3. If the enrollment application is approved, there will be no change. If the enrollment application is rejected by the utility, the VPP will unsubscribe from data publishing.\n\n## Pairing Code Device Discovery - Utility Commissioned Installation (Deprecated)\n[Diagram](https://d1byei05mtwnfj.cloudfront.net/apidocs/workflow/utility-commissioned-installation.jpg)\n\nThis flow has been deprecated. The [Device Partner Driven Enrollment](#section/Device-Onboarding/Device-Partner-Driven-Enrollment) flow is recommended for programs where the device owner is not involved in the enrollment process, such as direct install programs.\n\nThe utility commissioned [pairing code](#section/Pairing-Codes) flow works as follows:\n1. The device owner fills out an onboarding form on the VPP's site.\n2. The utility reviews the submission and approves it if eligible.\n3. The VPP informs the Device Partner of the service address and provides a pairing code.\n4. The Device Partner installs and activates the device.\n5. When the installation is complete, the Device Partner publishes a device enrollment event to the VPP.\n 1. The publish event includes the pairing code, allowing the VPP to match the devices to the correct enrollment form data.\n 2. If multiple devices are enrolled for this device owner, the Device Partner sends multiple publish payloads with the same pairing code.\n4. The VPP subscribes to each device for data publishing and provides a `DEVICE_PUBLISH_SECRET`.\n\n# Data Publishing\nAfter a device has been enrolled, the Device Partner will begin publishing data to the VPP's endpoints. The [VPP API](./vp-api.html) guide describes the endpoints that accept device telemetry and configuration updates (referred to as signals and settings), command status updates, and device enrollment updates. These endpoints are authenticated using the `DEVICE_PUBLISH_SECRET` or `PROGRAM_PUBLISH_SECRET` (depending on the endpoint) to create an HMAC.\n\nThe required data fields vary based on the device type, such as:\n* Hot Water Heaters: tank temperature, operating mode, power draw, etc.\n* Thermostats: temperature setpoints, operating mode, ambient temperature, etc.\n* Batteries: capacity, power flow, status, etc.\n\nEach device type has a set of mandatory data fields that must be implemented, plus optional data fields that can be provided to improve reporting. See [Device Type Specifications](#section/Device-Type-Specifications) for the specifications for each device type.\n\nBefore finalizing an integration, the VPP will work with each Device Partner to verify that all required data points for a given device type are implemented correctly according to the specifications.\n\nHaving accurate and complete data publishing as per the documentation is critical for properly managing each device type within utility programs and optimizing distributed energy initiatives. The required fields for each device type integration must be confirmed before final approval.\n\n# Demand Response Event Commands\n[Diagram](https://d1byei05mtwnfj.cloudfront.net/apidocs/workflow/demand-reponse-event-flow.jpg)\n\n## Scheduling and Canceling\n\nWhen a utility sends a command using the VPP's platform, the VPP [sends a command to the Device Partner](#operation/sendCommand) targeting a specific device or a group (if group management is supported). See [Device Type Specifications](#section/Device-Type-Specifications) for the commands for each device type. \n\nAs not all device models support all commands, while building the integration, the Device Partner must inform the VPP of which models support which commands. The types of commands accepted must be consistent per device type + kind. For example, if the Acme Corporation is a device partner who sets up a hot water heater (kind = `HWH`) with a model name of ACME1000 (type = `ACME1000`), all ACME devices of kind `HWH` and type `ACME1000` must support the same set of commands, but this set can be different than the command set supported by model `ACME1001`.\n\nThroughout the duration of a command, devices continue to send data to the VPP. Commands also [publish their status](./vp-api.html#operation/publishCommand). For group commands, an individual device may need to report that it opted out (separate from the status of the command status), which it reports via the [device command status endpoint](./vp-api.html#operation/publishDeviceCommand).\n\nThe VPP can cancel any command that has been sent to a Device Partner using the [cancel endpoint](#operation/cancelCommand). The VPP may cancel active commands at any point during their duration. The Device Partner should immediately return devices to normal operating modes when a cancellation command is received.\n\nCommands are sent from the VPP to the Device Partner at most 60 seconds before the start time, regardless of the VPP interface supporting program managers scheduling events hours or days in advance. The Device Partner must be able to accept both individual and group commands simultaneously for a given device.\n\n## Device Data for Events\n\nThe active operating mode of a device must align with the requested command mode if the device is participating in an event. For example, a water heater cannot report it is in 'NORMAL' mode if it is actively participating in a demand response event that calls for a ‘SHED’ (but it can if it has opted out of the event). The current mode should be updated accordingly as commands begin and end. Throughout each event, enrolled devices continue publishing telemetry data to the VPP's platform through the standard publishing endpoints.\n\nIndividual devices report opt-outs via the VPP endpoint [publish device command status endpoint](./vp-api.html#operation/publishDeviceCommand). For group commands, individual devices report opt-out status, as needed, via the Device Partner endpoint [command opt-out](./vp-api.html#operation/commandOptOut).\n\nProperly syncing modes and command statuses is crucial for accurate measurement and verification of demand response performance. The Device Partner integration must maintain consistency between the active command, device mode, and device command status.\n\n## Opting Out of Events\nFor demand response events targeting individual devices, opt-out status should be reported using the VPP endpoint [publish device command status endpoint](./vp-api.html#operation/publishDeviceCommand) endpoint.\n\nThis allows the Device Partner to share the specific UID of the device that has opted out. The payload should include the UID along with a status of \"OPT_OUT\" and relevant timestamp.\n\nFor group commands, the group-level Device Partner endpoint [command opt-out](./vp-api.html#operation/commandOptOut) should be used, and not the individual device opt-out endpoint. The group command status should be updated to \"OPT_OUT\" to indicate a specific or set of specific devices in the group has opted out.\n\nThe Device Partner API needs to implement both individual and group opt-out flows:\n* Individual devices: Report opt-out via the VPP endpoint [publish device command status endpoint](./vp-api.html#operation/publishDeviceCommand) endpoint\n* Group commands: Report that particular devices within a group have opted out via group-level Device Partner endpoint [command opt-out](./vp-api.html#operation/commandOptOut)\n\nProperly reporting opt-out status at both the individual device and group level allows the VPP to update event logs and measurement & verification accordingly.\n\n# Device Unenrollment\nIf a device is unenrolled from a VPP program via the Device Partner's app or portal, the device partner notifies the VPP via the [publish device enrollment](./vp-api.html#operation/publishDeviceEnrollment) endpoint. The payload should include the device UID and a status of \"unenrolled\". The VPP will remove the device from the program and no longer collect data or call events on the device.\n\nIf a program manager unenrolls a device via the VPP platform, the VPP will call the Device Partner endpoint to [unsubscribe](./vp-api.html#tag/Devices/operation/modifySubscription) from the device's data. The Device Partner should interpret the unsubscription as an unenrollment.\n\n# Integration Testing\nIntegrations are evaluated on the following workflows.\n\n## Enrollment & Unenrollment\n* Device enrolls in the VPP program\n* Device unenrolls from the VPP program\n\n## Telemetry\n* Device shares all required data points for the device type\n* Device shares power data in 5-minute increments or shares Energy Interval data\n\n## Events\n* Device successfully responds to group events, if applicable\n* Device successfully responds to individual device events, if applicable\n* Device successfully responds to cancelling an individual device event, if applicable\n* Device successfully responds to cancelling a group event, if applicable\n* Device signals for modes and command statuses align with test events before, during, and after the event window\n* Device signals change in the correct direction relative to test event commands\n* Device opts out of individual device event using [publish device command status endpoint](./vp-api.html#operation/publishDeviceCommand)\n* Device opts out of group event using [command opt-out](./vp-api.html#operation/commandOptOut)\n\n# Device Type Specifications\nDefinitions for `SIGNAL_KEY`, `SIGNAL_VALUE`, `SETTING_KEY`, and `VP_COMMAND_OBJECT` all depend on the type of device (`DEVICE_TYPE_ENUM`) interfacing with the Gravity Connect API. This section will outline those values per device type.\n\nNOTE: `VP_COMMAND_OBJECT` is only a portion of what is sent during an event. For the full payload, please see the [Send Command](#operation/sendCommand) endpoint.\n\n## Battery\n### Battery Command Payloads (VP_COMMAND_OBJECT)\n#### Standby\n```json\n{\n mode: 'STANDBY'\n}\n```\n\n#### Charge\n```json\n{\n mode: 'CHARGE',\n action: 'POWER',\n power: 4000\n}\n```\n\n```json\n{\n mode: 'CHARGE',\n action: 'FASTEST'\n}\n```\n\n#### Discharge\n```json\n{\n mode: 'DISCHARGE',\n action: 'POWER',\n power: 4000\n}\n```\n\n```json\n{\n mode: 'DISCHARGE',\n action: 'SITE_DEMAND',\n targetSiteDemand: 400\n}\n```\n\n```json\n{\n mode: 'DISCHARGE',\n action: 'SITE_DEMAND',\n targetSiteDemand: 400,\n maxPower: 10000\n}\n```\n\n### Battery Signals\n#### mode (String)\n* Example Values\n\t* `SELF_CONSUMPTION`\n\t* `BACKUP`\n\t* `CHARGE`\n\t* `DISCHARGE`\n\t* `STANDBY`\n\n#### status (String)\n* Internet connectivity of the device\n* Valid Values\n\t* `OFFLINE`\n\t* `ONLINE`\n\n#### grid-connection (String)\n* Connectivity to the grid. Disconnections are typically temporary events that indicate power outages.\n* Valid Values\n\t* `CONNECTED`\n\t* `DISCONNECTED`\n\n#### max-capacity (Float)\n* Maximum energy capacity for the device\n* Unit: Wh\n\n#### present-capacity (Float)\n* Remaining energy capacity for the device\n* Unit: Wh\n\n#### max-usable-capacity (Float)\n* Maximum usable energy capacity for the device\n* Unit: Wh\n\n#### present-usable-capacity (Float)\n* Usable energy capacity remaining in the device\n* Unit: Wh\n\n#### discharge-power (Float)\n* Present discharge power. Unsigned.\n* Unit: W\n\n#### charge-power (Float)\n* Present charge power. Unsigned.\n* Unit: W\n\n#### max-discharge-power (Float)\n* Maximum discharge power. Often fixed, but not always.\n* Unit: W\n\n#### max-charge-power (Float)\n* Maximum charge power. Often fixed, but not always. Often equivalent to max-discharge-power, but not always.\n* Unit: W\n\n#### house-power (Float)\n* Present load consumed by the site. Unsigned\n* Unit: W\n\n#### pv-power (Float)\n* Present power being generated by PV panels attached to the system. Unsigned\n* Unit: W\n\n### Battery Settings\n#### min-reserve-percent-mfg (Float)\n* The minimum state of charge, in %, that this device can reach during DR events. Only include a reserve value set by the homeowner if it is respected during DR events.\n* Unit: Percentage\n\n## HWH\n\n### HWH Command Payloads (VP_COMMAND_OBJECT)\n#### Shed\n```json\n{\n mode: 'SHED'\n}\n```\n\n#### Load Up\n```json\n{\n mode: 'LOAD_UP'\n}\n```\n#### Critical\n```json\n{\n mode: 'CRITICAL'\n}\n```\n\n#### Emergency\n```json\n{\n mode: 'EMERGENCY'\n}\n```\n\n#### Run Normal\n```json\n{\n mode: 'RUN_NORMAL'\n}\n```\n\n#### Advanced Load Up (Optional)\nWhere `energy` is an integer for Wh and `suggestedEfficiencyLevel` is an integer between 1 (representing low efficiency/fast heat up) and 9 (for high efficiency/slow heat up), or 10 for vacation mode.\n```json\n{\n mode: 'ADVANCED_LOAD_UP',\n energy: 1000\n suggestedEfficiencyLevel: 1\n}\n```\n\n#### Efficiency (Optional)\nWhere `suggestedEfficiencyLevel` is an integer between 1 (representing low efficiency/fast heat up) and 9 (for high efficiency/slow heat up), or 10 for vacation mode.\n```json\n{\n mode: 'EFFICIENCY',\n suggestedEfficiencyLevel: 1\n}\n```\n\n#### Duty Cycle (Optional)\nPercentage ranges from 0-100\n```json\n{\n mode: 'DUTY_CYCLE',\n percentage: 60\n}\n```\n\n### HWH Signals\n#### mode (String)\n* If additional modes are available, please let us know so we can consider standardized naming\n* Example Values\n\t* `NORMAL`\n\t* `SHED`\n\t* `CRITICAL`\n\t* `EMERGENCY`\n\t* `LOAD_UP`\n\t* `ADVANCED_LOAD_UP`\n\t* `ERROR`\n\t* `CYCLING`\n\t* `PRICE_STREAM`\n\t* `VARIABLE`\n* Non-CTA devices are TBD\n\n#### status (String)\n* Internet connectivity of the device\n* Valid Values\n\t* `OFFLINE`\n\t* `ONLINE`\n\n#### tank-temperature (Float)\n* In the case that both top and bottom temperature are reported, this would be the top temperature.\n* Unit: Degrees Fahrenheit\n* Not relevant for CTA devices\n\n#### tank-bottom-temperature (Float)\n* Optional, not all water heaters report temperature at the top and bottom of the tank\n* Unit: Degrees Fahrenheit\n* Not relevant for CTA devices\n\n#### setpoint-temperature (Float)\n* Unit: Degrees Fahrenheit\n\n#### present-capacity (Float)\n* For CTA2045, given the absence of tank-temperature / setpoint-temperature data\n* Unit: Wh\n\n#### max-capacity (Float)\n* For CTA2045, given the absence of tank-temperature / setpoint-temperature data\n* Unit: Wh\n\n#### power (Float)\n* Unit: W\n* Not relevant for CTA devices\n\n#### current (Float)\n* Optional, may not be available\n* Unit: A\n* Not relevant for CTA devices\n\n#### voltage (Float)\n* Optional, may not be available\n* Unit: V\n* Not relevant for CTA devices\n\n#### cta-op-state (String)\n* Optional setting used by CTA\n* Valid Values\n\t* `IDLE_NORMAL`\n\t* `RUNNING_NORMAL`\n\t* `RUNNING_CURTAILED`\n\t* `RUNNING_HEIGHTENED`\n\t* `IDLE_CURTAILED`\n\t* `SGD_ERROR_CONDITION`\n\t* `IDLE_HEIGHTENED`\n\t* `CYCLING_ON`\n\t* `CYCLING_OFF`\n\t* `VARIABLE_FOLLOWING`\n\t* `VARIABLE_NOT_FOLLOWING`\n\t* `IDLE_OPTED_OUT`\n\t* `IDLE_PRICE_STREAM`\n\t* `RUNNING_OPTED_OUT`\n\t* `RUNNING_PRICE_STREAM`\n\t* `IDLE_PRICE_STREAM`\n\n#### cta-advanced-present-capacity (Float)\n* Required if CTA advanced load up is supported\n* Unit: Wh\n\n#### cta-advanced-max-capacity (Float)\n* Required if CTA advanced load up is supported\n* Unit: Wh\n\n### HWH Settings\n#### max-setpoint (Float)\n* Defines the maximum setpoint that is allowed by the unit\n* Unit: Degrees Fahrenheit\n\n#### min-setpoint (Float)\n* Defines the minimum setpoint that is allowed by the unit\n* Unit: Degrees Fahrenheit\n\n#### cta-advanced-loadup-enabled (Boolean)\n* Optional setting used by CTA\n\n#### cta-user-preference-level (Integer)\n* Optional setting used by CTA. Expected values 0-10\n\n## TSTAT\n#### Temperature Units\nAs described in the following specification, all temperatures are sent and received in units of Fahrenheit for consistency. However, these temperatures can be displayed in Celsius to users in appropriate locales.\n\n### TSTAT Command Payloads (VP_COMMAND_OBJECT)\n#### Adjust Set Point\n```json\n{\n mode: 'HEAT',\n temperature: -2.0\n}\n```\n\n* This command accepts relative values only.\n* The setpoint command is always processed as relative to the homeowner’s setpoint. For example, if the homeowner’s setpoint is currently 75, and the VPP receives a command for -3 followed by a command for -2, the second command sets the setpoint to 73, not to 70.\n* Mode\n * Valid values\n * HEAT\n * COOL\n * Note that while other values can be sent as Signals, only these values will be sent in commands.\n* Temperature\n * Unit: degrees Fahrenheit\n * Sign: For all modes, positive is an increase in temperature and negative is a decrease in temperature\n\n\n### TSTAT Signals\n#### mode (String)\n* Current mode of the device. Please use the following exact values for heating, cooling, automatic, and fan modes. This signal also accepts other modes supported by the device that are not listed here, such as 'DRY'.\n* Valid Values\n\t* `HEAT`\n\t* `COOL`\n\t* `AUTO`\n\t* `FAN_ONLY`\n\n#### status (String)\n* Internet connectivity of the device\n* Valid Values\n\t* `OFFLINE`\n\t* `ONLINE`\n\n#### state (String)\n* Whether the device is on or off\n* Valid Values\n\t* `ON`\n\t* `OFF`\n\n#### humidity (Float)\n* Optional. Ambient humidity of the room, measured by the device. Range from 0 to 100\n* Unit: Percentage\n\n#### temperature (Float)\n* Ambient humidity of the room, measured by the device\n* Unit: Degrees Fahrenheit\n\n#### cool-setpoint-temperature (Float)\n* Optional; recommended if supported\n* Unit: Degrees Fahrenheit\n\n#### heat-setpoint-temperature (Float)\n* Optional; recommended if supported\n* Unit: Degrees Fahrenheit\n\n#### louver-swing (String)\n* Optional. Mode or speed of louver swing\n* Example Values\n\t* `AUTO`\n\t* `FAST`\n\t* `SLOW`\n\t* `OFF`\n\t* `ON`\n\n#### fan-mode (String)\n* Optional. Mode or speed of fan\n* Example Values\n\t* `HIGH`\n\t* `MEDIUM`\n\t* `LOW`\n\t* `OFF`\n\t* `ON`\n\n#### equipment-status (String)\n* Optional. Describes which parts of the equipment are currently running (typically more specific than 'mode'\n* Example Values\n\t* `FAN ONLY`\n\t* `HEATING`\n\t* `HEATING STAGE 2`\n\t* `NONE`\n\n#### runtime-fan (Float)\n* The number of seconds of runtime in the interval of time starting at the specified timestamp. Cadence: 5 minutes, clock-aligned\n* Unit: seconds\n\n#### runtime-heat (Float)\n* The number of seconds of runtime in the interval of time starting at the specified timestamp. Cadence: 5 minutes, clock-aligned\n* Unit: seconds\n\n#### runtime-cool (Float)\n* The number of seconds of runtime in the interval of time starting at the specified timestamp. Cadence: 5 minutes, clock-aligned\n* Unit: seconds\n\n#### power (Float)\n* Optional, the instantaneous power consumed by this device at the specified timestamp. Cadence: >= 5 minutes (not required to be clock aligned)\n* Unit: kW\n\n### TSTAT Settings\n#### max-setpoint (Float)\n* Defines the maximum setpoint that is allowed by the unit\n* Unit: Degrees Fahrenheit\n\n#### min-setpoint (Float)\n* Defines the minimum setpoint that is allowed by the unit\n* Unit: Degrees Fahrenheit\n\n## EVSE\n### EVSE Command Payloads (VP_COMMAND_OBJECT)\n#### Standby\nThis puts the EV Charger in an idle state.\n```json\n{\n mode: 'STANDBY'\n}\n```\n\n#### Dispatch - Limit Power\nLimit the charging power to the set `power` limit, in units or Watts.\n```json\n{\n mode: 'DISPATCH',\n action: 'LIMIT_POWER',\n power: 1000\n}\n```\n\n#### Dispatch - Percent Shed\n```json\n{\n mode: 'DISPATCH',\n action: 'PERCENT',\n limitPercent: 100\n}\n```\n\n### EVSE Signals\n#### status (String)\n* Internet connectivity of the device\n* Valid Values\n\t* `OFFLINE`\n\t* `ONLINE`\n\n#### mode (String)\n* The current operating state of the EVSE.\n* Valid Values\n\t* `INUSE`\n\t* `AVAILABLE`\n\t* `NEEDS_SERVICE`\n\n#### power (Float)\n* Current power consumption in Watts.\n* Unit: W\n* Example Values\n\t* `0`\n\t* `4500`\n\n#### power-limit (Float)\n* The current power limit applied at the EVSE.\n* Unit: W\n* Example Values\n\t* `0`\n\t* `4500`\n\n### EVSE Settings\n#### max-power (Float)\n* The maximum charging power that the EVSE supports.\n* Unit: W\n* Example Values\n\t* `0`\n\t* `4500`\n\n## V2G\n### V2G Command Payloads (VP_COMMAND_OBJECT)\n#### Charge\n```json\n{\n mode: 'CHARGE',\n action: 'POWER',\n power: 4000\n}\n```\n\n```json\n{\n mode: 'CHARGE',\n action: 'FASTEST'\n}\n```\n\n#### Discharge\n```json\n{\n mode: 'DISCHARGE',\n action: 'POWER',\n power: 4000\n}\n```\n\n```json\n{\n mode: 'DISCHARGE',\n action: 'SITE_DEMAND',\n targetSiteDemand: 400\n}\n```\n\n```json\n{\n mode: 'DISCHARGE',\n action: 'SITE_DEMAND',\n targetSiteDemand: 400,\n maxPower: 10000\n}\n```\n\n### V2G Signals/Settings\n### V2G Signals\n#### mode (String)\n* Example Values\n\t* `SELF_CONSUMPTION`\n\t* `BACKUP`\n\t* `CHARGE`\n\t* `DISCHARGE`\n\t* `STANDBY`\n\n#### status (String)\n* Internet connectivity of the device\n* Valid Values\n\t* `OFFLINE`\n\t* `ONLINE`\n\n#### max-capacity (Float)\n* Maximum energy capacity for the device\n* Unit: Wh\n\n#### present-capacity (Float)\n* Remaining energy capacity for the device\n* Unit: Wh\n\n#### max-usable-capacity (Float)\n* Maximum usable energy capacity for the device\n* Unit: Wh\n\n#### present-usable-capacity (Float)\n* Usable energy capacity remaining in the device\n* Unit: Wh\n\n#### discharge-power (Float)\n* Present discharge power. Unsigned.\n* Unit: W\n\n#### charge-power (Float)\n* Present charge power. Unsigned.\n* Unit: W\n\n#### max-discharge-power (Float)\n* Maximum discharge power. Often fixed, but not always.\n* Unit: W\n\n#### max-charge-power (Float)\n* Maximum charge power. Often fixed, but not always. Often equivalent to max-discharge-power, but not always.\n* Unit: W\n\n#### house-power (Float)\n* Present load consumed by the site. Unsigned\n* Unit: W\n\n#### pv-power (Float)\n* Present power being generated by PV panels attached to the system. Unsigned\n* Unit: W\n\n#### state (String)\n* State of use of the device (most commonly used for EV chargers)\n* Example Values\n\t* `UNREACHABLE`\n\t* `AVAILABLE`\n\t* `INUSE`\n\n#### power-limit (Float)\n* Max power presently allowed to charger; this is where we would expect to see a DR curtailment take effect\n* Unit: W\n\n### V2G Settings\n\n\n\n## Device Authentication\n Most of the device partner's endpoints will utilize the [device_partner_api_auth](#section/Authentication/device_partner_api_auth) authentications. The only exception is the [OAuth Device Discovery](#tag/OAuth-Device-Discovery-(Preferred)) endpoint which uses [device_partner_user_auth](#section/Authentication/device_partner_user_auth).\n\n For information on how to authenticate when publishing data to the VPP, please see the [Authentication section](./vp-api.html#section/Authentication) for those endpoints.\n\n# Energy Interval Data\n\n## Purpose\nThe Energy Interval endpoint collects energy interval data from devices, except low-voltage thermostats that do not record power data. Unlike other device telemetry, which is published to the VPP, energy intervals are polled by the VPP.\n\nThis data is more accurate than energy data that a VPP platform can compute from power data.\n\nProviders typically use this data for:\n* Performance reporting\n* Historical analysis\n* Resource planning\n* Incentive program disbursement\n\n## Endpoint Query Parameters\n* `start` and `end` use the same format as specified elsewhere for Gravity connect (as they are in the sample URL above)\n * `start` is inclusive, `end` is exclusive\n * The response should include all intervals that overlap with this window\n* `duration` = duration of each interval, in seconds\n * Support for 900 second (15 minute) intervals is required\n * Support for other typical intervals (e.g., 300, 3600) is optional\n\n## Response Properties and General Notes\n\n* `time` represents the start of the interval, such the `value` should represent the energy consumed between `time` and `time + duration`\n* `value` has units of watt-hours (Wh) and is signed:\n * For charge values, positive (>0)\n * For discharge values, negative (<0)\n* Intervals must be \"clock-aligned\" to 15-minute windows, eg 00:00:00, 00:15:00, 00:30:00, etc. See the examples below.\n* Data must be available consecutively, and it must only become available after any previous gaps have been filled in where appropriate. The VPP interprets gaps in the data as zero energy, which is appropriate for devices that are frequently \"off\", such as EV chargers and thermostats.\n * Otherwise, the VPP could not distinguish a temporary delay from a true lack of device activity.\n* For EV chargers and other devices that are \"off\", values of zero (0) should be present if they are part of a charging session, but do not need to be present for intervals outside of sessions (the VPP will infer the absence of data as non-charging time once the next explicit interval appears chronologically).\n* Zero (0) can also be used when the energy data is unavailable and not expected to become available later.\n* The VPP will typically poll this endpoint once per day per device, with a start time of the last recorded interval for the device. This picks up data that was delayed temporarily due to issues such as device connectivity.\n\n### Examples\n* The VPP requests: start time: 13:05. end time: 13:15\n * The response should include all energy consumption between 13:00 and 13:15, not just the energy consumed in the specified 10 minutes.\n* The VPP requests: start time: 12:00, end time: 15:13\n * The response should include data points for all complete 15-minute intervals, which is the intervals from 12:00 to 15:00. The data between 15:00 and 15:13 will be retrieved in the next query after the 15:00-15:15 interval is available.\n\n# FAQ\n### How far in advance can commands be scheduled? How long can commands last?\nCommands are sent in the 60 seconds before the start time and will not exceed a 24 hour duration. Commands with a start time in the past should still be considered valid so long as the current time is within the duration.\n\n### What is the difference between device registration, subscription, and enrollment?\nAn \"enrolled\" device has been approved to participate in a VPP program. Subscription refers to whether the VPP is choosing to receive data for that device. When modifying the subscription of a device, the VPP can choose to `register` or `unregister` the device. \n\n### How does the device partner know which `PROGRAM_PUBLISH_KEY` and `PROGRAM_PUBLISH_SECRET` to use when publishing data?\nThe VPP will provide a unique `PROGRAM_PUBLISH_KEY` and `PROGRAM_PUBLISH_SECRET` for new programs. The Device Partner should associate new devices with the program so that it can use the correct program credentials.\n\n### How frequently should device data be published to the VPP?\nTelemetry data in the lists of \"signals\" and \"settings\" should be published between every 5 and every 15 minutes. This data should contain 5 minute intervals for continuous signals. Categorical signals and settings that change infrequently can be updated only on change.\n\n### My device publishes data that doesn't correspond to an existing signal or setting. What should I do with it?\nThe signal and setting lists are constantly evolving. Please contact the Gravity Connect team with suggestions for updating the specification.\n\n### How should a Device Partner handle errors when publishing data to the VPP's endpoints?\nPlease see the [Error Handling section in the VPP API documentation](./vp-api.html#section/Error-Handling).\n\n### What's the difference between the command status and the device command status?\nDevice command status is for a specific device. Command status is used for groups of devices.\n \nFor individual device commands, use only the device command status endpoint.\n\nFor group commands, the command status reflects the state of the command at a scheduling engine level. For example, `OPT_OUT` would not apply and a status of `FAILED` means there was an issue scheduling the command as a whole. If a particular device's status does not reflect the greater command status (e.g., an individual device fails or opts out), report that difference via the device command status. Device command status that is the same as the current command status does not need to be reported.\n\n### Does `/subscription` control Command Status and Device Command Status publishing to the VPP?\nNo, this endpoint only controls the sending of signals and settings. In the case that an unsubscribed device is targeted by a command (which is not an expected situation), the response data should not be reported to the VPP.\n" x-logo: url: ./assets/vp_logo.png backgroundColor: '#FFFFFF' altText: Virtual Peaker Logo version: 2.0.6 title: Gravity Connect API (Device Partner) OAuth Device Discovery (Preferred) API license: name: BSD servers: - url: https://example.com security: - device_partner_api_auth: - device_partner_basic_auth - device_partner_user_auth: - user_read tags: - name: OAuth Device Discovery (Preferred) description: 'The OAuth device discovery flow works as follows: 1. The device owner fills out an onboarding form on Virtual Peaker''s site. 2. At the end of the form, we redirect them to the Device Partner''s OAuth authorization page via a link. 3. The user logs into the Device Partner''s app and grants OAuth access permissions. 4. The Device Partner app completes OAuth authorization code flow, exchanging the code for an access token. 5. Using the access token, the Device Partner calls their API to retrieve the user''s devices. 6. The Device Partner associates the devices with the correct Virtual Peaker program in their backend. 7. The Device Partner handles any additional onboarding logic in their system. 8. The Device Partner publishes enrolled device data to Virtual Peaker''s API. 9. Virtual Peaker discovers devices using the OAuth token provided. 10. We subscribe to devices for data publishing and provide a DEVICE_PUBLISH_SECRET. 11. Virtual Peaker may optionally pull initial device data from the Device Partner''s API. For each utility program, a separate client_id is created. This ID is passed in the OAuth link to associate devices with the correct program. ' paths: /devices: get: summary: Read current user's devices operationId: readCurrentUserDevices tags: - OAuth Device Discovery (Preferred) security: - device_partner_user_auth: - user_read responses: '200': description: successful operation content: application/json: schema: type: array items: $ref: '#/components/schemas/DeviceDetails' '400': $ref: '#/components/responses/badRequest' '401': $ref: '#/components/responses/unauthorized' default: description: unexpected error content: application/json: schema: $ref: '#/components/schemas/Details' /user: get: summary: Read current user's details operationId: readCurrentUser tags: - OAuth Device Discovery (Preferred) security: - device_partner_user_auth: - user_read responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/UserDetails' '400': $ref: '#/components/responses/badRequest' '401': $ref: '#/components/responses/unauthorized' default: description: unexpected error content: application/json: schema: $ref: '#/components/schemas/Details' components: responses: badRequest: description: Request was not properly formatted content: application/json: schema: $ref: '#/components/schemas/Details' unauthorized: description: The request was not properly authorized content: application/json: schema: $ref: '#/components/schemas/Details' schemas: Details: type: object required: - message properties: message: type: string description: A human readable response. Because there's no standard for what is included or how information should be formatted, this should not be parsed and utilized programmatically. DeviceDetails: type: object required: - uid - kind - type - isSubscribed properties: uid: type: string description: DEVICE_UID, unique within the partner kind: $ref: '#/components/schemas/DeviceKindEnum' name: type: string type: type: string description: model name/number serialNumber: type: string isSubscribed: type: boolean description: If true, Virtual Peaker has enabled publishing of device data DeviceKindEnum: type: string enum: - HWH - TSTAT - BATTERY - EVSE - V2G - STORAGE-HVAC ServiceAddress: type: object required: - streetAddress - city - state - postalCode - country properties: streetAddress: type: string streetAddress2: type: string city: type: string state: type: string description: Within the US, passed as a 2 letter abbreviation postalCode: type: string country: type: string description: A 2 letter indication of country. Following [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) UserDetails: type: object required: - userId properties: userId: type: string description: Unique identifier for the user within the device partner's platform accountNumber: type: string description: Utility customer identifier (if available) name: type: string email: type: string deviceUids: type: array items: type: string serviceAddress: $ref: '#/components/schemas/ServiceAddress' securitySchemes: device_partner_api_auth: type: oauth2 flows: clientCredentials: tokenUrl: https://example.com/oauth/token scopes: basic_partner_read_write: conducts all actions on the partners behalf device_partner_user_auth: type: oauth2 description: If using the OAuth onboarding method, this authentication method is used for the respective endpoints. Please the the FAQ for more details. flows: authorizationCode: authorizationUrl: https://example.com/oauth/authorize tokenUrl: https://example.com/oauth/token scopes: user_read: read details about new user x-tagGroups: - name: Base Implementation tags: - Devices - Commands - Energy Interval Endpoint - name: Device Onboarding tags: - OAuth Device Discovery (Preferred) - Pairing Code Device Discovery - End User App - Pairing Code Device Discovery - Utility Commissioned Installation - Device Partner Driven Enrollment - name: Group Management tags: - Group Management