Looks like the Great Firewall or something like it is preventing you from completely loading www.skritter.com because it is hosted on Google App Engine, which is periodically blocked. Try instead our mirror:

legacy.skritter.cn

This might also be caused by an internet filter, such as SafeEyes. If you have such a filter installed, try adding appspot.com to the list of allowed domains.

Authentication

Authentication is handled through OAuth 2.0. Generally speaking, your service, the client, directs the user to Skritter where they authorize your access to their data, and then information is redirected back to the client so you can fetch data through the API.

Quick Overview

OAuth is a way for you (the client) to get access to someone else's data (the user).

The recommended, and most secure, way of doing this is to send the user from your website to Skritter's. Our website checks with them to make sure they want to give you access, and if they agree, we redirect them back to your website with a code. Your client then immediately uses this code to get a token from our server which you then provide for any API request.

There are a few alternative paths to getting a token:

  • Have the user get redirected from Skritter's website back to yours with the token instead of the code. This is, however, less secure because the token is not passed back encrypted, and the user has access to it.
  • Get the password from the user, and submit it directly to Skritter's servers to get a token. If possible, avoid this one because the fewer people who have access to a person's password, the better. If you do use this, please do not store the user's password on your own servers. This, however, is usually a better solution for non-browser clients, such as mobile apps and desktop software.
  • Get a token with no specific user authorization. The API calls you make and data you receive is of course limited to data that's accessible to all Skritter users, but depending on your needs this may be the simplest solution.

Once you have a token, include it as the "bearer_token" parameter for any request, or in an HTTP header. That's all you need, going forward, as well as perhaps refreshing it once in a while to make sure you don't have to re-authenticate.

Important Terms

  • Client: You, you are the client. Or your software is.
  • User: The person whose account data you want to access.
  • Token: A string of text you get through authorization and that you provide with every API call
  • Code: A string of text you get through authorization that allows you to get a token.

Signing Up

Email team@skritter.com to create a 'client' account for Skritter. This is an otherwise normal account, except that when you log in you will be redirected to a client page where you can access your secret and change your client name, description, and redirect settings.

Obtaining Authorization

If you opt for the redirect method, send the user to this page. Responses will be returned based on the values passed in and the client redirect settings.

GET https://beta.skritter.com/api/v0/oauth2/authorize

Request

  • response_type
    required string, either 'code' or 'token'. A token can be used with the API immediately, whereas a code needs to be traded in for a token through a separate call. Using a code is more secure, if you have an independent server with which to fetch the token.
  • client_id
    required string, the username for the Skritter client account you created.
  • redirect_uri
    optional string, the URI to return authorization results to. If it does not match the setting for your client account, the authorization attempt will be rejected. If you have redirections turned off, this value is ignored. If redirections are on but your client account has no redirect URI set, this value is used, as long as it's a valid URI.
  • state
    optional string, which is returned unmodified as part of the response if provided, for client use.

Response

Note that this response is in the form of a GET request to the given (or default) redirect_uri

  • code
    string to be used separately by the client to fetch an access token from the server. Returned if response_type is 'code'.
  • access_token
    string to be used to fetch API results for the user by the client. Returned if response_type is 'token'.
  • refresh_token
    string that can be used by the client to receive a new access token with a later expiration date, rather than requiring the user to grant authorization repeatedly. Returned if response_type is 'token'.
  • expires_in
    integer time in seconds until this token is expired. Returned if response_type is 'token'.
  • token_type
    always 'bearer'. Returned if response_type is 'token'.
  • state
    unmodified value passed in by the client. Returned if a value was provided.
  • user_id
    User id for the logged in user.

Other OAuth Communications

This method is for all other authorization tasks which don't involve the user in the middle:

  • Obtaining an access token for an authorization code ('authorization_code')
  • Refreshing an existing access token ('refresh_token')
  • Authorizing with the user's password ('password')
  • Obtaining an access token for API calls that are not user-specific ('client_credentials')
GET or POST http://beta.skritter.com/api/v0/oauth2/token

