IT Nerd Space

How to authenticate to TP-Link cloud API

How to authenticate to TP-Link cloud API

This is breaking news! No need to hack into your phone’s backups any more to obtain the TP-Link token!

First you need to generate an UUID v4. You can open and pick the one they give you there (no need to create one every time, one is fine, just keep it). This will represent your Client Term ID (like the one of your Kasa App).

Now this is how you can authenticate to the TP Link cloud backend and obtain a token:

We have to do a POST request to, with the following payload:

 "method": "login",
 "params": {
 "appType": "Kasa_Android",
 "cloudUserName": "XXXXX",
 "cloudPassword": "XXXXX",
 "terminalUUID": "MY_UUID_v4"

In the payload, replace cloudUserName and cloudPassword with your TP-Link (or Kasa) credentials, and the terminalUUID with the one you got above.

Remember to pass the Header Content-Type: application/json as well.

No need to have any extra tool, you can simply try it with from your browser:

What you’ll get should look like this:

 "error_code": 0,
 "result": {
 "regTime": "2017-01-06 08:42:35",
 "email": "XXXXX",
 "token": "YOUR_TOKEN_HERE"

Isn’t that cool? Of course you can implement that in any language, Shell script with cURL, Python, Node.js,… Your token is response.result.token.

In a next post I’ll show how to do the same with Tasker! 😀

From here you can also have a look at this post: Get the end point URL and HS100 Device ID.

  • Thanks! This seemed to work for me without a UUID.. not sure if that’s a mistake on their end or it’s just not a necessary key

    • It seems you are right. I’ve tried with an empty UUID and it still works fine. But the “terminalUUID” field needs to be present in the payload thought, otherwise I get an error: {“error_code”:-20104,”msg”:”Parameter doesn’t exist”}.


    ps i created a simple PHP script that authenticates and grabs the specific info (token device ids etc) for you so you don’t have to keep doing it manually.

  • Ben Nikula

    Thanks for putting this together. When attempting to find my tp-link token, I get the error message “error_code”:-10100,”msg”:”JSON format error”. I built a request by pasting the template into

    curl -XPOST -H “Content-type: application/json” -d ‘{
    “method”: “login”,
    “params”: {
    “appType”: “Kasa_Android”,
    “cloudUserName”: “[email protected]”,
    “cloudPassword”: “complicatedPasswordWith$pecialCharacters”,
    “terminalUUID”: “d09fa2bb-26fc-4736-a7fb-525aa87a2c27”
    }’ ‘’

    If I enter in an incorrect password I get “error_code”:-20601,”msg”:”Password incorrect”, which leads me to believe I am almost getting this correct.

    Any Ideas?

    • HonoraryOrange

      Yeah I’m getting the same. Doesn’t work.

    • Do you have any “, ‘, /, or {} in your password? Maybe that could break the json, you would need to escape them. If that’s the case try a simpler password, just to validate the theory at least.

      • Ben Nikula

        I think that was it, actually! I escaped “/” and “”, and it worked. Thanks! Now onto the rest of the process…

  • JeremyH

    How long does a token last ? – I was away for a week and when I returned I had a problem where a script failed, I tested it in and got an “expired token” message, I tried Kasa, that controlled everything fine, so I came here to check for token and it gave me the same one I had before. Tried script again and everything works OK. Does anyone know if you need to access Kasa regularly or anything ?

  • Any idea how to do this locally instead of over the cloud? Sometimes my devices go offline for some reason!

  • Joe H

    Great work finding out how to get a token!
    I’m having a problem when I go to use the returned token though, always get: {“error_code”:-20651,”msg”:”Token expired”}
    When I use it.
    I’ve tried seeing whether there’s a time delay or something, but it doesn’t seem to matter how quick you are, it always says expired. Dunno whether having the Alexa skill connected makes a difference or something.
    Anyone else having the same problem?

    • Hum… I don’t have Alexa myself, so I can’t confirm. Others here might have it, hopefully they can help.

  • Richard

    I have 3 of these plugs so I switched 2 of them off at the wall I wasn’t sure how to identify the device ID for each plug. With a single plug switched on, I followed the instructions exactly on your post of how to control via IFTTT and tried basic triggers of email sent from Gmail/Contact added to Gmail just to test it but neither of these worked.

    Any idea what I could be doing wrong?

    EDIT: If I open the IFTTT app, the Activity shows ‘Usage limit exceeded’. If I click into the detail, it states ‘User Rate Limit Exceeded’

    • To easily identify the DevideID of each plug, within the Kasa app, give a name to each plug. Then use the method shown here to list all your devices. You’ll see the Alias and the corresponding Device ID of each plug.

      Regarding the rate limiting, I guess it’s something to do with IFTTT.

      • Richard

        Your other post describing how to get the list of devices gave me the correct device IDs and it is now working. Thank you for the quick reply!

        • Amazing Richard. I’m glad it worked for you. Enjoy your smartplugs.

  • Richard Nardone

    I created a script to get my token but I keep getting a format error.

    method: “login”,
    params: {
    appType: “Kasa_Android”,
    cloudUserName: “[email protected]”,
    cloudPassword: “SimplePasswordLettersandNumbers”,
    terminalUUID: “b6085622-86e0-4940-8fd3-4b60862de994”
    function(data,status) {
    }, “json” );

    The above code returns error:
    {“error_code”:-10100,”msg”:”JSON format error”}

    Anyone know what I’m doing wrong?

    • Try to force the header ‘Content-Type: application/json’, and remove the “json” you specified.

      • Richard Nardone

        The issue was using ajax shorthand ($.post). With shorthand you can’t specify the content-type. The “json” at the end of the code just specifies how you want the data result formatted (Accept Header). Once I updated the code to the following I was able to specify the content-type and retrieve the token without error:

        type: ‘POST’,
        contentType: “application/json”,
        url: myURL,
        data: myData,
        dataType: “json”,
        success: function(data, status) {

        My new result is:
        {“error_code”:0,”result”:{“regTime”:”2016-10-23 23:45:58″,”email”:”[email protected]”,”token”:”00xxx111-x1234b45cd6e7fghij89k0l”}}

        My “Success” data is being appended to DIV layers for testing purposes: