IOmeter Provider API

IOmeter Provider GraphQL API Documentation

API Endpoints
# Production:
https://provider-api.prod.iometer.cloud/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 the GraphQL over WebSocket Protocol to enable such subscriptions. The protocol is supported by most client libraries.

Authentication

API Authentication uses API Keys, consisting of a token and a secret. API Keys can be created within the Admin Backend.

To authenticate with the API, one needs to send a basic access authentication header on every request, using the token as the username and the secret as the password.

Example:

  • Token: zFfsKV98XcsMNtgj71jmx41oamNFKx9K
  • Secret: JjNQKxIYugVSqCrxkbNfQ8Onpvd07K2G
  • Header: Authorization: Basic ekZmc0tWOThYY3NNTnRnajcxam14NDFvYW1ORkt4OUs6SmpOUUt4SVl1Z1ZTcUNyeGtiTmZROE9ucHZkMDdLMkc=

App Deeplink

To open the IOmeter app via a deep link:

For Flutter:

final uri = Uri.tryParse(deeplink);
if (uri != null) {
    launchUrl(uri);
} else {
    //TODO: bad value, check your API response
}

For iOS (Swift):

if let url = URL(string: deeplink) {
    if UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
            if success {
                print("Deep link opened successfully")
            } else {
                print("Failed to open deep link")
            }
        })
    } else {
        print("Cannot open URL: \(deeplink)")
    }
} else {
    print("Invalid URL string")
}

For Android (Kotlin):

val intent = Intent(Intent.ACTION_VIEW, Uri.parse(deeplink))
// Check if there's an app that can handle the deep link
if (intent.resolveActivity(context.packageManager) != null) {
    context.startActivity(intent)
    println("Deep link opened successfully")
} else {
    println("No app found to handle the deep link")
}

Queries

provider

Description

Returns the current provider

Response

Returns a Provider!

Example

Query
query Provider {
  provider {
    id
    name
    installations {
      id
      externalId
      license {
        ...LicenseFragment
      }
      meters {
        ...MeterFragment
      }
      currentMeter {
        ...MeterFragment
      }
      devices {
        ...DeviceFragment
      }
      currentDevice {
        ...DeviceFragment
      }
    }
    installation {
      id
      externalId
      license {
        ...LicenseFragment
      }
      meters {
        ...MeterFragment
      }
      currentMeter {
        ...MeterFragment
      }
      devices {
        ...DeviceFragment
      }
      currentDevice {
        ...DeviceFragment
      }
    }
    signingKeys {
      id
      name
      enabled
    }
    signingKey {
      id
      name
      enabled
    }
    licensePools {
      id
      name
      size
      usage
      term {
        ...LicenseTermFragment
      }
    }
    licensePool {
      id
      name
      size
      usage
      term {
        ...LicenseTermFragment
      }
    }
    readings {
      readings {
        ...MeterReadingFragment
      }
      cursor
    }
  }
}
Response
{
  "data": {
    "provider": {
      "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
      "name": "Example Provider",
      "installations": [Installation],
      "installation": Installation,
      "signingKeys": [SigningKey],
      "signingKey": SigningKey,
      "licensePools": [LicensePool],
      "licensePool": LicensePool,
      "readings": MeterReadingsResponse
    }
  }
}

Mutations

createRegistrationToken

Description

Creates a new registration token.

Registration tokens are used by the IOmeter app to register new installations. An installation is only created once such a token has been used within the app.

If an installation has already been created using the same external id, a token for the existing installation is returned. Otherwise, a new random installation id is generated

Response

Returns a RegistrationToken!

Arguments
Name Description
installationId - Uuid

Token will be generated for the given installation id.

If omitted, a random installation id is generated everytime a token is generated. If a user has already registered with a given external id, it will automatically pick the installation id of the existing installation instead

externalId - String! The registration token requires an externalId, which can be used by the provider to identify the installation within the Provider API
signingKeyId - Uuid! The registration token requires a signing key to be signed with. All providers are outfitted with a default signing key, but further keys may be created within the Admin Backend. If a signing key is disabled or deleted, all tokens signed with this key will become void
license - LicenseInput! Installations need to be assigned a license, which will be taken from a license pool. Please contact your key account manager to obtain a license pool

Example

Query
mutation CreateRegistrationToken(
  $installationId: Uuid,
  $externalId: String!,
  $signingKeyId: Uuid!,
  $license: LicenseInput!
) {
  createRegistrationToken(
    installationId: $installationId,
    externalId: $externalId,
    signingKeyId: $signingKeyId,
    license: $license
  ) {
    installationId
    token
    qrCode
    deeplink
  }
}
Variables
{
  "installationId": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "externalId": "abc123",
  "signingKeyId": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "license": LicenseInput
}
Response
{
  "data": {
    "createRegistrationToken": {
      "installationId": "578936dc-8020-4022-a560-2f59d2dca9ee",
      "token": "abc123",
      "qrCode": "https://example.com",
      "deeplink": "https://example.com"
    }
  }
}

updateLicense

