Reverse Engineering the Renault Zoe API


Last year I published details of the BMW i3's API. I've now swapped my i3 for a Renault Zoe - so I thought I'd perform the same exercise.

All these API calls can be found by using the Renault ZE Services website. I am indebted to this German blog post for kicking off this work. I'd also like to thank Renault for their "esoteric" use of JavaScript!

What's Available?

This API is fairly limited, here's what you can do with it:

  • See battery status, range, charging status.
  • Start preconditioning
  • See preconditioning history
  • See and set charging schedule.
  • See charging history

Getting started

First, register with Renault ZE Services. This will give you a username and password.

Secondly, you'll need to get your VIN and API token. This can be obtained by posting the username and password to Renault. For example:

curl \
   -H "Content-Type: application/json" \
   -X POST \
   -d '{"username":"you@example.com","password":"P4ssw0rd"}' \
   https://www.services.renault-ze.com/api/user/login`

This will get you back some JSON with your API tokens. Here's an example:

{
    "token": "AAAA",
    "refresh_token": "BBBB",
    "user": {
        "id": "CCCC",
        "locale": "en_GB",
        "country": "GB",
        "timezone": "Europe/London",
        "email": "you@example.com",
        "first_name": "Terence",
        "last_name": "Eden",
        "phone_number": "+447700900123",
        "vehicle_details": {
            "timezone": "Europe/London",
            "VIN": "VVVV",
            "activation_code": "GGGG",
            "phone_number": "+447700900123"
        },
        "scopes": ["BATTERY_CHARGE_STATUS",
                   "BATTERY_CHARGE_HISTORY",
                   "BATTERY_CHARGE_REMOTE_ACTIVATION",
                   "BATTERY_CHARGE_SCHEDULING",
                   "AC_REMOTE_CONTROL",
                   "BATTERY_CHARGE_LOWALERT"],
        "active_account": "DDDD",
        "associated_vehicles": [{
            "VIN": "VVVV",
            "activation_code": "GGGG",
            "user_id": "XXXX"
        }],
        "gdc_uid": "YYYY"
    }
}

Battery Status

Let's start with the battery. We need to use your token and VIN from above.

curl \
   -H "Authorization: Bearer AAAA" \
   "https://www.services.renault-ze.com/api/vehicle/VVVV/battery"

This gets us:

{
    "charging": false,
    "plugged": true,
    "charge_level": 100,
    "remaining_range": 124.0,
    "last_update": 1476472742000,
    "charging_point": "INVALID"
}

A few point to note. The remaining_range is in Kilometres. The last_update is a Unix timestamp.

Preconditioning

The Zoe can be set to warm-up or cool down depending on the last temperate you set in the car. It will also blast the front window de-mister. The process takes five minutes, so you can set it shortly before you need to set off. Preconditioning will only work when the car's battery is above 45%.

Precondition Now

curl \
   -H "Authorization: Bearer AAAA" \
   "https://www.services.renault-ze.com/api/vehicle/VVVV/air-conditioning"

This command does not return any value. There is also no way to cancel the command remotely - you have to physically enter the car and turn it off.

Precondition Later

If you know that you want to leave at a specific time, you can set the car to precondition at a set time.

curl \
   -H "Authorization: Bearer AAAA" \
   -H 'Content-Type: application/json;charset=UTF-8' \
   --data-binary '{"start":"1753"}' \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/air-conditioning/scheduler'

As far as I can tell, the start time is when you want the conditioning to start - not when you want it to be finished.

There is no way to cancel a precondition.

Preconditioning Last Status

Want to see if the preconditioning message was received by the car correctly?

curl \
   -H "Authorization: Bearer AAAA" \
   "https://www.services.renault-ze.com/api/vehicle/VVVV/air-conditioning/last"

This returns information about who or what sent the request:

{
    "date": 1476538293000,
    "type": "USER_REQUEST",
    "result": "SUCCESS"
}

Preconditioning History

You can also see how often your car has been preconditioned.

curl \
   -H "Authorization: Bearer AAAA" \
   https://www.services.renault-ze.com/api/vehicle/VVVV/air-conditioning?begin=1016&end=1016
[{
    "date": 1476165377000,
    "type": "USER_REQUEST",
    "result": "ERROR"
}, {
    "date": 1476079325000,
    "type": "CAR_NOTIFICATION",
    "result": "ERROR"
}, {
    "date": 1476079270000,
    "type": "USER_REQUEST",
    "result": "SUCCESS"
}, {
    "date": 1476079266000,
    "type": "CAR_NOTIFICATION",
    "result": "SUCCESS"
}]

Start Charging

