Refresh token - Invalid grant_type parameter or parameter missing

MG

Hello,

I'm trying to manage my Bubendorf rollers from a Tasmota Berry script and with curl
When using the token I generated in the Netatmo app, it works fine (I can for instance open/close a shutter), both with Berry and with curl,...but during 3 hours only.

When trying to refresh the token (before the access token has expired), I always get this error : {"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

Here is the curl request (XXXXXXXX is the refresh token, YYYYYYY is client_id and ZZZZ is client_secret, all gotten in the Netatmo app)

curl  -X POST https://api.netatmo.com/oauth2/token -H "Content-Type: application/json" -d '{"grant_type":"refresh_token","refresh_token":"XXXXXXXX","client_id":"YYYYYYYY","client_secret":"ZZZZ"}'

I also tried with -H "Content-Type: application/x-www-form-urlencoded" but it does not make any difference

Here is the equivalent Berry code

cl = webclient()
cl.begin('https://api.netatmo.com/oauth2/token')
cl.add_header('Content-Type', 'application/json')
r = cl.POST('{"grant_type":"refresh_token","refresh_token":"XXXXXX","client_id":"YYYYYYY","client_secret":"ZZZZZZZ"}')
print('Refresh token - Result code: ',r)
s = cl.get_string()
print(s)

I also tried to pass the parameters in the URL, not in the body, but doesn't work either

curl -X POST "https://api.netatmo.com/oauth2/token?grant_type=refresh_token&refresh_token=XXXXXXXX&client_id=YYYYYYYY&client_secret=ZZZZZZZZZ" -H "Content-Type: application/x-www-form-urlencoded" -H "Content-Length:0"

Also tried with SoapUI but always same issue.

What's wrong ?
I looked at the other "Invalid grant_type" posts but could not find any solution to my problem
You might not know Berry but if I could make it work with curl I could certainly make it work with Berry too

Thank you

 

0

Comments

7 comments

  • Comment author
    mailpublic35
    • Edited

    Hello,
    I'm just a user, may be @Leslie the community manager will go there in a short time.
    She exchanged a lot on this thread: https://helpcenter.netatmo.com/hc/fr/community/posts/23896792864658-API-homesdata-and-homestatus
    It was very helpful for me.

    I create php script to manage token automaticaly (via crontab in my case), If it can help you, have a look there: https://github.com/Phil353556/netatmo-manage-tokens

    Phil

    0
  • Comment author
    MG

    Hello Phil,

    Thank you for your reply.
    I had already had a look on the post you mentioned and also to your php script but unfortunatly it didn't help me.
    Have you been able to refresh the token from curl Windows command (in command prompt) ? If yes, could you please share the syntax you used and in particular if you passed the parameters in the URL or in the body and how you entered the strings (with " or ' or \" or \' or a mix) ?
    I suspect, without being sure, that the '|' in the middle of the refresh token value is misinterpreted by curl (on Windows) and Berry.
    Not all languages handle strings the same way.

    0
  • Comment author
    mailpublic35

    Hello,

    I'm really sorry.
    I don't use windows anymore since decades. I only use linux (ubuntu on PC and Debian GNU/Linux on raspberry pi).
    May be others persons who will read, can help you?
    Phil

    0
  • Comment author
    nono303
    • Edited

    Hi,
    @Phil, many Thx for netatmo-manage-tokens! It works like a charm ;)
    @martin.gailly, here is the working cURL cmd line for refresh token on Windows (verified under PowerShell 7.5 & cURL 8.13, -v only for verbose output...)

    PS> curl -v https://api.netatmo.com/oauth2/token -F "grant_type=refresh_token" -F "refresh_token=rt*************************************" -F "client_id=ci*************************************" -F "client_secret=cs*************************************"

    * Host api.netatmo.com:443 was resolved.
    * IPv6: 2620:1ec:bdf::76
    * IPv4: 13.107.246.76
    *   Trying 13.107.246.76:443...
    * schannel: disabled automatic use of client certificate
    * ALPN: curl offers h2,http/1.1
    * ALPN: server accepted h2
    * Connected to api.netatmo.com (13.107.246.76) port 443
    * using HTTP/2
    * [HTTP/2] [1] OPENED stream for https://api.netatmo.com/oauth2/token
    * [HTTP/2] [1] [:method: POST]
    * [HTTP/2] [1] [:scheme: https]
    * [HTTP/2] [1] [:authority: api.netatmo.com]
    * [HTTP/2] [1] [:path: /oauth2/token]
    * [HTTP/2] [1] [user-agent: curl/8.13.0-DEV]
    * [HTTP/2] [1] [accept: */*]
    * [HTTP/2] [1] [content-length: 608]
    * [HTTP/2] [1] [content-type: multipart/form-data; boundary=------------------------Kov7IYnLYU32d9SVHIxcX0]
    > POST /oauth2/token HTTP/2
    > Host: api.netatmo.com
    > User-Agent: curl/8.13.0-DEV
    > Accept: */*
    > Content-Length: 608
    > Content-Type: multipart/form-data; boundary=------------------------Kov7IYnLYU32d9SVHIxcX0
    >
    * upload completely sent off: 608 bytes
    * schannel: remote party requests renegotiation
    * schannel: renegotiating SSL/TLS connection
    * schannel: SSL/TLS connection renegotiated
    * schannel: remote party requests renegotiation
    * schannel: renegotiating SSL/TLS connection
    * schannel: SSL/TLS connection renegotiated
    < HTTP/2 200
    < date: Fri, 11 Apr 2025 13:36:18 GMT
    < content-type: application/json
    < cache-control: no-store
    < x-azure-ref: 20250411T133618Z-*************************************
    < x-cache: CONFIG_NOCACHE
    <
    {"access_token":"at*************************************","refresh_token":"rt*************************************","expires_in":10800,"expire_in":10800,"scope":[sc*************************************]}
    * Connection #0 to host api.netatmo.com left intact

    0
  • Comment author
    MG

    Eureka !!!
    After many many tries, I finally figured out how to make it work / the syntax to use.
    The paramaters have to be passed in the body (not as URL parameters), as string (not Json), and with a '&' between each parameter 

    In Berry that makes :
    var url_token = "https://api.netatmo.com/oauth2/token"
    var post_data = "grant_type=refresh_token" + "&refresh_token=" + refresh_token + "&client_id=" + client_id + "&client_secret=" + client_secret
    cl = webclient()
    cl.begin(url_token)
    cl.add_header('Content-Type', 'application/x-www-form-urlencoded')
    r = cl.POST(post_data)

    If I may, the documentation is not very clear….

    1
  • Comment author
    mailpublic35

    Hello,
    Good to know you found the solution!
    Phil

    0
  • Comment author
    mailpublic35

    Hello @nono303,

    Really happy to know that the script can help you, it was the goal of sharing such script  :-) 
    Thanks
    Phil

    0

Please sign in to leave a comment.