An introduction to sharing content on LinkedIn using REST APIs and Python
Tags: python, rest, api
Published: 2022-03-14 11:02:34


# Introduction


[LinkedIn](https://www.linkedin.com/) is a popular social media platform that allows users to connect to each other and maintain professional network. You can manage your profile and also create a company profile for your organization. An interesting feature of LinkedIn is the ability to share posts on your feed or on your organization’s feed. You can embed URLs, provide hashtags and emojis and also share images and videos in your post. Although the primary way of sharing content on LinkedIn is by using the web application, you can also do it programmatically using the [REST APIs](https://docs.microsoft.com/en-us/linkedin/) provided by LinkedIn and a programming language of your choice.


In this article, we are going to learn how to use the [LinkedIn REST APIs](https://docs.microsoft.com/en-us/linkedin/) and share content from your personal profile as well as from an organization’s profile that you manage. Don’t worry if you do not have an organization as I will guide you from the scratch.


## Pre-requisites


In order to proceed further, we need to have the following pre-requisites.


1. **LinkedIn Account** – You need to have a LinkedIn account, if you do not have one, please head over to <https://www.linkedin.com/> and create one.
2. **REST APIs** – Some basic knowledge of using REST APIs.
3. **Python** – General programming knowledge of using python and using REST APIs in python.


Apart from the above-mentioned, I am going to use Jupyter notebooks to create the codebase and make it available using GitHub. At any point in time, you can choose to refer to the official documentation of LinkedIn from Microsoft, however, I will try to explain the process in simple terms.


# Creating the LinkedIn Company Page and Application


Assuming that you already have your LinkedIn account created, now we will create the following two assets.


1. [LinkedIn Company Page](https://business.linkedin.com/marketing-solutions/linkedin-pages) – Also, can be referred to as the Company page, we need to create it using your personal account. You will be an admin for the Company page that you create.
2. [An Application on the Developers portal](https://developer.linkedin.com/) – In order to get access to the LinkedIn REST APIs, we need to create an application, that will assume the permissions on our behalf and share content on your profile or from the organisation’s profile.


## Create the LinkedIn Company Page.


Let’s create a company page from your LinkedIn account. You can think of any dummy name for your company to proceed forward. I am going to use my company as “*DataScholar*”.


***Step 1***: Open LinkedIn account. Click on **Work** and select **Create a Company Page**. Click on **Company** and enter the details and click on **Create Page**.


![Figure 1 – Create LinkedIn company page](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled.png?resize=1024%2C411&ssl=1)Figure 1 – Create LinkedIn company page

***Step 2***: You need to provide the following details for your company page to be created.


1. **Name** – The name of your company. I am using *DataScholar*.
2. **Company** **URL** – The LinkedIn username of your company.
3. **Website** – The website your company is hosted on. I am going to use “*<https://thedatascholar.com>*”.
4. **Industry** – Select as *Software*.
5. **Company** **Size** – I have selected *between 0 and 1* since I am the sole user of the company.
6. **Company** **Type** – *Non-profit*.
7. **Logo** – Any custom image for your company logo.
8. **Tagline** – A short description of your company.


Once you have provided all these details, your LinkedIn company page has been created now.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-1.png?resize=1024%2C606&ssl=1)Figure 2 – LinkedIn company page
## Create the LinkedIn app in the Developer Portal.


In this section, we will dig a bit deeper and create an application on LinkedIn Developer’s platform that will allow us to interact with the LinkedIn assets programmatically.


***Step 1***: Navigate to <https://developer.linkedin.com/>. Click on **My Apps** and then select **Create App**. Enter the details for your application.


1. **App Name** – The name for your application. You can use the same name as your company.
2. **LinkedIn Page** – The company page that the app will be associated with.
3. **Privacy Policy URL** – Optional field.
4. **App Logo** – Upload a logo for your app.


Agree to the terms and then click on **Create App**.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-2.png?resize=1024%2C506&ssl=1)Figure 3 – Creating LinkedIn App

***Step 2***: Click **Verify** to verify your application.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-3.png?resize=1024%2C506&ssl=1)Figure 4 – Verify LinkedIn application
***Step 3***: Click **Generate URL** and copy the URL and click **I’m Done**.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-4-1.png?resize=1024%2C506&ssl=1)Figure 5 – Generate verification URL for the LinkedIn app
***Step 4***: Copy and hit the URL on the browser. It will ask you to verify the app for the page.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-5-1.png?resize=1024%2C506&ssl=1)Figure 6 – Verify LinkedIn app and Company association
***Step 5***: Click on **Verify**.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-6.png?resize=1024%2C506&ssl=1)Figure 7- LinkedIn app and Company association verified
Great! You have now successfully created a LinkedIn company page and also created an app to interact with LinkedIn using the REST APIs.


