Position
One role at one company.
Fields #
| Field | Type | Notes |
|---|---|---|
title | string | |
description | string | The free text a member writes under a role. It comes from the profile's experience section, which is a separate request - so it, employment_type, location, workplace_type, skills and tenure_months are filled only by profiles/enrich/detailed with include_experience_detail: true. All six are absent together when that fetch did not land, and absent individually when the member left that part of their profile blank. A Sales Navigator row carries none of them except tenure_months. |
current | boolean | |
employment_type | string | LinkedIn's own word - Full-time, Contract, Internship - passed through rather than mapped onto an enum of ours, which would need extending every time they add one. |
location | string | Where the ROLE was held, which is not company_location: a New York role at a Redmond employer is the ordinary case, not an anomaly. |
workplace_type | string | Remote, Hybrid or On-site. Absent means the member did not say, never that they were on site. |
skills | string[] | The skills the member attached to THIS role - a narrower and more useful claim than the profile-wide skills list. |
company_name | string | |
company_id | integer | Present when the card resolved the company. Pass it straight to companies/enrich. |
company_url | string | |
company_industry | string | Filled only by a profile fetch, along with company_employee_range and company_logo_url. company_location is the other way round, filled only by a Sales Navigator search row. The two upstream payloads carry different parts of a position, so a structurally absent field here is not missing data - it is telling you which source produced this entry. |
company_location | string | |
company_logo_url | string | |
company_employee_range | string | LinkedIn's employee band rendered as one string - 51-200, 10001+ - because the pair is only ever displayed. |
started_on | PartialDate | |
ended_on | PartialDate | Absent on a current role. |
tenure_months | integer | LinkedIn's own rendered run ("9 yrs 4 mos") as a single number, rather than one computed from the dates - a current role has no end date, and a role with a year and no month would have to be guessed at, so a derived figure would disagree with the profile it came from. The one of the six experience-section fields a Sales Navigator row also fills, meaning the same thing in each. One number sorts and filters. |
Absent is not null: a field we did not get is omitted rather than sent as an empty string, so you can tell "LinkedIn does not have this" from "this person left it blank".
Sample #
{
"title": "Head of Engineering",
"description": "Own the platform group: 4 teams, 30 engineers.\nRebuilt the match pipeline...",
"current": true,
"employment_type": "Full-time",
"location": "Helsinki, Uusimaa, Finland",
"workplace_type": "Hybrid",
"skills": ["Distributed Systems", "Engineering Management"],
"company_name": "Supercell",
"company_id": 1042569,
"company_url": "https://www.linkedin.com/company/1042569",
"company_employee_range": "201-500",
"started_on": { "year": 2023, "month": 4 },
"tenure_months": 41
}