name: instagram-poster description: Posts carousels and Reels to Instagram via Graph API. Use when "post this carousel to Instagram", "publish carousel", "post to Instagram", "post this reel", "publish reel". allowed-tools: Read, Glob, Bash
Instagram Poster
What This Does
Posts carousels and Reels directly to Instagram via the Graph API. Uploads media to Vercel Blob for public URLs, creates containers, and publishes - eliminating manual upload steps.
Supports:
- Carousels - 2-10 images, swipeable posts
- Reels - Short-form video (5-90 seconds)
Prerequisites
Before first use, ensure these are configured:
-
Environment variables (in
~/.zshrc):-
BLOB_READ_WRITE_TOKEN- Vercel Blob storage token
-
-
Config file (
~/.config/instagram-poster.yaml):- Contains Instagram access token and user ID
- Created by running
auth_setup.py(one-time OAuth)
Instructions - Carousels
Step 1: Locate Carousel Images
Find the most recent carousel folder in ~/Downloads/:
ls -td ~/Downloads/carousel* | head -1
Or use the specific folder if provided by the user.
Verify the images:
- Should contain 2-10 PNG images
- Named like
CarouselName01.png,CarouselName02.png, etc.
Step 2: Get User Approval (REQUIRED)
Before posting, ALWAYS show this confirmation:
Ready to post carousel to Instagram:
- X images from ~/Downloads/carouselYYMMDD/
- Caption preview: [first 100 chars of caption...]
Post now? (y/n)
DO NOT proceed without explicit user approval.
Step 3: Execute Posting
Run the post_carousel.py script:
Option A: Direct caption
python3 /Users/eddale/Documents/GitHub/powerhouse-lab/skills/instagram-poster/tools/post_carousel.py \
--folder <carousel_folder_path> \
--caption "<caption_text>"
Option B: Using a template
python3 /Users/eddale/Documents/GitHub/powerhouse-lab/skills/instagram-poster/tools/post_carousel.py \
--folder <carousel_folder_path> \
--template carousel \
--title "Your Headline Here" \
--topic "business"
Caption options (in priority order):
- If
--templateflag provided, render caption from template - If user provides
--caption, use it directly - If carousel folder contains
caption.txt, read it - Otherwise, ask user for caption
Step 4: Report Results
On success, display:
- Instagram post URL
- Number of images posted
- "Carousel is now live!"
On failure:
- Show error message
- Suggest checking token expiry if auth-related
Caption Templates
Use templates for consistent, high-performing captions. Templates live in resources/caption-templates.yaml.
Available Templates
| Template | Best For | Emoji | Hashtags |
|---|---|---|---|
carousel |
Standard educational carousel | Minimal | 5 |
educational |
Deep teaching content | None | 6 |
promotional |
Launch/offer content | Minimal | 4 |
story |
Personal narrative | Minimal | 5 |
quicktip |
Bite-sized actionable tips | Moderate | 5 |
Template Variables
| Variable | Description | Example |
|---|---|---|
{title} |
Main headline | "5 Things I Wish I Knew" |
{topic} |
Subject area (becomes hashtag) | "saas" or "coaching" |
{cta} |
Call to action (optional) | "DM me 'START'" |
If {cta} is not provided, the template's default CTA is used.
Using Templates
List available templates:
python3 .../post_carousel.py --list-templates
Post with template:
python3 .../post_carousel.py \
--folder ~/Downloads/carousel260120 \
--template educational \
--title "The One Skill That Changes Everything" \
--topic "business"
With custom CTA:
python3 .../post_carousel.py \
--folder ~/Downloads/carousel260120 \
--template promotional \
--title "Build Your First SaaS" \
--topic "saas" \
--cta "Link in bio - doors close Friday"
When to Use Templates vs Direct Caption
- Use template: Consistent brand voice, quick posting, following best practices
- Use direct caption: One-off special posts, very specific messaging, A/B testing
Caption Guidelines (Manual)
When writing captions manually (without templates), keep them concise. The carousel slides do the heavy lifting.
Pattern:
[Hook - what's the one thing?]
[1-2 sentences expanding]
Save this for later.
#hashtag1 #hashtag2 #hashtag3
Instructions - Reels
Step 1: Locate Video File
Find the Reel video file. Typically in a reels-builder output folder:
ls -td ~/Downloads/reels-builder-* | head -1
The video should be final.mp4 in that folder.
Video requirements:
- Duration: 5-90 seconds
- Format: MP4 or MOV
- Aspect ratio: 9:16 (portrait)
- Max size: 300MB
Step 2: Get User Approval (REQUIRED)
Before posting, ALWAYS show this confirmation:
Ready to post Reel to Instagram:
- Video: ~/Downloads/reels-builder-xxx/final.mp4 (X.X MB)
- Caption preview: [first 100 chars of caption...]
Post now? (y/n)
DO NOT proceed without explicit user approval.
Step 3: Execute Posting
Run the post_reel.py script:
python3 /Users/eddale/Documents/GitHub/powerhouse-lab/skills/instagram-poster/tools/post_reel.py \
--video <video_file_path> \
--caption "<caption_text>"
Caption options:
- If user provides caption, use it
- If reel folder contains
caption.txt, read it - Otherwise, ask user for caption
Step 4: Report Results
On success, display:
- Instagram Reel URL
- "Reel is now live!"
On failure:
- Show error message
- Video processing takes longer than images - if timeout, suggest checking Instagram directly
Caption Guidelines (Reels)
Reels captions can be longer since the video is the hook.
Pattern:
[Hook question or statement]
[Context about what they're watching]
[CTA - follow for more, link in bio, etc.]
#hashtag1 #hashtag2 #hashtag3
Error Handling
| Error | Meaning | Action |
|---|---|---|
| "Token expired" | Access token > 60 days old | Run refresh_token.py |
| "Rate limited" | Too many API calls | Wait 1 hour, retry |
| "Container processing failed" | Image/video issue | Check format/size/duration |
| "Video container failed to process" | Video encoding issue | Check codec (use H264), duration (5-90s) |
| "No config file" | First time use | Run auth_setup.py |
One-Time Setup Commands
Initial OAuth (creates config file):
python3 /Users/eddale/Documents/GitHub/powerhouse-lab/skills/instagram-poster/tools/auth_setup.py
Refresh token (before 60-day expiry):
python3 /Users/eddale/Documents/GitHub/powerhouse-lab/skills/instagram-poster/tools/refresh_token.py
Examples
User asks to post recent carousel
User: "post the carousel I just made"
1. Find: ls -td ~/Downloads/carousel* | head -1
2. Read images: Bonsai01.png through Bonsai08.png
3. Ask: "Ready to post 8-image Bonsai carousel. Caption?"
4. User provides caption
5. Confirm: "Post these 8 images with that caption?"
6. User: "yes"
7. Execute post_carousel.py
8. Return: "Posted! https://instagram.com/p/xxx"
User provides specific folder and caption
User: "publish carousel from ~/Downloads/carousel260114 with caption 'The one skill that changes everything'"
1. Verify folder exists, count images
2. Confirm: "Post 8 images with caption 'The one skill...'?"
3. User: "yes"
4. Execute and return URL
User asks to post a Reel
User: "post that reel I just made"
1. Find: ls -td ~/Downloads/reels-builder-* | head -1
2. Locate: final.mp4 in that folder
3. Check size: 3.1MB, duration looks good
4. Ask: "Ready to post Reel (3.1MB). Caption?"
5. User provides caption
6. Confirm: "Post this Reel with that caption?"
7. User: "yes"
8. Execute post_reel.py
9. Return: "Reel is live! https://instagram.com/reel/xxx"
User provides specific video path
User: "post reel from ~/Downloads/reels-builder-meta-reel/final.mp4"
1. Verify video exists, check size
2. Ask: "Caption for this Reel?"
3. User: "The future of content creation..."
4. Confirm: "Post this Reel with caption 'The future...'?"
5. User: "yes"
6. Execute and return URL
chat Comments (0)
Sign in to join the discussion and leave a comment.
Skill Details
Related Skills
Build your own?
Join 12,000+ developers contributing to the Claude ecosystem.
No comments yet. Be the first to share your thoughts!