Skip to main content

A clean, httpie-style command-line client for Meta's Graph API and Instagram Graph API.

Project description

meta-graph

A clean, httpie-style command-line client for Meta's Graph API and Instagram Graph API.

$ meta me
{"id": "10000...", "name": "Jane Doe"}

$ meta ig accounts
{"data": [{"page_id": "12345", "page_name": "My Page", "ig_user_id": "17841..."}], "count": 1}

$ meta ig publish 17841... --image-url https://example.com/img.jpg --caption "Hello world"
{"container_id": "18002...", "status": {"status_code": "FINISHED"}, "published": {"id": "17984..."}}

No SDK to wrap, no React app to log in to, no config server. Just your token and a thin HTTP shell.


Why

Meta ships SDKs (Python, JS, PHP) but no CLI. The SDKs are typed object hierarchies that don't translate to flags, and the official one is heavy and Marketing-skewed. meta-graph is the missing piece: a small, version-agile CLI that maps directly to the underlying HTTP API and bundles the entire Graph + Instagram reference offline.

Install

pip install meta-graph-cli    # binary becomes `meta`

Or from source:

git clone https://github.com/crimeacs/meta-graph-cli && cd meta-graph-cli
pip install -e .

Auth

Get a short-lived user token from the Graph API Explorer and either:

export META_GRAPH_TOKEN="EAA..."

…or write a config file at ~/.config/meta-graph/config.toml:

[default]
token = "EAA..."
api_version = "v22.0"
app_secret = "..."          # optional; enables appsecret_proof signing

[profile.prod]
token = "EAA..."

Use --profile prod to switch profiles.

meta token info             # decode scopes, expiry, app id
meta token refresh --app-id ... --app-secret ...   # short-lived → long-lived (~60 days)

Commands

Generic (works for any endpoint Meta exposes)

meta get /me fields=id,name,email
meta get /PAGE_ID/feed fields=id,message,created_time limit=50
meta post /PAGE_ID/feed message='Hello world'
meta delete /POST_ID
echo '[{"method":"GET","relative_url":"me"},
       {"method":"GET","relative_url":"me/accounts?limit=2"}]' | meta batch

Profile + Pages

meta me                      # /me
meta me pages                # /me/accounts (with linked IG account ids)
meta me permissions          # granted/declined permissions

Instagram (the headline curated surface)

# two flows, auto-detected from token prefix:
#   EAA…  → graph.facebook.com  (Instagram with Facebook Login; needs linked Page)
#   IGAA… → graph.instagram.com (Instagram with Instagram Login; no Page needed)
# Override the host with --base when needed.

# accounts
meta ig accounts                                    # works on either flow

# IG-direct shortcuts (no explicit ig_id needed)
meta ig me                                          # the IG account itself
meta ig me media [--all]                            # your media
meta ig me insights --metric impressions,reach --period day

# user
meta ig user IG_ID                                   # account fields
meta ig user IG_ID media [--all]                      # list media
meta ig user IG_ID stories                            # active stories
meta ig user IG_ID tags                               # tagged in
meta ig user IG_ID mentions                           # @mentions
meta ig user IG_ID insights --metric impressions,reach --period day
meta ig user IG_ID limit                              # 24h publish quota
meta ig user IG_ID live                               # active live broadcasts

# publish (two-step container flow handled for you)
meta ig publish IG_ID --image-url https://example.com/img.jpg --caption "..."
meta ig publish IG_ID --video-url https://example.com/clip.mp4
meta ig publish IG_ID --video-url https://... --reel
meta ig publish IG_ID --carousel "https://a.jpg,https://b.jpg,https://c.mp4" --caption "..."
meta ig publish IG_ID --story-image https://example.com/story.jpg
meta ig publish-status CONTAINER_ID

# media
meta ig media MEDIA_ID
meta ig media MEDIA_ID children
meta ig media MEDIA_ID comments [--all]
meta ig media MEDIA_ID insights --metric impressions,reach,saved,video_views
meta ig media MEDIA_ID delete

# comments
meta ig comment-on MEDIA_ID --message "Welcome!"
meta ig comment COMMENT_ID
meta ig comment COMMENT_ID reply --message "Thanks!"
meta ig comment COMMENT_ID hide
meta ig comment COMMENT_ID unhide
meta ig comment COMMENT_ID delete

