# Redgifs Video Scraper (`datawatcher/redgifs-scraper`) Actor

Scrapes public video data from redgifs.com searches, niches, profiles and video pages: creator, tags, views, likes, date, duration, size, audio flag, poster and thumbnail and the direct .mp4 video file URLs. Or just the video page and file URLs.

- **URL**: https://apify.com/datawatcher/redgifs-scraper.md
- **Developed by:** [DataWatcher](https://apify.com/datawatcher) (community)
- **Categories:** Videos
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 video results

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

## RedGIFs Video Scraper

Scrape **RedGIFs videos** from redgifs.com by keyword search, niche, account or post URL, and get clean data as JSON, CSV or Excel, or through the **API**. **Every video row has the direct link to the video file (`.mp4`)**: open it to play the video, or save it to download it. You also get the creator, the creator's **OnlyFans link**, tags, views, likes, date, duration, size, audio flag, poster and thumbnail. No login, no browser.

- Direct video links: `videoFileUrl` (full quality) and `previewVideoUrl` (smaller copy).
- Image posts are kept as rows with `mediaType` `image` and the full-size picture in `imageUrl`.
- Searches, niches and accounts are read page by page until your `maxResults` or another cap in the input is reached.

The actor reads public data and returns the links to the files.

Want the files saved, named creatorname_video-id.mp4? Use [RedGIFs Video Downloader](https://apify.com/datawatcher/redgifs-video-downloader) (it charges per saved file).

### ⭐ Why this one

> **1️⃣ One schema across video sites.**
> All our video actors share one output schema and one input schema. Build your pipeline once: our other video actors ([Erome Video Scraper](https://apify.com/datawatcher/erome-scraper), [XFree Video Scraper](https://apify.com/datawatcher/xfree-scraper), [Erome Video Downloader](https://apify.com/datawatcher/erome-video-downloader), [RedGIFs Video Downloader](https://apify.com/datawatcher/redgifs-video-downloader), [XFree Video Downloader](https://apify.com/datawatcher/xfree-video-downloader)) take the same input and return the same fields, so adding a site means changing the actor name, not your code.

- **Low price, no start fee.** $1.00 per 1,000 videos; the median RedGIFs scraper charges $9.50, and 3 of 5 add a start fee. You pay only for rows you get.
- **Every input a RedGIFs buyer needs.** Keyword searches, niches, accounts and post URLs, alone or mixed in one run, with one row per post.
- **A direct video link on every row.** `videoFileUrl` (full quality) and `previewVideoUrl` come with the data, so you can play or download the file at no extra request.
- **Links-only mode.** Turn on `onlyVideoUrls` for rows with just the post page and the two links: the fastest run, at the same price per post.
- **Honest runs.** A run summary with a list of failed inputs, and a health status (`ok`, `degraded` or `failed`) with the reason.
- **Creator data included.** Username, display name, profile link and OnlyFans link on every row, plus account data once per account.

### 🔎 What it extracts

One row per unique post. The page types it reads:

| Page type | Example URL | Input to use |
|---|---|---|
| Search | `https://www.redgifs.com/search/gifs?query=amateur&order=score` | `searchQueries` or `startUrls` |
| Account | `https://www.redgifs.com/users/creatorname` | `usernames` or `startUrls` |
| Niche | `https://www.redgifs.com/niches/just-boobs` | `tags` or `startUrls` |
| Post page | `https://www.redgifs.com/watch/examplepostid` | `videoUrls` or `startUrls` |

- Niche names are the slug of the niche URL (`just-boobs`).
- Search filter: `all` (default) or `post`. A search returns at most 10,000 results (a limit of the site).
- An `order` in a search, account or niche URL is used as given when the site accepts it.
- Account data (followers, total posts, bio and more) is saved once per account in the run stats (`accountProfiles`).

### 🚀 How to scrape RedGIFs videos

1. Open the actor on Apify and click **Try for free**.
2. Fill in a search, niches or accounts, or paste redgifs.com URLs into `startUrls` or `videoUrls`.
3. Click **Start**.
4. Download the **RedGIFs video data** as JSON, CSV or Excel from the Output tab, or fetch it with the Apify API.

Example inputs:

```json
{ "searchQueries": [{ "query": "amateur", "filter": "all" }], "maxResults": 50 }
```

```json
{ "tags": ["just-boobs"], "tagSort": "latest", "maxResults": 100 }
```

### 🤖 Use with AI agents (MCP)

AI assistants (Claude, ChatGPT, Cursor…) can run this actor through Apify's MCP server. Connect the server in your assistant, then ask, for example:

```text
Use the RedGIFs Video Scraper to get the 20 newest videos of the niche just-boobs with their direct .mp4 links.
```

### 🔌 Run it your way

- **Schedule it** with Apify schedules.
- **Call it from the Apify API** and its clients (Python, JavaScript).
- **Connect it** to Make, n8n, Zapier, webhooks or Google Sheets.
- **Ask an AI agent to run it**: see [Use with AI agents (MCP)](#-use-with-ai-agents-mcp).

### 🔀 Mixing inputs and duplicates

You can use all five source inputs in one run: `startUrls`, `searchQueries`, `usernames`, `tags`, `videoUrls`.

| Rule | What happens |
|---|---|
| One row per post | Matched by `id` over the whole run: a post found by a search and by its account is written once. |
| First input kept | `sourceType` and `sourceUrl` keep the first input that found it. |
| Same input twice | Read once. |
| `maxResults` | One cap for the run, split fairly over the inputs still to read. |
| Input check | Every input is checked: valid ones run, others get a clear message. |

### 🎬 Direct video links

> **`videoFileUrl` is the direct link to the video file**, e.g. `https://media.redgifs.com/ExamplePostId.mp4`.
> Open it in a browser to play the video, or save it to download it.
>
> **`previewVideoUrl` is the smaller copy**, e.g. `https://media.redgifs.com/ExamplePostId-mobile.mp4`.

- The links come with every row at no extra request.
- `url` is the post's page on redgifs.com, not the file.
- Image posts have no video link: their `videoFileUrl`, `previewVideoUrl` and `durationSeconds` are `null` and `imageUrl` holds the picture.

### ⚡ Links-only mode (`onlyVideoUrls`)

With `onlyVideoUrls` set to `true`, each row has only the post page and the two direct video links. It is the fastest run. The price per post is the same as for a full row. Image posts have no video links: their links-only row has empty video links and an extra `imageUrl`.

### ⚙️ Input

| Input | Type | Default | Range | Meaning |
|---|---|---|---|---|
| `startUrls` | list of URLs | none | redgifs.com URLs | Search, account, niche or post URLs. The kind is found from the URL. |
| `searchQueries` | list | none | – | Items `{"query": "...", "filter": "all" \| "post"}`. A plain text line means `{"query": text, "filter": "all"}`. |
| `usernames` | list of text | none | – | Account names, with or without `@`, or account URLs. Every post of each account. |
| `tags` | list of text | none | – | Niche slugs (e.g. `just-boobs`), or niche page URLs. |
| `tagSort` | text | empty (default order) | `latest` or `popular` | Order of searches, accounts and niches. |
| `videoUrls` | list of URLs | none | – | Post page URLs. One row per post. |
| `onlyVideoUrls` | yes/no | `false` | – | Rows are only `url`, `videoFileUrl`, `previewVideoUrl`. |
| `maxResults` | integer | `100` | 1 to 1,000 | Maximum posts returned over all inputs. |
| `maxRequests` | integer | `200` | 1 to 1,000 | Maximum requests of the run (list pages and posts). |
| `maxPagesPerSource` | integer | `100` | 1 to 100 | Maximum list pages for one search, account or niche (100 posts per page). |
| `maxScrollsPerPage` | integer | `100` | 1 to 100 | Not used on this site (pages are numbered). |
| `maxRequestRetries` | integer | `2` | 0 to 5 | Retries after a network error or a server error. |
| `requestTimeoutSecs` | integer | `30` | 5 to 120 | Time limit of one request, in seconds. |

Use at least one of `startUrls`, `searchQueries`, `usernames`, `tags` or `videoUrls`. When a cap ends the run, `stopReason` says which (see Run stats).

### 📦 Output: RedGIFs video data

Every full row has all of these fields. A missing text, number or object is `null`. A missing list is `[]`.

| Field | Type | Meaning |
|---|---|---|
| `recordType`, `schemaVersion`, `source` | text | Always `video`; the output schema version; the site (`redgifs`). |
| `id` | text | The site's id of the post. |
| `url` | text | The post's page on redgifs.com (not the file). |
| `mediaType` | text | `video` or `image`. |
| `imageUrl` | text or null | Direct link to the full-size image when `mediaType` is `image`; empty for videos. |
| `sourceType` | text | `search`, `profile`, `tag` or `direct_video`. |
| `sourceUrl` | text | The input that first found the post. |
| `title` | text or null | Always `null`: the site gives no title. |
| `creator` | object or null | `username`, `displayName`, `profileUrl`, `onlyfansUrl` of the account that posted it. |
| `taggedAccounts` | list | Always `[]`: the site has no tagged accounts. |
| `views` | integer or null | Views as a number at run time. |
| `likes` | integer or null | Likes. |
| `durationSeconds` | number or null | Length in seconds; `null` for images. |
| `width`, `height` | integer or null | Size in pixels. |
| `hasAudio` | yes/no or null | Whether the video has sound; `null` for images. |
| `thumbnailUrl` | text or null | Small preview image URL. |
| `posterUrl` | text or null | Larger preview image URL. |
| `tags` | list | Tags in the site's order, no repeats. |
| `videoFileUrl` | text or null | **Direct link to the video file** (`.mp4`, full quality). `null` for images. |
| `previewVideoUrl` | text or null | Direct link to the smaller `.mp4` copy. `null` for images. |
| `dates` | object | `posted` (when the post was published) and `scraped` (when the row was made), ISO 8601 UTC. |

#### Example: a full row

```json
{
  "recordType": "video",
  "schemaVersion": "4.4.0",
  "source": "redgifs",
  "id": "examplepostid",
  "url": "https://www.redgifs.com/watch/examplepostid",
  "mediaType": "video",
  "sourceType": "search",
  "sourceUrl": "https://www.redgifs.com/search/gifs?query=amateur",
  "title": null,
  "creator": { "username": "creatorname", "displayName": "Example Creator", "profileUrl": "https://www.redgifs.com/users/creatorname", "onlyfansUrl": "https://onlyfans.com/creatorname" },
  "taggedAccounts": [],
  "views": 12345,
  "likes": 123,
  "durationSeconds": 22.8,
  "width": 1080,
  "height": 1920,
  "hasAudio": true,
  "thumbnailUrl": "https://media.redgifs.com/ExamplePostId-mobile.jpg",
  "posterUrl": "https://media.redgifs.com/ExamplePostId-poster.jpg",
  "tags": ["Amateur", "Solo"],
  "videoFileUrl": "https://media.redgifs.com/ExamplePostId.mp4",
  "previewVideoUrl": "https://media.redgifs.com/ExamplePostId-mobile.mp4",
  "imageUrl": null,
  "dates": { "posted": "2025-01-01T12:00:00Z", "scraped": "2025-01-02T12:00:00Z" }
}
```

#### Example: a links-only row

```json
{
  "url": "https://www.redgifs.com/watch/examplepostid",
  "videoFileUrl": "https://media.redgifs.com/ExamplePostId.mp4",
  "previewVideoUrl": "https://media.redgifs.com/ExamplePostId-mobile.mp4"
}
```

### 📊 Run stats

Each run saves two records in the key-value store. `OUTPUT`:

| Key | Meaning |
|---|---|
| `status` | `success`, `partial` (some inputs failed, rows kept) or `failed`. |
| `sourcesProcessed` | Inputs read. |
| `listingPagesVisited` | List pages read. |
| `videoCardsFound` | Posts seen, before dedupe. |
| `uniqueVideosEmitted` | Rows written. |
| `duplicatesSkipped` | Posts already written. |
| `mediaUrlsFound`, `mediaUrlsMissing` | Rows with / without a `videoFileUrl` (images count as missing). |
| `requestsUsed` | Requests made. |
| `stoppedEarly` | `true` when a cap ended the run. |
| `stopReason` | The cap: `maxResults`, `maxRequests`, `maxPagesPerSource` or `chargeLimit`; else `null`. |
| `sourceErrors` | List of inputs that failed, with the message. |
| `sources` | One entry per input: type, URL, status, pages, videos. |
| `accountProfiles` | The account data, once per account read. |
| `chargedEvents` | How many times each billing event was charged. |

`RUN_HEALTH`: `{"status": "ok" | "degraded" | "failed", "reason": ...}`. `reason` says why a run is not `ok`.

### 💰 Pricing

Pay per event. There is no start fee. Free plan: each run returns up to 1,000 videos; upgrade your Apify plan for more.

| Event | Price | When it is charged |
|---|---|---|
| `video-scraped` | $0.0010 ($1.00 per 1,000) | Each unique post row written, with its direct links. Links-only rows too. |

- 1,000 videos, each with its direct `.mp4` link: $1.00.
- Duplicate posts are free. The links are included in the price.

### 🎯 Use cases

- Build a list of direct `.mp4` links for a niche, keyword or creator and hand it to your own player or downloader.
- Track a creator's new posts on a schedule, with views and likes.
- Find creators and their OnlyFans links in a niche.
- Research which tags and niches get the most views and likes.
- Run the same pipeline over several video sites, since they share one schema.

### ❓ FAQ

#### How do I export RedGIFs videos to Excel or CSV?

Run the actor, open the Output tab and pick Excel or CSV in the export options. JSON, XML and HTML are there too, and the Apify API returns the same data.

#### How do I get direct .mp4 links in my RedGIFs video data?

Every video row has `videoFileUrl` (full quality) and `previewVideoUrl`. Turn on `onlyVideoUrls` for rows with only the links, the fastest run.

#### Can I get RedGIFs data through an API?

Yes. Call the actor from the Apify API or its clients (Python, JavaScript), then read the rows from the run's dataset.

#### How much does it cost?

$1.00 per 1,000 videos with their direct links, no start fee. Duplicate posts are free.

#### Can I combine it with other video sites?

Yes. All our video actors share one output schema and one input schema, so rows from different sites fit one table. See the list below.

### Data notice

This actor returns only what the site shows publicly at run time. We don't store or keep that data and are not its controller — you decide how you use it.

### 🔗 Other video scrapers (same schema)

#### RedGIFs (this site)

- [RedGIFs Video Downloader](https://apify.com/datawatcher/redgifs-video-downloader): saves the video files (.mp4)

#### Erome

- [Erome Video Scraper](https://apify.com/datawatcher/erome-scraper): links and data
- [Erome Video Downloader](https://apify.com/datawatcher/erome-video-downloader): saves the video files (.mp4)

#### XFree

- [XFree Video Scraper](https://apify.com/datawatcher/xfree-scraper): links and data
- [XFree Video Downloader](https://apify.com/datawatcher/xfree-video-downloader): saves the video files (.mp4)

### 💬 Feedback and custom work

Need another portal, a field or a custom feed? Open an issue on the Issues tab.

# Changelog

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

# Actor input Schema

## `startUrls` (type: `array`):

Site URLs of any supported kind: search, account profile, tag or video page. The kind is found from the URL.

## `searchQueries` (type: `array`):

Searches, each {"query": "...", "filter": "all" | "post" | "tag"} (filter optional, default "all"). A plain text line is read as {"query": text, "filter": "all"}.

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

Account handles, with or without "@", or profile URLs. Every video of each account.

## `tags` (type: `array`):

Tag names exactly as the site writes them (case and prefixes kept, e.g. pl-Amatorzy), or tag page URLs.

## `tagSort` (type: `string`):

The order of tag pages. Empty - the site's default order.

## `videoUrls` (type: `array`):

Video page URLs. Each is read directly; one row per video.

## `onlyVideoUrls` (type: `boolean`):

Each row is only the three video links {"url", "videoFileUrl", "previewVideoUrl"}: the video page and its direct .mp4 files. Same price per video.

## `maxResults` (type: `integer`):

Maximum number of videos returned, in total. Shared fairly over the inputs (each search, profile, tag or video URL gets its part; what one cannot fill goes to the others). Free plan Apify users get at most 1000 videos per run, whatever is set here (paying users have no cap).

## `maxRequests` (type: `integer`):

Maximum number of page requests the run makes, in total (listing pages and load-more steps; a direct video URL is one request).

## `maxPagesPerSource` (type: `integer`):

Maximum number of listing pages read for one search, profile or tag.

## `maxScrollsPerPage` (type: `integer`):

Maximum number of "Show more" / load-more steps on one listing page.

## `maxRequestRetries` (type: `integer`):

Retries of a request that failed on a network error or a server error. A block (403, 429, a challenge page) is never retried.

## `requestTimeoutSecs` (type: `integer`):

Time limit of one page request.

## Actor input object example

```json
{
  "onlyVideoUrls": false,
  "maxResults": 100,
  "maxRequests": 200,
  "maxPagesPerSource": 100,
  "maxScrollsPerPage": 100,
  "maxRequestRetries": 2,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

## `results` (type: `string`):

One row per item.

## `runSummary` (type: `string`):

OUTPUT: status, sources, requests used, early stop and its reason, source errors, charged events.

## `runHealth` (type: `string`):

{status, reason}: ok, degraded, or failed.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("datawatcher/redgifs-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("datawatcher/redgifs-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 '{}' |
apify call datawatcher/redgifs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datawatcher/redgifs-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/aWcPOZa597tMsSSvA/builds/4PmLuBvQDmdNirZyk/openapi.json
