When to Use
- Feed analytics dashboard: Pull the last 50 posts with engagement metrics to populate a weekly performance report, calculating average likes and comments per post type.
- Content inventory sync: Build or refresh an internal content library by fetching all published media, their captions, and permalinks into a CMS or spreadsheet.
- Campaign retrospective: After a marketing campaign, retrieve media posted during a date range and compile engagement data for client reporting.
- Automated content archival: Run a nightly workflow to page through recent media and back up media URLs and captions to a durable storage system before CDN URLs expire.
- Competitive benchmarking: When using Business Discovery to access another Business account's feed (with user consent), compare posting frequency and engagement patterns.
Configuration
Connection
| Field | Required | Description |
accessToken | Required | Long-lived Instagram access token stored in BizFirst Credentials Manager. |
igUserId | Required | Instagram Business/Creator account ID. Pass your own or a discovered account ID. |
Operation
| Field | Required | Description |
resource | Required | Must be ig-user. |
operation | Required | Must be get-media. |
limit | Optional | Number of media objects per page. Default 25. Max 100. Clamped automatically. |
after | Optional | Cursor from previous page's paging.after value for forward pagination. |
fields | Optional | Comma-separated fields to return per media item. E.g. id,caption,media_type,like_count,permalink,timestamp. |
Sample Configuration JSON
{
"resource": "ig-user",
"operation": "get-media",
"accessToken": "{{ $credential.instagram.accessToken }}",
"igUserId": "17841400000000000",
"limit": 50,
"fields": "id,caption,media_type,media_url,like_count,comments_count,permalink,timestamp"
}
Validation Errors
| Error | Cause |
accessToken is required | accessToken field is missing or empty. |
igUserId is required | igUserId field is missing or empty. |
invalid_input | General config validation failure. |
Output
Success Port
| Field | Type | Description |
status | string | "success" |
media | array | Array of media item objects. Each item contains requested fields. |
paging.before | string | Cursor for the previous page. |
paging.after | string | Cursor for the next page. Pass as after in next call. |
paging.nextUrl | string | Full URL for the next page (Graph API convenience link). |
paging.previousUrl | string | Full URL for the previous page. |
payload | string | Raw JSON response from the Graph API. |
Error Port
Fires on authentication failure, invalid user ID, permission error, or rate limit exceeded.
| Field | Type | Description |
status | string | "error" |
errorCode | string | Graph API error code. |
errorMessage | string | Human-readable error description. |
payload | string | Raw error response. |
Sample Output JSON
{
"status": "success",
"media": [
{
"id": "17855590000000001",
"caption": "Summer collection launch! #fashion",
"media_type": "IMAGE",
"media_url": "https://scontent.cdninstagram.com/v/t51...",
"like_count": 842,
"comments_count": 37,
"permalink": "https://www.instagram.com/p/ABC123/",
"timestamp": "2025-06-15T14:30:00+0000"
},
{
"id": "17855590000000002",
"caption": "Behind the scenes at the shoot",
"media_type": "CAROUSEL_ALBUM",
"like_count": 651,
"comments_count": 24,
"permalink": "https://www.instagram.com/p/DEF456/",
"timestamp": "2025-06-13T10:00:00+0000"
}
],
"paging": {
"before": "QVFIUmJ...",
"after": "QVFIUmJ2...",
"nextUrl": "https://graph.facebook.com/v18.0/...",
"previousUrl": ""
}
}
Expression Reference
| Expression | Value |
{{ $output.instagram.media }} | Full media array |
{{ $output.instagram.media[0].id }} | First item's media ID |
{{ $output.instagram.media[0].caption }} | First item's caption |
{{ $output.instagram.media[0].permalink }} | First item's public post URL |
{{ $output.instagram.paging.after }} | Next-page cursor |
Node Policies & GuardRails
- Pagination loops: To retrieve more than 100 items, loop through pages by passing
paging.after into the next call's after field. Stop when paging.after is empty.
- Rate limit: 200 calls per user per hour. A full feed paginator requesting 25 items/page will exhaust quota after 200 pages (5,000 items). Use large
limit values (100) to minimise calls per run.
- Media URL expiry: Do not persist
media_url values long-term. Store permalink or id and re-fetch URLs on demand.
- GDPR: Caption text may contain personal mentions. Apply appropriate data retention and processing lawful basis when storing results.
Examples
Weekly engagement report — first page
{
"resource": "ig-user",
"operation": "get-media",
"accessToken": "{{ $credential.instagram.accessToken }}",
"igUserId": "{{ $env.IG_USER_ID }}",
"limit": 100,
"fields": "id,media_type,like_count,comments_count,timestamp"
}
Fetches up to 100 posts with minimal fields for an aggregation workflow. The next node iterates the media array and sums like_count and comments_count by media_type.
Paginated feed sync with loop
{
"resource": "ig-user",
"operation": "get-media",
"accessToken": "{{ $credential.instagram.accessToken }}",
"igUserId": "17841400000000000",
"limit": 100,
"after": "{{ $loopState.afterCursor }}",
"fields": "id,caption,permalink,timestamp,media_type"
}
Used inside a loop node. $loopState.afterCursor starts as empty and is updated from paging.after each iteration. The loop exits when paging.after is empty.