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
Description
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 installation_id query parameter identifying the installation.
If the request is refused, the redirect URL is called with an additional error query parameter which may be one of the following values:
access_denied, if user declined linking their accountunauthorized_client, if the partner isn't authorized to link their accountserver_error, if linking process failed for an unexpected reason
If provided the value of the state parameter will also be appended as a query parameter to the redirect URL
Example
Query
query ConnectUrl(
$redirectUrl: String!,
$state: String
) {
connectUrl(
redirectUrl: $redirectUrl,
state: $state
)
}
Variables
{
"redirectUrl": "abc123",
"state": "abc123"
}
Response
{"data": {"connectUrl": "xyz789"}}
installation
Description
Returns a single installation
Response
Returns an Installation
Arguments
| Name | Description |
|---|---|
id - Uuid!
|
Example
Query
query Installation($id: Uuid!) {
installation(id: $id) {
id
externalId
meters {
id
installation {
...InstallationFragment
}
number
}
currentMeter {
id
installation {
...InstallationFragment
}
number
}
devices {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
currentDevice {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
}
}
Variables
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee"
}
Response
{
"data": {
"installation": {
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"externalId": "xyz789",
"meters": [Meter],
"currentMeter": Meter,
"devices": [Device],
"currentDevice": Device
}
}
}
installations
Description
Returns list of installations that belong to this partner
Response
Returns [Installation!]!
Arguments
| Name | Description |
|---|---|
pagination - Pagination
|
Example
Query
query Installations($pagination: Pagination) {
installations(pagination: $pagination) {
id
externalId
meters {
id
installation {
...InstallationFragment
}
number
}
currentMeter {
id
installation {
...InstallationFragment
}
number
}
devices {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
currentDevice {
id
bridge {
...DeviceBridgeFragment
}
core {
...DeviceCoreFragment
}
}
}
}
Variables
{"pagination": Pagination}
Response
{
"data": {
"installations": [
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"externalId": "abc123",
"meters": [Meter],
"currentMeter": Meter,
"devices": [Device],
"currentDevice": Device
}
]
}
}
partner
Description
Returns the current partner
Response
Returns a Partner!
Example
Query
query Partner {
partner {
id
name
}
}
Response
{
"data": {
"partner": {
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"name": "Example Partner"
}
}
}
Mutations
disableInstallation
Description
Disables the partner for this installation
Subscriptions
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
}
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
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 |
|---|---|
id - Uuid!
|
Unique ID of the installation, automatically generated for each installation |
externalId - String
|
No longer supported |
meters - [Meter!]!
|
List of energy meters the installation has obtained readings from |
currentMeter - Meter
|
Most recent meter the installation has received data from |
devices - [Device!]!
|
List of IOmeter devices the installation has registered |
currentDevice - Device
|
Most recent device used by the installation |
Example
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"externalId": "abc123",
"meters": [Meter],
"currentMeter": Meter,
"devices": [Device],
"currentDevice": Device
}
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 |
Example
{
"id": "578936dc-8020-4022-a560-2f59d2dca9ee",
"installation": Installation,
"number": "1EMH0007058153"
}
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"
}
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
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"