# Instagram Hashtag Video Scraper & Filters — Beta (`zexorama/instagram-popular-video-selector-beta`) Actor

Instagram hashtag video/Reels scraper with chosen output fields and date, engagement and literal caption filters. Beta: one hashtag, up to 20 rows; popular-source availability varies. $0.01/start + $0.001/output row. No Instagram login.

- **URL**: https://apify.com/zexorama/instagram-popular-video-selector-beta.md
- **Developed by:** [Zeljko Vojnovic](https://apify.com/zexorama) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 valid output rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Hashtag Video Scraper & Filters — Beta

### Watch a short demo

[Watch the 36-second walkthrough](https://share.descript.com/view/YaTm5xqReph):
choose a ready-to-use input and inspect actual stored output from November 9, 2026.
The demo uses a saved successful run, not a fresh collection or a guarantee of
future availability. No Instagram credentials are required.

### Start with a ready-to-use example

- [Five coffee video links](https://apify.com/zexorama/instagram-popular-video-selector-beta/examples/get-coffee-video-links-from-instagram): up to 5 rows from 40 candidates; $0.015 when 5 rows are written.
- [Coffee videos with engagement thresholds](https://apify.com/zexorama/instagram-popular-video-selector-beta/examples/find-coffee-videos-with-100-likes-on-instagram): up to 20 rows, requiring source-reported likes/comments and selected data.
- [Lisbon caption and date filters](https://apify.com/zexorama/instagram-popular-video-selector-beta/examples/find-lisbon-video-references-with-caption-filters): a saved August-November 2026 example. Edit its date window for another period.

This is a paid beta: $0.01 per start + $0.001 per output row. Results may be
partial or unavailable; the start fee can apply to failed or zero-result runs.

Get up to **20 matching public Instagram videos/Reels from one hashtag**. Choose the fields you need, require specific data, and apply date, likes/comments or literal caption filters. The output report explains partial collection, missing data, shortfalls and confirmed delivery.

This is a limited beta. It searches an available **popular** window, not the latest feed or a complete Instagram inventory. It does not collect photos/carousels, profiles, followers or private posts, and it has no automatic alternative source. No Instagram password, cookies or Instagram user token is accepted.

### Example

Request up to five coffee videos from at most 40 candidates:

```json
{
  "queries": [{ "hashtag": "coffee", "limit": 5 }],
  "maxItems": 5,
  "candidatesPerHashtag": 40,
  "fields": ["id", "url", "caption", "contentType", "fieldStatus"],
  "requiredFields": ["id", "url"]
}
```

This is an input example, not a guarantee of five results. The Actor uses one collection mode; there is no provider or performance-profile selector.

Run options are separate from this JSON: use **256 MB memory**, a **240-second parent timeout** and a **finite maximum cost**. Set the recommended `maxTotalChargeUsd` to **$0.04**. The event price for at most 20 rows is still **$0.03**; the extra allowance provides headroom to finish delivery confirmation and the final report, and is not an additional charge. A cap set exactly to the expected event total can cause the platform to stop the run as soon as that limit is reached, before confirmation/reporting finishes. Do not select Unlimited: the PPE budget guard rejects an unknown/unbounded allowance (`DELIVERY_BUDGET_UNKNOWN`) before source acquisition. A smaller cap may permit fewer rows.

### Limits and defaults

- One hashtag per run. `queries[0].limit` and `maxItems` both default to **20**, with a maximum of **20**.
- `candidatesPerHashtag` defaults to **100**, with a maximum of **100**. Candidates can fail filters or lack required data; 100 candidates does not mean 100 matching results.
- `timeoutSecs` defaults to **120**, with an allowed range of 30–120 seconds for acquisition. `allowPartial` defaults to **true**.
- There are no default date bounds, likes/comments minimums or caption relevance rules. `metricScope` defaults to `source_reported`; `requiredFields` defaults to `id` and `url`.

The default projection includes ID, URL, content type, caption, publication date, likes, comments, plays, metric scope and matched/selected hashtags. **Plays are unavailable and remain null.** Choosing a smaller `fields` list can avoid unnecessary detail lookups. Add `fieldStatus` when you want explicit availability information.

### Fields and filtering

Available evidence may include `id`, `url`, `contentType`, `caption`, `publishedAt`, `ownerUsername`, `likesCount` and `commentsCount`. Source-reported counts are not independently verified Instagram-only metrics. Hidden or missing counts are not converted to zero. Plays and shares are unsupported.

`fields` controls the columns returned. `requiredFields` requires evidence even if a field is not projected; a record without that data is excluded. Other requested fields may remain `null`. Existing video/reel labels are preserved.

Optional `publishedAfter`/`publishedBefore`, `minLikes` and `minComments` narrow the result. Strict `instagram` scope cannot support active likes/comments thresholds or required likes/comments with this source. No unsupported metric is inferred.

`relevance.includeAny`, `excludeAny` and `localityAny` default to empty lists. They match literal whole words/phrases, without translation, stemming, regex or semantic analysis. Positive/locality terms are checked in caption text outside hashtags, mentions and URLs; exclusions inspect the full caption. Alternatives within an active list are OR conditions; active lists combine as AND conditions. A locality phrase is textual evidence, not verified geolocation.

### Availability and partial results

Some hashtags or details may be unavailable. Source-unavailable failures were observed for `skincare`, `food` and `уметност`; this does not prove those Instagram feeds are empty. Availability can change, including for tags that previously worked.

A run can return fewer records or fail with `OWN_SOURCE_UNAVAILABLE`. Filling the requested quota does not prove complete source coverage. There is no automatic paid fallback, retry-until-full behavior or promise of a filled quota. The dataset contains only selected output rows; `RUN_SUMMARY` separates selection, shortfall and physically confirmed delivery. An uncertain confirmation can occur after rows have already been stored.

### Beta pricing

The single beta tariff is **$0.01 per run start + $0.001 per physically written output row**. Run-platform usage is included in this tariff.

| Physically written rows | Beta run price |
| ---: | ---: |
| 0 | $0.010 |
| 5 | $0.015 |
| 20 | $0.030 |

The start event may apply to invalid, failed and zero-result runs. Optional null fields do not make an otherwise valid selected row free. Stored rows may be charged even if later confirmation fails. No automatic refund is promised. A spending cap can reduce the delivered prefix below the requested quantity. Pending/unknown billing is not a final invoice; subsequent platform storage/download interactions may have their own charges.

# Actor input Schema

## `queries` (type: `array`):

JSON array containing exactly one {hashtag, limit}. The per-hashtag output quota is 1–20 and defaults to 20 when omitted; enough qualifying source records are not guaranteed.

## `maxItems` (type: `integer`):

Maximum unique qualifying beta output records, from 1 to 20; defaults to 20. A smaller source sample or spending allowance can reduce delivery.

## `metricScope` (type: `string`):

Source-reported likes/comments may reflect a broader platform scope and are not verified Instagram-only counts. Strict Instagram leaves optional unsupported metrics null and rejects active likes/comments minima or required likes/comments. Plays/shares are unavailable in this product.

## `fields` (type: `array`):

Select output fields. Dates, owner and supported source-reported likes/comments are acquired when projected, required or needed by a filter. The existing default fields include dates, likes and comments. Unsupported optional plays/shares and strict-scope metrics remain null. Required fields still apply when omitted from this projection.

## `requiredFields` (type: `array`):

Fields that must be available for a record to qualify, independently of output projection. Dates and owner are supported in both scopes; likes/comments only in source_reported. Required plays/shares or strict Instagram likes/comments fail before acquisition.

## `publishedAfter` (type: `string`):

Absolute ISO timestamp with a timezone, inclusive. No relative dates.

## `publishedBefore` (type: `string`):

Absolute ISO timestamp with a timezone, exclusive. Must follow publishedAfter.

## `minLikes` (type: `integer`):

Optional source-reported minimum. Explicit zero requires a known value; missing or hidden likes do not pass. Unsupported in strict Instagram scope.

## `minComments` (type: `integer`):

Optional source-reported minimum. Explicit zero requires a known value; missing comments do not pass. Unsupported in strict Instagram scope.

## `candidatesPerHashtag` (type: `integer`):

Inspect at most this many popular-video candidates for the one hashtag, from 1 to 100. Separate from desired output quantity; candidates need not match all filters or provide every required field.

## `timeoutSecs` (type: `integer`):

Bounded source acquisition deadline, from 30 to 120 seconds. The parent run must leave at least another 30 seconds for processing and output confirmation.

## `allowPartial` (type: `boolean`):

Allow valid records from an incomplete source and retain an explicit partial report. Disable to reject incomplete acquisition. A filled output quota does not prove a complete source.

## `relevance` (type: `object`):

Literal consecutive caption words, normalized with trim, NFKC and lowercase; punctuation separates words, while diacritics and scripts remain distinct. includeAny and localityAny each require at least one phrase from the caption body after removing hashtags, mentions and URLs; excludeAny rejects matches anywhere in the full caption, including hashtags. Empty arrays impose no extra condition. At most20 unique phrases per array,1–80 characters each; no leading #/@, URLs, domains, paths, control characters or contradictory required/excluded phrases. This checks text evidence only: no language detection, geolocation, semantic or visual-relevance promise. Evidence is report-only; output fields are unchanged.

## Actor input object example

```json
{
  "queries": [
    {
      "hashtag": "coffee",
      "limit": 5
    }
  ],
  "maxItems": 5,
  "metricScope": "source_reported",
  "fields": [
    "id",
    "url",
    "caption",
    "contentType",
    "fieldStatus"
  ],
  "requiredFields": [
    "id",
    "url"
  ],
  "candidatesPerHashtag": 40,
  "timeoutSecs": 120,
  "allowPartial": true,
  "relevance": {
    "includeAny": [],
    "excludeAny": [],
    "localityAny": []
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `report` (type: `string`):

No description

# 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 = {
    "queries": [
        {
            "hashtag": "coffee",
            "limit": 5
        }
    ],
    "maxItems": 5,
    "fields": [
        "id",
        "url",
        "caption",
        "contentType",
        "fieldStatus"
    ],
    "candidatesPerHashtag": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("zexorama/instagram-popular-video-selector-beta").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 = {
    "queries": [{
            "hashtag": "coffee",
            "limit": 5,
        }],
    "maxItems": 5,
    "fields": [
        "id",
        "url",
        "caption",
        "contentType",
        "fieldStatus",
    ],
    "candidatesPerHashtag": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("zexorama/instagram-popular-video-selector-beta").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 '{
  "queries": [
    {
      "hashtag": "coffee",
      "limit": 5
    }
  ],
  "maxItems": 5,
  "fields": [
    "id",
    "url",
    "caption",
    "contentType",
    "fieldStatus"
  ],
  "candidatesPerHashtag": 40
}' |
apify call zexorama/instagram-popular-video-selector-beta --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zexorama/instagram-popular-video-selector-beta"
        }
    }
}
```

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/CYw04LdF5IFsUXBuT/builds/kFDL4xaHJjGzT6gqj/openapi.json