Description

Update license information for a single installation

Response

Returns a License!

Arguments
Name Description
installationId - Uuid!
setTerm - SetLicenseTerm Update the license term (period and autorenewal). Will automatically calculate a new end time for the license
setEndTime - SetLicenseEndTime Set the end time for the license. Will automatically remove any existing license term and instead set a hard end time for the license

Example

Query
mutation UpdateLicense(
  $installationId: Uuid!,
  $setTerm: SetLicenseTerm,
  $setEndTime: SetLicenseEndTime
) {
  updateLicense(
    installationId: $installationId,
    setTerm: $setTerm,
    setEndTime: $setEndTime
  ) {
    pool {
      id
      name
      size
      usage
      term {
        ...LicenseTermFragment
      }
    }
    term {
      period
      autoRenewal
    }
    startTime
    endTime
    status
  }
}
Variables
{
  "installationId": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "setTerm": SetLicenseTerm,
  "setEndTime": SetLicenseEndTime
}
Response
{
  "data": {
    "updateLicense": {
      "pool": LicensePool,
      "term": LicenseTerm,
      "startTime": "2024-12-31T24:30:15Z",
      "endTime": "2024-12-31T24:30:15Z",
      "status": "inactive"
    }
  }
}

Subscriptions

readings

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 Readings($startTime: DateTime) {
  readings(startTime: $startTime) {
    meter {
      id
      number
    }
    installation {
      id
      externalId
    }
    time
    receiveTime
    values {
      obisCode
      value
      unit
    }
  }
}
Variables
{"startTime": "2024-12-31T24:30:15Z"}
Response
{
  "data": {
    "readings": {
      "meter": MeterReadingMeter,
      "installation": MeterReadingInstallation,
      "time": "2024-12-31T24:30:15Z",
      "receiveTime": "2024-12-31T24:30:15Z",
      "values": [MeterReadingValue]
    }
  }
}

scheduledReadings

use readings instead
Response

Returns a Reading!

Arguments
Name Description
obisCodes - [ObisCode!]

Example

Query
subscription ScheduledReadings($obisCodes: [ObisCode!]) {
  scheduledReadings(obisCodes: $obisCodes) {
    meter {
      id
      installation {
        ...InstallationFragment
      }
      number
      latestReadings {
        ...ReadingFragment
      }
    }
    time
    obisCode
    value
    unit
  }
}
Variables
{"obisCodes": ["1-0:1.8.0"]}
Response
{
  "data": {
    "scheduledReadings": {
      "meter": Meter,
      "time": "2024-12-31T24:30:15Z",
      "obisCode": "1-0:1.8.0",
      "value": 987.65,
      "unit": "Wh"
    }
  }
}

Types

Boolean

Description

The Boolean scalar type represents true or false

Example
true

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"

Date

Description

RFC3339 Date string (YYYY-MM-DD)

Example
"2024-12-31"

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
localHttpPushStatus - LocalHttpPushStatus! Current status of the local HTTP push feature on the device
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "bridge": DeviceBridge,
  "core": DeviceCore,
  "localHttpPushStatus": "disabled"
}

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
123.45

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 Optional ID given by the provider when creating a registration token
license - License Assigned license for this installation
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",
  "license": License,
  "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
123

License

Description

License attached to an installation

Fields
Field Name Description
pool - LicensePool! License pool this license is taken from
term - LicenseTerm License term determining the runtime of the license. If empty license term is unlimited
startTime - DateTime! Date the license term will start
endTime - DateTime Date the license term will end, if license has a time limit
status - LicenseStatus! Current license status
Example
{
  "pool": LicensePool,
  "term": LicenseTerm,
  "startTime": "2024-12-31T24:30:15Z",
  "endTime": "2024-12-31T24:30:15Z",
  "status": "inactive"
}

LicenseInput

Fields
Input Field Description
poolId - Uuid! License pool id to be used for this token. Once a user registers using this token a license will be used up from this pool
startDate - Date! Start date for the installation license. License term will begin after this date
Example
{
  "poolId": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "startDate": "2024-12-31"
}

LicensePool

Fields
Field Name Description
id - Uuid!
name - String
size - Int! Amount of total licenses available in this pool
usage - Int! Amount of license that have been used up already
term - LicenseTerm License term determining the runtime of its licenses. If empty license terms will be unlimited
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "name": "xyz789",
  "size": 123,
  "usage": 123,
  "term": LicenseTerm
}

LicenseStatus

Values
Enum Value Description

inactive

License term hasn't started yet because start date has not been reached

active

License is currently active

expired

License term has ended and license has expired
Example
"inactive"

LicenseTerm

Description

Determines a runtime of a license, consisting of a period in months and an auto renewal option

Fields
Field Name Description
period - Int! Period of time in months the license will be valid for beginning with the license start date
autoRenewal - Boolean! If true, license will be automatically renewed at the end of its period
Example
{"period": 987, "autoRenewal": false}

LocalHttpPushStatus

Values
Enum Value Description

disabled

HTTP Push is disabled on the device

