IOmeter Partner API
IOmeter Partner GraphQL API Documentation
API Endpoints
# Production:
https://partner.prod.iometer.cloud/api/v1/query
Headers
Authorization: Basic BASE64(<TOKEN:SECRET>)
Links
GraphQL
GraphQL is an open-source data query and manipulation language for APIs and a query runtime engine. GraphQL enables declarative data fetching where a client can specify exactly what data it needs from an API.
For general information about the GraphQL, see graphql.org
GraphQL is served via HTTP, which allows to send GraphQL queries via standard HTTP GET and POST requests. Details about the HTTP transport can be found here: https://graphql.org/learn/serving-over-http/
There is also a GraphQL Playground available, which provides a simple to use Web GUI to explore the GraphQL API and to try out GraphQL queries.
While GraphQL can be used directly, there is also a large amount of client libraries available which help with consuming GraphQL APIs: https://graphql.org/code/
GraphQL also supports subscriptions, which allow the API to push data to the client. The IOmeter API uses either the GraphQL over WebSocket Protocol or the GraphQL over Server-Sent Events Protocol to enable such subscriptions.
Authentication
The API supports two authentication methods:
Basic Auth
Basic Auth uses a simple basic authentication header generated as follows:
"Basic " + base64("<partner_id>:<partner_secret>")
Example
- Partner ID:
b1451a19-53c7-4e8a-87a0-7c45d3807e9d - Partner Secret:
JjNQKxIYugVSqCrxkbNfQ8Onpvd07K2G - Header:
Authorization: Basic YjE0NTFhMTktNTNjNy00ZThhLTg3YTAtN2M0NWQzODA3ZTlkOkpqTlFLeElZdWdWU3FDcnhrYk5mUThPbnB2ZDA3SzJH
WSSE
WSSE transmits a digest consisting of the secret, a nonce and a timestamp.
The nonce is a randomly generated value with 16 bytes, timestamp is a UTC timestamp in RFC3339 format, and the secret is the partner secret.
The header is generated as follows:
func GenerateWSSE(partnerID string, secret string) string {
created := time.Now().UTC().Format(time.RFC3339)
nonceBytes := make([]byte, 16)
_, _ = rand.Read(nonceBytes)
nonce := hex.EncodeToString(nonceBytes)
text := nonce + created + secret
digestHash := sha256.New()
digestHash.Write([]byte(text))
digestString := hex.EncodeToString(digestHash.Sum(nil))
passwordDigest := base64.StdEncoding.EncodeToString([]byte(digestString))
return fmt.Sprintf(
"UsernameToken Username=\"%s\", PasswordDigest=\"%s\", Nonce=\"%s\", Created=\"%s\"",
partnerID,
passwordDigest,
nonce,
created,
)
}
Example
- Partner ID:
0da56783-39b2-4b43-adaa-301d247fcd59 - Partner Secret:
1NNbSclq0ULA364TZBB4Hr0EYoRK - Created:
2025-10-20T12:38:50Z - Nonce:
eb6c574e12fcfa4cd091a5b21ad0abdb - Password Digest:
NWNiYTMyNzNmZGQ2NWU2ODhjZjc1Mzg3MzliZGE4MTgyMjhjY2Q3NWU1NmYxMzEyM2NhMmI3MWI0ZmMwODY3MA== - Header:
Authorization: UsernameToken Username="0da56783-39b2-4b43-adaa-301d247fcd59", PasswordDigest="NWNiYTMyNzNmZGQ2NWU2ODhjZjc1Mzg3MzliZGE4MTgyMjhjY2Q3NWU1NmYxMzEyM2NhMmI3MWI0ZmMwODY3MA==", Nonce="eb6c574e12fcfa4cd091a5b21ad0abdb", Created="2025-10-20T12:38:50Z"
Account Linking
To start the account linking process, the Partner App needs to open the connection URL for the user.
The connection URL can be obtained from the connectUrl query:
query {
connectUrl(
redirectUrl: "https://example.com"
state: "123456"
)
}
The URL will open the IOmeter App, where the user will be asked to confirm linking their account to the partner.
If the user accepts, the redirect URI is called with the following additional parameter:
installation_id, which represents the unique account ID of the user
If account linking fails, the redirect URI is called with an error parameter instead which may have one of the following values:
access_denied, if user declined linking their accountunauthorized_client, if the the partner isn’t authorized to link their accountserver_error, if linking process failed for an unexpected reason
Once accounts are linked the Partner will have access to installation data using the Partner API.
Queries
connectUrl
Example
Query
query ConnectUrl(
$redirectUrl: String!,
$state: String
) {
connectUrl(
redirectUrl: $redirectUrl,
state: $state
)
}
Variables
{
"redirectUrl": "xyz789",
"state": "xyz789"
}
Response
{"data": {"connectUrl": "xyz789"}}
installation
Response
Returns an Installation
Arguments
| Name | Description |
|---|---|
id - Uuid!
|
Example
Query
query Installation($id: Uuid!) {
installation(id: $id) {
externalId
id
meter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
meters {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
currentMeter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
device {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
devices {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
currentDevice {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
readings {
readings {
...MeterReadingFragment
}
cursor
}
}
}
Variables
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee"
}
Response
{
"data": {
"installation": {
"externalId": "abc123",
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"meter": Meter,
"meters": [Meter],
"currentMeter": Meter,
"device": Device,
"devices": [Device],
"currentDevice": Device,
"readings": MeterReadingsResponse
}
}
}
installations
Response
Returns [Installation!]!
Arguments
| Name | Description |
|---|---|
pagination - Pagination
|
Example
Query
query Installations($pagination: Pagination) {
installations(pagination: $pagination) {
externalId
id
meter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
meters {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
currentMeter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
device {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
devices {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
currentDevice {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
readings {
readings {
...MeterReadingFragment
}
cursor
}
}
}
Variables
{"pagination": Pagination}
Response
{
"data": {
"installations": [
{
"externalId": "xyz789",
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"meter": Meter,
"meters": [Meter],
"currentMeter": Meter,
"device": Device,
"devices": [Device],
"currentDevice": Device,
"readings": MeterReadingsResponse
}
]
}
}
partner
Description
Returns the current partner
Response
Returns a Partner!
Example
Query
query Partner {
partner {
id
name
installations {
externalId
id
meter {
...MeterFragment
}
meters {
...MeterFragment
}
currentMeter {
...MeterFragment
}
device {
...DeviceFragment
}
devices {
...DeviceFragment
}
currentDevice {
...DeviceFragment
}
readings {
...MeterReadingsResponseFragment
}
}
installation {
externalId
id
meter {
...MeterFragment
}
meters {
...MeterFragment
}
currentMeter {
...MeterFragment
}
device {
...DeviceFragment
}
devices {
...DeviceFragment
}
currentDevice {
...DeviceFragment
}
readings {
...MeterReadingsResponseFragment
}
}
meters {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
meter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
connectUrl
readings {
readings {
...MeterReadingFragment
}
cursor
}
}
}
Response
{
"data": {
"partner": {
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"name": "Example Partner",
"installations": [Installation],
"installation": Installation,
"meters": [Meter],
"meter": Meter,
"connectUrl": "xyz789",
"readings": MeterReadingsResponse
}
}
}
readings
Response
Returns a MeterReadingsResponse!
Example
Query
query Readings(
$startTime: DateTime,
$limit: Int,
$cursor: String
) {
readings(
startTime: $startTime,
limit: $limit,
cursor: $cursor
) {
readings {
meter {
...MeterFragment
}
time
values {
...MeterReadingValueFragment
}
}
cursor
}
}
Variables
{
"startTime": "2024-12-31T24:30:15Z",
"limit": 123,
"cursor": "xyz789"
}
Response
{
"data": {
"readings": {
"readings": [MeterReading],
"cursor": "abc123"
}
}
}
Mutations
disableInstallation
Description
Disables the partner for this installation
Subscriptions
liveReadings
Response
Returns a MeterReading!
Arguments
| Name | Description |
|---|---|
installationId - ID!
|
|
obisCodes - [ObisCode]
|
Example
Query
subscription LiveReadings(
$installationId: ID!,
$obisCodes: [ObisCode]
) {
liveReadings(
installationId: $installationId,
obisCodes: $obisCodes
) {
meter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
time
values {
obisCode
value
unit
}
}
}
Variables
{
"installationId": 4,
"obisCodes": ["1-0:1.8.0"]
}
Response
{
"data": {
"liveReadings": {
"meter": Meter,
"time": "2024-12-31T24:30:15Z",
"values": [MeterReadingValue]
}
}
}
meterReadings
Description
Returns a stream of readings for the currently logged in provider.
NOTE: In rare cases it's possible that the same reading might be returned multiple times
Response
Returns a MeterReading!
Arguments
| Name | Description |
|---|---|
startTime - DateTime
|
At which timestamp to start returning readings from. Up to 24h supported. Time is based on when readings were received, which might diverge from the time the reading was taken |
Example
Query
subscription MeterReadings($startTime: DateTime) {
meterReadings(startTime: $startTime) {
meter {
id
installation {
...InstallationFragment
}
number
readings {
...MeterReadingsResponseFragment
}
}
time
values {
obisCode
value
unit
}
}
}
Variables
{"startTime": "2024-12-31T24:30:15Z"}
Response
{
"data": {
"meterReadings": {
"meter": Meter,
"time": "2024-12-31T24:30:15Z",
"values": [MeterReadingValue]
}
}
}
Types
Boolean
Description
The Boolean scalar type represents true or false
ConnectionStatus
Values
| Enum Value | Description |
|---|---|
|
|
Device is connected |
|
|
Device is disconnected |
Example
"connected"
CoreAttachmentStatus
Description
Current connection status of the core to the energy meter
Values
| Enum Value | Description |
|---|---|
|
|
Core is currently attached to an energy meter |
|
|
Core is currently not attached to an energy meter |
Example
"attached"
CorePowerStatus
Description
Current power status of the core
Values
| Enum Value | Description |
|---|---|
|
|
Core is currently running on battery power |
|
|
Core is currently running on wired power |
Example
"battery"
DateTime
Description
RFC 3339 Timestamp string (YYYY-MM-DDTHH:MM:SSZ)
Example
"2024-12-31T24:30:15Z"
Device
Description
Represents an IOmeter device in use by the user.
A device consists of two parts, the bridge and the core. The core is the piece attached to the meter, whereas the bridge is what is used to connect the meter to the local Wifi of the user
Fields
| Field Name | Description |
|---|---|
id - Uuid!
|
Unique ID of the device |
bridge - DeviceBridge!
|
Bridge, the part used to connect the core to the local Wifi of the user |
core - DeviceCore!
|
Core, the part attached to the energy meter |
Example
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"bridge": DeviceBridge,
"core": DeviceCore
}
DeviceBridge
Description
The part of the device used to connect the core to the local Wifi of the user
Fields
| Field Name | Description |
|---|---|
connectionStatus - ConnectionStatus!
|
Current connection status of the bridge to the IOmeter backend |
Example
{"connectionStatus": "connected"}
DeviceCore
Description
The part of the device attached to the energy meter
Fields
| Field Name | Description |
|---|---|
connectionStatus - ConnectionStatus!
|
Current connection status of the core to the bridge |
attachmentStatus - CoreAttachmentStatus!
|
Current connection status of the core to the energy meter |
batteryLevel - Int!
|
Current battery level of the device (0-100) |
powerStatus - CorePowerStatus!
|
Current power status of the core |
pinStatus - PinStatus!
|
Current pin status of the core |
Example
{
"connectionStatus": "connected",
"attachmentStatus": "attached",
"batteryLevel": 100,
"powerStatus": "battery",
"pinStatus": "missing"
}
Float
Description
The Float scalar type represents signed double-precision fractional values as specified by IEEE 754
Example
987.65
ID
Description
The ID scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID
Example
"4"
Installation
Description
Reflects a single installation (or user) which may own a number of (energy) meters and IOmeter devices.
Each installation is identified by either an InstallationID or optionally an ExternalID given by the provider when creating the registration token
Fields
| Field Name | Description |
|---|---|
externalId - String
|
No longer supported |
id - Uuid!
|
Unique ID of the installation, automatically generated for each installation |
meter - Meter
|
Return single meter. Either id or number required |
meters - [Meter!]!
|
List of energy meters the installation has obtained readings from |
currentMeter - Meter
|
Most recent meter the installation has received data from |
device - Device
|
Return single device by id |
Arguments
|
|
devices - [Device!]!
|
List of IOmeter devices the installation has registered |
currentDevice - Device
|
Most recent device used by the installation |
readings - MeterReadingsResponse!
|
Returns readings for this installation. Will at maximum return If no more readings are available, cursor will be null |
Arguments
|
|
Example
{
"externalId": "xyz789",
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"meter": Meter,
"meters": [Meter],
"currentMeter": Meter,
"device": Device,
"devices": [Device],
"currentDevice": Device,
"readings": MeterReadingsResponse
}
Int
Description
The Int scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1
Example
987
Meter
Description
Reflects an energy meter, identified by a unique ID and its meter number.
A single installation may have IOmeter devices attached to multiple meters at the same time
Fields
| Field Name | Description |
|---|---|
id - Uuid!
|
Unique ID of the meter, automatically generated |
installation - Installation!
|
Installation this meter belongs to |
number - MeterNumber!
|
Meter number of the meter |
readings - MeterReadingsResponse!
|
Returns readings for this meter. Will at maximum return If no more readings are available, cursor will be null |
Arguments
|
|
Example
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"installation": Installation,
"number": "1EMH0007058153",
"readings": MeterReadingsResponse
}
MeterNumber
Description
Energy meter number
Example
"1EMH0007058153"
MeterReading
Fields
| Field Name | Description |
|---|---|
meter - Meter!
|
Energy meter this reading was taken from |
time - DateTime!
|
Time this reading was taken |
values - [MeterReadingValue!]!
|
List of reading values, one for each OBIS code |
Example
{
"meter": Meter,
"time": "2024-12-31T24:30:15Z",
"values": [MeterReadingValue]
}
MeterReadingValue
Fields
| Field Name | Description |
|---|---|
obisCode - ObisCode!
|
OBIS code of this reading value Format defaults to |
Arguments
|
|
value - Float!
|
Reading value |
unit - String!
|
Unit of the reading value |
Example
{
"obisCode": "1-0:1.8.0",
"value": 987.65,
"unit": "Wh"
}
MeterReadingsResponse
Fields
| Field Name | Description |
|---|---|
readings - [MeterReading!]!
|
|
cursor - String
|
If more than limit readings are available, a cursor value is returned, which can be used in a subsequent call to return remaining readings |
Example
{
"readings": [MeterReading],
"cursor": "xyz789"
}
ObisCode
Description
ObisCode according to IEC 62056-6-1
Format: A-B:C.D.E
A: Medium (for electricity=1, for thermal energy (gas) =7)B: Channel (internal or external channel)C: Measured value (energy, voltage, etc)D: Measurement type (maximum, current value, etc)E: Tariff
Examples:
1-0:1.8.0: Positive active energy (A+) total [kWh]1-0:1.8.1: Positive active energy (A+) in tariff T1 [kWh]1-0:1.8.2: Positive active energy (A+) in tariff T2 [kWh]1-0:2.8.0: Negative active energy (A-) total [kWh]1-0:16.7.0: Sum active instantaneous power (A+ - A-) [kW]
Also supports hexadecimal format, example: 01-00:01.08.00*ff
Example
"1-0:1.8.0"
ObisFormat
Values
| Enum Value | Description |
|---|---|
|
|
Returns OBIS code in hexadecimal format with 6 value groups (A-B:C.D.E*F), example: 01-00:01.08.00*ff
|
|
|
Returns OBIS code in decimal format with 5 value groups (A-B:C.D.E), example: 1-0:1.8.0
|
|
|
Returns OBIS code in decimal format with 3 value groups (C.D.E), example: 1.8.0
|
|
|
Returns OBIS code in decimal format with 6 value groups (A-B:C.D.E*F), example: 1-0:1.8.0*255
|
Example
"hex"
Pagination
Partner
Fields
| Field Name | Description |
|---|---|
id - Uuid!
|
|
name - String!
|
|
installations - [Installation!]!
|
Returns list of installations that belong to this partner |
Arguments
|
|
installation - Installation
|
Returns a single installation |
Arguments
|
|
meters - [Meter!]!
|
Returns list of meters that belong to this partner Note that there might be multiple meters with the same meter number if multiple installations have used the same physical meter. In this case the most recent meter is returned |
Arguments
|
|
meter - Meter
|
Returns single meter. Either id or meter number required |
connectUrl - String!
|
Generate a connect URL URL will open the IOmeter app, in which the user may grant access of their installation to the partner. If access is granted, the redirect URL is called with an additional If the request is refused, the redirect URL is called with an additional
If provided the value of the |
readings - MeterReadingsResponse!
|
Returns readings for the current partner. Will at maximum return If no more readings are available, cursor will be null |
Arguments
|
|
Example
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"name": "Example Partner",
"installations": [Installation],
"installation": Installation,
"meters": [Meter],
"meter": Meter,
"connectUrl": "abc123",
"readings": MeterReadingsResponse
}
PinStatus
Description
Current pin status of the core
Values
| Enum Value | Description |
|---|---|
|
|
PIN has not been entered |
|
|
PIN is currently being entered |
|
|
PIN has been entered |
Example
"missing"
String
Description
The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text
Example
"abc123"
Uuid
Description
RFC 4122 Universally unique identifier
Example
"578936dc-8020-4022-a560-2f59d2dca9ee"