# FilmFreeway Festival Scraper (`hypebridge/filmfreeway-festival-scraper`) Actor

FilmFreeway Festival Scraper extracts public film-festival listings, submission deadlines, category-specific entry fees, event dates, venues, ratings, and qualification badges from FilmFreeway.

- **URL**: https://apify.com/hypebridge/filmfreeway-festival-scraper.md
- **Developed by:** [Hypebridge](https://apify.com/hypebridge) (community)
- **Categories:** Automation, Agents, Developer tools
- **Stats:** 2 total users, 1 monthly users, 90.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 festival details

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does FilmFreeway Festival Scraper do?

**FilmFreeway Festival Scraper** extracts public film-festival listings, submission deadlines, category-specific entry fees, event dates, venues, ratings, and qualification badges from [FilmFreeway](https://filmfreeway.com). It turns nested deadline and fee schedules into structured JSON that can be downloaded as JSON, CSV, Excel, or HTML.

### Why scrape FilmFreeway festivals?

- **Submission planning**: find festivals closing inside a specific date window.
- **Fee comparison**: compare current standard and Gold fees across categories and deadline tiers.
- **Festival research**: build datasets of locations, years running, ratings, reviews, and qualifying badges.
- **Market analysis**: track how submission pricing and calendars differ by genre or project type.

### What data can it extract?

| Field | Description |
| --- | --- |
| `name`, `url`, `festivalId` | Festival identity and canonical profile |
| `location`, `city`, `state`, `country` | Location from the directory listing |
| `entriesOpen` | Whether structured deadline and fee data is available |
| `deadlines` | Every dated row with label and FilmFreeway's current/upcoming/outdated state |
| `categories` | Submission categories with nested deadline tiers and fees |
| `feesFlat` | Analysis-ready category × tier × fee rows |
| `currentDeadlineDate`, `finalDeadlineDate` | Derived submission deadline dates |
| `minCurrentFee`, `maxCurrentFee` | Comparable current non-Gold fee range |
| `eventDateIso`, `eventDateText` | Event start date and displayed range |
| `rating`, `reviewCount`, `badges` | Reputation and qualification metadata |

### How to scrape FilmFreeway

1. Open the Actor and add FilmFreeway directory, curated-collection, or festival profile URLs.
2. Set **Maximum festivals** to cap output and cost.
3. Turn on **Get deadlines and entry fees** for full profile enrichment. Direct festival profile URLs are always enriched.
4. Run the Actor and download the Dataset.

#### Search for open festivals

```json
{
  "startUrls": [],
  "openSubmissionsOnly": true,
  "deadlineBefore": "2026-12-31",
  "projectCategories": ["5", "9"],
  "getFestivalDetails": true,
  "maxFestivals": 100
}
```

#### Scrape individual festival profiles

```json
{
  "startUrls": [
    { "url": "https://filmfreeway.com/BeverlyHillsFilmFestival" }
  ],
  "maxFestivals": 10
}
```

#### Use a curated collection

```json
{
  "curatedCollection": "academy-award-qualifying-festivals",
  "getFestivalDetails": true,
  "maxFestivals": 50
}
```

### Input notes

Leaving `startUrls` empty builds a FilmFreeway directory search from the filter fields. Country filtering is applied to directory-card location text because FilmFreeway's own country parameter does not reliably filter results. A direct profile URL cannot supply the directory-only `location`, `city`, `state`, or `country` fields.

FilmFreeway challenges ordinary server HTTP fingerprints even on residential IPs. The Actor therefore uses a pinned Python Impit Chrome transport with up to three prevalidated sticky residential sessions. A session keeps one IP, cookie jar, and client fingerprint together; challenged identities are retired as a unit instead of sleeping and retrying through random IPs. The Actor caps listing pagination at FilmFreeway's page 253 ceiling, text and nested arrays are bounded, sitemap enumeration never exceeds `maxFestivals`, and debug mode stores at most 20 failed-page artifact pairs.

Warmup tries at most three identities before work begins. Runtime replacement is capped at two more identities. Each identity is capped at 20 pages or 10 minutes. The circuit breaker stops the run when more than 20% of the last ten requests are challenged across at least three distinct URLs, so one unusually protected profile cannot falsely classify the entire site as unavailable.

### Output example

```json
{
  "url": "https://filmfreeway.com/ExampleFestival",
  "slug": "ExampleFestival",
  "name": "Example International Film Festival",
  "entriesOpen": true,
  "location": "Austin, Texas, United States",
  "currentDeadlineLabel": "Regular Deadline",
  "currentDeadlineDate": "2026-09-01",
  "finalDeadlineDate": "2026-11-01",
  "minCurrentFee": 35,
  "maxCurrentFee": 70,
  "currentFeeCurrency": "$",
  "categoryCount": 9,
  "deadlineCount": 4
}
```

### How much does it cost?

The Actor uses pay-per-event pricing. Basic directory records and entries-closed profiles use the `festival-listing-scraped` event. Profiles containing structured deadline data use `festival-detail-scraped`. The Apify Console shows the current event prices before each run; `maxFestivals` is the hard spend-control lever.

### Limitations

- Deadline and fee blocks exist only while a festival accepts submissions. Entries-closed profiles are returned without those arrays.
- `$` is mapped to USD only as a best-effort convenience because the symbol can also mean CAD, AUD, or NZD. Use the literal `currency` and `raw` fee fields for trusted comparison.
- FilmFreeway's organizer websites, emails, and social links are login-gated and are not included.
- The site declares a 20-second crawl delay. The Actor enforces that interval independently on each sticky identity. At the default three sessions, budget roughly `60 + ceil(total HTTP requests / 3) × 20` seconds and raise the Apify run timeout for very large crawls.
- The Actor emits only fully parsed listing or detail records. In a directory or curated search, a profile that remains inaccessible after bounded attempts emits no record and is replaced from a bounded backlog of later listing cards. Direct profile failures and systemic session-pool failures still fail the run loudly. The Actor never writes placeholder or fallback records.

### FAQ

#### Why are location fields empty for a direct festival URL?

Festival location is present on FilmFreeway directory cards, not the public profile. Use a directory or curated-collection start URL when location is required.

#### Why can an entries-closed item have no deadlines or fees?

FilmFreeway removes both structured blocks when submissions close. The Actor positively detects the site's **Entries Closed** marker and returns the remaining festival metadata.

#### Is scraping FilmFreeway legal?

This Actor extracts publicly available data. Check FilmFreeway's terms and applicable laws, and use the data only for a legitimate purpose.

### Support

Use the Actor's **Issues** tab for bugs and feature requests, or the **API** tab for programmatic runs.

> This Actor does not intentionally extract private data. Public pages may still contain personal information such as organizer phone numbers or mailing addresses. Ensure you have a lawful basis before collecting or processing personal data.

# Actor input Schema

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

FilmFreeway directory, curated collection, or festival profile URLs. Direct profile URLs always receive full detail extraction.

## `maxFestivals` (type: `integer`):

Hard cap on returned festivals.

## `getFestivalDetails` (type: `boolean`):

Visit each profile for full dates, categories, and fee tiers. Direct profile URLs ignore this toggle.

## `openSubmissionsOnly` (type: `boolean`):

Restrict generated searches to festivals currently accepting entries.

## `searchQuery` (type: `string`):

Free-text festival search.

## `deadlineBefore` (type: `string`):

Return festivals with an entry deadline before this date.

## `deadlineAfter` (type: `string`):

Return festivals with an entry deadline after this date.

## `eventDateBefore` (type: `string`):

Return festivals taking place before this date.

## `eventDateAfter` (type: `string`):

Return festivals taking place after this date.

## `projectCategories` (type: `array`):

Project types accepted by the festival.

## `niches` (type: `array`):

Festival genre filters.

## `maxEntryFee` (type: `integer`):

Approximate FilmFreeway server-side fee filter.

## `academyAwardQualifyingOnly` (type: `boolean`):

Only Academy Award qualifying festivals.

## `goldDiscountOnly` (type: `boolean`):

Only festivals with Gold discounts.

## `countries` (type: `array`):

Country names matched against listing locations.

## `sortBy` (type: `string`):

FilmFreeway directory sort order.

## `curatedCollection` (type: `string`):

Use one verified FilmFreeway curated collection when Start URLs is empty.

## `enumerateFromSitemap` (type: `boolean`):

Enumerate the corpus directly, still capped by Maximum festivals.

## `maxConcurrency` (type: `integer`):

One worker is bound to each validated residential identity. Capped at three to bound memory, proxy churn, and request rate.

## `proxyConfiguration` (type: `object`):

Untargeted Apify Residential proxy is the tested default. Each validated session retains one IP, cookie jar, and Chrome wire fingerprint.

## `debugMode` (type: `boolean`):

Save at most 20 failing HTML and metadata artifacts.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://filmfreeway.com/festivals?call_for_entries=1&sort=all_deadlines"
    }
  ],
  "maxFestivals": 100,
  "getFestivalDetails": false,
  "openSubmissionsOnly": true,
  "searchQuery": "horror",
  "projectCategories": [],
  "niches": [],
  "academyAwardQualifyingOnly": false,
  "goldDiscountOnly": false,
  "countries": [],
  "sortBy": "all_deadlines",
  "enumerateFromSitemap": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "debugMode": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Every field for every festival.

## `overview` (type: `string`):

Compact festival metadata view.

## `deadlinesAndFees` (type: `string`):

Deadline and entry-fee comparison view.

## `files` (type: `string`):

Bounded failure artifacts when debug mode is enabled.

# 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 = {
    "startUrls": [
        {
            "url": "https://filmfreeway.com/festivals?call_for_entries=1&sort=all_deadlines"
        }
    ],
    "maxFestivals": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("hypebridge/filmfreeway-festival-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 = {
    "startUrls": [{ "url": "https://filmfreeway.com/festivals?call_for_entries=1&sort=all_deadlines" }],
    "maxFestivals": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("hypebridge/filmfreeway-festival-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 '{
  "startUrls": [
    {
      "url": "https://filmfreeway.com/festivals?call_for_entries=1&sort=all_deadlines"
    }
  ],
  "maxFestivals": 100
}' |
apify call hypebridge/filmfreeway-festival-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hypebridge/filmfreeway-festival-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/Frgkvw77h8aJOCL2D/builds/aTatfqL7OKieF0l5e/openapi.json
