πŸ“˜

Access to our APIs is evaluated on a case-by-case basis. To find out if your use case is one that we support feel free to get in touch with the details of your project. [email protected].

OAuth2 is a protocol that allows external applications to act on behalf of Litmus users without the user having to reveal their Litmus username, password or API key, instead the user grants permissions to an application.

Litmus currently supports the OAuth2.0 Web Application Flow (also known as "Authorization Code Grant" flow).

Worked example

A minimal example of a partner app is available which can be used to walk through the flow using your own Litmus account. The source for this is also provided.

Before you start

  1. Contact [email protected] to request a new API application.
    You'll need to provide us:

    • application name
    • OAuth callback URI β€” whitelist a URI within your application that will handle exchanging an authorization code for a token (must be HTTPS, multiple can be provided)
  2. In return we'll provide you:

    • client_id
    • client_secret (must be kept private)

The Web Application Flow

1. Redirect the user to request authorization to access Litmus

GET https://litmus.com/oauth/authorize?
      response_type=code&
      client_id=XYZ&
      redirect_uri=https://yourapp.com/oauth/litmus/callback&
      state=xxxxxxxx&      # nonce (this should be a random unguessable string)
      scope=full

When logged in to Litmus, the user will be presented with your authorization request, eg

πŸ“˜

A user is only asked to authorize your application once. If you later repeat the flow (eg to get a new token after the last had expired) we skip to the next step, so later token requests should generally be invisible to your user. Because the Litmus session could end it's generally preferable to first try using a refresh token for this purpose.

2. Litmus redirects the user back to your application with a temporary code

Assuming the user authorizes your request, Litmus will send a temporary code to your redirect uri (along with relaying the state param which you provided, which should be checked to avoid cross site request forgery):

GET https://yourapp.com/oauth/litmus/callback?code=ABCD...&state=xxxxxxxx

If the user does not approve the request you'll instead receive an error:

GET https://yourapp.com/oauth/litmus/callback?error=access_denied

Because the request is made from the context of the end user's browser, their existing session with your web application should be used to tie this request back to them.

3. Exchange the code for an access token

Your application server should POST using its client_secret and the code to obtain a token:

POST https://litmus.com/oauth/token

JSON Post body parameters:

FieldDescription
client_idrequired

The client ID you received from Litmus
client_secretrequired

The client secret you received from Litmus
coderequired

The code you received in the previous step
redirect_uriThis must match redirect_uri provided in step 1, it should be omitted if this was not provided there
grant_typerequired

This must be authorization_code

JSON Response body

{
  "access_token": "XYZ",
  "expires_in": 7200,     // The remaining lifetime of the token in seconds
  "token_type": "Bearer"  // The token type, currently always Bearer

  // More fields may be provided
}

Like your client_secret the token should be stored securely.

4. Call Litmus API methods passing the token

Make authenticated calls to our APIs from your application server using the HTTP Authorization header:

$ curl -X "POST" "https://instant-api.litmus.com/v1/emails" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer a66841f0a212c0afb6344c6377df4dde0389922511540d9e3c1d11e2ab811a2e"\
       -d "{\"plain_text\":\"Hello World\"}" -v

> POST /v1/emails HTTP/1.1
> Host: instant-api.litmus.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Authorization: Bearer a66841f0a212c0afb6344c6377df4dde0389922511540d9e3c1d11e2ab811a2e
> Content-Length: 28
>

< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 21 Jun 2016 20:10:06 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 58
< Connection: keep-alive
< Strict-Transport-Security: max-age=3600; includeSubdomains; preload
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
<

{
  "email_guid": "113bdfdf-6d54-4cbe-8d38-dd66157e1751"
}

Scopes

Currently only one scope, full ("Use all Litmus features on your behalf") is currently provided (this is also the default when none is specified).

Token expiration and refresh

Token expiry should be anticipated (the default token time-to-live is 2hrs, but this may change).

Refresh tokens are supported and are the recommended approach to obtaining a new bearer token. Restarting the flow above will also issue a fresh token where the current litmus user has authorized your application already.

Token revocation

Token revocation should also be anticipated and handled gracefully by restarting the flow.

Libraries

A list of battle tested client libraries for simplifying integration can be found on the OAuth project site.

For integrating with ruby applications we also provide an omniauth-litmus strategy.