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:
- Integrate the Provider API and get a RegistrationToken object.
- Obtain the deep link URL from the
deeplink
field in RegistrationToken and open it within your app
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
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 |
---|---|
|
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"
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
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 |
---|---|
|
License term hasn't started yet because start date has not been reached |
|
License is currently active |
|
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
Example
{"period": 987, "autoRenewal": false}
LocalHttpPushStatus
Values
Enum Value | Description |
---|---|
|
HTTP Push is disabled on the device |
|
HTTP Push is enabled and working on the device |
|
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
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 |
Arguments
|
|
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
Example
"1-0:1.8.0"
ObisFormat
Values
Enum Value | Description |
---|---|
|
Returns OBIS code in hexadecimal format with 6 digits, example: '01-00:01.08.00*ff' |
|
Returns OBIS code in decimal format with 5 digits, example: '1-0:1.8.0' |
Example
"hex"
Pagination
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"
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
|
|
installation - Installation
|
Returns a single installation. Requires either id or externalID |
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
|
|
licensePools - [LicensePool!]!
|
Returns a list of all license pools available to this provider |
licensePool - LicensePool
|
Returns a single license pool by id |
Arguments
|
|
readings - MeterReadingsResponse!
|
Returns readings for the current provider. Readings are only saved for up to 24h. Will at maximum return If no more readings are available, cursor will be null |
Arguments
|
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
RegistrationToken
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
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
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"