Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with LinkedIn Learning

To integrate Lovable with LinkedIn Learning, create a Supabase Edge Function that calls the LinkedIn Learning API using OAuth2 credentials stored in Cloud → Secrets. The API provides access to course catalogs, learner progress data, and personalized recommendations. Use Lovable's chat to build corporate learning dashboards and course discovery UIs on top of the Edge Function proxy.

What you'll learn

  • How to set up LinkedIn Learning API credentials and understand the corporate access requirements
  • How to store LinkedIn Learning OAuth credentials securely in Cloud → Secrets
  • How to create an Edge Function that proxies LinkedIn Learning API requests
  • How to build a corporate learning dashboard showing course assignments and learner progress
  • How LinkedIn Learning's professional development focus differs from academic platforms like Coursera
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read50 minutesSocialMarch 2026RapidDev Engineering Team
TL;DR

To integrate Lovable with LinkedIn Learning, create a Supabase Edge Function that calls the LinkedIn Learning API using OAuth2 credentials stored in Cloud → Secrets. The API provides access to course catalogs, learner progress data, and personalized recommendations. Use Lovable's chat to build corporate learning dashboards and course discovery UIs on top of the Edge Function proxy.

Build corporate learning dashboards and course discovery tools with LinkedIn Learning API

LinkedIn Learning's API is designed primarily for enterprise learning management: organizations with LinkedIn Learning licenses can retrieve their course catalog, track learner progress, assign courses to employees, and pull completion certificates. The API is part of LinkedIn's broader developer ecosystem and uses the same OAuth2 infrastructure as other LinkedIn APIs. However, unlike LinkedIn's general social APIs, Learning API access requires an active LinkedIn Learning organizational license — individual accounts cannot access the full learner management endpoints.

The main use cases in Lovable are HR and L&D (Learning and Development) dashboards: visualizing which employees have completed required compliance training, tracking skill development across a team, surfacing recommended courses based on job title or department, and generating reports on learning activity. These dashboards pull data through the Edge Function and store it in Supabase for trend analysis and historical reporting.

LinkedIn Learning is distinct from Coursera in important ways. LinkedIn Learning is professional and corporate-focused: courses are shorter (typically 1-4 hours), taught by practitioners rather than professors, and oriented toward job-relevant skills like leadership, project management, and software tools. Coursera is academic: courses are longer, university-affiliated, include graded assignments, and often lead to certificates or degrees. For corporate L&D programs where the goal is practical skill development and compliance training, LinkedIn Learning is the appropriate API. For academic certificate programs or university partnerships, Coursera's API better fits the use case.

Integration method

Edge Function Integration

LinkedIn Learning uses OAuth2 for API authentication and provides endpoints for course catalog access, learner activity reporting, and skill recommendations. Because OAuth tokens must stay server-side, all API calls are proxied through a Supabase Edge Function. Your React frontend calls the Edge Function, which retrieves course and learner data using credentials stored in Cloud → Secrets.

Prerequisites

  • A Lovable account with a project that has Lovable Cloud enabled
  • An active LinkedIn Learning organizational license (API access requires a paid corporate LinkedIn Learning subscription)
  • A LinkedIn developer application registered at developer.linkedin.com with Learning API access approved
  • OAuth2 client credentials (client ID and client secret) from the LinkedIn developer portal
  • An OAuth2 access token with the r_learning_partner_reporting scope for learner data access

Step-by-step guide

1

Set up LinkedIn Learning API access and obtain OAuth credentials

