My online account view uses a GraphQL API to fetch the data. It makes a curl request with a JSON object:
{
"query": "query MeterReadings($accountNumber: String!, $activeFrom: DateTime) {
account(accountNumber: $accountNumber) {
properties(activeFrom: $activeFrom) {
activeWaterMeters {
id
numberOfDigits
readings(first: 50, excludeHeld: true, excludeQuarantined: true) {
edges {
node {
valueCubicMetres
readingDate
source
}
}
}
}
}
}
}",
"variables": {
"accountNumber": "A-********",
"activeFrom": "2025-08-18T11:39:34.944Z"
},
"operationName": "MeterReadings"
}
and returns
{
"data": {
"account": {
"properties": [
{
"activeWaterMeters": [
{
"id": "*******",
"numberOfDigits": 5,
"readings": {
"edges": [
{
"node": {
"valueCubicMetres": "22.000",
"readingDate": "2025-08-18",
"source": "CUSTOMER"
}
},
{
"node": {
"valueCubicMetres": "7.000",
"readingDate": "2025-04-07",
"source": "OPS"
}
}
]
}
}
]
}
]
}
}
}
The authentication appears to be via a JWT, which - slightly excitingly - is issued by kraken.tech. This is the smart utility platform created by Octopus Energy, and sold to other utility companies, suggesting the API is going to be of a fairly high quality.
The lack of any API key is disappointing, but the auth seems very simple: another GraphQL API request of the format
{
"query": "mutation ObtainKrakenToken($input: ObtainJSONWebTokenInput!) {
obtainKrakenToken(input: $input) {
token
payload
refreshToken
refreshExpiresIn
}
}",
"variables": {
"input": {
"email": "****@gmail.com",
"password": "********"
}
},
"operationName": "ObtainKrakenToken"
}
which returns
{
"data": {
"obtainKrakenToken": {
"token": "***",
"payload": {
"sub": "kraken|account-user:****",
"gty": "EMAIL-AND-PASSWORD",
"email": "****@gmail.com",
"tokenUse": "access",
"iss": "https://api.st.kraken.tech/v1/graphql/",
"iat": 1755517909,
"exp": 1755518809,
"origIat": 1755517909
},
"refreshToken": "****",
"refreshExpiresIn": 1755519709
}
}
}
I’ll do some more research into whether the Severn Trent instance of Kraken does indeed supports API keys, and they’re just not exposing it via a UI - in my Octopus account I can see there is a GraphQL request that will create an API key for me:
{
"query": "mutation regenerateSecretKey {
regenerateSecretKey {
key
__typename
}
}",
"variables": {},
"operationName": "regenerateSecretKey"
}
…which might also work for Severn Trent…