Tóm tắt
API LinkedIn cung cấp cho nhà phát triển quyền truy cập lập trình vào mạng lưới chuyên nghiệp của LinkedIn. Sử dụng xác thực OAuth 2.0, RESTful endpoints và GraphQL, bạn có thể thao tác hồ sơ, bài đăng, bình luận, trang công ty và quảng cáo. Giới hạn tốc độ là 100-500 yêu cầu/ngày/ứng dụng. Bài viết này tập trung vào các bước thực tế: thiết lập xác thực, truy xuất hồ sơ, đăng nội dung, quản lý trang công ty, API quảng cáo và chiến lược triển khai sản xuất.
Giới thiệu
LinkedIn sở hữu hơn 900 triệu người dùng chuyên nghiệp tại hơn 200 quốc gia. Nếu bạn xây dựng công cụ tuyển dụng, nền tảng tiếp thị hoặc ứng dụng B2B, tích hợp API LinkedIn là chìa khóa để tiếp cận nhóm khách hàng này.
Quản lý LinkedIn thủ công cho B2B mất đến 15-20 giờ/tuần (đăng bài, theo dõi tương tác, tạo khách hàng tiềm năng). Tích hợp API LinkedIn sẽ tự động hóa quy trình đăng bài, thu thập khách hàng, phân tích và tuyển dụng.
Bài viết này hướng dẫn bạn tích hợp API LinkedIn từ đầu đến cuối: xác thực OAuth 2.0, truy xuất hồ sơ, đăng bài, quản lý trang công ty, quảng cáo, webhook và các lưu ý triển khai sản xuất. Sau bài viết, bạn sẽ có thể triển khai tích hợp LinkedIn sẵn sàng cho sản xuất.
💡 Apidog đơn giản hóa kiểm thử tích hợp API. Bạn có thể kiểm thử endpoints LinkedIn, xác thực luồng OAuth, kiểm tra phản hồi API và debug quyền trong một workspace. Nhập đặc tả API, mô phỏng phản hồi, chia sẻ test case với team.
API LinkedIn là gì?
LinkedIn cung cấp API RESTful và GraphQL để truy cập dữ liệu mạng lưới chuyên nghiệp. Các chức năng chính của API gồm:
- Truy xuất hồ sơ người dùng (cần sự đồng ý)
- Làm việc với trang công ty và cập nhật
- Bài đăng, bình luận, phản ứng
- Kết nối (hạn chế)
- Đăng và ứng tuyển việc làm
- Quản lý quảng cáo
- Biểu mẫu khách hàng tiềm năng
- Nhắn tin (chỉ cho đối tác giới hạn)
Các tính năng chính
| Tính năng | Mô tả |
|---|---|
| RESTful + GraphQL | Nhiều kiểu API |
| OAuth 2.0 | Yêu cầu ủy quyền người dùng |
| Giới hạn tốc độ | 100-500 yêu cầu/ngày cho mỗi ứng dụng |
| Trang công ty | Các hoạt động CRUD đầy đủ |
| API Quảng cáo | Quản lý chiến dịch |
| Webhooks | Thông báo thời gian thực |
| Tải lên phương tiện | Hình ảnh và video |
Sản phẩm API
| API | Cấp độ truy cập | Trường hợp sử dụng |
|---|---|---|
| Đăng nhập bằng LinkedIn | Công khai | Xác thực người dùng |
| API Hồ sơ | Đối tác | Đọc hồ sơ người dùng |
| API Quản trị viên công ty | Đối tác | Quản lý trang công ty |
| API Quảng cáo | Đối tác | Quản lý chiến dịch quảng cáo |
| API Đăng tuyển việc làm | Đối tác | Đăng và quản lý việc làm |
| Nền tảng nhà phát triển tiếp thị | Đối tác | Truy cập API đầy đủ |
Phiên bản API
| Phiên bản | Trạng thái | Ngày kết thúc |
|---|---|---|
| v2 | Hiện tại | Đang hoạt động |
| v1 | Đã ngừng hỗ trợ | Tháng 12 năm 2023 |
Bắt đầu: Thiết lập xác thực
Bước 1: Tạo tài khoản nhà phát triển LinkedIn
- Truy cập Cổng thông tin nhà phát triển LinkedIn
- Đăng nhập bằng tài khoản LinkedIn
- Chọn Tạo ứng dụng trong dashboard Ứng dụng của tôi
- Điền tên, logo, mô tả ứng dụng
Bước 2: Cấu hình cài đặt ứng dụng
Lấy thông tin xác thực từ dashboard:
const LINKEDIN_CLIENT_ID = process.env.LINKEDIN_CLIENT_ID;
const LINKEDIN_CLIENT_SECRET = process.env.LINKEDIN_CLIENT_SECRET;
const LINKEDIN_REDIRECT_URI = process.env.LINKEDIN_REDIRECT_URI;
// Xem bảng điều khiển ứng dụng:
// https://www.linkedin.com/developers/apps/{appId}/auth
Bước 3: Yêu cầu quyền cần thiết
LinkedIn yêu cầu phê duyệt quyền:
| Quyền | Mô tả | Yêu cầu phê duyệt |
|---|---|---|
r_liteprofile |
Hồ sơ cơ bản (tên, ảnh) | Tự động phê duyệt |
r_emailaddress |
Địa chỉ email | Tự động phê duyệt |
w_member_social |
Đăng bài thay mặt người dùng | Xác minh đối tác |
r_basicprofile |
Hồ sơ đầy đủ | Xác minh đối tác |
r_organization_social |
Truy cập trang công ty | Xác minh đối tác |
w_organization_social |
Đăng bài lên trang công ty | Xác minh đối tác |
rw_ads |
Quản lý quảng cáo | Xác minh đối tác |
r_ads_reporting |
Phân tích quảng cáo | Xác minh đối tác |
Bước 4: Xây dựng URL ủy quyền
Tạo link cho luồng OAuth 2.0:
const getAuthUrl = (state, scopes = ['r_liteprofile', 'r_emailaddress']) => {
const params = new URLSearchParams({
response_type: 'code',
client_id: LINKEDIN_CLIENT_ID,
redirect_uri: LINKEDIN_REDIRECT_URI,
scope: scopes.join(' '),
state: state
});
return `https://www.linkedin.com/oauth/v2/authorization?${params.toString()}`;
};
// Sử dụng:
const state = require('crypto').randomBytes(16).toString('hex');
const authUrl = getAuthUrl(state, ['r_liteprofile', 'r_emailaddress', 'w_member_social']);
console.log(`Chuyển hướng người dùng đến: ${authUrl}`);
Bước 5: Trao đổi mã lấy Access Token
Xử lý callback OAuth:
const exchangeCodeForToken = async (code) => {
const response = await fetch('https://www.linkedin.com/oauth/v2/accessToken', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_id: LINKEDIN_CLIENT_ID,
client_secret: LINKEDIN_CLIENT_SECRET,
redirect_uri: LINKEDIN_REDIRECT_URI
})
});
const data = await response.json();
return {
accessToken: data.access_token,
expiresIn: data.expires_in // 60 ngày
};
};
// Callback handler
app.get('/oauth/callback', async (req, res) => {
const { code, state } = req.query;
try {
const tokens = await exchangeCodeForToken(code);
// Lưu trữ token an toàn
await db.users.update(req.session.userId, {
linkedin_access_token: tokens.accessToken,
linkedin_token_expires: Date.now() + (tokens.expiresIn * 1000)
});
res.redirect('/success');
} catch (error) {
console.error('Lỗi OAuth:', error);
res.status(500).send('Xác thực thất bại');
}
});
Bước 6: Làm mới Access Token
LinkedIn không cung cấp refresh token. Khi token hết hạn (60 ngày):
const refreshAccessToken = async (refreshToken) => {
// LinkedIn không hỗ trợ refresh token
// Người dùng phải xác thực lại sau 60 ngày
// Thông báo cho user khi sắp hết hạn
};
const ensureValidToken = async (userId) => {
const user = await db.users.findById(userId);
if (user.linkedin_token_expires < Date.now() + 86400000) { // 24h
await notifyUserToReauth(user.id);
throw new Error('Token đã hết hạn, vui lòng xác thực lại');
}
return user.linkedin_access_token;
};
Bước 7: Thực hiện các cuộc gọi API đã xác thực
Tạo client API tái sử dụng:
const LINKEDIN_BASE_URL = 'https://api.linkedin.com/v2';
const linkedinRequest = async (endpoint, options = {}) => {
const accessToken = await ensureValidToken(options.userId);
const response = await fetch(`${LINKEDIN_BASE_URL}${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'X-Restli-Protocol-Version': '2.0.0',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Lỗi API LinkedIn: ${error.message}`);
}
return response.json();
};
// Sử dụng:
const profile = await linkedinRequest('/me');
console.log(`Xin chào, ${profile.localizedFirstName} ${profile.localizedLastName}`);
Truy cập Hồ sơ
Lấy hồ sơ người dùng
const getUserProfile = async () => {
const response = await linkedinRequest('/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))');
return response;
};
// Sử dụng
const profile = await getUserProfile();
console.log(`Tên: ${profile.localizedFirstName} ${profile.localizedLastName}`);
console.log(`ID: ${profile.id}`);
console.log(`Ảnh: ${profile.profilePicture?.['displayImage~']?.elements?.[0]?.identifiers?.[0]?.identifier}`);
Lấy địa chỉ email
const getUserEmail = async () => {
const response = await linkedinRequest('/emailAddress?q=members&projection=(emailAddress*)');
return response;
};
// Sử dụng
const email = await getUserEmail();
console.log(`Email: ${email.elements?.[0]?.emailAddress}`);
Các trường hồ sơ có sẵn
| Trường | Quyền | Mô tả |
|---|---|---|
id |
r_liteprofile | ID thành viên LinkedIn |
firstName |
r_liteprofile | Tên |
lastName |
r_liteprofile | Họ |
profilePicture |
r_liteprofile | URL ảnh đại diện |
headline |
r_basicprofile | Tiêu đề chuyên môn |
summary |
r_basicprofile | Phần giới thiệu |
positions |
r_basicprofile | Lịch sử làm việc |
educations |
r_basicprofile | Lịch sử học vấn |
emailAddress |
r_emailaddress | Email chính |
Đăng nội dung
Tạo bài đăng
Đăng bài văn bản lên bảng tin cá nhân:
const createPost = async (authorUrn, postContent) => {
const response = await linkedinRequest('/ugcPosts', {
method: 'POST',
body: JSON.stringify({
author: authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: {
text: postContent.text
},
shareMediaCategory: 'NONE'
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
})
});
return response;
};
// Sử dụng
const post = await createPost('urn:li:person:ABC123', {
text: 'Vui mừng thông báo ra mắt sản phẩm mới của chúng tôi! 🚀 #đổi_mới #khởi_nghiệp'
});
console.log(`Bài đăng đã tạo: ${post.id}`);
Tạo bài đăng kèm hình ảnh
const createPostWithImage = async (authorUrn, postData) => {
// Bước 1: Đăng ký tải lên phương tiện
const uploadRegistration = await linkedinRequest('/assets?action=registerUpload', {
method: 'POST',
body: JSON.stringify({
registerUploadRequest: {
recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
owner: authorUrn,
serviceRelationships: [
{
relationshipType: 'OWNER',
identifier: 'urn:li:userGeneratedContent'
}
]
}
})
});
const uploadUrl = uploadRegistration.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
const assetUrn = uploadRegistration.value.asset;
// Bước 2: Tải hình ảnh lên URL đã cấp
await fetch(uploadUrl, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + await getAccessToken(),
'Content-Type': 'application/octet-stream'
},
body: postData.imageBuffer
});
// Bước 3: Tạo bài đăng với hình ảnh
const post = await linkedinRequest('/ugcPosts', {
method: 'POST',
body: JSON.stringify({
author: authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: {
text: postData.text
},
shareMediaCategory: 'IMAGE',
media: [
{
status: 'READY',
description: {
text: postData.imageDescription || ''
},
media: assetUrn,
title: {
text: postData.title || ''
}
}
]
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
})
});
return post;
};
Tạo bài đăng kèm video
const createPostWithVideo = async (authorUrn, postData) => {
// Đăng ký tải lên video
const uploadRegistration = await linkedinRequest('/assets?action=registerUpload', {
method: 'POST',
body: JSON.stringify({
registerUploadRequest: {
recipes: ['urn:li:digitalmediaRecipe:feedshare-video'],
owner: authorUrn,
serviceRelationships: [
{
relationshipType: 'OWNER',
identifier: 'urn:li:userGeneratedContent'
}
]
}
})
});
const assetUrn = uploadRegistration.value.asset;
// Tải lên video (sử dụng URL tải lên đã cấp)
// ... logic tải lên ...
// Tạo bài đăng
const post = await linkedinRequest('/ugcPosts', {
method: 'POST',
body: JSON.stringify({
author: authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: { text: postData.text },
shareMediaCategory: 'VIDEO',
media: [{ status: 'READY', media: assetUrn }]
}
},
visibility: { 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' }
})
});
return post;
};
Thông số kỹ thuật phương tiện
| Loại phương tiện | Định dạng | Kích thước tối đa | Thời lượng |
|---|---|---|---|
| Hình ảnh | JPG, PNG, GIF | 8MB | Không áp dụng |
| Video | MP4, MOV | 5GB | Tối đa 15 phút |
| Tài liệu | PDF, PPT, DOC | 100MB | Không áp dụng |
Quản lý trang công ty
Lấy thông tin công ty
const getCompanyInfo = async (companyId) => {
const response = await linkedinRequest(
`/organizations/${companyId}?projection=(id,localizedName,vanityName,tagline,description,universalName,logoV2(original~:playableStreams),companyType,companyPageUrl,confirmedLocations,industries,followerCount,staffCountRange,website, specialties)`
);
return response;
};
// Sử dụng
const company = await getCompanyInfo('1234567');
console.log(`Công ty: ${company.localizedName}`);
console.log(`Người theo dõi: ${company.followerCount}`);
console.log(`Trang web: ${company.website}`);
Đăng bài lên trang công ty
const createCompanyPost = async (organizationUrn, postContent) => {
const response = await linkedinRequest('/ugcPosts', {
method: 'POST',
body: JSON.stringify({
author: organizationUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: {
text: postContent.text
},
shareMediaCategory: postContent.media ? 'IMAGE' : 'NONE',
media: postContent.media ? [
{
status: 'READY',
media: postContent.media.assetUrn
}
] : []
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
})
});
return response;
};
// Sử dụng
const post = await createCompanyPost('urn:li:organization:1234567', {
text: 'Chúng tôi đang tuyển dụng! Hãy tham gia đội ngũ đang phát triển của chúng tôi. #nghe_nghiep #tuyen_dung'
});
Lấy số lượng người theo dõi công ty
const getFollowerCount = async (organizationId) => {
const response = await linkedinRequest(
`/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:${organizationId}`
);
return response;
};
Giới hạn tốc độ
Tìm hiểu giới hạn tốc độ
| API | Giới hạn | Khung thời gian |
|---|---|---|
| API Hồ sơ | 100 yêu cầu | Mỗi ngày |
| Bài đăng UGC | 50 bài đăng | Mỗi ngày |
| Quản trị viên công ty | 500 yêu cầu | Mỗi ngày |
| API Quảng cáo | 100 yêu cầu | Mỗi phút |
Header giới hạn tốc độ
| Header | Mô tả |
|---|---|
X-Restli-Quota-Remaining |
Số yêu cầu còn lại |
X-Restli-Quota-Reset |
Số giây cho đến khi đặt lại |
Khắc phục các vấn đề thường gặp
Lỗi 401 Unauthorized
Cách xử lý:
- Kiểm tra Access Token còn hạn (60 ngày)
- Xác minh scope token có đủ quyền cho resource
- Đảm bảo header
Authorization: Bearer {token}được gửi
Lỗi 403 Forbidden
Cách xử lý:
- Đảm bảo ứng dụng đã được cấp quyền cần thiết
- Người dùng đã phê duyệt các scope được yêu cầu
- Nếu cần, hoàn tất xác minh đối tác
Lỗi 429 Rate Limited
Cách xử lý:
- Triển khai hàng đợi request
- Cache phản hồi để giảm số lần gọi
- Sử dụng webhook thay vì polling liên tục
Danh sách kiểm tra triển khai sản xuất
Trước khi live:
- [ ] Hoàn thành xác minh Đối tác LinkedIn
- [ ] Triển khai OAuth 2.0 và lưu trữ token an toàn
- [ ] Thông báo hết hạn token (60 ngày)
- [ ] Thiết lập giới hạn tốc độ và queue
- [ ] Cấu hình webhook endpoints
- [ ] Xử lý lỗi toàn diện
- [ ] Ghi log toàn bộ API call
- [ ] Đánh giá tuân thủ brand guideline
Các trường hợp sử dụng thực tế
Nền tảng tuyển dụng
- Thách thức: Đăng tuyển trên nhiều kênh thủ công
- Giải pháp: Tích hợp API việc làm LinkedIn
- Kết quả: Tiết kiệm 80% thời gian, số lượt ứng tuyển tăng gấp 3
Tự động hóa tiếp thị B2B
- Thách thức: Lịch đăng bài không đều
- Giải pháp: Đăng bài tự động qua API UGC
- Kết quả: Tăng tương tác x5 lần, duy trì sự hiện diện thương hiệu
Kết luận
API LinkedIn mở ra nhiều chức năng mạng lưới chuyên nghiệp:
- Xác thực OAuth 2.0, token có hạn 60 ngày
- Truy cập API hồ sơ, đăng bài, trang công ty
- Quản lý giới hạn tốc độ chặt chẽ (100-500/ngày)
- Hầu hết API yêu cầu xác minh đối tác
- Apidog hỗ trợ kiểm thử API hiệu quả và làm việc nhóm
Phần Câu hỏi thường gặp
Làm cách nào để truy cập API LinkedIn?
Tạo tài khoản Nhà phát triển LinkedIn, tạo ứng dụng và hoàn tất xác minh Đối tác để truy cập API nâng cao.
Tôi có thể đăng bài tự động lên LinkedIn không?
Có, sử dụng API UGC với scope w_member_social (bài cá nhân) hoặc w_organization_social (bài công ty).
Giới hạn tốc độ của LinkedIn là gì?
Giới hạn dao động 100-500 yêu cầu/ngày tùy API. API Quảng cáo: 100 yêu cầu/phút.
Token LinkedIn có hiệu lực bao lâu?
Token hết hạn sau 60 ngày. Người dùng cần xác thực lại để tiếp tục truy cập API.
Tôi có thể truy cập danh bạ của người dùng không?
Không. LinkedIn đã loại bỏ quyền truy cập API danh bạ với hầu hết ứng dụng do chính sách quyền riêng tư.
Top comments (0)