DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for LinkedIn API Python Library
Moussa
Moussa

Posted on

LinkedIn API Python Library

Linkedin is an influential business-related social networking platform, which allows people from different places, cultures, and industries to create and expand their networks, so LinkedIn is one of the important tools inside any success bag.

Professional Organizations and Employees also today consider Linkedin as the main social platform for their business, the organization uses LinkedIn to find talented people and talented people take care of their profiles and activities to be found by the best organization.

To Make all of these easy and fast for both organizations and employees there are a lot of tools that collaborate with Linkedin APIs and get you back with the outcome in a few seconds one of these tools is Linkedin Python API let's deep dive into it!

Table of contents πŸ“’

What is Linkedin Python API? ❓

A Python wrapper for the Linkedin API, that helps you to interact with LinkedIn APIs from your own scripts to make a variety of stuff like sending messages, search profiles, getting jobs, and more. the fanciest part is all that you need is just a regular LinkedIn account, without creating an official LinkedIn app.

Before using this project, please consult Terms and Conditions and Legal Notice.

Getting Started ▢️

⚠️ Python >= 3.6 required

Check python installation.

To install the package run the following command:

pip3 install linkedin-api
Enter fullscreen mode Exit fullscreen mode

Example usage

from linkedin_api import Linkedin

# Authenticate using any Linkedin account email and password
try:
    api = Linkedin('me@mail.com', 'password')
    profile = api.get_profile('muhammedmoussa')
    print(profile)
except:
  print("An exception occurred")
Enter fullscreen mode Exit fullscreen mode

Sample response of profile fetch.

{
  "summary": "...",
  "industryName": "Financial Services",
  "lastName": "Moussa βœͺ",
  "address": "Hurghada, Egypt",
  "locationName": "Egypt",
  "student": false,
  "geoCountryName": "Egypt",
  "geoCountryUrn": "urn:li:******",
  "geoLocationBackfilled": false,
  "elt": false,
  "birthDate": {},
  "industryUrn": "urn:li:fs_industry:43",
  "firstName": "Muhammed ",
  "entityUrn": "urn:li:fs_profile:ACoAABT1wOkBUgS77T0NG2puPbStCWKVLIJHUaE",
  "geoLocation": {},
  "geoLocationName": "Hurghada, Al Bahr al Ahmar",
  "location": {},
  "headline": "JavaScript Developer at Paymob",
  "displayPictureUrl": "https://media-exp2.licdn.com/dms/image/C5603AQHwEFZkUOXalw/profile-displayphoto-shrink_",
  "img_100_100": "100_100/0/1647527431537?e=1663804800&v=beta&t=ILGlsVPFkYE6ScB9IXx8JX1o5j4SqVCFGVRlKgPPpmg",
  "img_200_200": "200_200/0/1647527431537?e=1663804800&v=beta&t=VfEVqlmBJPPgan1tBguYDmRHPTTHSgcY83fSp7GNd-E",
  "img_400_400": "400_400/0/1647527431537?e=1663804800&v=beta&t=zN_GOz0Y4PG3ZZMa2xqpNAyg704CE5qkP-_m-wyBl3w",
  "img_800_800": "800_800/0/1647527431537?e=1663804800&v=beta&t=k7971X7dfIT-iY-Ng0QNuInX74BhahiRviMyZESBW8w",
  "profile_id": "ACoAABT1wOkBUgS77T0NG2puPbStCWKVLIJHUaE",
  "profile_urn": "urn:li:fs_miniProfile:ACoAABT1wOkBUgS77T0NG2puPbStCWKVLIJHUaE",
  "member_urn": "urn:li:member:351650025",
  "experience": [],
  "education": [],
  "languages": [],
  "publications": [],
  "certifications": [],
  "volunteer": [],
  "honors": [],
  "projects": []
}
Enter fullscreen mode Exit fullscreen mode

Fetching Profile Details ℹ️

The package has a set of magical methods to interact with LinkedIn profile details, in addition to get_profile() method mentioned above, here is a list of some of these methods below.

from linkedin_api import Linkedin

try:
    api = Linkedin('me@mail.com', 'password')

    # Getting profile skills using Linkedin public profile id
    skills = api.get_profile_skills('muhammedmoussa')
    print(skills)

    # Getting profile contact info using Linkedin public profile id
    contact_info = api.get_profile_contact_info('muhammedmoussa')
    print(contact_info)

    # Getting profile badges using Linkedin public profile id
    badges = api.get_profile_member_badges('muhammedmoussa')
    print(badges)

except:
  print("An exception occurred")
Enter fullscreen mode Exit fullscreen mode

For a better vision of the plugin, here is a sample response of these methods.

// skills
[
  {"name": "JavaScript"},
  {
    "name": "TypeScript",
    "standardizedSkillUrn": "urn:li:fs_miniSkill:50517",
    "standardizedSkill": {
      "name": "TypeScript",
      "entityUrn": "urn:li:fs_miniSkill:50517"
    }
  },
  {"name": "Node.js"},
  {"name": "MongoDB"},
  {"name": "Python"},
  ...
]

// contact_info
{
   "email_address":"muhammedmoussa@hotmail.com",
   "websites":[
      {
         "url":"https://muhammedmoussa.github.io/",
         "label":"PERSONAL"
      }
   ],
   "twitter":[
      {
         "name":"muhammedMoussa",
         "credentialId":"urn:li:member:351650025;345345825"
      }
   ],
   ...
}

// badges
{
   "premium":false,
   "influencer":false,
   "entityUrn":"urn:li:fs_memberBadges:******",
   "openLink":false,
   "jobSeeker":false,
   "$type":"com.linkedin.voyager.identity.profile.MemberBadges"
}
Enter fullscreen mode Exit fullscreen mode

Connections Management 🌐

The package also has a set of magical methods to manage and control different network connections stuff as adding, unfollowing, or removing existing connections, retrieving, and accepting invites, also here is a list of some of these methods below.

from linkedin_api import Linkedin

try:
    api = Linkedin('me@mail.com', 'password')

    # Send connection request to a given profile id, will return a boolean.
    api.add_connection('muhammedmoussa')

    # Remove a connection with a given profile id, will return a boolean.
    api.remove_connection('muhammedmoussa')

    # Fetch connection invitations for the currently logged in user with start and limit params.
    invitations = api.get_invitations(start=0, limit=3)
    print(invitations)

    # Unfollow a given profile id, will return a boolean.
    api.unfollow_entity('muhammedmoussa')

except:
  print("An exception occurred")
Enter fullscreen mode Exit fullscreen mode

Sample response of invitations fetch.

[
  {
    "mailboxItemId": "*******",
    "toMemberId": "*******",
    "fromMember": {
      "memorialized": false,
      "firstName": "Muhammed ",
      "lastName": "Moussa",
      "entityUrn": "urn:li:fs_miniProfile:******",
      "publicIdentifier": "muhammedmoussa",
      "trackingId": "P8mZOe9HRLO5L84xOoN16g=="
    },
    "invitee": {},
    "invitationType": "PENDING",
    "entityUrn": "urn:li:fs_relInvitation:6954589454917320704",
    "toMember": {},
    "inviterActors": [],
    "sentTime": 1658103366339,
    "customMessage": false,
    "sharedSecret": "******",
    "unseen": true
  }
]
Enter fullscreen mode Exit fullscreen mode

Retrieve and Reply Messages πŸ’¬

Finally, the package also has a set of magical methods to deal with conversation stuff such as messages retrieving and sending, here is a list of some of these methods below.

from linkedin_api import Linkedin

try:
    api = Linkedin('me@mail.com', 'password')

    # Fetch list of conversations logged in user. return list.
    conversations = api.get_conversations()
    print(conversations)

    # Fetch conversation (message thread) details for a given LinkedIn profile. return dictionary.
    api.get_conversation_details('urn:li:fs_miniProfile:********')

    # Send a message to a given conversation. return boolean
    api.send_message('Hello There!', 'urn:li:fsd_conversation:********')

    # Send `seen` to a given conversation. return boolean.
    mark_conversation_as_seen('urn:li:fsd_conversation:********')

except:
  print("An exception occurred")
Enter fullscreen mode Exit fullscreen mode

Sample response of conversations fetch.