enabled

HTTP Push is enabled and working on the device

error

HTTP Push encountered some error
Example
"disabled"

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
latestReadings - [Reading!]! Returns latest meter reading for each OBIS code
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "installation": Installation,
  "number": "1EMH0007058153",
  "latestReadings": [Reading]
}

MeterNumber

Description

Energy meter number

Example
"1EMH0007058153"

MeterReading

Description

Represents a single meter reading taken at a particular time

Fields
Field Name Description
meter - MeterReadingMeter! Energy meter this reading was taken from
installation - MeterReadingInstallation! Installation this reading was taken for
time - DateTime! Time this reading was taken
receiveTime - DateTime!
values - [MeterReadingValue!]! List of reading values, one for each OBIS code
Example
{
  "meter": MeterReadingMeter,
  "installation": MeterReadingInstallation,
  "time": "2024-12-31T24:30:15Z",
  "receiveTime": "2024-12-31T24:30:15Z",
  "values": [MeterReadingValue]
}

MeterReadingInstallation

Fields
Field Name Description
id - Uuid! Unique ID of the installation, automatically generated for each installation
externalId - String Optional ID given by the provider when creating a registration token
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "externalId": "abc123"
}

MeterReadingMeter

Fields
Field Name Description
id - Uuid! Unique ID of the meter, automatically generated
number - MeterNumber! Meter number of the meter
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "number": "1EMH0007058153"
}

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": 123.45,
  "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

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 digits, example: '01-00:01.08.00*ff'

dec

Returns OBIS code in decimal format with 5 digits, example: '1-0:1.8.0'
Example
"hex"

Pagination

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

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"

Provider

Description

Represents a single energy provider.

All installations belong to exactly one energy provider

Fields
Field Name Description
id - Uuid!
name - String!
installations - [Installation!]! Returns list of installations that belong to this provider
Arguments
pagination - Pagination
installation - Installation Returns a single installation. Requires either id or externalID
Arguments
id - Uuid
externalId - String
signingKeys - [SigningKey!]! Returns a single signing key by id available to this provider. Signing keys are used to sign registration tokens
signingKey - SigningKey Returns list of all signing keys available to this provider. Signing keys are used to sign registration tokens
Arguments
id - Uuid!
licensePools - [LicensePool!]! Returns a list of all license pools available to this provider
licensePool - LicensePool Returns a single license pool by id
Arguments
id - Uuid!
readings - MeterReadingsResponse!

Returns readings for the current provider.

Readings are only saved for up to 24h.

Will at maximum return limit readings. If more readings are available, a cursor value is returned, which can be used in a subsequent call to return remaining readings.

If no more readings are available, cursor will be null

Arguments
startTime - DateTime

Return readings starting from this time stamp. By default, all readings are returned

limit - Int

Limit of readings to return per call. Defaults to 100. Maximum value 100

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
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "name": "Example Provider",
  "installations": [Installation],
  "installation": Installation,
  "signingKeys": [SigningKey],
  "signingKey": SigningKey,
  "licensePools": [LicensePool],
  "licensePool": LicensePool,
  "readings": MeterReadingsResponse
}

Reading

Description

Deprecated

Fields
Field Name Description
meter - Meter!
time - DateTime!
obisCode - ObisCode!
Arguments
format - ObisFormat
value - Float!
unit - String!
Example
{
  "meter": Meter,
  "time": "2024-12-31T24:30:15Z",
  "obisCode": "1-0:1.8.0",
  "value": 987.65,
  "unit": "Wh"
}

RegistrationToken

Fields
Field Name Description
installationId - Uuid!
token - String! Registration token in text form
qrCode - Uri! Relative URL to an QR code which contains this registration token. May be scanned by the IOmeter app to register an installation
deeplink - Uri!
Example
{
  "installationId": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "token": "abc123",
  "qrCode": "https://example.com",
  "deeplink": "https://example.com"
}

SetLicenseEndTime

Fields
Input Field Description
endTime - DateTime! Time the license is supposed to expire
Example
{"endTime": "2024-12-31T24:30:15Z"}

SetLicenseTerm

Fields
Input Field Description
period - Int! Period of time in months the license will be valid for beginning with the license start date
autoRenewal - Boolean! If true, license will be automatically renewed at the end of its period
Example
{"period": 987, "autoRenewal": false}

SigningKey

Description

Signing keys are asymmetric RSA keys which are used to sign registration tokens.

New signing keys can be created in the admin backend. When creating a registration token, one signing key needs to be selected to sign the token with

Fields
Field Name Description
id - Uuid!
name - String
enabled - Boolean! If key is disabled, all tokens signed with this key will be rejected
Example
{
  "id": "578936dc-8020-4022-a560-2f59d2dca9ee",
  "name": "abc123",
  "enabled": true
}

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
"xyz789"

Uri

Description

RFC 3986 Uniform resource identifier

Example
"https://example.com"

Uuid

Description

RFC 4122 Universally unique identifier

Example
"578936dc-8020-4022-a560-2f59d2dca9ee"