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>)

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 account
  • unauthorized_client, if the the partner isn’t authorized to link their account
  • server_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 account
  • unauthorized_client, if the partner isn't authorized to link their account
  • server_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

Response

Returns a String!

Arguments
Name Description
redirectUrl - String!
state - String

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

Response

Returns a Boolean!

Arguments
Name Description
installationID - String!

Example

Query
mutation DisableInstallation($installationID: String!) {
  disableInstallation(installationID: $installationID)
}
Variables
{"installationID": "abc123"}
Response
{"data": {"disableInstallation": true}}

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

connected

Device is connected

disconnected

Device is disconnected
Example
"connected"

CoreAttachmentStatus

Description

Current connection status of the core to the energy meter

Values
Enum Value Description

attached

Core is currently attached to an energy meter

detached

Core is currently not attached to an energy meter
Example
"attached"

CorePowerStatus

Description

Current power status of the core

Values
Enum Value Description

battery

Core is currently running on battery power

wired

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 dec

Arguments
format - ObisFormat
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

See also https://de.wikipedia.org/wiki/OBIS-Kennzahlen

Example
"1-0:1.8.0"

ObisFormat

Values
Enum Value Description

hex

Returns OBIS code in hexadecimal format with 6 value groups (A-B:C.D.E*F), example: 01-00:01.08.00*ff

dec

Returns OBIS code in decimal format with 5 value groups (A-B:C.D.E), example: 1-0:1.8.0

dec3

Returns OBIS code in decimal format with 3 value groups (C.D.E), example: 1.8.0

dec6

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

Fields
Input Field Description
offset - Int
limit - Int
Example
{"offset": 0, "limit": 20}

Partner

Fields
Field Name Description
id - Uuid!
name - String!
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "name": "Example Partner"
}

PinStatus

Description

Current pin status of the core

Values
Enum Value Description

missing

PIN has not been entered

pending

PIN is currently being entered

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"