Publish images to Instagram through Meta's Graph API. Part 1 is one-time manual setup (browser clicks); Part 2 is the repeatable automated publish (this skill does it for you).
# 1. Put credentials in .env (one time)
cp .env.example .env
# edit .env with ACCESS_TOKEN (and optionally IG_USER_ID)
# 2. Publish
python3 scripts/publish.py \
--image-url "https://example.com/photo.jpg" \
--caption "Hello from Instagram API"
The script prints the new post ID on success. Done.
These steps cannot be automated — they require human logins, email verification, and Meta's UI. Do them once, save the resulting ACCESS_TOKEN, and you never need to touch Meta's dashboard again unless permissions change.
Visit
Settings
↓
Account Type
↓
Switch to Professional Account
↓
Creator
Visit
Get Started
↓
Verify Email
↓
Accept Terms
Visit
Create App
↓
Use cases: Manage messaging & content on Instagram
↓
Do NOT connect a Business portfolio
> ⚠️ Skipping the Business portfolio avoids the "insufficient developer permissions" error later.
In App settings → Basic:
Use cases → Customize
↓
Left sidebar: API setup with Instagram login
↓
Add required messaging permissions
↓
Add account → authorize your Instagram account
↓
Generate token
↓
Check "I understand" → copy the token
The token starts with IGAA.... Save it to .env (next section).
| Field | Example | Lives in |
|---|---|---|
| --- | --- | --- |
ACCESS_TOKEN | IGAAxxxxx... | .env |
IG_USER_ID | 2700xxxxxx | .env (optional — script can auto-fetch) |
USERNAME | xxxxx | reference only |
> ⚠️ Never commit .env to git. The token is the only thing that authenticates posts on your behalf.
The three Graph API calls below are bundled in scripts/publish.py. You run one command; the script runs all three.
[1] Validate token → GET /me?fields=id,username
↓
[2] Create container → POST /{ig_user_id}/media (image_url + caption)
↓
[3] Publish → POST /{ig_user_id}/media_publish (creation_id)
.envcp .env.example .env
.env contents:
ACCESS_TOKEN=IGAAxxxxxxxxxxxxxxxxxxxx
IG_USER_ID=2700xxxxxxxx # optional — auto-detected if missing
The script reads .env from the skill directory. If you run it from elsewhere, pass --env /path/to/.env.
python3 scripts/publish.py \
--image-url "https://example.com/photo.jpg" \
--caption "Hello from Instagram API"
Optional flags:
| Flag | Default | Notes |
|---|---|---|
| --- | --- | --- |
--image-url URL | required | Must be publicly reachable by Meta's servers |
--caption TEXT | empty | Instagram's caption, with hashtags and mentions |
--env PATH | ./.env | Path to a .env file |
--api-version | v24.0 | Graph API version |
--dry-run | off | Validate token and build the container, but skip the final publish |
Successful output:
✓ Token valid — user: xxxxx (id: 2700xxxxxx)
✓ Container created: xxxxx
✓ Published: xxxxx
https://www.instagram.com/p/xxxxxxxxx
{"error": {"message": "Media download has failed"}}
Meta's servers cannot reach your image_url. Fix:
localhost, 127.0.0.1, and private network IPs{"error": {"message": "Unsupported post request"}}
Almost always a token-permission issue. Fix:
instagram_content_publish and instagram_basic are grantedACCESS_TOKEN in .envLong-lived tokens still expire (default ~60 days). If /me returns an auth error, regenerate the token in the App dashboard and update .env.
instagram-publish/
├── SKILL.md # this file
├── .env.example # template for ACCESS_TOKEN and IG_USER_ID
├── .gitignore # keeps .env out of git
└── scripts/
└── publish.py # the three-step publisher
共 1 个版本