Authorization Code Flow (3-legged OAuth)

If your application needs access to information from a member's LinkedIn profile, use the Authorization Code Flow to request permission from the member. Before a REST API call can be made, any required permissions must first be granted by the LinkedIn member. This ensures that members are made aware of what an application could potentially access or do on their behalf.

Your application requests members to grant these permissions during the authentication process. Permissions must be explicitly requested using the scope argument during the authorization step.

If your application requires multiple permissions to access all the data it requires, members who use your application are required to accept all of them. They cannot accept only a subset of the requested application permissions. To provide the best experience for the member, ensure that your application requests the fewest necessary permissions.

The Authorization Code Flow has the following steps:

  1. Configure your application to get the Client ID and Client Secret.
  2. Your application directs the browser to LinkedIn's OAuth 2.0 authorization page where the member authenticates. After authentication, LinkedIn's authorization server passes an authorization code to your application.
  3. Your application sends this code to LinkedIn and LinkedIn returns an access token.
  4. Your application uses this token to call APIs on behalf of the member.

Step 1: Configure Your Application

If you are just getting started, create a new application.

If you have an existing application, select it to modify its settings.

After selecting an application, click the "Auth" link in the navigation to view your application's credentials and configure a callback URL to your server. To ensure a secure authentication process and prevent fraudulent transactions, LinkedIn only communicates with URLs that you have identified as trusted.

Note

  • URLs must be absolute. For example, https://example.com/auth/callback, not /auth/callback.
  • URL arguments are ignored. For example, https://example.com/?id=1 is the same as https://example.com/.
  • URLs cannot include a #. For example, https://example.com/auth/callback#linkedin is invalid.

Redirect URLs

Each application is assigned a unique Client ID (also known as Consumer key or API key) and Client Secret. Make note of these values as they have to be integrated into the configuration files or the actual code of your application.

OAuth Values

Important

Your Client Secret protects your application's security so be sure to keep it secure! Do not share your Client Secret value with anyone, including posting it in support forums for help with your application.

Step 2: Request an Authorization Code

To request an authorization code, you must direct the member's browser to LinkedIn's OAuth 2.0 authorization page, where the member either accepts or denies your application's permission request.

Once the request is made, one of the following occurs:

  • If the member has not previously accepted the application's permission request, or the grant has expired or been manually revoked by the member, the browser is redirected to LinkedIn's authorization screen as shown in the screenshot below. When the member completes the authorization process, the browser is redirected to the URL provided in the redirect_uri query parameter.
  • If there is a valid existing permission grant from the member, the authorization screen is bypassed and the member is immediately redirected to the URL provided in the redirect_uri query parameter.

Note that if you ever change the scope permissions that your application requires, your application's users must re-authenticate to ensure that they have explicitly granted your application all of the permissions that it requests on their behalf.

GET https://www.linkedin.com/oauth/v2/authorization
Parameter Description Required
response_type The value of this field should always be: code Yes
client_id The API Key value generated when you registered your application. Yes
redirect_uri The URI your users are sent back to after authorization. This value must match one of the OAuth 2.0 Authorized Redirect URLs defined in your application configuration. For example, https://www.example.com/auth/linkedin. Yes
state A unique string value of your choice that is hard to guess. Used to prevent CSRF. For example, state=DCEeFWf45A53sdfKef424. No
scope URL-encoded, space-delimited list of member permissions your application is requesting on behalf of the user. These must be explicitly requested. For example, scope=r_liteprofile%20r_emailaddress%20w_member_social. See Permissions and Best Practices for Application Development for additional information. Yes

Scopes could previously be set as default through the developer portal instead of explicitly requesting them in this step. They must now be explicitly requested when requesting an authorization code.

Sample Request

GET https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id={your_client_id}&redirect_uri=https%3A%2F%2Fdev.example.com%2Fauth%2Flinkedin%2Fcallback&state=fooobar&scope=r_liteprofile%20r_emailaddress%20w_member_social

Once redirected, the member is presented with LinkedIn's authentication screen. This identifies your application and outlines the particular member permissions that your application is requesting. You can change the logo and application name in your application configuration.

Authorize Screen

Your Application is Approved

By providing valid LinkedIn credentials and clicking Allow, the member approves your application's request to access their member data and interact with LinkedIn on their behalf. This approval instructs LinkedIn to redirect the member to the callback URL that you defined in your redirect_uriparameter.

Attached to the redirect_uri are two important URL arguments that you need to read from the request:

  • code — The OAuth 2.0 authorization code.
  • state — A value used to test for possible CSRF attacks.

