LinkedIn Guide

Learn how to implement a custom LinkedIn authentication form into your application.

Step 1: Authenticate to LinkedIn

You have two options to initiate LinkedIn authentication

With Username / Password

For this method, you'll need to provide the LinkedIn username and password for authentication. Make a POST request to this Unipile API endpoint or use the appropriate SDK Method.

curl --request POST \
     --url https://{YOUR_DSN}/api/v1/accounts \
     --header 'X-API-KEY: {YOUR_ACCESS_TOKEN}' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "provider": "LINKEDIN",
  "username": "[email protected]",
  "password": "********"
}
'
const response = await client.account.connectLinkedin({
  username: "[email protected]",
  password: "********"
})

With Cookies

This method uses existing LinkedIn access tokens, specifically the li_at cookie and the you can get when connected to LinkedIn in your browser. Make a POST request to this Unipile API endpoint or use the appropriate SDK Method.

If you are able to retrieve the user agent from the browser where the cookie is obtained, please include it in the 'user_agent' parameter to avoid account disconnection.

curl --request POST \
     --url https://{YOUR_DSN}/api/v1/accounts \
     --header 'X-API-KEY: {YOUR_ACCESS_TOKEN}' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "provider": "LINKEDIN",
  "access_token": "***************************"
}
'
const response = await client.account.connectLinkedin({
  access_token: "**************",
})

Step 2 : Handle checkpoints

LinkedIn authentication may present checkpoints that the user needs to solve. Unipile's API can return the type of checkpoint, if any, along with a 202 status. You can detect these checkpoints in the response and display a screen or a new form.

In this case, a new Authentication Intent starts. This intent last 5 minutes and checkpoints must be solved in this time frame.

Here's an example of a checkpoint response, which include the type of checkpoint between 2FA, OTP, IN_APP_VALIDATION, CAPTCHA, CONTRACT_CHOOSER, but also the account_id which is required to identify the next request.

{
  "object": "Checkpoint",
  "account_id": "098dez89d",
  "checkpoint": {
    "type": "2FA"
  }
}

Step 3 : Solve checkpoints

Solve 2FA and OTP

Some checkpoints require a user input, like 2FA and OTP for linkedIn. To handle these checkpoints, make a POST request to the Unipile API using the Solve checkpoint endpoint or use an SDK Method by giving the account_id returned by the first request

curl --request POST \
     --url https://{YOUR_DSN}/api/v1/accounts/checkpoint \
     --header 'X-API-KEY: {YOUR_ACCESS_TOKEN}' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "provider": "LINKEDIN",
  "account_id": "098dez89d",
  "code": "***"
}
'
const response = await client.account.solveCodeCheckpoint({
  provider: "LINKEDIN",
  account_id: "fze98Vzev",
  code: "****",
});

The response of this request will indicate if the account is successfully connected, or if there is a new checkpoint to solve, the same way as before.

Handle In-App Validation

The IN_APP_VALIDATION checkpoint require a confirmation of the connection in the user's LinkedIn mobile app. In this case, your application should listen for an account status update to detect the user's action. You have two options to achieve this:

Option A: Long Request on GET Account Status

Make a GET request to the Unipile API to check the account's status. The request will only resolve when the account status changes to "connected," indicating a successful authentication. Implement a long polling mechanism in your application to handle this.

Option B: Account Status Webhook

Alternatively, you can set up an Account Status Webhook to receive notifications when the account status changes. This webhook can be configured to listen for status changes and trigger actions in your application when the LinkedIn account connection is confirmed.

Handle Captcha

We automatically solve captchas for end users. Contact us if you want to solve captchas your way.

Step 4 : Handle Intent Timeout

If the user takes more than 5 minutes to solve the checkpoint, the account will not be connected. Any subsequent request to solve a checkpoint outside a 5 minutes time frame will first respond a 408 - Request Timeout, then a 400 - Bad Request as the Authentication Intent will self destroy.


Connect through a Proxy

On Step 1, you can pass a proxy object to the request to connect a LinkedIn account through a Proxy.

curl --request POST \
     --url https://{YOUR_DSN}/api/v1/accounts \
     --header 'X-API-KEY: {YOUR_ACCESS_TOKEN}' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "provider": "LINKEDIN",
  "proxy": {
    "port": 1123,
    "host": "proxy.com",
    "username": "username",
    "password": "********"
  },
  "username": "[email protected]",
  "password": "**********"
}
'
const response = await client.account.connectLinkedin({
  username: "[email protected]",
  password: "********",
  proxy: {
    host: "proxy.com",
    port: 1123,
    username: "username",
    password: "*****",
  }
})

In this case, don't forget to handle the additional proxy related errors you can find on the API Reference.