OAuth2

The Media and Content APIs support OAuth2 bearer authentication. You can obtain a client_id and client_secret here, which you can use to issue access tokens, either using the regular Authorization Code Grant (for web apps), Implicit Grant (for single-page web apps) or Password Grant (server-side apps).

Endpoints

We support the following endpoints:

Name URL
authorization endpoint https://tt.se/o/oauth2/auth
token endpoint https://tt.se/o/oauth2/token
user endpoint https://tt.se/o/v2/user

Scopes

We define the following scopes, which determine which user information fields are exposed to the holder of the access_token. For API access to work, the token need to be issued with at least roles scope.

Scope Description
email Include email, the user email address.
roles Include roles, an array of role names assumed by the user.
user Include the user-specific fields name, family_name and given_name and user_id (if available)
customer Include the customer-specific fields customer_id, customer_name and department (if available)
profile Allow access to view and update user profile.
collection Allow access to view and update user collections.
admin Allow access to the organization user admin endpoints, provided the user has user admin privileges.

Do note that the while profile and collection scopes are implemented in the OAuth2 service, there are currently no APIs that use them. There are plans to change the endpoints api.tt.se/content/v1/profile and api.tt.se/content/v1/collection to require these scopes in the future.

Roles

We define the following well-known user roles.

Name Meaning
ROLE_TT User is a TT employee.
ROLE_OFP User is a TT customer.
ROLE_MEDIEBANK User has access to the Mediabank.

Client ID and secrets

The Client ID is a non-secret string that identifies an app or integration. It is paired with a Client Secret, both of which are necessary for issuing access_tokens.

Manage your Client ID/Secret here.

Issuing access_tokens

OAuth2 offers several ways for clients to obtain an access_token. Developers writing integrations running as a single user will probably use Password Grant.

A sample call using curl looks like this:

curl -XPOST -d username=<username> \
  -d password=<password> \
  -d client_id=<client_id> \
  -d client_secret=<client_id> \
  -d grant_type=password \
  -d scope="roles"
  https://tt.se/o/oauth2/token
  • username and password should be the regular TT login credentials.
  • client_id is the (non-secret) client ID issued by TT.
  • client_secret is the client secret issued by TT.
  • scope is a space-separated list of scope names (see above). It needs to include roles for API access to work; the other scopes are optional.

You will get a JSON result like this:

{
  "access_token": "a.n2Oc_XqcuBqe5RjLtiEnasIoRyB62As6JxsmwVHAaxq7DMLqRm43Qe0qzPgh37nvJfaP8x1EWA6GNTRG0ibsj0ZlMGHo7ev27zLb_lNQEnk",
  "refresh_token": "r.4LyAp206TaQzeQTee1LvHyLmWSVvXeTM8IIIY__5BF9dLkpEXqbTMg",
  "expires_in": 2592000,
  "id_token": "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsImtpZCI6IjdDZjVqR2JuS2dLdUFYZElSeXpJdnRfaGYtOVZ1YmYyVzlBbHBUMzg1eWciLCJqa3UiOiJodHRwczovL3R0LnNlL28vb2F1dGgyL2NlcnRzIn0.eyJzdWI
iOiJmcmVkcmlrLmFwcGVsYmVyZyIsInNjb3BlIjoicm9sZXMiLCJyb2xlcyI6WyJST0xFX09GUF9BRE1JTiIsIlJPTEVfREVXQVJfU0VORCZVU0VSIiwiUk9MRV9ERVdBUl9VU0VSIiwiUk9MRV9JVERSSUZUIiwiUk9MRV9JVFVUViIsI
lJPTEVfU0dCIiwiUk9MRV9TQ0FOUElYIiwiUk9MRV9UVCIsIlJPTEVfQ09ORkxVRU5DRSIsIlJPTEVfREFTSEJPQVJEX0FETUlOIl0sImlhdCI6MTU2MjMxNjEwNSwibmJmIjoxNTYyMzE2MTA0LCJleHAiOjE1NjI5MjA5MDUsImF1ZCI
6WyJhb0pydXN2dF9QenZlNFhoazNwWFM5YzhwUDlOaUNrdmpIVnJ5eUphQWtBIl0sImlzcyI6Imh0dHBzOi8vdHQuc2UifQ.gKn90_M015Ue51GLisbf3Ezrij3PzcXZTTvnACVGn4FNO4NGlnjVKJgtVKFADIzgLiX-6EgOaJbQDrwrknapQptQUponAYrX39_Q1BCwF7OxQd0MCaevZesWj9dB3uSx",
  "token_type": "Bearer"
}
  • access_token is your access token. It should be passed al in the Authorization header when making API calls.
  • refresh_token can be used to generate new tokens after they expire.
  • id_token is a JWT object representing your user.

When exploring the API and using the examples in the Content API section it is conventient to export the token as an environment variable:

export TOKEN=a.n2Oc_XqcuBqe5RjLtiEnasIoRyB62As6JxsmwVHAaxq7DMLqRm43Qe0qzPgh37nvJfaP8x1EWA6GNTRG0ibsj0ZlMGHo7ev27zLb_lNQEnk

Refreshing access_tokens

The access_token is valid for 7 days. When it expires you can use the refresh_token to generate a new set of tokens without having to supply username and password:

curl -XPOST -d client_id=<client_id> \
  -d client_secret=<client_secret> \
  -d grant_type=refresh_token \
  -d refresh_token=<refresh_token> \
  https://tt.se/o/oauth2/token

Refreshing will invalidate the original access_token if it wasn't already expired.

Making authenticated requests

Once an access_token has been obtained, it can be used to make authenticated requests to the Media API and Content API by passing it in the HTTP Authorization header.

GET /content/v1/text/search HTTP/1.1
Host: api.tt.se
Authorization: Bearer a.n2Oc_XqcuBqe5RjLtiEnasIoRyB62As6JxsmwVHAaxq7DMLqRm43Qe0qzPgh37nvJfaP8x1EWA6GNTRG0ibsj0ZlMGHo7ev27zLb_lNQEnk

Verifying access_tokens

access_tokens can be verified by calling the user endpoint (see Endpoints above) with an Authorization header:

curl -H "Authorization: Bearer $TOKEN" https://tt.se/o/v2/user

If the token is valid, the call will return HTTP 200 and a JSON structure containing the fields defined by the scopes used to issue the token.

{                                                                                                                       "sub": "username",
  "scope": "roles profile email",
  "roles": [
    "ROLE_OFP",
    ...
  ],
  "name": "Firstname Lastname",
  "family_name": "Lastname",
  "given_name": "Firstname",
  "email": "user@domain.com"
}

If the token is invalid or has expired, tthe call will instead return HTTP 401 (Unauthorized).

OpenID Connect

We support OpenID Connect. The configuration can be found here.