RESTful HTTP service that wraps instagrapi so you can call Instagram's private API from any programming language. Run it as a Docker sidecar next to your application; hit it from Node, Go, PHP, Java, C#, Ruby, Swift, Bash β anything that speaks HTTP.
This is the cross-language exit when your stack is not Python and the maintained Instagram libraries in your own language have gone stale or been archived (which, as of 2026, is most of them β see the language-by-language survey on instagrapi.com).
instagrapi is the actively-maintained Python wrapper for Instagram's private mobile API β full write surface (post, DM, story), pydantic-typed responses, first-class challenge_required and 2FA handling. If your application is in Python, you import it directly.
If your application is in a different language, your options for Instagram have been narrowing fast. The most-starred libraries on GitHub's instagram-api topic are mostly stale or explicitly archived: the canonical Node/TypeScript client (dilame/instagram-private-api) hasn't shipped a meaningful release since August 2024; the canonical Go client (ahmdrz/goinsta) was archived in 2021; the Swift options are dead. Instagram's surface keeps moving and the per-language wrapper authors largely stopped chasing it.
instagrapi-rest solves that the simple way: run the actively-maintained Python library behind an HTTP boundary, and call it from whatever language you actually write your business logic in.
This is OSS infrastructure, not a managed service. Self-hosting means you bring:
- Instagram accounts (and the operational headache of keeping them un-banned)
- Residential or mobile proxies (Instagram's anti-abuse system flags datacenter IPs hard)
- Session storage and rotation
- Retry logic when challenges fire mid-script
If those line items sound like work you don't want, the same team behind instagrapi runs HikerAPI as a managed equivalent β same Instagram surface, sessions and proxies handled on our side, called over HTTPS with an API key. It exists precisely because self-hosting instagrapi-rest has real ops cost. Use whichever fits β both paths are first-class.
docker run -d -p 8000:8000 subzeroid/instagrapi-restOpen http://localhost:8000/docs for the live OpenAPI / Swagger UI.
Get a session id (replace <USERNAME>/<PASSWORD>):
curl -X POST http://localhost:8000/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=<USERNAME>&password=<PASSWORD>"Fetch a public profile:
curl "http://localhost:8000/user/by/username?username=instagram&sessionid=<SESSIONID>"The service is plain HTTP + JSON, so any HTTP client in any language works. Below are the shortest possible call snippets for the most common stacks; full working clients live in ./golang and ./swift.
Node.js / TypeScript:
const r = await fetch(`http://localhost:8000/user/by/username?username=instagram&sessionid=${SID}`);
const user = await r.json();
console.log(user.full_name, user.follower_count);Go (full example: golang/client.go):
resp, _ := http.Get("http://localhost:8000/user/by/username?username=instagram&sessionid=" + sid)
defer resp.Body.Close()
var user map[string]any
json.NewDecoder(resp.Body).Decode(&user)PHP:
$user = json_decode(file_get_contents(
"http://localhost:8000/user/by/username?username=instagram&sessionid=$sid"
), true);Java (with java.net.http.HttpClient):
HttpResponse<String> r = HttpClient.newHttpClient().send(
HttpRequest.newBuilder(URI.create("http://localhost:8000/user/by/username?username=instagram&sessionid=" + sid)).build(),
HttpResponse.BodyHandlers.ofString());Ruby:
require "net/http"; require "json"
user = JSON.parse(Net::HTTP.get(URI("http://localhost:8000/user/by/username?username=instagram&sessionid=#{sid}")))Swift (full example: swift/client.swift).
For typed client generation in C++, C#, F#, D, Erlang, Elixir, Nim, Haskell, Lisp, Clojure, Julia, R, Kotlin, Scala, OCaml, Crystal, Rust, Objective-C, Visual Basic, .NET, Pascal, Perl, Lua and others, see the Generating client code section below.
- Authorization β login, 2FA, settings management
- Media β info, delete, edit, like, archive
- Video / Photo / IGTV / Reels / Album β upload to feed and story, download
- Story β info, delete, mark as seen, download
- User β followers / following, info, follow / unfollow, remove follower
- Insights β media, account
Install ImageMagick (required for photo upload):
sudo apt install imagemagick
Then comment the strict policy line in /etc/ImageMagick-6/policy.xml:
<!--<policy domain="path" rights="none" pattern="@*"/>-->Run the prebuilt Docker image:
docker run -p 8000:8000 subzeroid/instagrapi-rest
Or clone and build locally:
git clone https://github.com/subzeroid/instagrapi-rest.git
cd instagrapi-rest
docker build -t instagrapi-rest .
docker run -p 8000:8000 instagrapi-rest
Or use docker-compose:
docker-compose up -d
Or run without Docker:
python3 -m venv .venv
. .venv/bin/activate
pip install -U wheel pip -Ur requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Live API documentation at http://localhost:8000/docs (Swagger UI):
curl -X 'POST' \
'http://localhost:8000/auth/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=<USERNAME>&password=<PASSWORD>&verification_code=<2FA CODE>'
curl -X 'POST' \
'http://localhost:8000/photo/upload_to_story' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'sessionid=<SESSIONID>' \
-F 'file=@photo.jpeg;type=image/jpeg'
curl -X 'POST' \
'https://localhost:8000/photo/upload_to_story/by_url' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'sessionid=<SESSIONID>&url=https%3A%2F%2Fapi.telegram.org%2Ffile%2Ftest.jpg'
curl -X 'POST' \
'http://localhost:8000/video/upload_to_story' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'sessionid=<SESSIONID>' \
-F 'file=@video.mp4;type=video/mp4'
curl -X 'POST' \
'https://localhost:8000/video/upload_to_story/by_url' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'sessionid=<SESSIONID>&url=https%3A%2F%2Fapi.telegram.org%2Ffile%2Ftest.MP4'
The service exposes an OpenAPI spec at /openapi.json. Use @openapitools/openapi-generator-cli to generate a typed client in any supported language:
openapi-generator-cli generate -g <language> -i http://localhost:8000/openapi.json --skip-validate-spec
--skip-validate-spec is sometimes needed for transient validator errors.
When you start running this against a real Instagram surface β daily monitoring, multi-account orchestration, anything beyond ad-hoc β you will hit the same friction the Python world hits with instagrapi directly:
- Account bans β Instagram rotates abuse-detection rules; accounts that scraped fine last week get flagged this week.
- Proxy hunting β datacenter IPs are flagged on first contact; you need residential or mobile proxies, and you need to rotate them.
- Sessions β losing a session means re-logging in, which means the
challenge_requiredcycle, which means manual SMS / email retrieval.
instagrapi-rest does not solve any of this β it just gives you HTTP access to the same library that hits the same wall. The honest options when you reach this point are:
- Build the ops layer yourself β proxy pool, account warming, challenge-handler workers. This is real engineering, measured in weeks.
- Use HikerAPI β same Instagram surface as a managed HTTPS endpoint with an API key. Proxies and sessions handled on our side. The two products coexist deliberately: this repo is the OSS path; HikerAPI is the managed path. Pick whichever matches the cost shape you want.
subzeroid/instagrapiβ the underlying Python librarysubzeroid/aiograpiβ async fork ofinstagrapisubzeroid/hikerapi-mcpβ MCP server for HikerAPI (LLM tool surface)- instagrapi.com β guides, integration recipes, error reference
- HikerAPI β managed Instagram API
- LamaTok β managed TikTok API
- DataLikers β Instagram + TikTok cached datasets
Run all tests:
docker-compose run api pytest tests.py
A single test:
docker-compose run api pytest tests.py::test_media_pk_from_code
Without docker-compose:
docker run --rm -v "$(pwd):/app" instagrapi-rest pytest tests.py
For debugging with the dev server bound:
docker-compose run --service-ports api