# Configure your LinkedIn App


Let’s configure the LinkedIn app that we have created in the previous section. We will add the products required to access the LinkedIn REST APIs and store the app credentials.


## Add the products for your LinkedIn App.


Once you have created the LinkedIn App, you need to define what are the products that you are going to use with your app. Based on this, your app will be provided with the necessary permissions that you need. There are three products available to choose from.


1. **Share on LinkedIn** – This allows you to post content from your profile.
2. **Sign In with LinkedIn** – This allows you to use LinkedIn social sign on your webpage.
3. **Marketing Developer Platform** – Allows you to post content from your page.


As a part of this article, I am going to add all three products to my app.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-7.png?resize=1024%2C506&ssl=1)Figure 8 – Add products to LinkedIn app
The **Marketing Developer Platform** requires additional access. You will receive a form for this. Fill up the form and wait for approval (2 business days). Click on the **View Access Form** and fill it up with relevant details.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-8.png?resize=1024%2C561&ssl=1)Figure 9 – Fill up review form for Marketing Developer Platform
Once you submit the form, it might take up to 2 business days to get an answer by email. You will then notice the app has been added to your product list.


💡 The ***Marketing Developer Platform*** allows you to post content from your company page. Without adding it, you can still post content from your personal LinkedIn profile.


## Fetch and store the app credentials.


***Step 1***: On your LinkedIn app, click on the **Auth** tab. You can find the **Client ID** and **Client Secret** that you need later.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-9.png?resize=1024%2C506&ssl=1)Figure 10 – Store LinkedIn app credentials
***Step 2***: Add the redirect URL for your App. This can simply be your webpage URL appended with “*/auth/linkedin/callback*”.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-10.png?resize=1024%2C561&ssl=1)Figure 11 – Setup app Redirect URI
***Step 3***: Get the **Organization ID** from the company URL.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-11.png?resize=912%2C68&ssl=1)Figure 12 – Get Organization ID
# Start assembling your Python code


Now let’s start building the python program that would allow us to interact with the LinkedIn REST APIs.


## Setup static variables and libraries


In order to work with REST APIs in python, we will leverage the `requests` library. You can install it using the python `pip` manager. In addition to that, we will also create variables to store our `client_id`, `client_secret`, and `organization_id` that we have obtained in the previous section.

