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)

# accounts
meta ig accounts

# 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.0.tar.gz (21.0 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.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: meta_graph_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 21.0 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.0.tar.gz
Algorithm Hash digest
SHA256 6d75d463113052af32b1e289016fb0be07c627cb4c83b85fb8640b00e1dc10c5
MD5 caf7066eefaaf83b2b3e4fc14255616b
BLAKE2b-256 9169dee26db4659fe17e4b69f79aac3cbfa9709cde3a174a9130eb8f1f5c6666

See more details on using hashes here.

Provenance

The following attestation bundles were made for meta_graph_cli-0.1.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: meta_graph_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.5 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b70bb5a7c345dab1e0d49d317fedad24edc078a837732149bfbe574383a46cfb
MD5 0abf1ffeb8bdc0644db9124eeeb94043
BLAKE2b-256 3ba489c2bb6a42f613510fe9bb74b936b1a63740a98fe778090f5443872c8f0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for meta_graph_cli-0.1.0-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