You may have set your Zoe only to charge at specific times - perhaps to take advantage of cheap rate electricity. You can override this by issuing the charge command.

curl \
   -H "Authorization: Bearer AAAA" \
   https://www.services.renault-ze.com/api/vehicle/VVVV/charge

Again, this won't return a response. If your battery cannot be charged, you'll be notified via email or SMS depending on the preference you set up when you registered.

Charging History

curl \
   -H "Authorization: Bearer AAAA" \
   https://www.services.renault-ze.com/api/vehicle/VVVV/charge/history?begin=1016&end=1016

The begin and end take MMYY as their arguments. That is, if you want October 2016 you need to use 1016.

This returns an array, the most recent charging session at the top.

[{
    "date": 1476538527000,
    "type": "START_NOTIFICATION",
    "charging_point": "SLOW",
    "charge_level": 99,
    "remaining_autonomy": 119
}, {
    "date": 1476472727000,
    "type": "END_NOTIFICATION",
    "charging_point": "INVALID",
    "charge_level": 100,
    "remaining_autonomy": 124
}, {
    "date": 1476462129000,
    "type": "START_NOTIFICATION",
    "charging_point": "ACCELERATED",
    "charge_level": 34,
    "remaining_autonomy": 42,
    "remaining_time": 10500000
}]

The remaining_autonomy is, again, the range in Km. The remaining time is expressed in milliseconds. So 10500000 is the equivalent of 2 hours and 55 minutes.

Notifications

You can use the website to set up notifications. For example, if there is a problem with your charge, Renault will send you an SMS. This API call lets you see what notifications you have set up.

Set Notifications

curl \
   -H "Authorization: Bearer AAAA" \
   -X PUT \
   -H 'Content-Type: application/json;charset=UTF-8' \
   --data-binary '{"battery_status":"EMAIL","charge_start":"SMS","charge_end":"SMS","charge_problem":"SMS","low_battery":"SMS","low_battery_reminder":"SMS","do_not_disturb":null}' \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/settings/notification'

You can change any of the options with EMAIL or SMS.

You can set a "do not disturb" option. This will suppress all notifications during specific times. Sadly, this is a fairly blunt instrument - you can only set one time which then is enforced every day.

In the above example, change "do_not_disturb":null to

"do_not_disturb":{"start":"1710","end":"1811"}}'

This will give you peace between 5:10pm and 6:11pm.

See Notifications

You can use the website to set up notifications. For example, if there is a problem with your charge, Renault will send you an SMS. This API call lets you see what notifications you have set up.

curl \
   -H "Authorization: Bearer AAAA" \
   https://www.services.renault-ze.com/api/vehicle/VVVV/settings/notification

This returns:

{
    "battery_status": "EMAIL",
    "charge_start": "NONE",
    "charge_end": "SMS",
    "charge_problem": "SMS",
    "low_battery": "SMS",
    "low_battery_reminder": "SMS",
    "do_not_disturb": null
}

Charging Times

The Zoe's charging calendar is, sadly, crap. You can say "charge between these times" but you can only have one schedule per day. So if you only want the car to charge between 0300-0700 and 1800-2200 on Mondays - you're out of luck.

It also seemed to force me to set a schedule for every day.

This is a multi-stage process.

Create a schedule

In this example, I'm setting the charging to be active on Monday from 0100 for 1 hour and 15 minutes.
All other days start at different times, but last only for 15 minutes.
All start times must be at 00, 15, 30, 45 minutes. All durations must be in increments of 15 minutes.

curl \
   -H 'Authorization: Bearer AAAA' \
   -X PUT \
   --data-binary '{"optimized_charge":false,"mon":{"start":"0100","duration":"0115"},"tue":{"start":"0200","duration":"0015"},"wed":{"start":"0300","duration":"0015"},"thu":{"start":"1600","duration":"0015"},"fri":{"start":"1900","duration":"0015"},"sat":{"start":"1400","duration":"0015"},"sun":{"start":"1200","duration":"0015"}}' \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/charge/scheduler/offboard'

View the schedule

Let's make sure the schedule has been sent correctly

curl \
   -H 'Authorization: Bearer AAAA' \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/charge/scheduler/onboard'

Returned - hopefully! - is the schedule:

{
    "enabled": false,
    "schedule": {
        "mon": {
            "start": "0100",
            "duration": "0115"
        },
        "tue": {
            "start": "0200",
            "duration": "0015"
        },
        "wed": {
            "start": "0300",
            "duration": "0015"
        },
        "thu": {
            "start": "1600",
            "duration": "0015"
        },
        "fri": {
            "start": "1900",
            "duration": "0015"
        },
        "sat": {
            "start": "1400",
            "duration": "0015"
        },
        "sun": {
            "start": "1200",
            "duration": "0015"
        }
    }
}

