Instagram Dataset Media Downloader avatar

Instagram Dataset Media Downloader

Pricing

Pay per usage

Go to Apify Store
Instagram Dataset Media Downloader

Instagram Dataset Media Downloader

Automatically downloads expiring media (videos and images) from Instagram Reel Scraper and Post Scraper datasets. Stores files in a named key-value store with full traceability back to the original reel or post.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Vít Tuhý

Vít Tuhý

Maintained by Community

Actor stats

0

Bookmarked

15

Total users

2

Monthly active users

8 days ago

Last modified

Share

Instagram Reels and Posts Media Downloader

Downloads expiring media (videos and images) from Instagram Reel Scraper and Instagram Post Scraper datasets before the URLs expire.

Instagram CDN links are signed and short-lived. Decoding the oe expiry parameter on sampled reels gives roughly 32 hours, so run this Actor within about a day of the scrape - ideally wired to the scraper's Integrations tab so it fires automatically on every run.

The Actor grabs the media and stores it permanently in an Apify key-value store, with full traceability back to the original content.

How it works

  1. Reads a dataset by ID (from a Reel or Post Scraper run)
  2. Auto-detects whether the dataset came from the Reel Scraper or Post Scraper
  3. Downloads all media files (videos, images, carousel children) through Apify Proxy
  4. Streams each file into a key-value store
  5. Pushes one dataset item per file and writes a _manifest JSON summarizing the run

Downloads run on Crawlee's FileDownload crawler, which handles concurrency autoscaling, retries with backoff, proxy session rotation, and a persistent request queue.

Source detection

SourceDetected byFields downloaded
Instagram Reel ScraperdownloadedVideo field or productType: "clips"videoUrl (video)
Instagram Post ScraperdisplayUrl field presentdisplayUrl (image), videoUrl (video, when present), plus all childPosts media for carousel/sidecar posts

File naming in the key-value store

Every file is keyed by the Instagram shortcode so you can trace it back to the original content:

SourceMediaKey formatExample
Reel ScraperVideoreel-{shortCode}reel-CxYz123
Post ScraperImagepost-{shortCode}-imagepost-AbCd456-image
Post ScraperVideopost-{shortCode}-videopost-AbCd456-video
Post ScraperCarousel child imagepost-{childShortCode}-imagepost-EfGh789-image
Post ScraperCarousel child videopost-{childShortCode}-videopost-EfGh789-video

Proxy

Instagram fingerprints datacenter IP ranges. Running unproxied sends requests straight from Apify platform IPs, which Meta can rate-limit and attribute back to Apify infrastructure. The Actor therefore defaults to Apify Proxy with the RESIDENTIAL group.

If your account has no residential access, the Actor falls back to automatic proxy group selection, and then to no proxy at all - each step logs a warning rather than failing the run. Check the log if downloads start failing.

Migration safety

Apify can move a running Actor between servers at any time. This Actor is built to survive that:

  • Downloads live in a persistent request queue, so files already downloaded are not fetched again after a restart
  • Requests are deduplicated on the media key, not the URL, because Instagram CDN URLs carry expiring signed query parameters that change between reads
  • Run counters use Crawlee's useState, which is persisted to the key-value store on the migrating event
  • The _manifest is rebuilt from the Actor's own dataset at the end of the run, not from an in-memory array, so it stays complete across a migration

Input

FieldTypeRequiredDefaultDescription
datasetIdStringYes-ID of the dataset to read media URLs from
proxyConfigurationObjectNoApify Proxy, RESIDENTIALProxy used for downloads
keyValueStoreNameStringNorun's default KVSName of the key-value store to save media into
maxConcurrencyIntegerNo5Upper bound on parallel downloads (1-50)
maxRequestRetriesIntegerNo3Retries for non-proxy failures such as timeouts (0-10)
maxSessionRotationsIntegerNo5Retries with a fresh proxy IP after a proxy error or block (0-20)

Crawlee counts these two budgets separately - a proxy error rotates the session and does not consume a request retry. Rotations happen with no backoff, so a URL whose CDN edge rejects your proxy type will exhaust the rotation budget within a couple of seconds and then be recorded as failed.

concurrency is still accepted as an alias for maxConcurrency so integrations built against v1.x keep working.

Example input

{
"datasetId": "{{resource.defaultDatasetId}}",
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
},
"maxConcurrency": 10
}

Output

The Actor pushes one dataset item per media file:

{
"shortCode": "CxYz123",
"originalId": "3210987654321",
"ownerUsername": "natgeo",
"caption": "Amazing wildlife footage...",
"timestamp": "2026-06-20T12:00:00.000Z",
"postType": "Video",
"kvsKey": "reel-CxYz123",
"mediaType": "video",
"sourceUrl": "https://...",
"contentType": "video/mp4",
"sizeBytes": 5242880,
"status": "ok"
}

Files that fail every retry are pushed with "status": "failed" and an error field instead of contentType/sizeBytes. For carousel children, items also include parentShortCode and childIndex.

The same array is written to the _manifest key in the media key-value store.

Downloaded files can be accessed via:

  • Apify Console: Storage > Key-value stores
  • API: https://api.apify.com/v2/key-value-stores/{storeId}/records/{key}

Integration setup

The primary use case is running this Actor automatically after a Reel or Post Scraper run finishes.

  1. Open your Instagram Reel Scraper or Instagram Post Scraper Actor (or Task) in Apify Console
  2. Go to the Integrations tab
  3. Click Add integration > Run Actor
  4. Configure:
    • When: Run succeeded
    • Actor: Select instagram-media-downloader (this Actor)
    • Input:
{
"datasetId": "{{resource.defaultDatasetId}}"
}
  1. Click Save

{{resource.defaultDatasetId}} is replaced with the dataset ID from the scraper run that triggered the integration. It is only substituted by the integration system - if you run this Actor standalone and leave the template in the field, the run fails immediately with an explanatory message.

If you run the scraper via a saved Task (e.g. "Scrape NatGeo reels daily"), open the Task, go to its Integrations tab, and follow the same steps. Every scheduled or manual run of that Task will then trigger the media download.

Custom key-value store name

{
"datasetId": "{{resource.defaultDatasetId}}",
"keyValueStoreName": "natgeo-reels-{{resource.id}}"
}

{{resource.id}} is the run ID of the source scraper. Named stores are retained indefinitely; the default store follows the run's retention period.

Data retention

Storage counts toward your Apify plan limits. To manage it:

  • Delete old key-value stores via Console or API when you no longer need the media
  • Use the _manifest key to audit what is stored before cleanup

Limitations

  • URLs that expired before the run will fail after all retries; the Actor logs a warning and continues
  • The Actor does not re-upload to external storage (S3, GCS, etc.) - files stay in Apify KVS
  • Very large datasets need proportionally more run time; memory stays flat because downloads are streamed