Skip to main content

Customer API Overview

The Customer API is a GraphQL interface designed as the Customer interface for our energy platform to utilize for mobile apps and customer web portals. Rather than exposing fragmented endpoints, the API is built around a user-centric graph structure. Starting from the authenticated customer (me), client applications can navigate through contracts, physical metering points, time-series energy usage, invoices, assets, and self-service mutations.


Environments

The Customer API is hosted on the following environments:

EnvironmentBase URL
Staginghttps://customer.api.staging.energyzero.nl
Productionhttps://customer.api.energyzero.nl

Authorization requirements

All requests—including data retrieval, mutations, and GraphQL schema introspection—require a valid HTTP Authorization header:

Authorization: Bearer <YOUR_ACCESS_TOKEN>

Note: Information on how to authenticate and acquire an access token is covered in the Authentication Guide.


API design

The API follows a strict hierarchical domain model. Understanding this structure helps developers query data efficiently without unnecessary roundtrips.

Core Domain Overview

  1. User Entrypoint (me): Represents the authenticated entity and contains personal profile data and vendor association.
  2. Contracts (Contract): Central entity binding delivery/billing addresses, payment methods, monthly deposits, and lifecycle statuses (PENDING, ACTIVE, ENDED, CANCELLED).
  3. Metering Points (MeteringPoint): Represents physical electricity or gas connections on the grid.
  4. Usages & Costs (Usage / Costs): Time-series consumption/production records and interval cost breakdowns.
  5. Invoices (Invoice): Financial documents, deposit adjustments, and downloadable PDF assets.
  6. Smart Assets (VehicleAsset / ChargingPoleAsset): Managed EV vehicles and charging poles supporting smart charging settings and V2G (Vehicle-to-Grid) metrics.
  7. Mutations: Allowed customer operations such as updating payment methods, shifting monthly deposit amounts, or adjusting vehicle charge schedules.

Schema Discovery via GraphQL Introspection

To ensure client integrations are always aligned with the latest platform features without manually maintaining exhaustive markdown type references, developers should utilize GraphQL Introspection. Our GraphQL schema is fully self-documenting: field descriptions, deprecation warnings, scalars, and input validation requirements are embedded directly into the schema.

Fetch the complete Schema Definition Language (.graphql file) directly from the endpoint using for example npx or any client interface you prefer:

npx get-graphql-schema [https://customer.api.energyzero.nl](https://customer.api.energyzero.nl) \
-h "Authorization=Bearer YOUR_ACCESS_TOKEN" > customer-schema.graphql

Run an introspection HTTP request to fetch type metadata:

curl -X POST [https://customer.api.energyzero.nl](https://customer.api.energyzero.nl) \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"query": "{ __schema { queryType { name } mutationType { name } types { name kind description } } }"
}'

Point GraphQL clients such as Postman, Insomnia, Altair, or GraphQL Playground to the endpoint URL.

Include your HTTP header:

Authorization: Bearer YOUR_ACCESS_TOKEN

The IDE will automatically introspect the schema and generate an interactive documentation sidebar.


Core Operations & Examples

Below are practical query and mutation patterns reflecting common application workflows.

1. Fetching Customer Profile & Contracts

Retrieve the logged-in customer's details along with active energy contracts and metering point identifiers:

query GetCustomerOverview {
me {
id
customerNumber
firstName
surname
email
contracts(first: 5) {
edges {
node {
id
status
energyContractType
hasElectricity
hasGas
monthlyDeposit {
incl
excl
vat
}
deliveryAddress {
street
houseNumber
postalCode
city
}
meteringPoints {
id
identifier
type
gridOperator
}
}
}
}
}
}

2. Querying Metering Point Usages

Fetch hourly or daily consumption/production time-series data for a specific metering point:

query GetMeteringPointUsages($meteringPointId: UUID!,$from: Time!) {
me {
contracts(first: 1) {
edges {
node {
meteringPoints(id: $meteringPointId) {
identifier
type
usages(
type: ELECTRICITY_USAGE
from: $from
requestUnit: DAYS
requestAmount: 7
granularity: HOUR
) {
id
start
amount
type
}
}
}
}
}
}
}

3. Energy Market Trading Prices

Query spot/future trading prices for gas or electricity across dynamic interval granularities:

query GetEnergyPrices($from: Time!) {
prices(
energyType: ELECTRICITY
from: $from
requestUnit: DAYS
requestAmount: 1
granularity: HOUR
) {
timestamp
price {
incl
excl
}
isAverage
source
}
}

4. Self-Service Mutations

The API provides specific customer self-service mutations:

Update Monthly Deposit

mutation AdjustMonthlyDeposit($input: UpdateMyMonthlyDepositInput!) {
updateMyMonthlyDeposit(input: $input) {
... on NewMonthlyDepositAmount {
monthlyDeposit {
incl
excl
}
}
... on CalculatedMonthlyDepositAmount {
calculatedMonthlyDeposit {
incl
excl
}
}
}
}

Set Vehicle Smart Charging Settings

mutation ConfigureSmartCharging($input: SetChargeSettingsInput!) {
setChargeSettings(input: $input) {
socTarget
socMin
immediateMode
schedule {
byDay {
keepTargetSocMinutes
monday {
departureTime
enabled
}
}
}
}
}


Error Handling

Errors follow the RFC 9457 Problem Details specification. Domain-specific errors (such as AddressNotFoundError or UsageOutsideOfThresholdError) are exposed via union response types on mutations.

Example payload structure for validation or execution errors:

{
"errors": [
{
"message": "Validation failed for input",
"extensions": {
"title": "Bad Request",
"status": 400,
"detail": "Usage outside allowed deposit threshold margin",
"timestamp": "2026-07-24T10:00:00Z",
"errors": [
{
"pointer": "yearlyGasUsage",
"detail": "Value exceeds expected consumption limit"
}
]
}
}
]
}