Ovo Energy API - Get your energy data from Ovo

Just wondering if anyone is still using this? I’ve been using it for some time, loading the data into an influx db, but it stopped working a few days ago. I’ve managed to determine the following.

The initial login seems to work

https://my.ovoenergy.com/api/v2/auth/login

The select account returns a 404 error - no Route matched with those values
https://smartpaymapi.ovoenergy.com/first-login/api/bootstrap/v2/

The call to get data fails 401 due to the account cookie not being created from above - OAuth plugin - No refresh_token present
https://smartpaymapi.ovoenergy.com/usage/api/{{topic}}/{{account}}?date={{date}}

I suspect the api has changed. I also have an OVO home assistant plugin which has stopped working.

Has anyone else had the same problem, is there a way to fix this?

It seems the token has been moved to a different property, if you alter your code to this

msg.cookies = { "refresh_token": msg.responseCookies?.restricted_refresh_token };

It should work.

Thanks for the suggestion.
Is that in the “pass_on_cookies” node? I tried changing that, and it didnt seem to work.

tried setting msg.cookies to the expression
{ "refresh_token": msg.responseCookies.restricted_refresh_token}
(its invalid with the msg.responseCookies?. format)
this sets a cookies object with a json value of refresh_token followed by all fields for the input to the api call, but it still then returns 404.

This is the cookies object for the input (with value set to REDACTED

{"refresh_token":{"Max-Age":"1800","Expires":"Sat, 27 Sep 2025 22:58:37 GMT","SameSite":"None","Path":"/","Domain":"my.ovoenergy.com","value":"REDACTED_DATA”}}

I think I’m getting very lost here!

I'm not sure what functions you are using so hard to advise you, but where ever you have the http post request to https://my.ovoenergy.com/api/v2/auth/login
then you need to grab responseCookies.restricted_refresh_token from the output and add that as msg.cookies { "refresh_token":previous object here} when requesting data.

NOTE you want the whole object not just the value!

I’m still using your code with just a few amendments. I think I’ve done what you suggest. After the changes, this is the value of the msg.cookies object before the call to the second api, requesting the account data.
{"refresh_token":{"Max-Age":"1800","Expires":"Sat, 27 Sep 2025 22:58:37 GMT","SameSite":"None","Path":"/","Domain":"my.ovoenergy.com","value":"REDACTED_DATA”}}

however that call still fails with a 404 - payload.message = no Route matched with those values

The cookies object looks to be what. you suggest, with all fields present?

For some reason the refresh token is missing from the response now, however there is a token in restricted property, so just use that. I think this is the change node you are referring to though that's not from my flow -

I think i’ve done that, but it’s not working. This is the flow for the login, which I think is your original code

[{"id":"f671a4119c7066e1","type":"tab","label":"Flow 3","disabled":false,"info":"","env":[]},{"id":"84c3d76e5b03d8a3","type":"http request","z":"f671a4119c7066e1","name":"Login","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://my.ovoenergy.com/api/v2/auth/login","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":610,"y":460,"wires":[["f95fc1327f10af74","73fb58756c1167bb"]]},{"id":"632620b197f8a476","type":"http request","z":"f671a4119c7066e1","name":"get account Id","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://smartpaymapi.ovoenergy.com/first-login/api/bootstrap/v2/","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":940,"y":460,"wires":[["56851280f3fc7920","73fb58756c1167bb"]]},{"id":"f95fc1327f10af74","type":"change","z":"f671a4119c7066e1","name":"pass on cookies","rules":[{"t":"set","p":"cookies","pt":"msg","to":"responseCookies.restricted_refresh_token","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":460,"wires":[["632620b197f8a476","73fb58756c1167bb"]]},{"id":"56851280f3fc7920","type":"change","z":"f671a4119c7066e1","name":"Save account","rules":[{"t":"set","p":"account","pt":"flow","to":"payload.accounts[0].accountId","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1120,"y":460,"wires":[[]]},{"id":"8d4e350943061b4d","type":"inject","z":"f671a4119c7066e1","name":"Set uid/pw","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"{\"username\":\"user\",\"password\":\"password\",\"rememberMe\":false}","payloadType":"json","x":310,"y":460,"wires":[["d35c589314307290"]]},{"id":"d35c589314307290","type":"change","z":"f671a4119c7066e1","name":"","rules":[{"t":"set","p":"login","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":460,"wires":[["84c3d76e5b03d8a3"]]},{"id":"98a0445860c552bb","type":"comment","z":"f671a4119c7066e1","name":"Enter login details here","info":"","x":110,"y":460,"wires":[]},{"id":"73fb58756c1167bb","type":"debug","z":"f671a4119c7066e1","name":"debug 18","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":960,"y":580,"wires":[]}]

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil: icon.

See this post for more details - How to share code or flow json

Thanks for that, I was just thinking it didnt look right. Hopefully the above can now be copied

OK I found the old flow you are using, you do not need the first part as you will already have your customer id ? It looks like this part of the API has also changed.

So just modify the bit after that to use the new responseCookies.restricted_refresh_token in the set date function.

I dont have the customer id, is that the numeric account id from the web page? Should I just store this in the flow variable, is it a string or number?
Is it a set of msg.cookies to responseCookies.restricted_refresh_token that is needed?

If you have a working flow, that could be helpful to me!

you should already have account id stored as a flow variable. In fact as this will never change you could just hardcode it in the requests if you wanted to. Just modify the set date function as above and you should be good to go.

msg.cookies = { "refresh_token": msg.responseCookies?.refresh_token };

I’ve got this working again, following your advice:-

  • Set my ovo account no to the flow value and removed the one off login/get account flow
  • added the following to the set date node
    msg.cookies = { "refresh_token": msg.responseCookies?.restricted_refresh_token };

I really appreciate your help on this, it’s all feeding an influx DB with some nice graphs in grafana, covering over 12 months of data. No idea how you reverse engineer these api’s!
Thanks again for all your help & patience.

2 Likes