# Instagram Mentions Scraper — Tagged Posts, New Tags Only (`steadyfetch/instagram-mentions-scraper`) Actor

Instagram mentions scraper for the posts that tag an account: every post on its Tagged tab with link, caption, date, counts and the author. Schedule it and only the posts that newly tag you come back — posts you already have are never charged twice. From $1.20 per 1,000 posts.

- **URL**: https://apify.com/steadyfetch/instagram-mentions-scraper.md
- **Developed by:** [Steadyfetch Team](https://apify.com/steadyfetch) (community)
- **Categories:** Social media, Automation, Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 tagged posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Mentions Scraper — Tagged Posts, New Tags Only

**Every Instagram post that tags your account — and, on a schedule, only the posts that newly tag you. Put in a handle and get its Tagged tab back as rows: post link, caption, date, likes, comments, views and the account that posted it. From $1.20 per 1,000 posts; a post you already have is never charged twice.**

Type Instagram handles or profile links — your brand, your clients, your competitors. For each account the run reads the posts other accounts published that tag it (Instagram's own Tagged tab), newest first. Schedule it daily with **"New tags only"** on and each run returns just the posts that tagged the account since the last one. No login, no cookies, no proxy to set up. A handle that names no account, an account with no tagged posts, and a read that did not go through are never charged, and nothing is charged for starting a run.

**Using an AI agent?** Pin this actor in Apify's MCP server with one link: `https://mcp.apify.com?tools=steadyfetch/instagram-mentions-scraper`

- **Actor id:** `steadyfetch/instagram-mentions-scraper`
- **Input:** `{ "usernames": ["glossier"], "maxPostsPerAccount": 50 }` — `usernames` is the one field you have to set.
- **Cap the bill:** set `maxTotalChargeUsd` on the run (a run option, not Actor input), e.g. `0.50` — the run stops when it reaches it.
- **Price:** from $0.0012 per tagged post ($0.002 on the Apify free plan), plus one $0.003 account lookup per account on its first charged post. Full table below.
- **How often it changes:** an active account is tagged every day; a brand that curates its Tagged tab may show the same posts for years. Every row says how new the account's newest tagged post is.

*Unofficial. Not affiliated with, endorsed by, or sponsored by Instagram or Meta Platforms, Inc.*

### What you get

One row per tagged post:

| Column | What it holds |
|---|---|
| `taggedUsername` · `taggedUserId` · `taggedFullName` · `taggedFollowersCount` · `taggedIsVerified` | the account the post tags (yours, or the one you asked about) |
| `postId` · `shortcode` · `url` | the post and its link |
| `postedAt` · `mediaType` · `isReel` · `carouselCount` · `videoDurationSeconds` | when it was posted, and what it is (photo, video, carousel) |
| `caption` · `likeCount` · `commentCount` · `viewCount` | what it says and how it did — `null` when the author hides the counts |
| `authorUsername` · `authorFullName` · `authorUserId` · `authorProfileUrl` · `authorIsVerified` · `authorIsPrivate` | who posted it — the creator, customer or collaborator who tagged you |
| `taggedUsers` · `coauthors` · `locationName` · `isPaidPartnership` · `sponsorTags` | everyone tagged on it, its co-authors, its place, and its paid-partnership label |
| `thumbnailUrl` · `videoUrl` | the media links Instagram serves (they expire after a few days) |
| `newestTaggedPostAt` · `taggedTabStale` | the date of the account's newest tagged post, and `true` when it is more than 90 days old |
| `charged` · `chargedEvents` · `status` · `statusReason` | what the row was charged, and why it says what it says |

Every column is always present: a field Instagram did not send is `null`, never missing, and nothing is guessed.

**Tagged posts, not every mention.** This actor reads the Tagged tab: posts where the author tagged the account. A caption that writes @handle without tagging the account is not on that tab and is not returned.

**Some Tagged tabs are not live.** Big brands often curate their Tagged tab, so it can show posts from years ago and nothing new. Every row carries `newestTaggedPostAt`, `taggedTabStale` turns `true` past 90 days, and the run's status line names the account, so you know before you schedule it.

### What a row looks like

```json
{
  "taggedUsername": "sample_brand",
  "taggedFollowersCount": 48210,
  "postId": "3000000000000000001",
  "url": "https://www.instagram.com/p/SAMPLE00001/",
  "postedAt": "2026-10-21T18:00:00Z",
  "mediaType": "video",
  "isReel": true,
  "caption": "Sample caption: my morning routine with @sample_brand",
  "likeCount": 312,
  "commentCount": 14,
  "viewCount": 5120,
  "authorUsername": "sample_creator_1",
  "authorFullName": "Sample Creator 1",
  "authorIsVerified": false,
  "taggedUsers": ["sample_brand"],
  "isPaidPartnership": false,
  "newestTaggedPostAt": "2026-10-21T18:00:00Z",
  "taggedTabStale": false,
  "charged": true,
  "chargedEvents": { "post": 1, "profile-lookup": 1 },
  "status": "delivered"
}
```

### Price

You pay per event, and only for what was delivered:

| Event | When it is charged | Apify free plan | Bronze | Silver | Gold and up |
|---|---|---|---|---|---|
| `post` | each new tagged post delivered | $0.002 | $0.0016 | $0.0014 | $0.0012 |
| `profile-lookup` | once per account per run, on its first charged post | $0.003 | $0.003 | $0.003 | $0.003 |
| `check` | once per account, only when a repeat run found nothing new for you | $0.005 | $0.005 | $0.005 | $0.005 |

Examples: 50 tagged posts for one account is $0.063 from Gold, $0.103 on the Apify free plan. A daily run for one account that finds 3 new tags is $0.0066 from Gold; a day with nothing new is one $0.005 check. No start fee, ever.

### Only the posts that newly tag you

Every run remembers, in a key-value store in your own Apify account (`ig-mentions-account`), which tagged posts it delivered for which account. With **"New tags only"** on (the default), a later run for the same account skips those posts: no row and no charge. The Tagged tab is read newest first, so the run stops as soon as it reaches posts you already have. Posts older than 90 days in that memory count as new again.

When a repeat run reads an account and every post on its tab is one you already have, that account's row says so and is charged one **check** ($0.005), once, for the read. A first run is never charged a check, nor is an account with no tagged posts, a read a limit of yours cut short, or any run with "New tags only" off. Turn it off and the posts you already have come back again, marked `repeat: true`, with no result fee.

**Posted after** narrows any run to posts on or after a date ("2026-10-01") or inside a rolling window ("7 days", "24 hours").

### Honest rows: what "not charged" actually means

Every account that returns fewer posts than you asked for gets one row saying which of these happened:

- `nothing_found` — the tab returned all it had, your "Posted after" date was reached, the tab came back empty twice, or no account goes by that handle.
- `already_delivered` — the tab returned only posts you already have, so the run stopped reading (the one row that may carry a check, and it says so).
- `your_limit_reached` — your own limit (posts per account, maximum cost, run seconds) stopped it.
- `limit_reached` — this actor's own page limit for one account, or this run reached its limit; the row says which.
- `plan_limit_reached` — the Apify free plan's daily allowance for this actor; the row says when it resets.
- `try_again` — the read did not go through; a re-run is the fix.
- `not_accepted` / `not_supported` — an input value it cannot use, or an answer this actor does not read yet; the row says what.

Apart from a check named on its own row, none of these is charged, and the run still finishes successfully. A time limit ends the collecting, never the delivering: posts already in hand are always written out. The last row is the run's own summary: what was delivered, what was asked for, which accounts' tabs are not live, and what stopped it. Results may fail when Instagram changes; failed items are never charged.

### How often this data changes

An account that customers and creators tag is tagged daily, and a daily or weekly run with "New tags only" on returns just the new posts. Likes, comments and views keep moving for days after a post goes up. A brand that curates its Tagged tab changes it rarely — the `newestTaggedPostAt` column shows you which kind of account you have.

### Use it as an API endpoint (Standby)

Every input above also works as one HTTP request to this actor's endpoint (also on its Endpoints tab), by GET with the fields in the query string or by POST with the same fields as a JSON body:

```bash
curl -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  "https://steadyfetch--instagram-mentions-scraper.apify.actor/?usernames=glossier&maxPostsPerAccount=20"
```

| Setting | What it does |
|---|---|
| `usernames` | An Instagram handle or profile link. Repeat it or separate with commas for more than one. |
| `maxPostsPerAccount` | How many tagged posts for each account. 50 if you leave it out. |
| `postedAfter` | Only posts on or after this date (2026-10-01) or inside this window (7 days). |

The posts come back in the response as JSON, with the same columns as a dataset row, charged per post (and one lookup per account) at the same prices as a run. One request takes up to 10 accounts at 50 posts each (3 accounts at 20 on the Apify free plan). The endpoint keeps no memory of what you already have, so every request reads fresh and no check is ever charged there — schedule a run of the actor for "new tags only". A request that returns no posts is not charged; if a request's charge cannot be completed, its posts are not sent.

### Limits and good manners

- **Max posts per account:** 50 by default, up to 500. Above that the run continues at 500 and one uncharged row says so.
- **Pages per account:** at most 30 (21 posts a page).
- **Hashtags and post links are not this actor's input.** It reads the posts that tag an account; a hashtag goes to the Instagram Hashtag Scraper and a post's comments to the Instagram Comments Scraper. Either is refused here on an uncharged row that says so.
- Only public data: what Instagram shows any visitor on an account's Tagged tab.

### Related actors

- [Instagram Hashtag Scraper](https://apify.com/steadyfetch/instagram-hashtag-scraper) — the posts under a hashtag or keyword.
- [Instagram Profile Posts Scraper](https://apify.com/steadyfetch/instagram-profile-posts) — an account's own posts and reels.
- [Instagram Comments Scraper](https://apify.com/steadyfetch/instagram-comments-scraper) — the comments under a post.
- [Instagram Bio Scraper](https://apify.com/steadyfetch/instagram-profile-details-scraper) — the full record of the accounts that tagged you.

### Reliability

Every row says what it was charged. A read that fails is tried again before it is reported; a row that cannot be delivered is never charged; and the run never ends on a limit it set itself without saying so on the last row.

### Support

Questions, an account that returns something odd, or a column you need: open an issue on the Issues tab and it will be looked at.

If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

# Changelog

This Actor's version history is a separate document: https://apify.com/steadyfetch/instagram-mentions-scraper/changelog.md

# Actor input Schema

## `usernames` (type: `array`):

Instagram handles or profile links, one per line — "nike", "@nike" or https://www.instagram.com/nike/. Each returns the posts other accounts published that tag it (its Tagged tab), newest first. A handle that names no account, and a read that did not go through, come back as labelled rows and are never charged. A hashtag or a post link is refused with a row pointing to the actor that reads it. Big brands often curate their Tagged tab, so it can show years-old posts: every row carries the date of the account's newest tagged post, and the run page names an account whose tab is not live. Leave empty and the run returns built-in sample rows instead, so you can see the output shape at no result fee.

## `maxPostsPerAccount` (type: `integer`):

Hard cap on the tagged posts delivered for EACH account — 50 across 3 accounts delivers up to 150. The Tagged tab is read 21 posts a page, newest first. An account that runs short leaves an uncharged row saying so. At most 500 per account: ask for more and the run continues at 500, with one uncharged row saying so, rather than being refused.

## `postedAfter` (type: `string`):

Only posts published on or after this date: a date ("2026-10-01"), a date and time ("2026-10-01T08:30:00Z") or a rolling window counted back from the run's start ("7 days", "2 weeks", "24 hours"). The tab is read newest first, so the run stops reading once it reaches older posts. A value this actor cannot read is refused on an uncharged row, never ignored. Leave empty for no date limit.

## `newPostsOnly` (type: `boolean`):

ON (default): a post already delivered to you for the same account is skipped — no row, no charge — so a scheduled run returns only the posts that newly tag the account. When a repeat read finds nothing new at all, that account is charged one check ($0.005) for the read, once, and its row says so; a first read, an empty tab and a read this run's own limit cut short are never charged a check. OFF: posts you already have are handed back again, marked repeat: true, with no result fee, and no check is charged. Posts older than 90 days in your memory count as new again.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly before this many seconds and reports what is left, instead of being killed by a timeout. A time limit ends the collecting, never the delivering: posts already in hand are always written out, and posts the clock does not reach are not charged. Between 30 seconds and 1 hour: set it outside that and the run continues at the nearest one, with one uncharged row saying so.

## `resumeFromDatasetId` (type: `string`):

The dataset ID of a previous run of this actor. Posts already in it are treated as posts you already have and are skipped, so a follow-up run delivers only new ones, even from a different Apify account. Selecting it here is what grants this run permission to read it.

## Actor input object example

```json
{
  "usernames": [
    "glossier"
  ],
  "maxPostsPerAccount": 50,
  "newPostsOnly": true,
  "maxRunSeconds": 1800
}
```

# Actor output Schema

## `posts` (type: `string`):

One row per tagged post delivered: the account it tags, the post link and shortcode, caption, media type, posted date, like/comment/view counts, the author (handle, name, verified), the accounts tagged on it, place, co-authors and paid-partnership flag — plus the tagged account's own name, followers and the date of its newest tagged post, with `taggedTabStale: true` when that date is more than 90 days old. Every row carries `charged`, `chargedEvents` and `status`, so the invoice reconciles from the dataset itself: `post` ($0.002 on the Apify free plan, $0.0016 on Bronze, $0.0014 on Silver, $0.0012 from Gold) on every post delivered new, `profile-lookup` ($0.003) on the first charged post of each account in a run, and `check` ($0.005) only on the one row of an account that a repeat read found nothing new for. Posts you already have for the same account are skipped and never charged again — that check reads a key-value store in your own account, so a run on a scoped API token without key-value store permission says so on its status line and on an uncharged row; with "New tags only" off they come back marked `repeat: true`, uncharged.

## `misses` (type: `string`):

One row for every account that returned less than it was asked for, with `status` saying which: `nothing_found` (the tab has no more posts, your posted-after date was reached, the tab came back empty twice, or no account goes by that handle), `already_delivered` (the tab returned only posts you already have — the one row that may carry the $0.005 `check`, and it says so), `limit_reached` (this actor's own page limit for one account, or this run reached its limit), `your_limit_reached` (your own result limit, cost limit or run clock stopped it first), `plan_limit_reached` (the Apify free plan's daily allowance), `try_again` (the read failed and a re-run is the fix), `not_accepted` (an input value), `not_supported` (Instagram answered in a shape this actor does not read yet). Apart from a check named on its own row, none of these is charged.

## `summary` (type: `string`):

Tagged posts delivered, what was asked for, account lookups charged, posts your account already had, posts tagging more than one of your accounts, checks charged, the accounts whose Tagged tab is not live, what stopped the run, the charged-event totals, and — when this run's token could not open the repeat memory — `repeatCheck: "unavailable_scope"`.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "usernames": [
        "glossier"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/instagram-mentions-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "usernames": ["glossier"] }

# Run the Actor and wait for it to finish
run = client.actor("steadyfetch/instagram-mentions-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "usernames": [
    "glossier"
  ]
}' |
apify call steadyfetch/instagram-mentions-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyfetch/instagram-mentions-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MgMxxI3UEA6u5JctA/builds/VRKuDhk0HWPae0mAK/openapi.json