{% embed https://gist.github.com/aveek22/89b1b6d2423cdeefff59779b30ede7f6 %}

In the next steps, we need to get an Access Token that can be used to share content from the LinkedIn profile. The Access Token can be obtained in two steps as follows.


1. A **GET** request that will ask the user to allow your app to obtain the required permissions and redirect you to a new URL. From this URL, you’ll need to extract the value in the parameter code.
2. A **POST** request that will return your brand new Access Token.


## Create the GET request to obtain verification code


Setup the following details to build the URL.


* `base_url`: The LinkedIn endpoint to obtain authorization code.
* `redirect_uri`: The redirect URL you have set while creating your app.
* `scope`: The scope required to publish content from your personal profile.
* `state`: A random text that will be returned to you after authorization. This allows you to verify the response from CSRF attacks. For simplicity, let’s not bother much about it now.



.gist table { margin-bottom: 0; }












 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
 [Learn more about bidirectional Unicode characters](https://github.co/hiddenchars)

  [Show hidden characters]({{ revealButtonHref }})










|  |  |
| --- | --- |
|  | base\_url = "<https://www.linkedin.com/oauth/v2/authorization&quot>; |
|  | redirect\_uri = "<https://thedatascholar.com/auth/linkedin/callback&quot>; |
|  | scope = "w\_member\_social,r\_liteprofile" |
|  |  |
|  | url = f"{base\_url}?response\_type=code&client\_id={client\_id}&state=random&redirect\_uri={redirect\_uri}&scope={scope}" |
|  | print(url) |








[view raw](https://gist.github.com/aveek22/8978355f31b779cc8cd2b6d844bf9d34/raw/0e906ad72da0c40e5cdb0350023360cf299eaa94/social_linkedin_auth.py)
[social\_linkedin\_auth.py](https://gist.github.com/aveek22/8978355f31b779cc8cd2b6d844bf9d34#file-social_linkedin_auth-py) 
 hosted with ❤ by [GitHub](https://github.com)




When you run the above code, it will print the URL on your console. Copy the URL and hit it in your browser. You will be asked to log in with your LinkedIn credentials. Once your login is verified, it will redirect you to the address mentioned in the `redirect_uri`. You will also receive two parameters, `code`, and `state` in this URL. Copy the value of the `code` and store it for processing the next request.


💡 To publish content from your company page, you need more permissions in your scope. This can be obtained once you have received verification for the **Marketing Developer Platform** from the LinkedIn team.


## Create the POST request to obtain the Access Token


Now that the verification code has been obtained, we can get the access token by sending a POST request to LinkedIn. You need to provide the following as a payload in the POST request.


* `grant_type`: The grant type should be ‘*authorization\_code*’.
* `code`: The authorization code obtained in the previous step.
* `redirect_uri`: The redirect URI of your app.
* `client_id`: The client ID that we stored earlier.
* `client_secret`: The client secret that we stored earlier.



.gist table { margin-bottom: 0; }












 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
 [Learn more about bidirectional Unicode characters](https://github.co/hiddenchars)

  [Show hidden characters]({{ revealButtonHref }})










|  |  |
| --- | --- |
|  | url\_access\_token = "<https://www.linkedin.com/oauth/v2/accessToken&quot>; |
|  | auth\_code = "YOUR\_AUTH\_CODE\_FROM\_PREVIOUS\_VERIFICATION" |
|  |  |
|  | payload = { |
|  | 'grant\_type' : 'authorization\_code', |
|  | 'code' : auth\_code, |
|  | 'redirect\_uri' : redirect\_uri, |
|  | 'client\_id' : client\_id, |
|  | 'client\_secret' : client\_secret |
|  | } |
|  |  |
|  | response = requests.post(url=url\_access\_token, params=payload) |
|  | response\_json = response.json() |
|  |  |
|  | # Extract the access\_token from the response\_json |
|  | access\_token = response\_json['access\_token'] |








[view raw](https://gist.github.com/aveek22/253b85ff96e450d7171833e4dade52ad/raw/b548453262cb41de94e03136184b22169f9c9aae/social_linkedin_access_token.py)
[social\_linkedin\_access\_token.py](https://gist.github.com/aveek22/253b85ff96e450d7171833e4dade52ad#file-social_linkedin_access_token-py) 
 hosted with ❤ by [GitHub](https://github.com)




If the POST request is successful, you will receive a JSON response that will contain the `access_token`. I have extracted and stored it in a separate variable.


## Get your LinkedIn profile ID


In order to post content from your LinkedIn profile, you need to obtain your profile ID. This can be done by querying the LinkedIn REST API directly.



.gist table { margin-bottom: 0; }












 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
 [Learn more about bidirectional Unicode characters](https://github.co/hiddenchars)

  [Show hidden characters]({{ revealButtonHref }})










|  |  |
| --- | --- |
|  | # Get LinkedIn user ID |
|  | url = "<https://api.linkedin.com/v2/me&quot>; |
|  |  |
|  | header = { |
|  | 'Authorization' : f'Bearer {access\_token}' |
|  | } |
|  |  |
|  | response = requests.get(url=url, headers=header) |
|  | response\_json\_li\_person = response.json() |
|  |  |
|  | person\_id = response\_json\_li\_person['id'] |








[view raw](https://gist.github.com/aveek22/de44ea0d5a0d322a0ce98c2e26ea4502/raw/6c478f3028fcd1f7a120388b8e41d12214029f9d/social_linkedin_profile.py)
[social\_linkedin\_profile.py](https://gist.github.com/aveek22/de44ea0d5a0d322a0ce98c2e26ea4502#file-social_linkedin_profile-py) 
 hosted with ❤ by [GitHub](https://github.com)




Notice that I have passed the `access_token` as a bearer token in the authorization header. Also, I have stored the LinkedIn profile ID in a variable called `person_id`.


## Share content from LinkedIn Personal Profile


Let’s prepare the content that we want to share from our LinkedIn personal profile. I have selected a random [article from Redhat](https://www.redhat.com/en/topics/api/what-is-a-rest-api) that I would like to share. Also, I would like to add a thumbnail image to the content that is shared. For that, you can choose any image that is publicly available. Notice that the payload contains the key `owner` and the value is the profile ID that we obtained in the earlier step. This value determines if the post is to be shared from the personal profile or from the company page.



.gist table { margin-bottom: 0; }












 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
 [Learn more about bidirectional Unicode characters](https://github.co/hiddenchars)

  [Show hidden characters]({{ revealButtonHref }})










|  |  |
| --- | --- |
|  | url = "<https://api.linkedin.com/v2/shares&quot>; |
|  |  |
|  | headers = { |
|  | 'Authorization' : f'Bearer {access\_token}', |
|  | 'Content-Type' : 'application/json' |
|  | } |
|  |  |
|  | payload = { |
|  | "content": { |
|  | "contentEntities": [ |
|  |  { |
|  | "entityLocation": "<https://www.redhat.com/en/topics/api/what-is-a-rest-api&quot>;, |
|  | "thumbnails": [ |
|  |  { |
|  | "resolvedUrl": "<https://images.pexels.com/photos/2115217/pexels-photo-2115217.jpeg&quot>; |
|  |  } |
|  |  ] |
|  |  } |
|  |  ], |
|  | "title": "What is a REST API?" |
|  |  }, |
|  | 'distribution': { |
|  | 'linkedInDistributionTarget': {} |
|  |  }, |
|  | 'owner': f'urn:li:person:{person\_id}', |
|  | 'text': { |
|  | 'text': f'Learn more about REST APIs in details. \n#restapi #api' |
|  |  } |
|  | } |
|  |  |
|  | response = requests.post(url=url, headers=headers, json = payload) |
|  |  |
|  | print(response.json()) |








[view raw](https://gist.github.com/aveek22/aa6f179dcd42bfb25caa7ea7cae09ec6/raw/64abc195a831f960f0227f6092bbad6873c86a33/social_linkedin_share_post_personal.py)
[social\_linkedin\_share\_post\_personal.py](https://gist.github.com/aveek22/aa6f179dcd42bfb25caa7ea7cae09ec6#file-social_linkedin_share_post_personal-py) 
 hosted with ❤ by [GitHub](https://github.com)




If you want to understand the payload in more depth, please refer to the [official documentation](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api?tabs=http#post-shares). There is a clear explanation of what each of the fields in the payload is about. Once the request is successful, the content will be shared from your personal profile and it will appear in the feed as follows.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-12.png?resize=841%2C1024&ssl=1)Figure 13 – Post shared from the personal profile on LinkedIn
## Share content from LinkedIn Company Page


Sharing content from an organization’s page is almost similar to that of sharing from a personal profile. The only key that determines whether the post content is to be shared from a personal or organization’s profile is the `owner`. The following values are accepted for the `owner` key.


* **Personal Profile**: `urn:li:person:{person_id}`
* **Organization**: `urn:li:organization:{organization_id}`


You can fetch the organization\_id from the URL of your company page. With that, now the payload can be modified and content shared from the organization’s profile.



.gist table { margin-bottom: 0; }












 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
 [Learn more about bidirectional Unicode characters](https://github.co/hiddenchars)

  [Show hidden characters]({{ revealButtonHref }})










|  |  |
| --- | --- |
|  | url = "<https://api.linkedin.com/v2/shares&quot>; |
|  |  |
|  | headers = { |
|  | 'Authorization' : f'Bearer {access\_token}', |
|  | 'Content-Type' : 'application/json' |
|  | } |
|  |  |
|  | payload = { |
|  | "content": { |
|  | "contentEntities": [ |
|  |  { |
|  | "entityLocation": "<https://www.redhat.com/en/topics/api/what-is-a-rest-api&quot>;, |
|  | "thumbnails": [ |
|  |  { |
|  | "resolvedUrl": "<https://images.pexels.com/photos/2115217/pexels-photo-2115217.jpeg&quot>; |
|  |  } |
|  |  ] |
|  |  } |
|  |  ], |
|  | "title": "What is a REST API?" |
|  |  }, |
|  | 'distribution': { |
|  | 'linkedInDistributionTarget': {} |
|  |  }, |
|  | 'owner': f'urn:li:organization:{organization\_id}', |
|  | 'text': { |
|  | 'text': f'Learn more about REST APIs in details. \n#restapi #api' |
|  |  } |
|  | } |
|  |  |
|  | response = requests.post(url=url, headers=headers, json = payload) |
|  |  |
|  | print(response.json()) |








[view raw](https://gist.github.com/aveek22/651ce87c660ebee304b78dbd85713343/raw/a360f2f6cab61ffa847998ad86a9640e93248861/social_linkedin_share_post_organization.py)
[social\_linkedin\_share\_post\_organization.py](https://gist.github.com/aveek22/651ce87c660ebee304b78dbd85713343#file-social_linkedin_share_post_organization-py) 
 hosted with ❤ by [GitHub](https://github.com)




This will post the content from your organization’s profile and you will have it on your feed.


![](https://i0.wp.com/datacloudmag.com/wp-content/uploads/2022/03/Untitled-13.png?resize=888%2C1024&ssl=1)Figure 14 – Post shared from organization’s profile on LinkedIn
💡 To post content from the organization’s profile, you need to wait until you have received the email from LinkedIn which might take 2 business days.


# Conclusion


In this article, we have focused on how to use the LinkedIn REST APIs and share content from a personal profile as well as from an organization’s profile. This is just a beginner level introduction to using the LinkedIn REST APIs. Apart from sharing content, you can also use other [products](https://developer.linkedin.com/product-catalog) to interact with LinkedIn Ads, and Campaign Management Tools.


## Resources


If you want to learn more about LinkedIn REST APIs, I would recommend reading through the following.


* <https://docs.microsoft.com/en-us/linkedin/shared/authentication/authentication>
* <https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api>
* <https://developer.linkedin.com/product-catalog>