Search

How to Create a LinkedIn Developer App for Laravel (Step by Step)

How to Create a LinkedIn Developer App for Laravel (Step by Step)

Series: Laravel + LinkedIn Auto-Posting Overview · Part 1: Developer app · Part 2: OAuth token · Part 3: Token renewal · Part 4: post:share command

Before Laravel can post anything to LinkedIn, LinkedIn needs to know about your application. That happens in the LinkedIn Developer Portal, where you create an app, attach the products that grant API permissions, and register the URLs LinkedIn may redirect back to.

Also Read: Livewire 4 Islands in Filament: Where They Actually Help

This part covers every screen you'll touch, the settings that matter, and the mistakes that cost the most time: an unverified page, a missing product, or a redirect URL that doesn't match.

About the screenshots: the images in this article are simplified illustrations of the Developer Portal screens, so they stay readable as LinkedIn's UI changes. Labels and field names match the portal at the time of writing.

What you need before you start

  • A personal LinkedIn account. It will be the app's owner.
  • A LinkedIn company page where you are an admin. Every developer app must be associated with one, even if you only post to your personal profile.
  • A privacy policy URL (for example https://thewebtier.com/privacy-policy).
  • A square app logo, at least 100×100 px.
  • The HTTPS URL of your Laravel site.

Step 1: Create the app

Go to linkedin.com/developers/apps and click Create app.

Illustration of the LinkedIn Developer Portal 'Create an app' form with app name, LinkedIn Page, privacy policy URL and logo fields Illustration: the "Create an app" form.

Fill in:

Also Read: Filament on Laravel 13: The Complete Compatibility Checklist

FieldWhat to enterTip
App nameTheWebTier PublisherReaders see it on the consent screen, so make it recognisable
LinkedIn PageYour company pageSearch by name or paste the page URL
Privacy policy URLhttps://yoursite.com/privacy-policyMust be reachable
App logoSquare PNG/JPGAlso shown on the consent screen
Legal agreementTick to acceptRead the API Terms of Use

Click Create app. You'll land on the app's Settings tab.

Step 2: Verify the company page

A new app is linked to your page but not yet verified, and some products can't be added until it is.

  1. On the Settings tab, find the LinkedIn Page card and click Verify.
  2. Click Generate URL.
  3. Open that URL while logged in as a page admin (probably you) and approve.

Refresh the Settings tab. The page should now say Verified.

Common gotcha: if you're not a super admin of the page, the verification link does nothing useful. Send it to someone who is.

Step 3: Add the products (this is where scopes come from)

LinkedIn doesn't let you pick scopes directly. You add products, and each product unlocks a set of OAuth scopes. Open the Products tab.

Illustration of the Products tab showing 'Share on LinkedIn' and 'Sign In with LinkedIn using OpenID Connect' as added Illustration: the two self-serve products you need.

Also Read: Laravel and PHP

Request these two. Both are self-serve and are usually granted instantly:

ProductScopes it grantsWhy you need it
Share on LinkedInw_member_socialCreate posts as the authenticated member
Sign In with LinkedIn using OpenID Connectopenid, profile, emailRead your member ID (sub), which becomes the post author urn:li:person:{id}

What about posting as a company page?

Posting as your page (urn:li:organization:…) needs w_organization_social, which comes from the Community Management API product. That product:

  • requires an access request and review by LinkedIn, and
  • at the time of writing, has to be requested on an app that has no other products, so many teams create a second app just for it.

Start with member posting. The code in this series takes the author URN as configuration, so moving to a page later won't need a rewrite. See Community Management API for the review requirements.

Step 4: Configure OAuth on the Auth tab

Open the Auth tab. This is where you'll find your credentials and register redirect URLs.

Also Read: Best Filament Themes and PHP Starter Kits for 2026 (v5-Ready)

Illustration of the Auth tab showing Client ID, masked Client Secret, authorized redirect URLs and OAuth 2.0 scopes Illustration: the Auth tab after adding redirect URLs. The secret is masked.

4a. Copy the Client ID and Client Secret

Treat the Client Secret like a database password. Never commit it, never put it in a query string, never paste it in a support ticket. If it leaks, use Generate a new Client Secret on this tab.

4b. Add the authorized redirect URLs

Click the pencil next to Authorized redirect URLs for your app and add:

https://yoursite.com/admin/linkedin/callback
https://yoursite.com/linkedin/cli-callback

The first URL is for the one-click web flow and the second is for the linkedin:auth artisan command. Both are built in Part 2.

Also Read: Claude Code & Cursor on Filament: AI Agent Rules That Work - Laravel

LinkedIn's rules for redirect URLs:

  • They must be absolute (https://…), not /admin/linkedin/callback.
  • Query parameters are ignored when matching.
  • They can't contain #.
  • The value your app sends must match exactly. https://www. and https:// count as different URLs, and so do URLs with and without a trailing slash.

For local development, add your local URL as well (for example a Laravel Herd or Valet .test domain served over HTTPS, or a tunnel URL).

4c. Check the scopes

Under OAuth 2.0 scopes you should see openid, profile, email and w_member_social. If w_member_social is missing, the Share on LinkedIn product wasn't added. Go back to Step 3.

Step 5: Put the credentials in Laravel

Add the values to .env:

LINKEDIN_CLIENT_ID=86xxxxxxxxxxxx
LINKEDIN_CLIENT_SECRET=WPL_AP1.xxxxxxxxxxxxxxxx
LINKEDIN_REDIRECT_URI="${APP_URL}/admin/linkedin/callback"
LINKEDIN_CLI_REDIRECT_URI="${APP_URL}/linkedin/cli-callback"
LINKEDIN_API_VERSION=202609
[email protected]

A .env file in a code editor showing LinkedIn client ID, secret, redirect URIs and API version The LinkedIn block in .env. Keep APP_URL accurate, because the redirect URIs are built from it.

Also Read: How to Create a WordPress Plugin from Scratch (2026 Guide)

Then register them in config/services.php. We use the key linkedin-openid because that's the name of Laravel Socialite's LinkedIn driver, so Socialite picks it up automatically:

// config/services.php
'linkedin-openid' => [
    'client_id'     => env('LINKEDIN_CLIENT_ID'),
    'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
    'redirect'      => env('LINKEDIN_REDIRECT_URI'),

    // Our own keys (Socialite ignores these)
    'cli_redirect'  => env('LINKEDIN_CLI_REDIRECT_URI'),
    'api_version'   => env('LINKEDIN_API_VERSION', '202609'),
    'notify_email'  => env('LINKEDIN_NOTIFY_EMAIL'),
],

Why LINKEDIN_API_VERSION? Every call to LinkedIn's versioned REST API must send a LinkedIn-Version: YYYYMM header, and LinkedIn sunsets each version after about a year. The October 2025 version, for example, is retired on 15 October 2026. Keeping the version in .env means an upgrade is a config change, not a deploy. Check the versioning page twice a year.

In production, cache the config so env() is only read once:

php artisan config:cache

Step 6 (optional): Smoke-test with the Token Generator

Before writing any OAuth code, you can confirm the app works using LinkedIn's built-in OAuth Token Generator:

  1. Choose your app.
  2. Tick openid, profile and w_member_social.
  3. Click Request access token and approve.

Then call the userinfo endpoint:

curl -s https://api.linkedin.com/v2/userinfo \
  -H "Authorization: Bearer YOUR_TOKEN" | jq

If you see your sub, name and email, the app is configured correctly. This token also lasts 60 days, so it's fine for a quick test. For production you'll generate tokens from Laravel (Part 2) so they can be renewed without manual steps (Part 3).

Troubleshooting checklist

SymptomCauseFix
unauthorized_scope_error / "Invalid scope"Product not addedAdd Share on LinkedIn / Sign In with LinkedIn using OpenID Connect
"The redirect_uri does not match the registered value"URL mismatch (www, slash, http vs https)Copy the URL from .env into the Auth tab exactly
Can't add a productPage not verifiedFinish Step 2
Everything worked, now 401sToken expired (60 days) or scopes changedSee Part 3

Key takeaways

  • LinkedIn gives you scopes through products. For personal posting you need Share on LinkedIn and Sign In with LinkedIn using OpenID Connect.
  • Redirect URLs must match exactly and be absolute HTTPS URLs.
  • Keep the secret and the API version in .env, and read them only through config().

Next up

Part 2: Get a LinkedIn OAuth Access Token in Laravel →, where you'll connect your account with Socialite or a plain-PHP artisan command and store the token encrypted.

Further reading: LinkedIn Authentication overview, Getting access to LinkedIn APIs, Laravel configuration docs.

Usama Muneer

Usama Muneer

Coder, Blogger, Tech Speaker & Web Technologies Enthusiast. Passionate about working on open-source Programming languages & Tools while utilizing my Product Development skills.

Your experience on this site will be improved by allowing cookies Cookie Policy