The code is a value that you exchange with LinkedIn for an OAuth 2.0 access token in the next step of the authentication process. For security reasons, the authorization code has a 30-minute lifespan and must be used immediately. If it expires, you must repeat all of the previous steps to request another authorization code.

Before you use the authorization code, your application should ensure that the value returned in the state parameter matches the state value from your original authorization code request. This ensures that you are dealing with the real member and not a malicious script. If the state values do not match, you are likely the victim of a CSRF attack and your application should return a 401 Unauthorized error code in response.

Application is Rejected

If the member chooses to cancel, or the request fails for any reason, the client is redirected to your redirect_uri callback URL with the following additional query parameters appended:

  • error - A code indicating one of these errors:
    • user_cancelled_login - The member declined to log in to their LinkedIn account.
    • user_cancelled_authorize - The member refused to authorize the permissions request from your application.
  • error_description - A URL-encoded textual description that summarizes the error.
  • state - A value passed by your application to prevent CSRF attacks.

Step 3: Exchange Authorization Code for an Access Token

The next step is to get an access token for your application using the authorization code from the previous step. To do this, make the following HTTP POST request with a Content-Type header of x-www-form-urlencoded:

https://www.linkedin.com/oauth/v2/accessToken
Parameter Description Required
grant_type The value of this field should always be: authorization_code Yes
code The authorization code you received in Step 2. Yes
redirect_uri The same redirect_uri value that you passed in the previous step. Yes
client_id The Client ID value generated in Step 1. Yes
client_secret The Secret Key value generated in Step 1. See the Best Practices Guide for ways to keep your client_secret value secure. Yes

Sample Request (Secure Approach)

POST /oauth/v2/accessToken HTTP/1.1
Host: www.linkedin.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code={authorization_code_from_step2_response}&redirect_uri=hhttps%3A%2F%2Fdev.example.com%2Fauth%2Flinkedin%2Fcallback&client_id={your_client_id}&client_secret={your_client_secret}

Access Token Response

A successful access token request returns a JSON object containing the following fields:

  • access_token — The access token for the application. This value must be kept secure as specified in the API Terms of Use.
  • expires_in — The number of seconds remaining until the token expires. Currently, all access tokens are issued with a 60 day lifespan.

NOTE] The length of access tokens is ~500 characters. We recommend that you plan for your application to handle tokens with length of at least 1000 characters in order to accommodate any future expansion plans. This applies to both access tokens and refresh tokens.

Access Token Scopes and Lifetime

Access tokens stay valid until the number of seconds indicated in the expires_in field in the API response. You can go through the OAuth flow on multiple clients (browsers or devices) and simultaneously hold multiple valid access tokens as long as the same scope is requested. If you request a different scope than the previously granted scope, all the previous access tokens are invalidated.

Step 4: Make Authenticated Requests

Once you've obtained an access token, you can start making authenticated API requests on behalf of the member by including an Authorization header in the HTTP call to LinkedIn's API.

Sample Request

GET /v2/me HTTP/1.1
Host: api.linkedin.com
Connection: Keep-Alive
Authorization: Bearer {access_token}

Handling Invalid Tokens

If you make an API call using an invalid token, you'll receive a 401 Unauthorized response from the server, and you'll have to regenerate the token. A token could be invalid due to the following reasons:

  • It has expired.
  • The member revoked the permission they initially granted to your application.
  • The member permissions (scope) for your application were changed.
  • If a subsequent OAuth2 flow generated a new access token, the previous token is invalidated.

A predictable expiry time is not the only contributing factor to an invalid token so it's very important that you code your applications to properly handle a 401 Unauthorized error by redirecting the member back to the start of the authorization workflow.

Note

A 500 Internal Server Error is returned if there are downstream failures when verifying the access token.

Step 5: Refresh Access Token

To protect members' data, LinkedIn does not generate long-lived access tokens. Make sure your application refreshes access tokens before they expire, to avoid unnecessarily sending your application's users through the authorization process again.

Refreshing a Token

Refreshing an access token is a seamless user experience. To refresh an access token, go through the authorization process again to fetch a new token. This time however, in the refresh workflow, the authorization screen is bypassed and the member is redirected to your callback URL, provided the following conditions are met:

  • The member is still logged into www.linkedin.com
  • The member's current access token has not expired

If the member is no longer logged in to www.linkedin.com or their access token has expired, they are sent through the normal authorization process.

Programmatic refresh tokens are available for a limited set of partners. If this feature has been enabled for your application, see Programmatic Refresh Tokens for instructions.