Built for builders too.
Schedule Instagram Stories, posts and reels from your own code, and read their results. Use the REST API, the MCP server for AI assistants and our open-source tools, all with one API key.
Quickstart
Create an API key on the Developers page in the app. Then list your connected Instagram accounts. This call works on every plan.
curl https://storylink.pro/api/v1/connections \
-H "Authorization: Bearer sl_live_…"
# → 200 OK
# { "data": [{ "id": "cnx_…", "platform": "instagram", "username": "…", "status": "active" }] }const res = await fetch("https://storylink.pro/api/v1/connections", {
headers: { Authorization: `Bearer ${process.env.STORYLINK_API_KEY}` },
});
const { data } = await res.json();
// data[0].username, data[0].statusimport os, requests
r = requests.get(
"https://storylink.pro/api/v1/connections",
headers={"Authorization": f"Bearer {os.environ['STORYLINK_API_KEY']}"},
)
for c in r.json()["data"]:
print(c["username"], c["status"])Authentication
Send your key on every request in the Authorization: Bearer sl_live_… header. The X-Storylink-Api-Key header also works.
- Free: read data from the current month.
- Pro: read your full history.
- Business: also create and schedule content, with a key that has “Allow creating and scheduling content”. You choose this when you create the key, and you can’t change it later.
You can limit a key to one workspace. A key with no workspace reads every workspace in your account, and writes to the oldest one.
POST /v1/stories, /v1/posts and /v1/reels accept an Idempotency-Key header of up to 255 characters. For 24 hours, a retry with the same key and body gets the first response again, and creates nothing new.
Keep keys on your server. Never put a key in a browser or a mobile app. If a key leaks, revoke it on the Developers page.
Endpoints
The base URL is https://storylink.pro/api/v1. Requests and responses are JSON.
Stories
- POST
/storiesSchedule - GET
/storiesList - GET
/stories/{id}Get one - PATCH
/stories/{id}Update - DELETE
/stories/{id}Cancel - POST
/stories/{id}/retry-publishRetry a failed publish - GET
/stories/{id}/insightsInsights
Posts
- POST
/postsSchedule - GET
/postsList - GET
/posts/{id}Get one - PATCH
/posts/{id}Update - DELETE
/posts/{id}Cancel - POST
/posts/{id}/retry-publishRetry a failed publish - GET
/posts/{id}/insightsInsights
Reels
- POST
/reelsSchedule - GET
/reelsList - GET
/reels/{id}Get one - PATCH
/reels/{id}Update - DELETE
/reels/{id}Cancel - POST
/reels/{id}/retry-fb-cross-postRetry the Facebook cross-post - GET
/reels/{id}/insightsInsights
Media
- POST
/media/uploadsCreate an upload
Connections
- GET
/connectionsList accounts - GET
/connections/{id}Get one account - GET
/connections/{id}/followersFollower history
The OpenAPI spec has every request and response schema.
Errors
A failed request returns an error object with a code, a message and a docs_url. The docs_url links to the code in this list.
invalid_api_key- The API key is not valid.
api_key_revoked- Someone revoked the API key.
api_key_expired- The API key expired.
plan_not_entitled- Your plan does not include this request. Writes need Business, and data from before this month needs Pro.
rate_limited- Too many requests. Wait for the number of seconds in the Retry-After header.
validation_failed- A parameter is missing or not valid. The param field names it.
media_not_ready- A media upload is not complete yet.
connection_not_eligible- The connection can’t do this. For example, a reel with no Instagram connection can’t retry its Facebook cross-post.
not_found- Nothing with this id exists, or your key can’t see it.
story_not_in_scheduled_state- The story’s status does not allow this. You can update or cancel only a scheduled story, and retry only a failed one.
post_not_in_scheduled_state- The post’s status does not allow this. You can update or cancel only a scheduled post, and retry only a failed one.
reel_not_in_scheduled_state- The reel’s status does not allow this. You can update or cancel only a scheduled reel, and retry only a failed one.
workspace_read_only- The workspace’s Instagram account is disconnected. Reads still work, but writes don’t. Reconnect the account in the app.
workspace_suspended- Storylink suspended this workspace. Contact us.
idempotency_key_reuse_with_different_body- You sent this Idempotency-Key before, with a different body.
idempotency_request_in_progress- A request with this Idempotency-Key is still running.
meta_api_error- Meta returned an error. The message field has the details.
storage_cap_exceeded- Your media storage is full.
internal_error- Something failed on our side. Try again, or contact us.
MCP server
Storylink runs a Model Context Protocol server at https://storylink.pro/mcp. Connect Claude or another MCP client with your API key. Then ask about the views, reach and replies of your stories, on all your accounts.
A read-only key gets 15 tools. A key that can write gets 28.
claude mcp add --transport http storylink https://storylink.pro/mcp \
--header "Authorization: Bearer sl_live_…"{
"mcpServers": {
"storylink": {
"command": "npx",
"args": ["-y", "storylink-mcp"],
"env": { "STORYLINK_API_KEY": "sl_live_…" }
}
}
}The source is in storylink-mcp. For ready-made Instagram reports, add storylink-skills.
Then ask, for example: “Why did my story views drop last week?”
Rate limits
- 60 requests a minute for each key. The MCP server uses the same limit.
- Above the limit, the API returns
429 rate_limitedwith aRetry-Afterheader. - Media that you upload counts toward your plan’s storage.
- Instagram’s own publishing limits also apply.
Open source
These projects are public at github.com/storylinkpro, under the MIT license. Issues and pull requests are welcome.
npx @storylinkpro/instagram-stories-api stories
import { createClient } from "@storylinkpro/instagram-stories-api";
const ig = createClient({
accessToken: process.env.INSTAGRAM_ACCESS_TOKEN,
igUserId: process.env.INSTAGRAM_USER_ID,
});
for (const story of await ig.stories()) {
const { views, reach, replies } = await ig.storyInsights(story.id);
}Storylink is not affiliated with Meta Platforms, Inc.
Support
Building something?
Open an issue on GitHub, or write to us.