Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Instagram Graph API integration via curl. Use this skill to fetch and publish Instagram media.
.claude/skills/nicepkg-instagram/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 14% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 144% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 103% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 114% | 0% |
Use the Instagram Graph API by directly executing curl commands to read and publish Instagram content.
> Official docs: https://developers.facebook.com/docs/instagram-api
Use this skill when you need to:
INSTAGRAM_ACCESS_TOKEN: a long-lived user access tokenINSTAGRAM_BUSINESS_ACCOUNT_ID: your Instagram Business account IDSet the environment variables, for example:
bashexport INSTAGRAM_ACCESS_TOKEN="EAAG..." export INSTAGRAM_BUSINESS_ACCOUNT_ID="1784140xxxxxxx"
These examples use Graph API version v21.0. You can replace this with the latest version if needed.
Depending on which endpoints you use, make sure your app has requested and been approved for (at least):
instagram_basicpages_show_listinstagram_content_publish (for publishing media)instagram_manage_insights and related permissions (for insights / some hashtag use cases)> Important: When using $VAR in a command that pipes to another command, wrap the command containing $VAR in bash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly. > bash > bash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq '.' >
All examples below assume you have already set:
bashINSTAGRAM_ACCESS_TOKEN INSTAGRAM_BUSINESS_ACCOUNT_ID
Fetch the most recent media (photos / videos / Reels) for the account:
bashbash -c 'curl -s -X GET "https://graph.facebook.com/v21.0/${INSTAGRAM_BUSINESS_ACCOUNT_ID}/media?fields=id,caption,media_type,media_url,permalink,timestamp" --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
Notes:
id: media ID (used for details / insights later)caption: caption textmedia_type: IMAGE / VIDEO / CAROUSEL_ALBUMmedia_url: direct URL to the mediapermalink: Instagram permalinktimestamp: creation timeIf you already have a media id, you can fetch more complete information. Replace <your-media-id> with the id field from the "Get User Media" response (section 1 above):
bashbash -c 'curl -s -X GET "https://graph.facebook.com/v21.0/<your-media-id>?fields=id,caption,media_type,media_url,permalink,thumbnail_url,timestamp,username" --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
> Note: hashtag search requires proper business use cases and permissions as defined by Facebook/Instagram. Refer to the official docs.
This usually involves two steps:
Replace <hashtag-name> with any hashtag name you want to search for (without the # symbol), e.g., "travel", "food", "photography":
bashbash -c 'curl -s -X GET "https://graph.facebook.com/v21.0/ig_hashtag_search?user_id=${INSTAGRAM_BUSINESS_ACCOUNT_ID}&q=<hashtag-name>" --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
Note the id field in the returned JSON for use in the next step.
Replace <hashtag-id> with the id field from the "Search Hashtag" response (section 3.1 above):
bashbash -c 'curl -s -X GET "https://graph.facebook.com/v21.0/<hashtag-id>/recent_media?user_id=${INSTAGRAM_BUSINESS_ACCOUNT_ID}&fields=id,caption,media_type,media_url,permalink,timestamp" --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
Publishing an image post via the Graph API usually requires two steps:
Write the request data to /tmp/request.json:
json{ "image_url": "https://example.com/image.jpg", "caption": "Hello from Instagram API 👋" }
Replace https://example.com/image.jpg with any publicly accessible image URL and update the caption text as needed.
bashbash -c 'curl -s -X POST "https://graph.facebook.com/v21.0/${INSTAGRAM_BUSINESS_ACCOUNT_ID}/media" -H "Content-Type: application/json" -d @/tmp/request.json --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
The response will contain an id (media container ID), for example:
json{ "id": "1790xxxxxxxxxxxx" }
Note this ID for use in the next step.
Write the request data to /tmp/request.json:
json{ "creation_id": "<your-creation-id>" }
Replace <your-creation-id> with the id field from the "Create Media Container" response (section 4.1 above):
bashbash -c 'curl -s -X POST "https://graph.facebook.com/v21.0/${INSTAGRAM_BUSINESS_ACCOUNT_ID}/media_publish" -H "Content-Type: application/json" -d @/tmp/request.json --header "Authorization: Bearer ${INSTAGRAM_ACCESS_TOKEN}"'
If successful, the response will contain the final media id:
json{ "id": "1791yyyyyyyyyyyy" }
You can then use the "Get details for a single media" command to fetch its permalink.
(#10) Application does not have permission for this actionINSTAGRAM_ACCESS_TOKEN is a valid long-lived tokenINSTAGRAM_ACCESS_TOKEN is sensitive; avoid printing it in logs or chat transcriptsv21.0 version in URLs to the latest<your-media-id> instead of shell variables in URLs to avoid dependencies and make examples self-contained| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 9,096 | 7,414 | -18% | 1 | 1 | 0% | 1,567 | 2,255 | +44% | 0 | 0 | — |
case-02 | fail→fail | 8,383 | 2,402 | -71% | 1 | 1 | 0% | 1,499 | 2,352 | +57% | 0 | 0 | — |
case-03 | fail→fail | 7,957 | 7,702 | -3% | 1 | 1 | 0% | 1,541 | 2,364 | +53% | 0 | 0 | — |
case-09 | pass→pass | 2,882 | 2,007 | -30% | 1 | 1 | 0% | 379 | 2,138 | +464% | 0 | 0 | — |
case-04 | pass→pass | 9,890 | 3,453 | -65% | 1 | 1 | 0% | 1,842 | 2,519 | +37% | 0 | 0 | — |
case-05 | pass→pass | 9,360 | 5,166 | -45% | 1 | 1 | 0% | 1,660 | 2,809 | +69% | 0 | 0 | — |
case-06 | fail→pass | 13,803 | 4,229 | -69% | 1 | 1 | 0% | 2,225 | 2,543 | +14% | 0 | 0 | — |
case-07 | pass→pass | 2,881 | 2,224 | -23% | 1 | 1 | 0% | 433 | 2,220 | +413% | 0 | 0 | — |
case-08 | pass→pass | 5,896 | 2,028 | -66% | 1 | 1 | 0% | 876 | 2,203 | +151% | 0 | 0 | — |
case-10 | fail→pass | 7,651 | 5,724 | -25% | 1 | 1 | 0% | 1,180 | 2,875 | +144% | 0 | 0 | — |
case-11 | fail→pass | 7,307 | 3,405 | -53% | 1 | 1 | 0% | 1,144 | 2,327 | +103% | 0 | 0 | — |
case-12 | pass→pass | 3,470 | 2,457 | -29% | 1 | 1 | 0% | 622 | 2,351 | +278% | 0 | 0 | — |
case-13 | fail→pass | 10,646 | 1,694 | -84% | 1 | 1 | 0% | 1,533 | 2,067 | +35% | 0 | 0 | — |
case-14 | pass→pass | 7,148 | 3,627 | -49% | 1 | 1 | 0% | 1,261 | 2,405 | +91% | 0 | 0 | — |
case-15 | pass→pass | 5,903 | 2,099 | -64% | 1 | 1 | 0% | 841 | 2,174 | +159% | 0 | 0 | — |
case-16 | pass→pass | 5,766 | 1,669 | -71% | 1 | 1 | 0% | 910 | 2,150 | +136% | 0 | 0 | — |
case-17 | pass→pass | 2,830 | 1,966 | -31% | 1 | 1 | 0% | 465 | 2,121 | +356% | 0 | 0 | — |
case-18 | pass→pass | 16,520 | 11,385 | -31% | 1 | 1 | 0% | 2,576 | 3,826 | +49% | 0 | 0 | — |
case-19 | pass→pass | 7,719 | 2,971 | -62% | 1 | 1 | 0% | 1,290 | 2,431 | +88% | 0 | 0 | — |
case-20 | fail→fail | 6,228 | 6,957 | +12% | 1 | 1 | 0% | 1,028 | 3,192 | +211% | 0 | 0 | — |
case-21 | fail→pass | 7,726 | 7,061 | -9% | 1 | 1 | 0% | 1,505 | 3,227 | +114% | 0 | 0 | — |
case-22 | pass→pass | 11,152 | 8,203 | -26% | 1 | 1 | 0% | 1,665 | 3,429 | +106% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +23 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.