# hashtags
meta ig hashtag search "barista"
meta ig hashtag recent HASHTAG_ID
meta ig hashtag top HASHTAG_ID

# discovery + embed
meta ig business-discovery IG_ID --username @nasa
meta ig oembed https://www.instagram.com/p/SHORTCODE/

Discovery (offline; ships with the wheel)

meta nodes                   # every documented Graph + IG node
meta edges page              # edges of /page
meta fields user             # documented fields of /user

Output

meta get /me                    # compact JSON, jq-friendly
meta get /me --pretty           # indented + colored when stdout is a TTY
meta get /me --jq '.id'         # passthrough to jq if installed; tiny fallback otherwise

Errors go to stderr as JSON. Exit codes:

code meaning
0 success
1 Graph API error
2 usage error (bad flags / JSON)
3 auth (token missing / invalid / expired)

Design

  • Thin HTTP wrapper. No FB SDK; just requests. The CLI follows the Graph API shape directly so anything Meta documents is reachable via meta get/post/delete.
  • Auto retry on transient codes (1, 2) and rate limits (4, 17, 32, 613) with exponential backoff + jitter.
  • appsecret_proof signing on every request when app_secret is configured (recommended for Live-mode apps).
  • Cursor pagination via --all on listing commands; underlying client.paginate() follows paging.next until exhausted.
  • Batched requests via meta batch (reads JSON array from stdin).
  • Bundled docs at docs/reference.md — every Graph + Instagram endpoint scraped in one searchable markdown file. Regenerated via python scripts/scrape.py && python scripts/concat.py && python scripts/build_data.py.

Claude Code skill

A Claude Code skill that teaches Claude how to drive this CLI for natural-language Instagram/Meta tasks ships at skills/meta-graph/. Install with:

mkdir -p ~/.claude/skills && cp -r skills/meta-graph ~/.claude/skills/

Then ask Claude things like "post this image to Instagram with caption '…'" or "reply to all unanswered comments on this Reel" — it'll resolve your IG account, run the right meta ig … invocations, and surface error codes with actionable fixes. See skills/README.md for details.

Library use

from meta_graph.client import GraphClient

client = GraphClient(token="EAA...", version="v22.0", app_secret="...")
me = client.get("/me", fields="id,name")
for media in client.paginate("/IG_ID/media", fields="id,caption,timestamp"):
    print(media["id"], media.get("caption"))

Development

pip install -e .[dev]
pytest -q                       # unit + vcr replay
ruff check src/ tests/
mypy --strict src/meta_graph

License

MIT — see LICENSE.

The bundled docs/reference.md is scraped from https://developers.facebook.com/docs/ and is © Meta Platforms, Inc.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meta_graph_cli-0.1.1.tar.gz (22.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meta_graph_cli-0.1.1-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file meta_graph_cli-0.1.1.tar.gz.

File metadata

  • Download URL: meta_graph_cli-0.1.1.tar.gz
  • Upload date:
  • Size: 22.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meta_graph_cli-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2c8ed2af4bb450bbcc48468f730ef0d830fff1302fc7d36adb46896c407a9c1e
MD5 bccdeadb7c89ce16ba220508b2c3b7a5
BLAKE2b-256 0417515bcc4a3faf2744dc7400c0cf8a0995970d03543efbd90228f028c2fc26

See more details on using hashes here.

Provenance

The following attestation bundles were made for meta_graph_cli-0.1.1.tar.gz:

Publisher: release.yml on crimeacs/meta-graph-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file meta_graph_cli-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: meta_graph_cli-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meta_graph_cli-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 695e3ce0965abc0a56a771555f7da379993bbb3d41094ed32961e79f9e78a29e
MD5 23f7147fc2e19391370af03bfe1a85ff
BLAKE2b-256 f05fc1f51e2feef1517b558a7d3015c4215ace3a869a1fb33aafc2f3a1ff6a68

See more details on using hashes here.

Provenance

The following attestation bundles were made for meta_graph_cli-0.1.1-py3-none-any.whl:

Publisher: release.yml on crimeacs/meta-graph-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page