TÓM TẮT
Instagram Graph API cho phép các nhà phát triển quản lý tài khoản Instagram doanh nghiệp và nhà sáng tạo một cách có lập trình. API này sử dụng xác thực Facebook Login OAuth 2.0, các điểm cuối (endpoints) dựa trên GraphQL để xuất bản nội dung, thông tin chi tiết (insights), bình luận và nhắn tin, với giới hạn tốc độ là 200 lượt gọi mỗi giờ cho mỗi ứng dụng. Bài viết này hướng dẫn thiết lập xác thực, xuất bản nội dung, truy xuất thông tin chi tiết, quản lý bình luận và các chiến lược tích hợp sản xuất.
Giới thiệu
Instagram có hơn 2 tỷ người dùng hoạt động hàng tháng, với hơn 200 triệu doanh nghiệp sử dụng tài khoản Instagram Business. Đối với các nhà phát triển xây dựng công cụ quản lý mạng xã hội, nền tảng phân tích hoặc tích hợp thương mại điện tử, việc tích hợp Instagram Graph API là điều cần thiết để tự động hóa quy trình, tiết kiệm thời gian và mở rộng hiệu quả.
Thực tế: Quản lý thủ công trên 10 tài khoản Instagram có thể tiêu tốn 20-30 giờ mỗi tuần. Tích hợp API giúp tự động hóa xuất bản nội dung, kiểm duyệt bình luận, phân tích cảm xúc và báo cáo hiệu suất.
Bài viết này hướng dẫn toàn trình tích hợp Instagram Graph API, bao gồm xác thực OAuth, đăng tải nội dung, lấy insights, quản lý bình luận, tích hợp webhook và checklist triển khai sản xuất.
💡 Apidog giúp kiểm thử tích hợp API nhanh chóng: kiểm tra endpoints, xác thực OAuth, debug phản hồi API, mô phỏng phản hồi, chia sẻ test case cho nhóm.
Instagram Graph API là gì?
Instagram Graph API cung cấp quyền truy cập có lập trình tới tài khoản doanh nghiệp và nhà sáng tạo trên Instagram thông qua Facebook Graph API. Các tính năng chính:
- Xuất bản nội dung (ảnh, video, reels, carousel)
- Lấy thông tin chi tiết và phân tích về phương tiện
- Quản lý bình luận, đề cập
- Nhắn tin trực tiếp (Instagram Graph API + Messenger Platform)
- Theo dõi hashtag, đề cập
- Quản lý Stories
- Thẻ mua sắm, sản phẩm
Các tính năng chính
| Tính năng | Mô tả |
|---|---|
| API dựa trên đồ thị (Graph) | Truy cập tài nguyên dựa trên nút |
| OAuth 2.0 | Xác thực bằng Facebook Login |
| Webhooks | Thông báo real-time cho bình luận, đề cập |
| Giới hạn tốc độ | 200 lượt gọi/giờ/ứng dụng |
| Xuất bản nội dung | Ảnh, video, reels, carousel |
| Thông tin chi tiết (Insights) | Chỉ số tương tác, phạm vi tiếp cận, lượt hiển thị |
| Kiểm duyệt | Quản lý bình luận, đề cập, tin nhắn |
Yêu cầu tài khoản
| Loại tài khoản | Quyền truy cập API |
|---|---|
| Doanh nghiệp | Đầy đủ |
| Nhà sáng tạo | Đầy đủ |
| Cá nhân | Không (phải chuyển đổi) |
| Riêng tư | Giới hạn thông tin chi tiết |
Tổng quan kiến trúc API
API sử dụng endpoint:
https://graph.facebook.com/v18.0/
So sánh các phiên bản API
| Phiên bản | Trạng thái | Ngày kết thúc | Trường hợp sử dụng |
|---|---|---|---|
| v18.0 | Hiện tại | T3/2026 | Tích hợp mới |
| v17.0 | Không dùng nữa | T1/2026 | Tích hợp cũ |
| v16.0 | Đã ngừng hoạt động | Đã hết hạn | Không sử dụng |
Luôn triển khai với phiên bản mới nhất để đảm bảo ổn định.
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 Facebook
- Truy cập Cổng nhà phát triển Facebook
- Đăng nhập Facebook
- Tạo ứng dụng Facebook (loại: Business)
- Thêm sản phẩm Instagram Graph API
Bước 2: Liên kết tài khoản Instagram doanh nghiệp
- Vào Cài đặt Trang Facebook → Instagram
- Nhấn Kết nối tài khoản
- Đăng nhập Instagram và xác nhận ủy quyền
- Đảm bảo Instagram Business đã liên kết
Lưu ý: Chỉ tài khoản Business/Creator mới truy cập được API.
Bước 3: Lấy mã truy cập (Access Tokens)
Tạo URL xác thực OAuth:
const FB_APP_ID = process.env.FB_APP_ID;
const FB_APP_SECRET = process.env.FB_APP_SECRET;
const FB_REDIRECT_URI = process.env.FB_REDIRECT_URI;
const getAuthUrl = (state) => {
const params = new URLSearchParams({
client_id: FB_APP_ID,
redirect_uri: FB_REDIRECT_URI,
scope: 'instagram_basic,instagram_content_publish,instagram_manage_comments,instagram_manage_insights,pages_read_engagement',
state: state
});
return `https://www.facebook.com/v18.0/dialog/oauth?${params.toString()}`;
};
Các quyền cần yêu cầu
| Quyền | Mô tả |
|---|---|
instagram_basic |
Thông tin hồ sơ, danh sách phương tiện |
instagram_content_publish |
Đăng ảnh, video, carousel |
instagram_manage_comments |
Đọc/ghi bình luận |
instagram_manage_insights |
Truy cập dữ liệu phân tích |
pages_read_engagement |
Truy cập Trang để đăng |
pages_manage_posts |
Đăng lên Trang kết nối |
Bước 4: Đổi mã token ngắn hạn lấy mã token dài hạn
const exchangeForLongLivedToken = async (shortLivedToken) => {
const response = await fetch(
`https://graph.facebook.com/v18.0/oauth/access_token?` +
`grant_type=fb_exchange_token&` +
`client_id=${FB_APP_ID}&` +
`client_secret=${FB_APP_SECRET}&` +
`fb_exchange_token=${shortLivedToken}`
);
const data = await response.json();
return data;
};
// Usage
const longLivedToken = await exchangeForLongLivedToken(shortLivedToken);
console.log(`Token expires: ${new Date(longLivedToken.expires_at * 1000)}`);
Bước 5: Lấy ID tài khoản Instagram doanh nghiệp
const getInstagramAccountId = async (pageId, accessToken) => {
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}?fields=instagram_business_account&access_token=${accessToken}`
);
const data = await response.json();
return data.instagram_business_account.id;
};
// Usage
const igAccountId = await getInstagramAccountId('12345678', accessToken);
console.log(`Instagram Account ID: ${igAccountId}`);
Bước 6: Thực hiện các cuộc gọi API đã xác thực
const IG_BASE_URL = 'https://graph.facebook.com/v18.0';
const instagramRequest = async (endpoint, params = {}) => {
const url = new URL(`${IG_BASE_URL}${endpoint}`);
url.searchParams.append('access_token', process.env.INSTAGRAM_ACCESS_TOKEN);
Object.entries(params).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
const response = await fetch(url.toString());
if (!response.ok) {
const error = await response.json();
throw new Error(`Instagram API Error: ${error.error.message}`);
}
return response.json();
};
// Usage
const account = await instagramRequest(`/me`);
console.log(`Instagram Account: ${account.username}`);
Xuất bản nội dung
Đăng ảnh
const publishPhoto = async (igAccountId, photoData) => {
// Bước 1: Tạo media container
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
image_url: photoData.imageUrl,
caption: photoData.caption,
location_id: photoData.locationId, // Optional
is_carousel_item: 'false'
});
const creationId = containerResponse.id;
// Bước 2: Xuất bản media
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Usage
const post = await publishPhoto({
igAccountId: '17841400000000000',
imageUrl: 'https://example.com/image.jpg',
caption: 'Excited to announce our new product! 🚀 #launch #innovation',
locationId: '123456789' // Optional
});
console.log(`Published media ID: ${post.id}`);
Đăng video
const publishVideo = async (igAccountId, videoData) => {
// Bước 1: Tạo container
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
video_url: videoData.videoUrl,
cover_url: videoData.coverUrl, // Thumbnail optional
caption: videoData.caption,
media_type: 'REELS', // hoặc 'VIDEO'
share_to_feed: 'true'
});
const creationId = containerResponse.id;
// Đợi xử lý video
await waitForVideoProcessing(creationId);
// Bước 2: Xuất bản
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
const waitForVideoProcessing = async (creationId, maxAttempts = 30) => {
for (let i = 0; i < maxAttempts; i++) {
const status = await instagramRequest(`/${creationId}`);
if (status.status_code === 'FINISHED') {
return true;
} else if (status.status_code === 'EXPIRED') {
throw new Error('Video processing expired');
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error('Video processing timeout');
};
Đăng băng chuyền (carousel)
const publishCarousel = async (igAccountId, carouselData) => {
const children = [];
// Bước 1: Tạo container cho từng item
for (const item of carouselData.items) {
const containerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
[item.type === 'video' ? 'video_url' : 'image_url']: item.url,
caption: item.caption || '',
is_carousel_item: 'true'
});
children.push(containerResponse.id);
}
// Bước 2: Tạo container carousel
const carouselContainerResponse = await instagramRequest(`/${igAccountId}/media`, {
method: 'POST',
media_type: 'CAROUSEL',
children: children.join(','),
caption: carouselData.caption
});
const creationId = carouselContainerResponse.id;
// Bước 3: Xuất bản carousel
const publishResponse = await instagramRequest(`/${igAccountId}/media_publish`, {
method: 'POST',
creation_id: creationId
});
return publishResponse;
};
// Usage
const carousel = await publishCarousel('17841400000000000', {
caption: 'Product showcase 2026',
items: [
{ type: 'image', url: 'https://example.com/img1.jpg', caption: 'Product 1' },
{ type: 'image', url: 'https://example.com/img2.jpg', caption: 'Product 2' },
{ type: 'video', url: 'https://example.com/vid1.mp4', caption: 'Demo' }
]
});
Loại phương tiện
| Loại phương tiện | Tham số | Trường hợp sử dụng |
|---|---|---|
IMAGE |
image_url, caption | Bài đăng ảnh |
VIDEO |
video_url, cover_url, caption | Bài đăng video |
REELS |
video_url, cover_url, caption, share_to_feed | Thước phim (Reels) |
CAROUSEL |
children (mảng), caption | Nhiều phương tiện |
Truy xuất phương tiện và thông tin chi tiết
Lấy phương tiện của người dùng
const getUserMedia = async (igAccountId, limit = 25) => {
const response = await instagramRequest(`/${igAccountId}/media`, {
fields: 'id,caption,media_type,media_url,permalink,timestamp,like_count,comments_count',
limit: limit.toString()
});
return response;
};
// Usage
const media = await getUserMedia('17841400000000000');
media.data.forEach(item => {
console.log(`${item.media_type}: ${item.caption}`);
console.log(`Likes: ${item.like_count}, Comments: ${item.comments_count}`);
console.log(`URL: ${item.permalink}`);
});
Lấy thông tin chi tiết về phương tiện
const getMediaInsights = async (mediaId) => {
const response = await instagramRequest(`/${mediaId}/insights`, {
fields: 'impressions,reach,engagement,saved,video_views,profile_visits,follows'
});
return response;
};
// Usage
const insights = await getMediaInsights('17890000000000000');
insights.data.forEach(metric => {
console.log(`${metric.name}: ${metric.values[0].value}`);
});
Các chỉ số thông tin chi tiết
| Chỉ số | Mô tả | Loại phương tiện |
|---|---|---|
impressions |
Tổng lượt xem | Tất cả |
reach |
Tài khoản duy nhất tiếp cận | Tất cả |
engagement |
Lượt thích + bình luận + lưu | Tất cả |
saved |
Số lần được lưu | Tất cả |
video_views |
Lượt xem video (3s+) | Video, Reels |
plays |
Tổng lượt phát video | Video, Reels |
profile_visits |
Lượt vào hồ sơ từ bài đăng | Tất cả |
follows |
Lượt theo dõi từ bài đăng | Tất cả |
comments |
Số lượng bình luận | Tất cả |
like_count |
Số lượng lượt thích | Tất cả |
Lấy thông tin chi tiết tài khoản
const getAccountInsights = async (igAccountId, metricNames, since = null, until = null) => {
const params = {
metric: metricNames.join(','),
period: 'day'
};
if (since) params.since = since;
if (until) params.until = until;
const response = await instagramRequest(`/${igAccountId}/insights`, params);
return response;
};
// Usage
const accountInsights = await getAccountInsights(
'17841400000000000',
['impressions', 'reach', 'profile_views', 'email_contacts', 'website_clicks'],
'2026-02-23',
'2026-03-25'
);
accountInsights.data.forEach(metric => {
console.log(`${metric.name}:`);
metric.values.forEach(value => {
console.log(` ${value.end_time}: ${value.value}`);
});
});
Các chỉ số cấp tài khoản
| Chỉ số | Mô tả |
|---|---|
impressions |
Tổng lượt xem hồ sơ + nội dung |
reach |
Tài khoản duy nhất tiếp cận |
profile_views |
Lượt truy cập hồ sơ |
website_clicks |
Lượt nhấp liên kết tiểu sử |
email_contacts |
Lượt nhấp nút email |
phone_call_clicks |
Lượt nhấp nút điện thoại |
text_message_clicks |
Lượt nhấp SMS |
get_directions_clicks |
Lượt nhấp địa chỉ |
follower_count |
Tổng người theo dõi |
audience_city |
Thành phố người theo dõi |
audience_country |
Quốc gia người theo dõi |
audience_gender_age |
Phân tích giới tính, độ tuổi |
Quản lý bình luận
Lấy bình luận
const getMediaComments = async (mediaId, limit = 50) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
fields: 'id,text,timestamp,username,hidden',
limit: limit.toString()
});
return response;
};
// Usage
const comments = await getMediaComments('17890000000000000');
comments.data.forEach(comment => {
console.log(`@${comment.username}: ${comment.text}`);
console.log(`Hidden: ${comment.hidden}`);
});
Trả lời bình luận
const replyToComment = async (mediaId, commentId, replyText) => {
const response = await instagramRequest(`/${mediaId}/comments`, {
method: 'POST',
response_to: commentId,
message: replyText
});
return response;
};
// Usage
const reply = await replyToComment(
'17890000000000000',
'17900000000000000',
'Thank you for your interest! Check your DM for details.'
);
console.log(`Reply posted: ${reply.id}`);
Ẩn bình luận
const hideComment = async (commentId) => {
const response = await instagramRequest(`/${commentId}`, {
method: 'POST',
hide: 'true'
});
return response;
};
// Usage
await hideComment('17900000000000000');
console.log('Comment hidden');
Xóa bình luận
const deleteComment = async (commentId) => {
await instagramRequest(`/${commentId}`, {
method: 'DELETE'
});
console.log('Comment deleted');
};
Webhooks
Cấu hình Webhooks
const subscribeToWebhooks = async (appId, pageId, accessToken) => {
// Đăng ký sự kiện Instagram
const response = await fetch(
`https://graph.facebook.com/v18.0/${appId}/subscriptions`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
object: 'instagram',
callback_url: 'https://myapp.com/webhooks/instagram',
verify_token: process.env.WEBHOOK_VERIFY_TOKEN,
access_token: accessToken,
fields: ['comments', 'mentions', 'message_reactions']
})
}
);
return response.json();
};
Xử lý Webhooks
const express = require('express');
const app = express();
// Xác thực webhook
app.get('/webhooks/instagram', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (mode === 'subscribe' && token === process.env.WEBHOOK_VERIFY_TOKEN) {
console.log('Webhook verified');
res.status(200).send(challenge);
} else {
res.status(403).send('Verification failed');
}
});
// Xử lý sự kiện webhook
app.post('/webhooks/instagram', express.json(), async (req, res) => {
const body = req.body;
if (body.object !== 'instagram') {
return res.status(404).send('Not found');
}
for (const entry of body.entry) {
const igId = entry.id;
const changes = entry.changes;
for (const change of changes) {
switch (change.field) {
case 'comments':
await handleNewComment(change.value);
break;
case 'mentions':
await handleMention(change.value);
break;
case 'message_reactions':
await handleReaction(change.value);
break;
}
}
}
res.status(200).send('OK');
});
async function handleNewComment(data) {
console.log(`New comment on media ${data.media_id}`);
console.log(`From: ${data.from_id}`);
console.log(`Text: ${data.text}`);
// Auto-reply hoặc moderate
if (isSpam(data.text)) {
await hideComment(data.id);
}
}
Các trường Webhook
| Trường | Kích hoạt |
|---|---|
comments |
Bình luận mới hoặc trả lời |
mentions |
Người dùng đề cập đến tài khoản |
message_reactions |
Phản ứng với tin (Story) |
story_status |
Trả lời/xem tin (Story) |
Giới hạn tốc độ
Hiểu về giới hạn tốc độ
- 200 lượt gọi/giờ/ứng dụng (tất cả người dùng cộng lại)
- Business Discovery: 200 lượt gọi/giờ/người dùng
- Xuất bản nội dung: Giới hạn theo hành động cụ thể
Vượt quá sẽ báo lỗi HTTP 400, mã phụ 613.
Best practices
- Cache responses – Không truy xuất lại dữ liệu không đổi
- Batch requests – Mở rộng trường để giảm số gọi API
- Dùng webhooks – Nhận cập nhật real-time thay vì polling
- Thực hiện backoff – Backoff cấp số nhân khi gặp lỗi 429
const makeRateLimitedRequest = async (endpoint, params = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await instagramRequest(endpoint, params);
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Khắc phục sự cố thường gặp
Vấn đề: Mã token OAuth đã hết hạn
Triệu chứng: Nhận lỗi “Invalid OAuth access token”.
Giải pháp:
- Làm mới token trước khi hết hạn 60 ngày
- Lưu ngày hết hạn token, cảnh báo trước khi hết hạn
- Xác thực lại người dùng khi token hết hạn
Vấn đề: Xuất bản phương tiện thất bại
Triệu chứng: Lỗi khi xuất bản.
Giải pháp:
- URL ảnh phải public, không bảo vệ đăng nhập
- Ảnh JPEG/PNG, <8MB
- Video MP4, <1GB, <90s
- Đợi video xử lý xong mới publish
Vấn đề: Thông tin chi tiết không khả dụng
Triệu chứng: API Insights trả về dữ liệu trống.
Giải pháp:
- Đảm bảo tài khoản là Business/Creator
- Đợi 24-48h cho dữ liệu đầy đủ
- Kiểm tra tài khoản hoạt động đủ
Danh sách kiểm tra triển khai sản phẩm
Trước khi production:
- [ ] Đảm bảo tất cả tài khoản là Business/Creator
- [ ] OAuth 2.0 với token dài hạn
- [ ] Lưu token an toàn (mã hóa)
- [ ] Tự động làm mới token
- [ ] Webhook endpoint dùng HTTPS
- [ ] Triển khai kiểm soát tốc độ, xếp hàng request
- [ ] Xử lý lỗi toàn diện
- [ ] Log mọi request API
- [ ] Quy trình kiểm duyệt nội dung
- [ ] Test nhiều loại tài khoản
Các trường hợp sử dụng thực tế
Công cụ lên lịch đăng bài trên mạng xã hội
- Thách thức: Đăng bài thủ công trên >50 tài khoản khách hàng
- Giải pháp: Lên lịch xuất bản qua Instagram API
- Kết quả: Tiết kiệm 80% thời gian, đảm bảo lịch đều đặn
Triển khai:
- Lịch nội dung kéo thả, lên lịch tự động
- Đăng tự động ảnh, video, carousel
- Gợi ý hashtag thông minh
Tự động hóa dịch vụ khách hàng
- Thách thức: Phản hồi chậm bình luận khách hàng
- Giải pháp: Tự động trả lời câu hỏi qua webhook
- Kết quả: Phản hồi trung bình 5 phút, 90% hài lòng
Triển khai:
- Phát hiện từ khóa (giá, tồn kho, vận chuyển)
- Auto-reply link sản phẩm
- Chuyển truy vấn phức tạp cho CSKH
Kết luận
Instagram Graph API cung cấp quyền truy cập toàn diện tới các tính năng tài khoản Business/Creator.
Những điểm cần lưu ý:
- Xác thực OAuth 2.0 với token 60 ngày
- Đăng ảnh, video, reels, carousel tự động
- Insights API cung cấp dữ liệu tương tác, phạm vi, nhân khẩu học
- Webhook giám sát bình luận, đề cập real-time
- Giới hạn tốc độ 200 request/giờ/app — cần tối ưu
- Apidog giúp kiểm thử API, hỗ trợ teamwork hiệu quả
Phần hỏi đáp
Làm cách nào để truy cập Instagram API?
Tạo tài khoản nhà phát triển Facebook, tạo ứng dụng Business, thêm Instagram Graph API và xác thực OAuth với các quyền cần thiết.
Tôi có thể tự động đăng bài lên Instagram không?
Có. Sử dụng Content Publishing API để đăng ảnh, video, reels, carousel lên tài khoản Business/Creator.
Những loại tài khoản Instagram nào hỗ trợ API?
Chỉ Business/Creator có toàn quyền API. Cá nhân bị giới hạn hoặc không có.
Làm cách nào để lấy bình luận từ Instagram?
Sử dụng endpoint /media-id/comments để lấy bình luận. Webhook cung cấp thông báo real-time.
Giới hạn tốc độ của Instagram là gì?
200 request/giờ/ứng dụng. Một số endpoint còn giới hạn thêm trên mỗi người dùng.
Tôi có thể đăng Tin (Stories) qua API không?
Có, sử dụng quy trình xuất bản nội dung tương tự như feed.
Làm cách nào để truy cập Instagram Insights?
Yêu cầu quyền instagram_manage_insights khi OAuth. Dùng endpoint Insights để lấy chỉ số phương tiện và tài khoản.
Tôi có thể tự động trả lời bình luận không?
Có. Dùng Comments API để đăng trả lời; nhiều thương hiệu đã tự động hóa CSKH thông qua tính năng này.
Top comments (0)