generated: '2026-07-27' method: searched source: >- https://assets.virtualpeaker.io/gravity-connect/vp-api.html (Authentication, Error Handling and payload-size sections) and https://assets.virtualpeaker.io/gravity-connect/device-partner-api.html (Getting Started, Glossary, Authentication, Device Enrollment, Commands, Integration Testing sections), plus the two harvested OpenAPI documents in openapi/. api_name: Gravity Connect API spec_version: 2.0.6 summary: >- Gravity Connect is a two-sided contract. The VPP (Virtual Peaker) calls endpoints the Device Partner implements, authenticated with OAuth 2.0; the Device Partner calls Virtual Peaker's publishing endpoints, authenticated with an HMAC-SHA256 signature over the raw request body. Everything is JSON over HTTPS, timestamps are ISO 8601, addresses use ISO 3166-1 alpha-2 country codes, and there is no pagination, no idempotency key, no request-id header and no documented rate-limit header anywhere in the contract. authentication: vpp_to_device_partner: style: oauth2 flows: - flow: clientCredentials scope: basic_partner_read_write note: program-specific clientId + clientSecret issued by the Device Partner - flow: authorizationCode scope: user_read note: only for the OAuth Device Discovery enrollment flow (homeowner consent) token_endpoint: OEM-hosted (the spec ships https://example.com/oauth/token as a placeholder) client_authentication: Send as Basic header (per the published Postman setup instructions) device_partner_to_vpp: style: hmac-sha256 header: Authorization value_format: 'Publish ' signed_material: the raw JSON request body secrets: - name: PROGRAM_PUBLISH_SECRET scope: program-level publishes, issued when a program is set up - name: DEVICE_PUBLISH_SECRET scope: device-level publishes, issued when each device is enrolled via /subscription key_in_path: PROGRAM_PUBLISH_KEY is a path parameter on every publishing endpoint reference_implementation: >- Node.js snippet published inline in the VPP API guide — crypto.createHmac('sha256', secret).update(body).digest('hex') history: "1.2.0 of the spec clarified that the header is Authorization, not Authentication" see_also: authentication/virtual-peaker-authentication.yml idempotency: supported: false evidence: >- No Idempotency-Key header, no idempotency parameter and no idempotency language appears in either OpenAPI document or in either published guide. Retries are instead made safe by semantics: publishes are keyed on device UID + signal/setting key + timestamp, and commands carry a COMMAND_REFERENCE_ID assigned by the VPP. pagination: supported: false evidence: >- No limit/offset/cursor/page parameters exist on any of the 23 operations. Collection reads are scoped to a single device, user or group and return complete arrays. filtering_and_expansion: supported: false note: >- No sparse fieldsets, no expand parameter. Shape is fixed per device type; the variable part of the payload is the device-type-specific SIGNAL_KEY / SETTING_KEY / VP_COMMAND_OBJECT vocabulary documented per device type (Battery, TSTAT, HWH, EVSE, storage HVAC). metadata: supported: false note: no free-form metadata bag; device identity is the OEM's DEVICE_UID plus kind and type enums. request_tracing: request_id_header: null correlation: >- Commands are correlated by COMMAND_REFERENCE_ID, which the VPP mints and the Device Partner echoes on every status publish (publishCommand, publishDeviceCommand) and on readCommandState / cancelCommand / commandOptOut. versioning: scheme: >- Specification version (semver-ish, currently 2.0.6) carried in the OpenAPI info.version and in the changelog section of both guides; the VPP publishing host additionally pins a major version in the URI path (https://partner.virtualpeaker.io/v1). version_header: null current: 2.0.6 changelog: changelog/virtual-peaker-changelog.yml payloads: media_type: application/json max_request_size_bytes: 262144 max_request_size_note: >- "The maximum payload size for all requests listed below is 262,144 bytes" — VPP publishing endpoints; added to the spec in 1.2.2. timestamps: ISO 8601 (e.g. 2021-01-28T15:36:48.586697) country_codes: ISO 3166-1 alpha-2 (required on published house/service addresses since 1.3.3) pairing_code_format: >- 8 characters — 2 alphanumeric program prefix + 5 random numerics + 1 Luhn check digit (e.g. A1123455); both sides may validate it. error_envelope: format: custom problem_json: false shape: >- Errors are documented per operation as 400 / 401 / 404 / default responses with a description only; there is no shared error schema, no error code registry and no application/problem+json. see_also: errors/virtual-peaker-problem-types.yml retries: policy: exponential backoff retry_on: [429, 502, 503, 504] discard_on: all other error codes verbatim: >- "For the following error codes, please retry using exponential backoff: 429, 502, 503, 504. All other requests that receive an error should be discarded." source: https://assets.virtualpeaker.io/gravity-connect/vp-api.html rate_limits: documented: false signaling_headers: [] note: >- No published quota, no X-RateLimit-* headers, no Retry-After guidance. 429 is only referenced as a retryable status in the error-handling section. event_delivery: model: webhook-style publish direction: Device Partner -> VPP note: >- The glossary defines webhooks explicitly — "Gravity Connect uses webhooks for Device Partners to publish data updates instead of the VPP polling for data." The five publish operations are the event surface. see_also: asyncapi/virtual-peaker-gravity-connect-webhooks.yml timing: command_lead_time: >- "Commands are sent from the VPP to the Device Partner at most 60 seconds before the start time" — regardless of how far in advance the program manager scheduled the event. telemetry_cadence: >- Integration testing requires the device to share power data in 5-minute increments, or to expose the Energy Interval endpoint (readDeviceEnergyInterval). concurrency: >- A Device Partner must accept both individual and group commands simultaneously for a given device. related_artifacts: - authentication/virtual-peaker-authentication.yml - scopes/virtual-peaker-scopes.yml - errors/virtual-peaker-problem-types.yml - lifecycle/virtual-peaker-lifecycle.yml - changelog/virtual-peaker-changelog.yml - sandbox/virtual-peaker-sandbox.yml