通过 API 发布到 Instagram 是一个两步调用:先用 POST /<IG_ID>/media 创建一个媒体容器,再用 POST /<IG_ID>/media_publish 发布它。真正难的部分不是这两个调用本身,而是账号要求、Meta 的应用审核,以及创建容器这一步返回 200 并不代表内容已经真正上线。
本文面向正在评估是否要自建这套集成的开发者。
Instagram API 到底能发布什么?
Meta 的内容发布文档为容器列出了四种 media_type 值:VIDEO、REELS、STORIES 和 CAROUSEL。如果你传入 image_url 而不指定 media_type,默认就是单张图片。
| 形式 | 是否支持 | 文档中的说明 |
|---|---|---|
| 单张图片 | 支持 | JPEG 格式,以公开可访问的 image_url 传入 |
| 视频/Reels | 支持 | media_type=REELS 配合 video_url |
| Stories | 支持 | media_type=STORIES |
| 轮播 | 支持 | 最多 10 张图片、视频,或两者混合 |
有两点会让人意外。第一,Stories 是可以发布的,但当你读取一条已发布的 Story 时,media_type 返回的是 IMAGE 或 VIDEO,所以你必须请求 media_product_type 字段才能知道它实际是什么。第二,轮播中的图片都会被裁剪成和第一张一致,默认为 1:1,也就是说裁剪方式并不由你决定。
最关键的门槛不在于内容形式,而在于账号本身。发布要求 Instagram 专业账号(商业或创作者类型)与一个 Facebook 主页绑定,并授予 instagram_basic、instagram_content_publish 和 pages_read_engagement 权限。个人 Instagram 账号无论代码怎么写,都完全无法通过 API 发布。如果你的用户是使用个人账号的创作者,这个集成在你写第一行代码之前就已经行不通了。
注: 本文数据截至 2026 年 9 月,依据 Meta 的 Instagram 平台内容发布文档核实。平台可能随时改动,恕不另行通知。
认证是怎么工作的?应用审核要多久?
你先通过 Facebook 登录获取一个用户访问令牌,然后在服务端用 grant_type=fb_exchange_token 调用 GET oauth/access_token,把短期令牌换成长期令牌。Meta 的文档说明长期用户令牌的有效期约为 60 天。Meta 描述的自动刷新机制适用于由 SDK 管理的令牌,所以如果你自己手动交换令牌,就需要在第 60 天之前自己实现刷新或重新授权流程。
在你自己应用角色之外的任何人使用这个集成之前,都需要为发布权限通过应用审核。Meta 在这些开发者文档中没有公布保证的审核周期,所以要把审核时长视为未知数,并为至少一轮被拒做好准备。提交材料中需要包含屏幕录像,也就是说,你需要在应用还不能服务真实用户、也还没获得批准的情况下,先做出一个能用的演示。
发布调用的具体顺序是怎样的?
- 把媒体上传到一个公网可访问的位置。Meta 是通过 URL 拉取媒体的,所以一个 60 秒就过期的签名 URL 会导致失败。
- 用
image_url或video_url、caption,以及(如果不是纯图片)media_type调用POST /<IG_ID>/media,会返回一个容器 ID。 - 轮询
GET /<IG_CONTAINER_ID>?fields=status_code,直到状态变为FINISHED。Meta 建议每分钟轮询一次,总共不超过五分钟。 - 用
creation_id设为该容器 ID,调用POST /<IG_ID>/media_publish。 - 保存返回的媒体 ID。这个 ID(而不是容器 ID)才是已发布帖子的标识。
# 1. create the container
curl -X POST "https://graph.facebook.com/v23.0/$IG_ID/media" \
-d "image_url=https://example.com/photo.jpg" \
-d "caption=Ship it." \
-d "access_token=$TOKEN"
# -> {"id":"17889455560051444"}
# 2. poll until FINISHED
curl "https://graph.facebook.com/v23.0/17889455560051444?fields=status_code&access_token=$TOKEN"
# 3. publish
curl -X POST "https://graph.facebook.com/v23.0/$IG_ID/media_publish" \
-d "creation_id=17889455560051444" -d "access_token=$TOKEN"
容器的 status_code 可能是 IN_PROGRESS、FINISHED、ERROR、EXPIRED 或 PUBLISHED。EXPIRED 表示该容器在 24 小时内没有被发布。对于轮播,你需要为每一项分别创建一个容器(带 is_carousel_item=true),再创建一个 media_type=CAROUSEL 的父容器,附带一个用逗号分隔的 children 列表。
速率限制是怎样的?
文档明确规定:每个 Instagram 账号在滚动的 24 小时内,通过 API 发布的帖子上限为 100 条,一个轮播算作一条帖子。你可以通过 GET /<IG_ID>/content_publishing_limit 读取当前用量,而不用靠猜,在批量发布之前应该先这样做。
这是一个滚动窗口,不是自然日。如果你在下午 3 点用完了 100 条额度,到午夜也不会重新获得额度。你构建的任何队列都需要按这个滚动窗口建模,而不是按每日计数器。
注: 本文数据截至 2026 年 9 月,依据 Meta 的 Instagram 平台内容发布文档核实。平台可能随时改动,恕不另行通知。
真正会花掉你三周时间的是什么?
不是这两个 API 调用,而是以下四件事:
应用审核。 在 Meta 批准 instagram_content_publish 之前你无法上线,而在你把整个功能做出来之前,你也无法进行干净的演示。要为重新提交预留时间。
令牌刷新。 60 天有效期的长期令牌意味着你需要一个后台任务,一个在界面上提示“这个账号需要重新连接”的失败状态,以及在令牌失效之前(而不是之后)就发邮件提醒用户。跳过这一步,每个集成都会在上线两个月后悄无声息地停止工作。
媒体托管和格式限制。 Meta 是从你的 URL 拉取媒体的,这意味着你需要公开托管、正确的内容类型,以及转码成 Instagram 能接受的格式。单张图片必须是 JPEG。视频需要能顺利通过 Instagram 自己的处理流程,而这个处理是在你的调用返回之后才发生的。
异步失败处理。 创建容器调用返回 200,只代表 Meta 接受了这个任务。这条帖子仍然可能在处理过程中失败,你只能通过轮询 status_code 看到 ERROR 才会知道。如果你的数据模型只有“已发布”和“失败”两种状态,你就会把那些从未真正出现过的帖子报告为发布成功。你需要建模一个 processing(处理中)状态和一个真正的终态检查,具体做法见我们的社交媒体排期发布 API 指南。
而且这些工作量还要乘上平台数量。Reels 和 Stories 各有自己的特殊之处,如果你还想支持TikTok或 LinkedIn,就要重新面对一套不同的认证模型、不同的上传流程和不同的审核流程。
简短总结
- 两个调用:创建容器,然后
media_publish,中间轮询status_code。 - 需要一个绑定了 Facebook 主页的 Instagram 专业账号。
- 每滚动 24 小时通过 API 最多发布 100 条帖子,用
content_publishing_limit查看用量。 - 长期令牌有效期约 60 天,上线前就要做好刷新机制。
- 应用审核是强制的,其时长在文档中没有公布。
如果你在写代码的同时也在起草文案,免费的 Instagram 字数计数器能告诉你截断会发生在哪里。
一次性搞定,而不是每个平台都做一遍
与其为每个网络单独写一套集成,另一种做法是用一个已经处理好令牌、容器、轮询和重试的 API。BulkPublish 通过一个统一的 REST API 和 SDK 发布到 15 个平台,所以一条 Instagram 帖子和一条 LinkedIn 帖子是同一个调用,只是渠道 ID 不同。令牌刷新、滚动窗口限制和异步状态检查都由我们这边处理,某个平台发布失败会被报告为 partial(部分成功),而不是虚假的成功。参考文档在/developers/,REST 集成页面在/integrations/rest-api/。