{{ leftover_code }}


Reverse-engineering a SimpliSafe API

Note: All information below was gathered by sniffing network traffic between the SimpliSafe mobile application and the web using Charles Proxy. No information was provided by SimpliSafe.

Background

I purchased a SimpliSafe alarm system and I've been very happy with it in general. The equipment was reasonably priced and easy to install, and the no-contract monitoring is reliable.

The big disappointment, however, has been with their iPhone application. It's nothing more than a mobile website wrapped with PhoneGap. It's clunky to use and constantly requires me to enter my login credentials. Having to constantly re-enter my username and password defeats the convenience of using the app.

I asked on their forums if they have plans to release a native iOS application but didn't get a positive response. I also asked if there were any plans to create an API for developers and got a flat "no" for a response.

Objectives

I wanted to create my own native iOS application that was visually appealing and would stay logged in. I also wanted to create Python scripts so that I can arm the alarm with voice commands on my Ubi.

All the examples below are written with cURL. They should be easily translated into your programming language of choice.

Sniffing the Traffic

I decided to fire up Charles Proxy and watch the network traffic between the app and SimpliSafe's servers. I was pleased to see that all the communications are done over HTTP with JSON responses.

The Login

The first network call I found was the login. It posts a username and password to the login URL: https://simplisafe.com/mobile/login/

HTTP POST parameters:

$ curl -X POST -c cookies.txt -d 'name=me@fake.com&pass=fakepass&device_name=my_iphone&device_uuid=51644e80-1b62-11e3-b773-0800200c9a66&version=1200&no_persist=1&XDEBUG_SESSION_START=session_name' https://simplisafe.com/mobile/login/

A successful login will get back a JSON response like this: (pretty-printed here for better readability)

{
    "return_code": 1,
    "session": "5e550f797d225ed807d6f395a6533f1e",
    "uid": "12345",
    "username": "me@fake.com"
}

A return_code of 0 indicates a failed login.

Login Cookies

Passing the -c cookies.txt parameter to the curl command will save the cookies from the HTTP response to a file called cookies.txt. The file will look something like this: (I modified the values to protect my credentials)

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

simplisafe.com  FALSE   /       FALSE   1410496182      vid     6921507
simplisafe.com  FALSE   /       FALSE   1410496182      sid     b20a9ed63d551c237c566731ec65f139
#HttpOnly_.simplisafe.com       TRUE    /       FALSE   1410496182      SESS1b361eg11731czc1408a3ba712e086e9    f21z7fa23d281x336d232014fd33e112
.simplisafe.com TRUE    /       FALSE   0       DRUPAL_UID      89102

The cookie keys are vid, sid, SESS1b361eg11731czc1408a3ba712e086e9, and DRUPAL_ID.

I had trouble parsing these values in Python, it was throwing errors about an invalid key. I ended up having to parse them manually and recreate the Cookie HTTP response header by hand.

Getting Your Location Information

Once you log in, you have the information you'll need to make the next call to the location URL: https://simplisafe.com/mobile/<UID>/locations

Note: You will need to replace <UID> with the uid value you got in the login response.

HTTP POST parameters:

We pass the -b cookies parameter to the curl command to use the cookie file we created.

$ curl -X POST -b cookies.txt -d 'no_persist=1&XDEBUG_SESSION_START=session_name' https://simplisafe.com/mobile/12345/locations

A successful request will return a response similar to this:

{
    "num_locations": 1,
    "locations": {
        "98765": {
            "street1": "123 Fake Street",
            "street2": "",
            "city": "Lawrence",
            "state": "Kansas",
            "postal_code": "66044",
            "s_status": "20",
            "system_state": "Off"
        }
    }
}

Hopefully the address information matches your location. The important piece of info we need is the location ID, 98765 in the example response. You can also see the current system status in the system_state property. (Off in the example response above)

Note: I only have a single location, so I don't know for certain what a response will look like with multiple locations. I have every reason to believe the num_locations property will reflect the number of locations and the locations property will have multiple keys.

I don't have any information about the purpose of the s_status property or what the value 20 represents. If you have any ideas, please let me know!

Changing the State of the Alarm (home, away, off)

Finally, we are getting to the good stuff! Now that we have a location identifier, we can manipulate the state of the system by calling the URL: https://simplisafe.com/mobile/<UID>/sid/<LID>/set-state

Note: Replace <UID> with your user ID and <LID> with your location ID.

We can set three possible states: home, away, and off. Use lower-case values.

HTTP POST parameters:

$ curl -X POST -b cookies.txt -d 'state=home&mobile=1&no_persist=1&XDEBUG_SESSION_START=session_name' https://simplisafe.com/mobile/12345/sid/98765/set-state

A successful request will return a result like this:

{ "result": 4 }

The numeric value for the result key will correspond to the state you sent:

Getting Recent Events

You can obtain a list of the ten most recent events by calling the URL: https://simplisafe.com/mobile/<UID>/sid/<LID>/events

Note: Replace >UID< with your user ID, >LID< with your location ID.

HTTP POST parameters:

$ curl -X POST -b cookies.txt -d 'no_persist=1&XDEBUG_SESSION_START=session_name' https://simplisafe.com/mobile/12345/sid/98765/events

A successful request will return you a list of events like this:

{
    "events": {
        "return_code": 1,
        "events": [{
            "event_time": "11:27pm",
            "event_desc": "System Armed (home mode)",
            "event_date": "09/12/13"
        }, {
            "event_time": "7:00am",
            "event_desc": "System Disarmed",
            "event_date": "09/12/13"
        }, {
            "event_time": "10:27pm",
            "event_desc": "System Armed (home mode)",
            "event_date": "09/11/13"
        }, {
            "event_time": "4:50pm",
            "event_desc": "Automatic Test",
            "event_date": "09/11/13"
        }, {
            "event_time": "7:00am",
            "event_desc": "System Disarmed",
            "event_date": "09/11/13"
        }, {
            "event_time": "10:58pm",
            "event_desc": "System Armed (home mode) 62VX4 "Bedroom Keypad"",
            "event_date": "09/10/13"
        }, {
            "event_time": "7:00am",
            "event_desc": "System Disarmed",
            "event_date": "09/10/13"
        }, {
            "event_time": "12:19am",
            "event_desc": "System Armed (home mode) 62VX4 "Bedroom Keypad"",
            "event_date": "09/10/13"
        }, {
            "event_time": "9:59am",
            "event_desc": "System Disarmed: Keypad Master PIN",
            "event_date": "09/09/13"
        }, {
            "event_time": "9:58am",
            "event_desc": "System Armed (home mode) 22J84 "Kitchen Keypad"",
            "event_date": "09/09/13"
        }]
    }
}    

Logging Out

While it may not be strictly necessary, it's a good idea to clean up after ourselves and log out of the system with the URL: https://simplisafe.com/mobile/logout

HTTP POST Parameters

$ curl -X POST -b cookies.txt -d 'no_persist=1&XDEBUG_SESSION_START=session_name' https://simplisafe.com/mobile/logout

A successful logout will return this response:

{ "return_code": 1 }

Note: Once you log out, you will not be able to use the cookie.txt file we created earlier.


Comments

blog comments powered by Disqus