Retrieve a VPP enrollment
curl --request GET \
--url https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "enr_7c2f1a9e4b0d8f3a6e2c5d10",
"object": "vpp_enrollment",
"live_mode": true,
"device_id": "dev_63a6087272941ef077a8fd3e",
"program_id": "vpr_5c8d1f2a7b3e4d6c9a0f1b2c",
"oem_id": "oem_6a3a8dada72cd0a249ff9528",
"enrollment_state": "ACTIVE",
"enrollment_step": "ACTIVE",
"suspension_reasons": [],
"terms": {
"rewards": [
{
"basis": "FIXED",
"rate": 15,
"period": "QUARTER"
},
{
"basis": "DELIVERED_KWH",
"rate": 0.35
}
],
"opt_out_policy": "ALLOWED",
"notice_days": 30
},
"time_enrolled": "2026-01-24T14:15:22Z",
"time_unenrolled": null,
"time_created": "2026-01-20T09:30:00Z",
"time_updated": "2026-08-12T09:30:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}Enrollments
Retrieve a VPP enrollment
Retrieves a single enrollment with its current lifecycle state.
GET
/
vpp-enrollments
/
{enrollment_id}
Retrieve a VPP enrollment
curl --request GET \
--url https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://fleet-api.flatpeak.com/vpp-enrollments/{enrollment_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "enr_7c2f1a9e4b0d8f3a6e2c5d10",
"object": "vpp_enrollment",
"live_mode": true,
"device_id": "dev_63a6087272941ef077a8fd3e",
"program_id": "vpr_5c8d1f2a7b3e4d6c9a0f1b2c",
"oem_id": "oem_6a3a8dada72cd0a249ff9528",
"enrollment_state": "ACTIVE",
"enrollment_step": "ACTIVE",
"suspension_reasons": [],
"terms": {
"rewards": [
{
"basis": "FIXED",
"rate": 15,
"period": "QUARTER"
},
{
"basis": "DELIVERED_KWH",
"rate": 0.35
}
],
"opt_out_policy": "ALLOWED",
"notice_days": 30
},
"time_enrolled": "2026-01-24T14:15:22Z",
"time_unenrolled": null,
"time_created": "2026-01-20T09:30:00Z",
"time_updated": "2026-08-12T09:30:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}{
"object": "error",
"type": "invalid_request",
"code": "access_denied",
"message": "The requested resource could not be found.",
"context": "api.price_get",
"live_mode": true,
"time_created": "2026-01-01T00:00:00Z"
}Authorizations
Authenticate with the bearer_token obtained from the authentication endpoint.
Response
Enrollment response.
A device's membership of a VPP program. When the program has enrollment.approval_required, requests wait for your decision at AWAITING_APPROVAL. Changes fire vpp_enrollment.update.
The enrollment lifecycle state. enrollment_step gives the detail.
| Value | Meaning |
|---|---|
PENDING | Onboarding: consent, a connected tariff, telemetry, the dispatch test and approval |
ACTIVE | Enrolled and dispatchable |
SUSPENDED | Not dispatchable until every reason in suspension_reasons clears |
LEAVING | A request to leave is waiting for your approval. The device serves only the commitments it already has |
ENDED | Unenrolled. Terminal |
REJECTED | Ineligible, turned down by you, or onboarding failed. Terminal |
Available options:
PENDING, ACTIVE, SUSPENDED, LEAVING, ENDED, REJECTED Example:
"ACTIVE"
The step within enrollment_state.
| Step | State | Meaning |
|---|---|---|
REQUESTED | PENDING | The customer asked to join |
AWAITING_CONSENT | PENDING | Waiting for the consent scopes the program needs |
AWAITING_TARIFF | PENDING | Waiting for a connected tariff at the device's location |
AWAITING_TELEMETRY | PENDING | Waiting for the feeds the program requires |
TESTING_DISPATCH | PENDING | Running the program's dispatch test |
AWAITING_APPROVAL | PENDING | Waiting for your approval |
ACTIVE | ACTIVE | Enrolled |
SUSPENDED | SUSPENDED | Suspended |
UNENROLLING | LEAVING | The customer or the OEM asked to leave. The request waits for your approval |
UNENROLLED | ENDED | Unenrolled |
INELIGIBLE | REJECTED | The device does not qualify, or you unenrolled it while it was PENDING |
FAILED | REJECTED | Onboarding could not complete, for example a failed dispatch test |
Available options:
REQUESTED, AWAITING_CONSENT, AWAITING_TARIFF, AWAITING_TELEMETRY, TESTING_DISPATCH, AWAITING_APPROVAL, ACTIVE, SUSPENDED, UNENROLLING, UNENROLLED, INELIGIBLE, FAILED Example:
"ACTIVE"
Why the enrollment is suspended: an empty list unless enrollment_state is SUSPENDED.
| Value | Meaning |
|---|---|
DISPATCH_UNRESPONSIVE | The device is not acting on instructions |
CONSENT_REVOKED | The customer withdrew a consent scope the program requires |
TELEMETRY_STALLED | A required feed is present but silent beyond its cadence |
USER_PAUSED | Paused by the customer |
Available options:
DISPATCH_UNRESPONSIVE, CONSENT_REVOKED, TELEMETRY_STALLED, USER_PAUSED Was this page helpful?