LinkedIn Learning API access requires two things: an active organizational LinkedIn Learning license and a LinkedIn developer application with the Learning API product enabled. Start by going to developer.linkedin.com and signing in with your LinkedIn account. Click 'Create app' and fill in the app name, your company's LinkedIn page (required), and app logo. Under 'Products', look for 'Learning and Development API' — request access to this product. LinkedIn reviews these requests and may contact you to verify your organizational license. Once your app is approved, go to the app's 'Auth' tab in the developer portal. Note the Client ID and Client Secret. For the OAuth2 scopes needed, request: r_learning_partner_catalog (course catalog read), r_learning_partner_reporting (learner activity data), and rw_learning_partner_admin if you need to assign courses programmatically. To generate an access token for your organization's learning data, use the OAuth2 client credentials flow (also called two-legged OAuth or application-only auth). Make a POST request to https://www.linkedin.com/oauth/v2/accessToken with grant_type=client_credentials, your client_id, and client_secret. This returns an access token valid for 30 minutes. For production use, your Edge Function must refresh this token before it expires — the short expiry is a LinkedIn API constraint you cannot configure around. Note: the LinkedIn Learning API is not publicly available. If you do not have an organizational LinkedIn Learning license, you will receive authorization errors when attempting to access learner data endpoints. The catalog endpoints may be accessible with lower-tier access, but learner reporting requires the full organizational license.

Pro tip: LinkedIn Learning API tokens expire in 30 minutes. Build your Edge Function to perform token refresh automatically using the client credentials flow before each API call, rather than relying on a stored token in Secrets.

Expected result: You have a LinkedIn developer application with Learning API access approved, a client ID, a client secret, and can successfully generate access tokens using the client credentials flow.

2

Store LinkedIn Learning credentials in Cloud → Secrets

Open your Lovable project and click the '+' icon next to the Preview label to open the Cloud panel. Navigate to the Secrets tab and add the following secrets: - Name: LINKEDIN_CLIENT_ID — Value: your LinkedIn application Client ID - Name: LINKEDIN_CLIENT_SECRET — Value: your LinkedIn application Client Secret - Name: LINKEDIN_ORG_ID — Value: your LinkedIn organization ID (visible in your LinkedIn company page URL) Because LinkedIn Learning API tokens expire in 30 minutes and cannot be stored long-term, the Edge Function will request a fresh token on each invocation using the client credentials flow. This means you do not need to store an access token as a secret — the client ID and secret are sufficient for the Edge Function to authenticate itself. The organization ID is needed for endpoints that scope data to your specific LinkedIn Learning contract, such as learner reporting and course assignment. You can find it by navigating to your company's LinkedIn page and extracting the numeric ID from the URL. Keep these credentials strictly in Cloud → Secrets. LinkedIn's API uses client credentials that, if exposed, could be used to access your organization's employee learning records — a significant privacy concern. Never paste them into Lovable's chat or into source code.

Expected result: LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET, and LINKEDIN_ORG_ID appear in Cloud → Secrets with masked values.

3

Create the LinkedIn Learning API proxy Edge Function

Create a Supabase Edge Function that handles token generation and API proxying for LinkedIn Learning. Because tokens expire in 30 minutes, the function performs a fresh token request on each invocation using the client credentials flow, then uses the resulting token to call the LinkedIn Learning API endpoint. The function handles three types of requests: course catalog search (GET /v2/learningAssets), learner activity reporting (GET /v2/learningAssetsAvailableToOrganizationUser), and organization learning summary (GET /v2/learnerActivitySummaryReports). Each maps to a different LinkedIn Learning API endpoint with different required parameters. Paste the prompt below into Lovable's chat to create the function. Verify it deploys successfully by checking Cloud → Edge Functions.

Lovable Prompt

Create a Supabase Edge Function at supabase/functions/linkedin-learning/index.ts. On each request, first obtain a fresh OAuth token by POSTing to https://www.linkedin.com/oauth/v2/accessToken with grant_type=client_credentials, client_id=LINKEDIN_CLIENT_ID, and client_secret=LINKEDIN_CLIENT_SECRET from Deno.env. Then use that token to call the LinkedIn Learning API. Accept a JSON body with 'endpoint' (catalog | learner_activity | org_summary) and 'params' (optional query parameters). Return the LinkedIn Learning API response as JSON with CORS headers.

Paste this in Lovable chat