Request

  • grant_type
    required string, 'authorization_code', 'refresh_token', 'password', or 'client_credentials'.
  • client_id
    required string, the username for the Skritter client account you created.
  • client_secret
    optional string, the secret you can obtain through your Skritter client account. This either needs to be provided as a parameter (POST requests only), or through HTTP headers. 'password' grant_type requests must always provide the client secret through HTTP headers. More about that described below.
  • redirect_uri
    required string if grant_type is 'authorization_code' and redirects are enabled for your client account. Is checked against the one set in your client account.
  • code
    required string if grant_type is 'authorization_code'. The value obtained through user authorization. Once exchanged, the code is invalid.
  • refresh_token
    required string if grant_type is 'refresh_token'.
  • username
    required string if grant_type is 'password'. Username for the user the client is fetching an access token for.
  • password
    required string if grant_type is 'password'. Password for the user the client is fetching an access token for.
  • callback
    optional function name that will receive the JSON formatted response.

Response

This is a normal JSON formatted response.

  • access_token
    string to be used to fetch API results for the user by the client. Returned if response_type is 'token'.
  • refresh_token
    string that can be used by the client to receive a new access token with a later expiration date, rather than requiring the user to grant authorization repeatedly. Returned if response_type is 'token'.
  • expires_in
    integer time in seconds until this token is expired. Returned if response_type is 'token'.
  • token_type
    always 'bearer'. Returned if response_type is 'token'.
  • user_id
    User id for the logged in user.
    (all but "client_credentials")
  • used_recovery
    true if grant_type was "password" and user used a recovery password

Passing Your Secret Through HTTP Headers

When you use the /token request, you need to provide your client secret one way or another. You can include it straight as a POST parameter, or you can include it encoded in an HTTP header. To encode client credentials, use Base64 to encode the string (client-name):(client-secret), then prepend 'basic: ' to that string.

Examples

Getting authorization via proxy (recommended for websites)


    # first redirect your user to https://beta.skritter.com/api/v0/oauth2/authorize
    # with the appropriate parameters.
    # upon their return to the redirect_uri given,
    # get the code from the GET parameter


    import json
    import urllib
    import urllib2

    url = 'https://beta.skritter.com/api/v0/oauth2/token'


    # the exact same redirect_uri that was used to get the code
    REDIRECT_URI = 'https://mysite.com/skritterapi/getcode'

    OAUTH_CODE = '8eac0f0300e0fb4aa11870055ad932'
    OAUTH_CLIENT_NAME = 'notherGuy'
    OAUTH_CLIENT_SECRET = '...' # get from client page

    params = {
        'grant_type':     'authorization_code',
        'client_id':      OAUTH_CLIENT_NAME,
        'client_secret':  OAUTH_CLIENT_SECRET,
        'redirect_uri':   REDIRECT_URI,
        'code':       OAUTH_CODE,
    }

    data = urllib.urlencode(params)
    request = urllib2.Request(url, data)

    response = urllib2.urlopen(request)
    packet = json.loads(response.read())
    print packet.get('access_token')
    

Logging in using a password (recommended for clients)


    from base64 import b64encode
    import json
    import urllib
    import urllib2

    url = 'https://beta.skritter.com/api/v0/oauth2/token'
    OAUTH_CLIENT_NAME = 'notherGuy'
    OAUTH_CLIENT_SECRET = '...' # get from client page

    USER_NAME = 'notherGuy'     # whose account you want access to
    USER_PASSWORD = '...'       # get from user input, don't store it

    params = {
        'grant_type':  'password',
        'client_id':   OAUTH_CLIENT_NAME,
        'username':    USER_NAME,
        'password':    USER_PASSWORD,
    }
    credentials = "%s:%s" % (OAUTH_CLIENT_NAME, OAUTH_CLIENT_SECRET)
    credentials = b64encode(credentials)
    credentials = "basic %s" % credentials

    data = urllib.urlencode(params)
    request = urllib2.Request(url, data)

    # urllib2 apparently prepends HTTP_, your mileage may vary
    request.add_header('AUTHORIZATION', credentials)

    response = urllib2.urlopen(request)
    packet = json.loads(response.read())
    print packet.get('access_token')
    

Security

Please be aware of security issues which depend on your specific client setup. Some key things to keep in mind:

  • Keep your client secret value as safe as possible, preferably only on your servers if you have them, and not on user devices.
  • If possible, do not give users access to the access token values. Use an authorization code to keep the access token only on client and Skritter servers.
  • Handle the user password as little as possible, preferably not at all. If you do handle the user's Skritter password to obtain a token, remove it from your system once you have the token and refresh it as needed. The fewer places a user has their password stored, the better.
  • Use only one redirect URI ever, and set it on your account, to prevent authorization info from being sent to anywhere else.