Deploy the schedule

Be default, the schedule isn't activated. It needs to be "deployed" in order to send it to the car.

curl \
   -H 'Authorization: Bearer AAAA' \
   -X POST \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/charge/scheduler/offboard/deploy'

Deactivate the schedule

If you deactivate the schedule then the car will charge whenever it is plugged in.

curl \
   -H 'Authorization: Bearer AAAA' \
   -X PUT \
   --data-binary '{"enabled":false}' \
   'https://www.services.renault-ze.com/api/vehicle/VVVV/charge/scheduler/onboard'

That's all folks?

There are a few other API calls - mostly around registering and removing vehicles, and updating personal details. I've not detailed these because I didn't want to test them with my live account.

What's Missing?

Sadly, the Renault API is quite poor compared to BMW's API. Here's what I'd love to see:

  • Vehicle status - doors locked, headlights on.
  • Efficiency - last journey, total.
  • Mileage.
  • Physical location.

The End Result

Further Reading

A living copy of this documentation is available on my GitHub account.


Share this post on…

34 thoughts on “Reverse Engineering the Renault Zoe API”

  1. Kent says:

    I used your guide to make some munin-graphs for my car, pulling data from the renault website every 30 minutes (since the info only updates every 30 minutes), but after running for one night, I notice the token is changing. Any way to get around this, or do I need to keep updating the token as well?

    Reply
    1. Terence Eden says:

      I just kept updating the token. Before every call I request a new one. Doesn't take much time.

      Reply
      1. Kent says:

        Cheers, I'll need to modify my script accordingly then. I just hardcoded the token, hoping that it would not change.

        Reply
  2. Hi, I'm developing an app but I've seen that the preconditioning request responds with a 500 internal server error.
    Does the preconditioning API still works for you? It could be that I've implemented something wrong but I've no way to tell.

    Reply
      1. Dario Mantegazza says:

        I've made it work. I get a 202 Accepted when I tell it to preheat. I've to test it more to check if it actually works. Thanks

        Reply
        1. Martin says:

          How did make it work ? When I send "/api/vehicle/"+vin+"/air-conditioning" I get {u'timestamp': 1498469572731, u'message': u'java.lang.NullPointerException', u'code': -292571559}

          Reply
          1. Michael says:

            You have to add the following to your curl "-X Post" to get it working. Got the same error in my first try.

            Reply
  3. Peter says:

    Many thanks for this work. I have reproduced some of this in Perl – my particular need is to do preconditioning schedule and to ensure that charging keeps the battery level less than 80% and above a minimum based on the day of the week.

    All works fine. My only issue is that deploying the schedule returns
    503 Service Unavailable
    However it is still deployed. Do others get the same result?

    Reply
    1. @edent says:

      That's an interesting idea, I presume to extend longevity? You almost certainly don't need to do this. The BMS (battery management system) does this for you. Your battery already has around 20% reserved.

      Reply
  4. Peter says:

    Thanks for the quick reply ... Smart charging times was probably just an excuse to get into the API! I had understood that to keep between 20% and 80% would help battery life - but must admit that online advise seems mixed on these issues. Scheduling preconditioning is useful; we precondition three days a week at the same time each morning, so this way it does not rely on memory.

    By the way doing https://www.services.renault-ze.com/api/vehicle/VVVV/air-conditioning/scheduler using method of GET, rather than POST returns the current schedule.

    Certainly not the best of APIs and annoying that there isn't access to more data ....

    Reply
  5. Bård says:

    Hello! Is the preconditioning still working for you? I can’t make it work. I can get the battery status, but the preconditioning doesn’t start.

    Reply
    1. Dario Mantegazza says:

      I Couldn't make it work from the beginning.
      I'm worried that renault has somehow blocked that funcitonality as server level.

      Reply
  6. mickeypeach says:

    I’m going to be a total newbie here, but how do you run this code ? what do you use to run it ? I tried command prompt and it keeps coming back with
    curl \ -H “Content-Type: application/json” \ -X POST \ -d ‘{“username”:”*****@gmail.com”,”password”:”*****”}’ \ https://www.services.renault-ze.com/api/user/login`
    curl: (6) Could not resolve host: \
    curl: (6) Could not resolve host: \
    curl: (6) Could not resolve host: \
    curl: (6) Could not resolve host: \
    {“code”:403850,”message”:”com.worldline.renault.myzeonline.exception.InvalidAuthenticationException”,”timestamp”:1529873009563}
    I tried Python and that’s full of syntax errors.
    Sorry to a be a dumb ass.

    Reply
  7. Simon Webb says:

    Hi, being really silly where does the token and vin number sit in the curl code?

    curl \
    -H "Authorization: Bearer AAAA" \
    "https://www.services.renault-ze.com/api/vehicle/VVVV/battery"

    ///////

    Is like this?

    curl \
    -H "Authorization: Token VIN" \
    "https://www.services.renault-ze.com/api/vehicle/VVVV/battery"

    Many thanks

    Simon

    Reply
    1. @edent says:

      Hi Simon,

      To get your access token an VIN, first do this:

      curl \
         -H "Content-Type: application/json" \
         -X POST \
         -d '{"username":"you@example.com","password":"P4ssw0rd"}' \
         https://www.services.renault-ze.com/api/user/login`
      

      You will need to put in your actual username and password.

      That will give you a token and a VIN. Let's say the token is ABCDE (it will be much longer) and your VIN is 12345.

      Then do:

      curl \
         -H "Authorization: Bearer ABCDE" \
         "https://www.services.renault-ze.com/api/vehicle/1235/battery"
      

      You will need to replace ABCDE with your real token and 12345 with your real VIN.

      Good luck!

      Reply
  8. Detlef says:

    Hi. i am from Germany (sorry for my bad english). I want to use it from my Windows 10 PC. Curl is installed.
    But every time it answered with: {"code":403850,"message":"com.worldline.renault.myzeonline.exception.InvalidAuthenticationException","timestamp":1551277938305}
    But my username and password are ok. I think the given syntax for curl under Windows is wrong.
    Do you have an idea?

    Reply
    1. says:

      I'm sorry - I do not have this car anymore, and I don't user Windows. Hopefully someone else will know what to do.

      Reply
  9. Filipe says:

    Hello All, The Renault ZE API changed. There is a new API but its not "public" yet, unfortunately. Its called "My Renault"!

    Reply
    1. Chris says:

      Hi,
      I got the same issue as Detlef, the same response... Is it because the old API isn't available anymore? And do you know more about the new API "My Renault"?
      Best,
      Chris

      Reply
  10. Jörg says:

    Hi Terence,
    many thanks for your work and making this public. I find it well written and easy to use, great fun.
    I added my ZOE to iobroker (home automation) and, today, i created a IOS shortcut to start the AirCon with just one tap, or when attached to Siri, using a voice command.

    I am intenting to publish the IOS short cut.
    Would you mind if i put this webpage in there as a reference?

    Thanks again
    Jörg

    Reply
  11. Filipe says:

    @Chris, All
    Unfortunately, dont now much about new API. I tried to reverse engineer the android app, found some baseUrl and discover how to request the ZOE status successfully, by exploiting a bug in IOS app version, but I still dont know how to authenticate and get the authorisation token (bearer) (without it nothing can be done). I searched web for any help but no luck. So far i am stuck on how to get the authorisation bearer. 🙁

    Reply
  12. Giuliano says:

    May i ask you at who will read this message one thing about what and how renault will take data from driving a Zoe around with a leased battery?
    What they share?
    Location GPS? Speed of the vehicle? Accelleration/deceleration? Amps drow from the battery or regain from the regen?
    Balance value? Voltages?

    I'm asking this just because I would like to know if I hack the Zoe to be some sort of backup generator so the battery will be drained from other source so not the main drive unit.

    Sound silly but I just would like to know if the bms or any control or monitor of the battery will freak out if this occur (an external source of energy need..)

    Imagine to go to the battery and physically connect the 400v battery to 220v inverter and get this way energy back from the battery to power other stuff.

    Renault will notice that? They will void the lease/get back to me in some way?

    Reply
    1. says:

      You do not own the battery. I suspect you will void your lease if you do this. The battery is not designed to be directly connected to your home energy supply. Renault do have a Vehicle To Grid platform which is designed to use the battery to power your home. Chat to them about it.

      Please don't attach your own wires to the car. You will hurt yourself.

      Reply
  13. giuliano bordoniia says:

    Hi, thanks for your reply.
    I know I will void the lease if I modify the battery, but I would like to know if they can detect wireless any malfunctions of intrusion in the system.

    I mean what information is shared during operation with the renault?

    Reply
    1. says:

      As the API shows, Renault can monitor the state of their battery. If you modify their vehicle, or damage it, they will probably know.

      Reply
      1. Richie says:

        Has Renault services changed their site ? Non of the links work. Thanks

        Reply
        1. @edent says:

          This blog post is 7 years old. I assume Renault have changed things since then.

          Reply

What links here from around this blog?

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">