supabase/functions/linkedin-learning/index.ts
1// supabase/functions/linkedin-learning/index.ts
2const LINKEDIN_TOKEN_URL = 'https://www.linkedin.com/oauth/v2/accessToken';
3const LINKEDIN_API_BASE = 'https://api.linkedin.com';
4
5async function getAccessToken(): Promise<string> {
6 const clientId = Deno.env.get('LINKEDIN_CLIENT_ID');
7 const clientSecret = Deno.env.get('LINKEDIN_CLIENT_SECRET');
8 if (!clientId || !clientSecret) throw new Error('LinkedIn credentials not configured');
9
10 const tokenBody = new URLSearchParams({
11 grant_type: 'client_credentials',
12 client_id: clientId,
13 client_secret: clientSecret,
14 });
15
16 const response = await fetch(LINKEDIN_TOKEN_URL, {
17 method: 'POST',
18 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
19 body: tokenBody,
20 });
21
22 const data = await response.json();
23 if (!data.access_token) throw new Error(`Token fetch failed: ${JSON.stringify(data)}`);
24 return data.access_token;
25}
26
27Deno.serve(async (req) => {
28 if (req.method === 'OPTIONS') {
29 return new Response(null, {
30 headers: {
31 'Access-Control-Allow-Origin': '*',
32 'Access-Control-Allow-Methods': 'POST, OPTIONS',
33 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
34 },
35 });
36 }
37
38 try {
39 const accessToken = await getAccessToken();
40 const { endpoint, params } = await req.json();
41 const orgId = Deno.env.get('LINKEDIN_ORG_ID');
42
43 let apiUrl: string;
44 if (endpoint === 'catalog') {
45 const q = new URLSearchParams({ q: 'criteria', ...(params || {}) });
46 apiUrl = `${LINKEDIN_API_BASE}/v2/learningAssets?${q}`;
47 } else if (endpoint === 'learner_activity') {
48 const q = new URLSearchParams({ organizationId: orgId!, ...(params || {}) });
49 apiUrl = `${LINKEDIN_API_BASE}/v2/learnerActivityReports?${q}`;
50 } else if (endpoint === 'org_summary') {
51 apiUrl = `${LINKEDIN_API_BASE}/v2/learnerActivitySummaryReports?organizationId=${orgId}`;
52 } else {
53 return new Response(JSON.stringify({ error: 'Invalid endpoint' }), {
54 status: 400,
55 headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
56 });
57 }
58
59 const apiResponse = await fetch(apiUrl, {
60 headers: {
61 'Authorization': `Bearer ${accessToken}`,
62 'X-Restli-Protocol-Version': '2.0.0',
63 },
64 });
65
66 const data = await apiResponse.json();
67 return new Response(JSON.stringify(data), {
68 status: apiResponse.status,
69 headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
70 });
71 } catch (err) {
72 return new Response(JSON.stringify({ error: err.message }), {
73 status: 500,
74 headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
75 });
76 }
77});

Pro tip: LinkedIn Learning API requires the X-Restli-Protocol-Version: 2.0.0 header on all requests. Omitting this header causes inconsistent response formats and may result in 400 errors on some endpoints.

Expected result: The linkedin-learning Edge Function is deployed. Calling it with { endpoint: 'catalog' } returns LinkedIn Learning course objects including titles, descriptions, and learning asset URNs.

4

Build the corporate learning dashboard

With the Edge Function deployed, use Lovable's chat to generate the learning dashboard components. For an L&D dashboard, the most valuable views are: an overview of organizational learning activity (total completions, hours logged, active learners), a per-employee progress table with filtering by department or manager, and a course catalog browser for discovering and assigning new content. The LinkedIn Learning API returns learning asset URNs as identifiers rather than simple IDs. When displaying courses, use the content title and a constructed URL in the format https://www.linkedin.com/learning/{course-slug} to link users directly to the course on LinkedIn Learning. For progress visualization, store API responses in Supabase rather than fetching live for every dashboard load. LinkedIn's learner reporting API has rate limits and higher latency than typical REST APIs — caching results hourly in a Supabase table significantly improves dashboard performance. Store the raw API response alongside a fetched_at timestamp and return cached data if it is less than one hour old. For complex enterprise deployments with thousands of employees, department hierarchies, and custom learning path tracking, RapidDev's team can help architect the data pipeline from LinkedIn Learning API through Supabase to your dashboard.