{
  "metadata": {
    "unreadCount": 0
  },
  "elements": [
    {
      "dashEntityUrn": "urn:li:fsd_conversation:*****",
      "notificationStatus": "ACTIVE",
      "read": true,
      "groupChat": false,
      "totalEventCount": 2,
      "unreadCount": 0,
      "lastActivityAt": 1658148419804,
      "firstMessageUrn": "urn:li:fs_event:(*****,2-MTY1ODEwNDYyNzczOGI4ODE2Mi0wMDQmY2I0M2UwZDctZmM5ZS00NmY0LTg3OWQtNGVhMGIyYzgxZmM1XzAxMw==)",
      "backendUrn": "urn:li:messagingThread:*****",
      "receipts": [
        {
          "fromEntity": "urn:li:fs_miniProfile:******",
          "seenReceipt": {
            "seenAt": 1658148419629,
            "eventUrn": "urn:li:fs_event:(*****,******)"
          },
          "fromParticipant": {
            "string": "urn:li:member:351650025"
          }
        }
      ],
      "lastReadAt": 1658148672641,
      "archived": false,
      "blocked": false,
      "entityUrn": "urn:li:fs_conversation:*****",
      "sdkEntityUrn": "urn:li:msg_conversation:(urn:li:fsd_profile:******,*****)",
      "viewerCurrentParticipant": true,
      "featureTypes": [],
      "withNonConnection": false,
      "muted": false,
      "events": [
        {
          "createdAt": 1658148419796,
          "reactionSummaries": [],
          "dashEntityUrn": "urn:li:fsd_message:******",
          "quickReplyRecommendations": [],
          "entityUrn": "urn:li:fs_event:(*****,******)",
          "eventContent": {
            "com.linkedin.voyager.messaging.event.MessageEvent": {
              "messageBodyRenderFormat": "DEFAULT",
              "body": "",
              "attributedBody": {
                "text": "How are you?"
              }
            }
          },
          "subtype": "MEMBER_TO_MEMBER",
          "from": {
            "com.linkedin.voyager.messaging.MessagingMember": {
              "miniProfile": {
                "memorialized": false,
                "firstName": "Muhammed ",
                "lastName": "Moussa βœͺ",
                "dashEntityUrn": "urn:li:fsd_profile:******",
                "entityUrn": "urn:li:fs_miniProfile:******",
                "backgroundImage": {},
                "publicIdentifier": "muhammedmoussa",
                "picture": {},
                "trackingId": "gHcY3a/hRK6s0z/HDf7cTg=="
              },
              "entityUrn": "urn:li:fs_messagingMember:(*****,******)",
              "nameInitials": "MM"
            }
          },
          "previousEventInConversation": "urn:li:fs_event:(*****,2-MTY1ODEwNDczMDM3OWIyMzUzMi0wMDQmY2I0M2UwZDctZmM5ZS00NmY0LTg3OWQtNGVhMGIyYzgxZmM1XzAxMw==)",
          "backendUrn": "urn:li:messagingMessage:******"
        }
      ],
      "participants": []
    }
  ],
  "paging": {
    "count": 20,
    "start": 0,
    "links": []
  }
}
Enter fullscreen mode Exit fullscreen mode

You maybe notice some different in parameters here instead of passing URLs we passing urn, this leads to one of the most important key concepts here URN IDs and public IDs.

  • URN ID: A Uniform Resource Name (URN) is a Uniform Resource Identifier (URI) that uses the urn scheme. URNs are globally unique. example of LinkedIn profile URN: urn:li:fs_miniProfile:ACoAABQ11fIBQLGQbB1V1XPBZJsRwfK5r1U2Rzt

  • URL: A Uniform Resource Locator (URL), colloquially termed a web address, is a reference to a web resource that specifies its location on a computer network. example of LinkedIn profile URL: https://www.linkedin.com/in/muhammedmoussa/

For more information about this and how the package works with LinkedIn APIs check LinkedIn API docs.

What's next? ⏭

We walked through the LinkedIn Python API package and some of its features, as we mentioned above how important is LinkedIn as a tool for every professional especially the organization when wailing to upgrade the traditional job posting, talent hunting, or hiring process in general. so today we have a bunch of tools that work on top of LinkedIn or people data and offer great tools that can change the game. here is a list of some of the services:

Top comments (0)

Hacktoberfest is happening now!



It is a month-long celebration of open source. For a lot of devs, its their introduction to open source.


Check out the Hacktoberfest tag on DEV to keep up with the latest!