Instagram Location Scraper
Scrape Instagram posts by location ID or URL: captions, likes, comments, media URLs, hashtags, owner and timestamp.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
locationIds,startUrls,resultsLimit(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.0004 per result = $0.4 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Result returned | Charged per post returned. Failed/empty runs not charged. | $0.0004 |
| Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.001 |
Pay-per-event pricing: you are billed per result, not per subscription — a run that returns nothing costs nothing beyond the start fee. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-04, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
locationIds | Instagram location/place ids (number in /explore/locations/<id>/). | array |
startUrls | Or /explore/locations/<id>/ URLs. | array |
resultsLimit | Charged per post. | integer |
sessionCookies | Optional, and normally not needed — runs work with no cookie at all. Supply your own Instagram account cookie here to run on your own account's rate limit, and to reach feeds the no-setup route does not cover. In Chrome: F12 -> Application -> Cookies -> https://www.instagram.com -> copy the sessionid value. Use an account you own and are authorized to automate. Cookie values are never logged or written to output. | array |
notionConnector | Optional Notion delivery. | string |
notionParentId | Optional Notion data-source id. | string |
What you get
A structured dataset — each result includes fields like:
ownerUsernamecaptionlikesCountcommentsCounturlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
5 ready-to-run use cases
Scrape Bondi Beach Instagram Posts (Sydney)
Scrape Bondi Beach Instagram Posts (Sydney). Runs on any profile or place URL you paste. No login needed.
Scrape Disneyland Instagram Posts (California)
Scrape Disneyland Instagram Posts (California). Runs on a tagged Instagram place. No login needed.
Scrape Eiffel Tower Instagram Posts (Paris)
Scrape Eiffel Tower Instagram Posts (Paris). Runs on a tagged Instagram place — captions, likes, comments, media URLs, owner and timestamp. No login needed.
Scrape Santorini Instagram Posts (Greece)
Scrape Santorini Instagram Posts (Greece). Runs on a tagged Instagram place — captions, likes, comments, media URLs, owner and timestamp. No login needed.
Scrape Times Square Instagram Posts (NYC)
Scrape Times Square Instagram Posts (NYC). Runs on a tagged Instagram place — captions, likes, comments, media URLs, owner and timestamp. No login needed.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos or users and export clean rows: stars, forks, language, topics, license, plus user bio, company, location and follower count.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tags. Get structured questions with score, answers, views, tags, author, and link as JSON or CSV.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata - version, license, repo, keywords, and npm download counts. Search by keyword or look up exact names. No API key needed.
arXiv Scraper
Search arXiv and get clean JSON: titles, abstracts, authors, categories, DOI, dates and PDF links. No API key. Sort by relevance or date; push to Notion.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers by keyword. Get titles, authors, venue, year, citations, concepts, OA links and full abstracts as structured JSON. No API key.
Crossref Scholarly Works Scraper
Search 150M+ scholarly works on Crossref and export DOI, authors, journal, citation count, and abstracts as JSON or CSV. Filter by type and date.
Where this tool sits
- Categories
- Developer & Research Tools
⚡ Instagram Location Scraper — Posts by Place
Scrape Instagram posts by location/place at a flat per-post rate. Give it location IDs or /explore/locations/<id>/ URLs and get back the posts at each place: caption, likes, comments, media URLs, owner, hashtags, mentions and timestamp. Export to JSON, CSV or Excel, call it from the API, or have every run delivered straight to Notion. $0.40 per 1,000 posts plus a $0.001 run-start fee — built for local lead gen, event coverage, geo-trend tracking and market research.
> Runs work out of the box. No login, no cookie, no app review, nothing to supply. Instagram location feeds are login-gated — there is no logged-out endpoint that returns them — so this Actor reads them through a licensed data source. Paste location IDs and press start.
What you need to know before you run it
Place feeds work out of the box. The licensed data source is what keeps that promise. You supply nothing.
Out of the box you get the place's _recent_ feed. This is the one real limitation and it is worth knowing before you start: the licensed source serves the recent tab of a place. The top / ranked tab is read only when you supply your own Instagram cookie — with one, the Actor pages both tabs and dedupes across them.
To read the top/ranked tab as well, or to run on your own account's rate limit rather than the licensed source's, put your own cookie in sessionCookies:
- In Chrome:
F12→ Application → Cookies →https://www.instagram.com→ copy thesessionidvalue. Pasting the whole cookie string works too. One per line; several are rotated. - Your cookie takes priority over everything else. When you supply one the run uses it and nothing else — that is the point.
- Use a throwaway account you own and are authorized to automate. Never one you care about.
- If your cookie turns out to be dead, or gets checkpointed mid-run, the run does not come back empty: it falls back to the licensed source and still delivers posts.
Cookie values, proxy URLs and request headers are never logged or written to output. Logs carry only slot numbers, counts, reasons and totals.
Why this scraper
- 💸 Flat per-post pricing — $0.40 / 1,000 posts plus $0.001 per run start, billed per post actually returned. No volume tiers, no plan gates, no minimum spend.
- 🔓 Nothing to supply — the login gate on this feed is handled for you through a licensed data source. Your own cookie, if you paste one, is used on its own instead.
- 🧹 Clean, flat records — one tidy object per post, ready for sheets, dashboards or LLM pipelines. No nested GraphQL soup to unpack. Rows come back in the same shape whichever lane served them, and duplicates are removed across tabs and pages.
- 📬 Built-in Notion delivery — push every run into Notion via Apify connectors, zero extra code.
- 🚦 Honest errors — a clear diagnostic row (
NO_RESULTS,RATE_LIMITED,NOT_FOUND,PARTIAL) instead of silent emptiness, and those rows are never charged.
What you can scrape
| Mode | Input | Returns |
|---|---|---|
| Location ID | locationIds (e.g. 212988663) | Posts at that place — recent feed, plus top/ranked with your own cookie |
| Location URL | startUrls — /explore/locations/<id>/ | Same, ID parsed from the URL |
Input
locationIds— Instagram location/place IDs (the number in/explore/locations/<id>/).startUrls— or paste full/explore/locations/<id>/URLs instead.sessionCookies*(optional)* — leave empty and the licensed data source is used. Paste your own throwaway-accountsessionidcookie(s), one per line, to add the top/ranked tab and a private rate limit.resultsLimit— max posts for the whole run (default50, up to2000), counted across every location rather than per location. You pay per post.proxyConfiguration— preconfigured; leave as is unless you have your own proxy servers. Your ownproxyUrlsare used exactly as supplied; metered Apify groups (RESIDENTIAL) are not offered and are replaced with rotating datacenter addresses, with a warning in the log.notionConnector/notionParentId— optional Notion delivery.
Input field names follow the conventions used across similar Actors, so switching to this one is usually a drop-in change — the same startUrls / resultsLimit / proxyConfiguration shape you already have in your scripts will run here unchanged.
Example input
{
"locationIds": ["212988663", "213385402"],
"startUrls": ["https://www.instagram.com/explore/locations/214335386/"],
"resultsLimit": 200,
"sessionCookies": []
}
sessionCookies is optional — shown here empty, which is the normal case. Fill it only if you want the top/ranked tab as well, or a rate limit that is entirely yours:
{
"locationIds": ["212988663"],
"sessionCookies": ["sessionid=12345%3AAbCdEf%3A12%3AAbCd..."]
}
Output (one record per post)
{
"type": "image",
"shortCode": "Cabc123XyZ",
"url": "https://www.instagram.com/p/Cabc123XyZ/",
"caption": "Sunset over the bay 🌅 #travel",
"hashtags": ["travel"],
"mentions": [],
"likesCount": 12840,
"commentsCount": 213,
"videoViewCount": null,
"displayUrl": "https://...jpg",
"videoUrl": null,
"images": ["https://...jpg"],
"isVideo": false,
"dimensions": { "height": 1080, "width": 1080 },
"ownerUsername": "someaccount",
"ownerId": "123456789",
"timestamp": "2024-06-12T14:00:00.000Z",
"locationId": "212988663"
}
type is image, video or carousel. Video posts include videoUrl and videoViewCount; carousels list every frame in images. Every record carries the locationId it came from, so a multi-location run stays easy to group.
What people use it for
- Local lead generation — pull the accounts posting from a venue, neighbourhood or trade-show hall, then filter by follower-ish signals (likes/comments) to find the people worth contacting.
- Event coverage — scrape the venue's location page during and after an event to collect the user-generated content, photographers and hashtags around it.
- Geo trend tracking — run the same set of
locationIdson a schedule and watch which places, captions and hashtags are climbing. - Hospitality & retail research — see what customers actually post at a restaurant, hotel or store, not what the brand posts about itself.
- Content sourcing — collect media URLs and owner handles at a place so you can ask permission to repost.
Pricing
$0.40 per 1,000 posts ($0.0004 each), plus $0.001 each time a run starts.
Flat rate — no volume tiers, no plan gates — and you are only charged for posts actually returned. Sample rows, diagnostic rows, duplicates and no-result runs cost only the start fee.
Worked examples
| Run | Posts returned | Cost |
|---|---|---|
| One location, default limit | 50 | $0.021 |
Five locations, resultsLimit 1,000 | 1,000 | $0.401 |
| Diagnostic row only (no results) | 0 | $0.001 |
Running it on a schedule or from code
The Actor is a normal Apify Actor, so anything the platform offers works: Schedules for a daily geo sweep, Webhooks to fire when a run finishes, and the API to start runs from your own backend.
curl -X POST "https://api.apify.com/v2/acts/Dami_Studio~instagram-location-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"locationIds":["212988663"],"resultsLimit":100}'
Results land in the run's dataset and can be pulled as JSON, CSV, Excel, XML or RSS from the dataset items endpoint, or pushed straight into Notion with the optional connector inputs.
Limitations — read these before you buy
- There is no keyless path to this data. Location feeds are login-gated; anyone claiming a logged-out route is scraping something else. The licensed data source is what makes runs work with nothing supplied — and because a logged-out request here always fails, the Actor does not waste a round trip on one.
- The recent feed is what you get by default. The top/ranked tab needs your own cookie in
sessionCookies, as above. - A run can stop before your requested limit. The licensed source is metered per request, so each run carries a request ceiling; without your own cookie a run tops out at roughly 900 posts in practice. When it stops, everything already collected is delivered and correct, and one uncharged
PARTIALrow says that it stopped and why. Re-run to continue. - If you supply your own cookie, its lifetime is not under anyone's control. Instagram invalidates sessions on its own schedule, especially for accounts that suddenly read a lot. Expect to refresh yours periodically, and paste several so one death does not stall a run.
- Use throwaway accounts only. Automated reading can get an account rate-limited or checkpointed. Never paste a
sessionidyou care about. - Depth is capped by Instagram, not by us. Location feeds paginate a limited way back; asking for 2,000 posts at a small, quiet place will simply return everything available and stop, which is usually far fewer.
likesCountcan benull. Instagram hides like counts on some posts and for some viewers. Comment counts are more consistently present.- Media URLs expire.
displayUrl,videoUrlandimagesare signed CDN links that stop working after a while — download what you need soon after the run. - Private accounts are never included, and posts can disappear between the run and when you read the data.
- No comment text or follower counts. This Actor returns the location feed's post objects only; per-post comment threads and profile stats are a different job.
FAQ
Do I need to supply a cookie? No. Instagram location feeds require a logged-in caller — there is no logged-out endpoint that returns them — but the Actor reads them through a licensed data source, so runs work with sessionCookies empty.
Then what does supplying a cookie buy me? Two things: the top/ranked tab of a place, which the licensed source does not serve, and a rate limit that is entirely yours.
Is my main account at risk? Only if you choose to supply a cookie at all — and if you do, use a throwaway account, never your personal one.
How do I find a location ID? Open the place on Instagram — the URL is /explore/locations/<id>/. That <id> is what goes in locationIds. You can also paste the whole URL into startUrls and let the Actor parse it.
Can I pass several locations at once? Yes. locationIds and startUrls are both lists and can be combined in one run. Note that resultsLimit is the total for the run, not a per-location quota, so locations are filled in order — run one location per job if you need even coverage across many places.
Do I need a proxy? No — proxying is preconfigured with rotating datacenter addresses. If you enter your own proxy servers they are used exactly as given.
I got a NO_RESULTS / PARTIAL row — why? That is the Actor telling you exactly what happened instead of failing silently: NO_RESULTS means the place genuinely had nothing to return (very new, very quiet or restricted places do this), and PARTIAL means the run stopped early, so what you have is complete and correct as far as it goes. Both rows are free.
What happens on a failed run? Nothing beyond the start fee. Per-post charges only fire for genuine posts pushed to the dataset.
Billing
Two charges apply: a $0.001 run-start fee each time a run begins, and a $0.0004 per-post fee for posts actually delivered, charged once per unique post. Samples, diagnostics, duplicates, blocked look-ups and no-result runs never incur the per-post fee — a run that returns nothing costs only the $0.001 start fee.