Lovable Prompt

Create a learning dashboard with three sections: (1) an overview card showing total learning hours, completions, and active learners this month from the linkedin-learning Edge Function org_summary endpoint; (2) a searchable table of employees showing their LinkedIn Learning activity including courses completed, hours logged, and last active date from the learner_activity endpoint; (3) a course catalog section that lets users search LinkedIn Learning courses by keyword and skill. Store fetched data in Supabase with a 1-hour cache TTL.

Paste this in Lovable chat

Expected result: A learning dashboard displays organizational learning statistics, an employee activity table, and a course search panel. Data loads from the Edge Function on the first visit and from Supabase cache on subsequent visits within the hour.

Common use cases

Employee learning progress dashboard

Build an HR dashboard that shows which employees have completed required courses, tracks hours of learning per team, and flags overdue compliance training. The dashboard pulls learner activity from the LinkedIn Learning API via the Edge Function and displays it in sortable tables with completion percentage charts.

Lovable Prompt

Create an employee learning dashboard that calls the linkedin-learning Edge Function to fetch learning activity for all employees in my organization. Show a table with employee name, courses completed this quarter, total learning hours, and a completion badge for any required compliance courses. Add a filter to view by department or manager.

Copy this prompt to try it in Lovable

Personalized course recommendation widget

Add a course recommendation panel to an existing HR or onboarding tool that suggests LinkedIn Learning courses based on an employee's job title, department, or skill gaps. The recommendations are fetched from the LinkedIn Learning API and displayed with course title, duration, skill level, and an enrollment deep link.

Lovable Prompt

Build a course recommendations panel that calls the linkedin-learning Edge Function with a job title parameter and returns relevant LinkedIn Learning courses. Display the top 6 recommendations as cards with thumbnail, course title, instructor name, duration, and a direct link to the course on LinkedIn Learning. Add a 'Save for Later' button that stores the course URL in Supabase.

Copy this prompt to try it in Lovable

Learning path assignment and tracking tool

Create a tool where managers can assign specific LinkedIn Learning courses or learning paths to team members, track completion, and send reminders for incomplete assignments. Assignments are stored in Supabase and completion data is synced from the LinkedIn Learning API.

Lovable Prompt

Build a learning assignment tool where managers can search LinkedIn Learning courses via the Edge Function, assign them to team members by email, set a due date, and save assignments to a Supabase table called 'learning_assignments'. Show each assigned employee's completion status by checking the Edge Function for their learning activity. Send a reminder notification 3 days before the due date.

Copy this prompt to try it in Lovable

Troubleshooting

API returns 403 Forbidden with 'Not enough permissions to access: GET /v2/learnerActivityReports'

Cause: The LinkedIn Learning API scope granted to your application does not include learner reporting, or your organizational LinkedIn Learning license does not include API access to reporting data.

Solution: Go to developer.linkedin.com, open your app, and check the requested OAuth2 scopes under the Auth tab. Verify that r_learning_partner_reporting is included. If it is not listed as an available scope, your app may not have been approved for Learning API access — contact LinkedIn's developer support. Additionally, confirm with your LinkedIn Learning account manager that your organizational license includes API access to learner reporting.

Token request fails with 'invalid_client' error

Cause: The client credentials stored in Cloud → Secrets do not match the credentials in the LinkedIn developer portal, or the LinkedIn application's products do not include the Learning API.

