Instagram

Pull public Instagram posts (images, carousels, reels) by profile or hashtag and emit structured JSON (caption, media, likes, comments).

Overview

The Instagram node scrapes PUBLIC Instagram posts and returns them as a JSON array. Each post carries its caption, owner, timestamp, like/comment counts, and image/video URLs (carousel children flattened). Pipe the array into Extract Field, JSON Process or a List node to fan out, or straight into a Generate Text node for content analysis.

When to Use

Configuration

Search by

Mode Input Description
profile (Profile) Usernames One username per line, up to 5 (nike; @ optional). Use {} to inject an upstream list
hashtag (Hashtag) Hashtags One hashtag per line, up to 5 (running; # optional). Use {} to inject an upstream list

Fields

Field Type Default Description
Posts per source number 20 How many posts per profile / hashtag (1–100)
Period select Last 30 days Last 24 hours, Last 7 days, Last 30 days or All time, by the post’s date (honoured by the scraper)
Creative format toggles none (no filter) Keep only posts whose creative is vertical (reels / portrait), square or horizontal, classified from the post’s real pixels. Fewer posts than requested may come back
Copy all videos toggle off Copy every returned post’s video into your library (the expensive bytes; they count toward storage)
AI analysis toggle + model + focus off Run a content-analyst pass on every post — asset type, format, visual hooks, audiences, graphic identity, content angles, value, CTA and a summary. Priced per requested post by the model’s tier, settled per post analysed

After a run the node card features one post — creative, owner, caption, likes / comments, format — with a thumbnail strip and ‹ › to move between posts; the Results tab lists them all, filters by format, and clicking a row features it.

Creatives in your library

Instagram’s image and video links are signed and expire, so after every run the node copies each post’s images and video covers into your library (they count towards your storage; they stay out of the media picker until you press Save to library on a post). The featured post’s video is copied when the node’s video output is wired; turn on Copy all videos to copy every post’s video. When storage is full, or on an install without media storage, the posts keep their original links and the run still succeeds.

Inputs & Outputs

Inputs: in (optional) — upstream text: profiles (one per line) in profile mode, or hashtags in hashtag mode.

Outputs:

Handle Carries
json the whole array of posts (below) — fan out with a List node
text the featured post’s caption
image the featured post’s first image (or its video cover)
video the featured post’s first video

The json handle emits an array of posts, each shaped as:

{
  "postId": "3712…",
  "shortCode": "DdMeNa0O_x_",
  "url": "https://www.instagram.com/p/DdMeNa0O_x_/",
  "type": "image",
  "caption": "New York, Paris, Melbourne…",
  "ownerUsername": "nike",
  "timestamp": "2026-09-12T17:01:28.000Z",
  "likesCount": 53999,
  "commentsCount": 169,
  "images": ["https://…/creative.jpg"],
  "videos": [],
  "videoPreviews": [],
  "hashtags": ["running"]
}

Pricing

1 credit per requested post, rounded up to the next tier of the requested total (Posts per source × number of sources).

Requested total Credits
up to 10 10 CR
up to 20 20 CR
up to 50 50 CR
up to 100 100 CR
up to 200 200 CR
up to 500 500 CR

AI analysis add-on

Turning on AI analysis adds a per-post cost by the model’s tier — +1 (economy) / +3 (standard) / +4 (premium) — settled for the posts actually analysed.

Requested batch Analysis model Total
20 posts economy 20 + 20 × 1 = 40 CR
2 profiles × 30 posts (tier 100) standard 100 + 100 × 3 = 400 CR

Providers

Uses Apify (apify/instagram-scraper). Needs APIFY_API_TOKEN, or a connected nodaro.ai account (the run — scrape and analysis — is relayed and billed there). AI analysis additionally needs an LLM key on a local run.

Running it (editor vs. API)

A real profile scrape (media copy included) routinely runs longer than a browser’s ~100-second HTTP limit, so the request returns a job id right away and the scrape finishes on the server. In the editor and in a workflow there is nothing to do — both poll for you and show the posts when they land.

A direct API/SDK caller gets { "jobId": "…", "status": "pending" } and reads the result from the job: