# LinkedIn API Access: What Standard Developer Access Gets You

LinkedIn API access is mostly approval-gated – the self-serve products you can enable today, how to set them up, and what to build on for the rest.

LinkedIn API access begins the same way for everyone: you arrive at the developer portal with a specific job in mind, create an application, open the Products tab, and find the list of things you can switch on is far shorter than expected. This guide covers exactly what standard developer access grants, how to set it up, and what to do about the jobs it does not cover.

> **The short version.** Only a small set of LinkedIn products can be enabled without review, and every one of them is scoped to the member who authenticates: reading that member's own name, headline, photo and primary email through Sign in with LinkedIn, and posting or commenting as that member through Share on LinkedIn. Verified on LinkedIn adds a self-serve Development tier for testing. There is no endpoint a standard developer account can call to search for arbitrary people, look up another member by profile URL, send ordinary member-to-member messages, or read a member's inbox. For those jobs you drive an account you already own, which is what [Linked API](/pricing) does.

## What you can enable self-serve today

LinkedIn states the rule plainly in its [access documentation](https://learn.microsoft.com/en-us/linkedin/shared/authentication/getting-access):

> "Most permissions and partner programs require explicit approval from LinkedIn. Open Permissions are the only permissions that are available to all developers without special approval."

These are the Open Permissions, added through the Products tab on your own application:

| Product | Permission | What it grants |
|---|---|---|
| Sign in with LinkedIn using OpenID Connect | `profile` | **Member Auth**: Retrieve authenticated member's name, headline, and photo. |
| Sign in with LinkedIn using OpenID Connect | `email` | **Member Auth**: Retrieve authenticated member's primary email address. |
| Share on LinkedIn | `w_member_social` | **Member Auth**: Post, comment and like posts on behalf of an authenticated member. |

One more route is self-serve and often missed. **Verified on LinkedIn** offers a Development tier you can enable immediately, restricted to admin accounts and intended for testing, plus a Lite tier you request self-serve for consenting members, per [LinkedIn's Verified API documentation](https://www.linkedin.com/help/linkedin/answer/a9385085). Its endpoints take their own scopes: [`/identityMe`](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/verified-on-linkedin/api-reference/identity-me) requires `r_profile_basicinfo`, and [`/verificationReport`](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/verified-on-linkedin/api-reference/verification-report) requires `r_verify_details`, with the older `r_verify` still accepted.

Read the pattern rather than the list. **Every self-serve permission acts on the member who just signed in.** You get their details because they authenticated, and you publish as them because they authorised it. Nothing in this set reaches outward to other members.

## How to get self-serve LinkedIn API access

The self-serve path is short, and most of the friction is in details that are easy to get wrong.

1. **Create an application** in the LinkedIn Developer Portal. You will be asked to associate it with a LinkedIn Page, so have one ready or create it first – an application cannot exist without it.
2. **Enable your products** on the application's Products tab. Sign in with LinkedIn using OpenID Connect and Share on LinkedIn appear immediately. Verified on LinkedIn is requested from the same tab: accept the terms and the Development tier is provisioned automatically, while Lite is a self-serve request. Anything reviewed shows an application flow instead of a switch.
3. **Configure your redirect URL** on the Auth tab. It must match byte for byte what your application sends, including the scheme and any trailing path, per LinkedIn's [3-legged OAuth flow](https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow). A mismatch fails the authorisation request rather than degrading.
4. **Request only the scopes your enabled products grant.** A scope your application has not been granted is rejected outright, so a request that mixes granted and ungranted scopes returns nothing at all.
5. **Send the member through the authorisation flow**, exchange the returned code for an access token, and make your first call as that member.

## What standard developer access does not reach

Four jobs come up constantly, and none of them is reachable this way:

![Self-serve LinkedIn access covers you, not other people: included are your own name, headline and photo, your email address, posting as you, and your verified identity, all granted when you sign in; not included are finding people, reading a profile, sending a message and reading an inbox, which need an account you already own](/images/guides/linkedin-api-access-scope.webp)

Some of these capabilities do exist inside narrowly scoped reviewed and partner integrations, which are bound to a product context rather than exposed as general-purpose endpoints and are [approval-gated](https://learn.microsoft.com/en-us/linkedin/shared/authentication/getting-access). If you work in Sales Navigator, that picture is covered in our [Sales Navigator API guide](/guides/linkedin-sales-navigator-api).

The practical position is simpler than the documentation makes it look: **for these four jobs there is nothing a standard developer account can switch on.**

## What to build on instead

The alternative is to work through an account you already have. The member is you or your team, the account is one you own, and the primitives are exposed programmatically. Both routes below are first-class – pick by how you want to work, not by how much you want to build.

### Build it in – REST, Node and Python SDKs, CLI

Compose the primitives and embed them in your product. A search returns each person's `publicUrl`, which you pass straight into a fetch:

```typescript
import { LinkedApi } from '@linkedapi/node';

const linkedapi = new LinkedApi({
  linkedApiToken: 'your-linked-api-token',
  identificationToken: 'your-identification-token',
});

const workflow = await linkedapi.searchPeople.execute({
  term: "Head of Engineering",
  limit: 10,
  filter: {
    locations: ["San Francisco"],
    industries: ["Software Development"],
  },
});

const { data, errors } = await linkedapi.searchPeople.result(workflow.workflowId);

if (errors?.length) {
  errors.forEach((error) => console.warn(`${error.type}: ${error.message}`));
}

if (data) {
  for (const person of data) {
    const detail = await linkedapi.fetchPerson.execute({ personUrl: person.publicUrl });
    const result = await linkedapi.fetchPerson.result(detail.workflowId);

    if (result.data) {
      console.log(result.data.name, result.data.headline, result.data.location);
    }
  }
}
```

```python
from linkedapi import LinkedApi, LinkedApiConfig, SearchPeopleParams, FetchPersonParams

linkedapi = LinkedApi(
    LinkedApiConfig(
        linked_api_token="your-linked-api-token",
        identification_token="your-identification-token",
    )
)

workflow = linkedapi.search_people.execute(
    SearchPeopleParams(
        term="Head of Engineering",
        limit=10,
        filter={
            "locations": ["San Francisco"],
            "industries": ["Software Development"],
        },
    )
)

result = linkedapi.search_people.result(workflow.workflow_id)

for error in result.errors or []:
    print(f"{error.type}: {error.message}")

if result.data:
    for person in result.data:
        detail = linkedapi.fetch_person.execute(
            FetchPersonParams(person_url=person.public_url)
        )
        person_result = linkedapi.fetch_person.result(detail.workflow_id)

        if person_result.data:
            print(
                person_result.data.name,
                person_result.data.headline,
                person_result.data.location,
            )
```

The same primitives cover the other three jobs. Messaging is `sendMessage`, and the inbox is a two-step pattern rather than a single read: `syncInbox` starts monitoring, then `pollInbox` retrieves what has arrived since. The same operations run from the shell as `linkedin person search`, `linkedin person fetch`, `linkedin message send`, `linkedin inbox sync` and `linkedin inbox get`.

Each job has its own guide with the depth this page deliberately skips: [people search](/docs/searching-for-people), [profile data](/guides/linkedin-profile-scraper), and [messaging and inbox](/guides/how-to-automate-linkedin-messages).

### Run it out of the box – MCP, the AI-agent-friendly CLI, ready-made skills

If you would rather not build the integration at all, an AI agent can do it. Connect the [MCP server](/mcp), point an agent at the [CLI](/cli) from Claude Code, Cursor or Codex, or install ready-made skills with `npx @linkedapi/skills`. You describe the job in plain language and the agent composes and runs the same workflows. Nothing to wire, no flows to configure.

## When the self-serve products are the right answer

Reach for LinkedIn's own products, not an alternative, when the job actually matches what they do:

- **You need members to sign in.** Sign in with LinkedIn using OpenID Connect is built for exactly this, and nothing else should be used for authentication.
- **You need to publish as the member who authorised you.** Share on LinkedIn covers posting, commenting and liking on their behalf.
- **You need identity verification signals.** Verified on LinkedIn is the route, starting on the Development tier.

The account-based route earns its place when the job reaches beyond the authenticated member – reading data about other people, or acting continuously rather than at the moment someone clicks a button.

## Frequently Asked Questions (FAQ)

#### What LinkedIn API access can I get without approval?

The Open Permissions – `profile` and `email` through Sign in with LinkedIn using OpenID Connect, and `w_member_social` through Share on LinkedIn – plus Verified on LinkedIn, whose Development tier is provisioned automatically on accepting the terms and whose Lite tier is a self-serve request. Every one of these acts on the member who authenticated.

#### How do I set up self-serve LinkedIn API access?

Create an application in the Developer Portal and associate it with a LinkedIn Page, enable your products on the Products tab, set the redirect URL on the Auth tab so it matches your application exactly, request only the scopes your enabled products grant, then send the member through the authorisation flow and exchange the code for a token.

#### Why can't I search for people with standard developer access?

There is no general-purpose people-search endpoint available to a standard developer account. Search capabilities exist inside narrowly scoped reviewed and partner integrations tied to a product context, not as an open endpoint. The alternative is to run the search through an account you own.

#### Can I read another member's profile with standard developer access?

No. The self-serve permissions return the authenticated member's own details, not other members'. Reading another member's profile from a URL is not something a standard developer account can enable, which is why account-based routes exist.

#### What do I use when self-serve products don't cover the job?

An account-based API that drives a LinkedIn account you already own. Linked API exposes people search, profile fetch, messaging and inbox as programmable primitives through the REST API, Node and Python SDKs and the CLI, or out of the box through MCP, the AI-agent-friendly CLI and ready-made skills.

## Build on the account you already have

If the self-serve products cover your job, use them. If your job needs to reach past the member who signed in, Linked API runs those operations on an account you own, through a dedicated cloud browser at a human pace. Embed it through the [REST API, SDKs and CLI](/sdks), or skip the build and let an agent run it through [MCP](/mcp) or [ready-made skills](/skills). Pricing is flat per seat – see [pricing](/pricing).

*Facts verified 3 August 2026 – LinkedIn permission names, product availability and endpoint scopes checked against LinkedIn's official developer and help documentation on that date.*