Solution: Go to developer.linkedin.com and open your application. Copy the Client ID and Client Secret from the Auth tab. Verify they match exactly what is stored in LINKEDIN_CLIENT_ID and LINKEDIN_CLIENT_SECRET in Cloud → Secrets. Also confirm under Products that your app has been approved for the Learning and Development API — if it shows as pending, your API calls will fail until approval is granted.

API responses are missing the X-Restli-Protocol-Version header and return unexpected data formats

Cause: The Edge Function is not sending the required X-Restli-Protocol-Version: 2.0.0 header on API requests. LinkedIn's API supports multiple protocol versions with different response structures.

Solution: Add the X-Restli-Protocol-Version: 2.0.0 header to every LinkedIn API request in your Edge Function. Without this header, the API may default to protocol version 1.0.0 which uses different field names and response structures that will not match your frontend's expectations.

typescript
1// Always include this header in LinkedIn API requests
2const apiResponse = await fetch(apiUrl, {
3 headers: {
4 'Authorization': `Bearer ${accessToken}`,
5 'X-Restli-Protocol-Version': '2.0.0', // required
6 },
7});

Best practices

  • Obtain fresh OAuth tokens on each Edge Function invocation using the client credentials flow — LinkedIn tokens expire in 30 minutes and cannot be stored long-term
  • Include the X-Restli-Protocol-Version: 2.0.0 header on all LinkedIn API requests to ensure consistent response formatting
  • Cache learner activity reports in Supabase with at least a 1-hour TTL — the reporting API has higher latency than typical REST APIs and the data changes infrequently
  • Store the LinkedIn learning asset URN alongside any course records in your Supabase database so you can reconstruct the direct course URL without additional API calls
  • Scope API access to the minimum required permissions — request r_learning_partner_reporting only if you need learner data, and r_learning_partner_catalog only if you need course catalog access
  • Confirm that your organizational LinkedIn Learning license includes API access before building the integration — learner reporting endpoints return 403 for accounts without the correct license tier
  • Build your dashboard to work with cached data as the primary source and fresh API data as the refresh mechanism, rather than making live API calls on every page load

Alternatives

Frequently asked questions

Do I need a paid LinkedIn Learning subscription to use the API?

Yes — the LinkedIn Learning API for learner reporting and course management requires an active LinkedIn Learning organizational license. Individual LinkedIn Premium accounts do not grant API access to learner data. The API is designed for HR and L&D teams at organizations that have purchased LinkedIn Learning licenses for their employees. If you only need to link to LinkedIn Learning courses (not access learner data), you can do this with direct URLs without any API access.

Why do LinkedIn Learning API tokens expire so quickly?

LinkedIn Learning uses the OAuth2 client credentials flow with a 30-minute token lifetime as a security measure — short-lived tokens limit the window of exposure if a token is compromised. Unlike user-based OAuth tokens that support refresh tokens, client credentials tokens cannot be refreshed; you simply request a new one. The Edge Function pattern in this tutorial handles this by requesting a fresh token on each function invocation, which adds a small latency overhead (typically 200-400ms) but ensures the token is always valid.

Can employees of my organization log in with LinkedIn to see their own learning progress?

LinkedIn Learning's organization API uses service-to-service authentication (client credentials) rather than user-delegated OAuth. This means your Lovable app calls the API on behalf of the organization, not individual users. To show individual employees their own learning data, your app needs to map the employee's Lovable user ID to their LinkedIn member URN and filter the learner activity API response by that URN. Employees do not need to authenticate with LinkedIn in your app — the organizational API credentials are sufficient to retrieve their data.

What is the difference between LinkedIn Learning and Lynda.com?

Lynda.com was the original platform that LinkedIn acquired in 2015. It was fully rebranded and integrated into LinkedIn Learning in 2016-2017. The Lynda.com brand is no longer active — all courses, content, and API access now goes through LinkedIn Learning. If you see references to the Lynda API in older tutorials or documentation, those apply to what is now the LinkedIn Learning API.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.