# Firefox Add-ons Scraper (`axiomworks/firefox-addons-scraper`) Actor

Scrape Firefox extensions from Mozilla's public API by search term, category, or add-on URL. Get names, authors, user counts, ratings, versions, permissions, categories, and download URLs. The Actor deduplicates results across targets and requires no login.

- **URL**: https://apify.com/axiomworks/firefox-addons-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.19 / 1,000 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

**Returns:** one row per Firefox extension with `name`, `slug`, `authors`, `users`, `ratingAverage`, `version`, and `downloadUrl`.
**Input:** `{"searchQueries":["ad blocker"],"maxItems":20}`
**Best for:** extension research, catalog monitoring, and comparing add-on adoption.

```json
{"id":"607454","name":"uBlock Origin","slug":"ublock-origin","authors":["Raymond Hill"],"users":11432495,"ratingAverage":4.8017,"version":"1.75.0"}
```

### What does Firefox Add-ons Scraper do?

Firefox Add-ons Scraper extracts public extension records from the Mozilla Add-ons API. Search by words, browse a category, or provide an add-on page URL, slug, numeric ID, or GUID. Each result is a structured row with a stable add-on ID and the API endpoint used as its source URL. The Actor needs no login. By default it reads the Firefox extension catalog; set `addonType` to collect themes, dictionaries, or language packs instead. It does not collect add-ons for a different browser.

This Firefox scraper is useful when you need to compare extensions in a topic, track the visible catalog over time, or create an internal reference list. The Firefox Add-ons API provides the fields directly, including usage, downloads, ratings, current version, permissions, categories, and file metadata. The Actor preserves missing values as null when the API does not publish them. It does not fabricate a value to fill a spreadsheet cell.

Searches can overlap. A single extension may match several terms or categories, but its Mozilla ID appears only once in a run. You can combine all three target inputs, and the Actor processes them until it reaches `maxItems` or exhausts the targets. Results are collected at run time; schedule repeated runs if you need a history of changes.

### What data can you get?

The dataset includes the following fields. Numeric values and metadata reflect Mozilla's API response when the Actor ran. Localized text uses English when available, then another available locale. Descriptions and release notes decode HTML entities and preserve line breaks between paragraphs and list entries. Arrays can be empty when the API reports no values. A URL in a field is data from the API; the Actor does not visit outside sites linked by an extension.

| Field | Description | Example |
|---|---|---|
| `id` | Stable Mozilla add-on ID, stored as text | `607454` |
| `sourceUrl` | API endpoint that supplied this record | `https://addons.mozilla.org/api/v5/addons/addon/ublock-origin/?lang=en-US` |
| `name` | Localized extension name | `uBlock Origin` |
| `slug` | Slug used in the add-on URL | `ublock-origin` |
| `guid` | Extension identifier in the API | `uBlock0@raymondhill.net` |
| `summary` | Short extension summary | `Finally, an efficient wide-spectrum content blocker.` |
| `authors` | Listed author names | `["Raymond Hill"]` |
| `authorUrls` | Listed Mozilla author profile URLs | `[...]` |
| `users` | Average daily users reported by Mozilla | `11432495` |
| `weeklyDownloads` | Weekly downloads reported by Mozilla | `242563` |
| `ratingAverage` | Average user rating | `4.8017` |
| `ratingCount` | Number of ratings | `22174` |
| `version` | Current version label | `1.75.0` |
| `permissions` | Permissions listed for the current file | `["storage","tabs"]` |
| `categories` | Directory category slugs | `["privacy-security"]` |
| `tags` | Directory search tags | `["privacy"]` |
| `created` | Add-on creation time | `2015-04-25T07:26:22Z` |
| `lastUpdated` | Last update time shown by the API | `2026-09-26T16:26:20Z` |
| `license` | Current version's license name | `GNU General Public License v3.0 only` |
| `homepage` | Author-supplied homepage URL | `https://github.com/gorhill/uBlock#ublock-origin` |
| `iconUrl` | Icon URL listed by Mozilla | `https://addons.mozilla.org/user-media/addon_icons/607/607454-64.png?modified=mcrushed` |
| `promoted` | Promotion category (`recommended`, `spotlight`, ...), or `none` when not promoted | `recommended` |
| `fileSize` | Current downloadable file size in bytes | `4650100` |
| `addonType` | Add-on type reported by Mozilla | `extension` |
| `addonUrl` | Public add-on page | `https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/` |
| `description` | Full description, HTML tags removed and entities decoded | `uBlock Origin is not an "ad blocker"...` |
| `supportUrl` | Developer support site | `https://old.reddit.com/r/uBlockOrigin/` |
| `supportEmail` | Developer support email, null when not public | `null` |
| `requiresPayment` | Whether payment is required | `false` |
| `hasPrivacyPolicy` | Whether a privacy policy exists | `true` |
| `isExperimental` | Experimental flag | `false` |
| `ratingBayesianAverage` | Bayesian average rating | `4.8014` |
| `textReviewCount` | Ratings that include review text | `5867` |
| `releaseNotes` | Current version release notes as plain text, null when none | `null` |
| `minFirefoxVersion` / `minAndroidVersion` | Minimum supported versions | `115.0` |
| `optionalPermissions` / `hostPermissions` / `dataCollectionPermissions` | Further permission lists of the current file | `["<all_urls>"]` |
| `screenshotUrls` | Full-size screenshot URLs | `["https://addons.mozilla.org/user-media/previews/full/238/238546.png"]` |
| `downloadUrl` | Current XPI file URL | `https://addons.mozilla.org/firefox/downloads/file/5034826/ublock_origin-1.75.0.xpi` |

A field such as `ratingAverage` is a point-in-time measurement, not a prediction. `users` is the API's average daily users value, while `weeklyDownloads` is its separate weekly download count. Those quantities should not be added together. A `promoted` value of `none` means the API lists no promotion for that item. The record still remains useful through its other fields.

### How to use

Open the Actor in Apify Console. Enter at least one search query, category slug, or add-on URL/slug in the Input form. A search such as `ad blocker` returns matching extensions. A category such as `privacy-security` browses that section of the directory. A direct slug such as `ublock-origin` retrieves a particular add-on. Set the sort order and maximum result count, then start the run. Open the Dataset tab when it finishes to review or export the records as JSON, CSV, Excel, or another available dataset format.

Start with a modest `maxItems` while checking whether a term gives the right results. Increase it for a broader collection. The Actor stops as soon as the limit is reached, even when a search has another page. A repeated add-on ID from another query does not use a result slot. For a focused comparison, direct add-on URLs usually make the input easier to audit than a broad search term.

Search and category results use the API's paginated search endpoint. The Actor follows pages until no next page is provided or it has enough unique items. It spaces requests at about two per second and retries temporary blocks with backoff. Proxy use is optional; the default is no proxy. If a run is persistently blocked, enable Apify Proxy in the input and try again. A nonexistent add-on or an unmatched search produces no placeholder row.

### Input

Provide at least one of the three target fields. All other fields are optional. A direct URL must be an HTTPS Firefox add-on page on `addons.mozilla.org`; a slug, numeric ID, or GUID can be supplied without the URL. Search queries and category slugs can be combined, and duplicates in each list are removed before requests begin.

| Field | Type | Required | How it works |
|---|---|---|---|
| `searchQueries` | string array | One target field | Terms searched in the Firefox extension catalog; prefilled with `ad blocker` in Console. |
| `categories` | string array | One target field | Mozilla Add-ons category slugs to browse; default empty. |
| `addonUrls` | string array | One target field | Add-on page URLs (any sub-page), slugs, numeric IDs, or GUIDs for direct lookups; default empty. |
| `addonType` | enum | No | `extension`, `statictheme`, `dictionary`, `language`, or `any` (searches only; categories always use extension for `any`); default `extension`. |
| `sort` | enum | No | `users`, `rating`, `updated`, `created`, or `hotness`; default `users`. |
| `maxItems` | integer | No | Number of unique records to return, from 1 to 10000; default 50. |
| `proxyConfiguration` | object | No | Apify Proxy settings; default uses no proxy. |

```json
{
  "searchQueries": ["ad blocker", "privacy tools"],
  "categories": ["privacy-security"],
  "addonUrls": ["https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/"],
  "sort": "users",
  "maxItems": 50,
  "proxyConfiguration": {"useApifyProxy": false}
}
```

The lists are processed in this order: queries, categories, then direct add-ons. That matters when `maxItems` is smaller than the combined number of matches. For a direct comparison of a few known extensions, leave the query and category arrays empty. For discovery, use a query or category first and narrow it based on the returned names, categories, and summaries.

### Output

These are two real records from a local direct lookup run. This compact example shows a subset of their fields; the actual dataset includes every field in the table above. Values change as Mozilla updates listings and as authors publish new versions.

```json
[
  {"id":"607454","sourceUrl":"https://addons.mozilla.org/api/v5/addons/addon/ublock-origin/?lang=en-US","name":"uBlock Origin","slug":"ublock-origin","guid":"uBlock0@raymondhill.net","authors":["Raymond Hill"],"users":11432495,"weeklyDownloads":242563,"ratingAverage":4.8017,"version":"1.75.0","categories":["privacy-security"]},
  {"id":"506646","sourceUrl":"https://addons.mozilla.org/api/v5/addons/addon/privacy-badger17/?lang=en-US","name":"Privacy Badger","slug":"privacy-badger17","authors":["EFF Technologists"],"categories":["privacy-security"]}
]
```

Each row contains `sourceUrl` so you can trace it to the exact API request. The stable `id` lets you join snapshots from separate runs, while `slug` is useful for readable reports. Store a run date alongside an exported dataset if you intend to compare changing counts or versions later. The Actor itself returns current records and does not calculate changes between runs.

### How much does it cost?

The Actor is charged per result returned. `maxItems` caps the number of results and therefore caps the number of result events from a run. Repeated IDs are removed and are not returned twice. See the Pricing tab for the current rate and billing details. Test a small target set first if you are estimating how many records a larger search might return.

### Use with AI agents (MCP)

An AI agent can discover and run this Actor through Apify MCP. Add the following server configuration to a compatible MCP client. The tool path is the Actor's Store path. Keep authentication in your client's normal secure settings rather than placing a token in the URL.

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com/?tools=axiomworks/firefox-addons-scraper"}}}
```

You can ask an agent to search Firefox extensions about password management and compare their `users`, `ratingAverage`, and `version`. You can ask it to fetch a list of known add-on slugs and return their `permissions` and `license`. You can also ask it to review a privacy category dataset and group records by `authors` or `categories`. The agent receives structured rows, so ask it to cite the `sourceUrl` for any finding it presents.

An agent should pass at least one target list in its API call. Console prefills help a person try the Actor, but they do not add a target automatically to an API call. The descriptions in the input schema explain valid values and the `maxItems` range. A narrow prompt and a small limit are usually easiest to inspect before starting a larger collection.

### Integrations and API

Use the Actor from an Apify API client or your own HTTP client. Set your API token in the client's authentication settings or an authorization header. The examples below fetch returned dataset items, which have the same field names as the Output table. Replace the query with a category or a direct slug to collect a different slice of the catalog.

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/firefox-addons-scraper").call(
    run_input={"searchQueries": ["ad blocker"], "maxItems": 20}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["id"], item["name"], item["sourceUrl"])
```

**JavaScript**

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/firefox-addons-scraper').call({
  searchQueries: ['ad blocker'], maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~firefox-addons-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["ad blocker"],"maxItems":20}'
```

Apify integrations can route completed datasets to other services, including spreadsheets, automation workflows, and webhooks. Configure those in the Integrations tab of the Actor. The same output schema is used whether a run starts in Console, through MCP, or with the API. If you need periodic records, schedule runs and store each dataset separately with its run date.

### FAQ

**Can I request one exact extension?** Yes. Put its Mozilla add-on page URL or slug in `addonUrls`. The Actor uses the slug in the public add-on API endpoint. A page URL for another site or browser is rejected as input.

**Why did my run return zero items?** Check that your query or category has Firefox extension matches, or that a direct slug still exists. A temporary API block can also prevent results. The run log reports the target failure; try again later or enable a proxy if access remains blocked.

**Can I get more than one page?** Yes. Search and category collections move through pages while there are more results and the run has room under `maxItems`. A very broad search may have more matches than you ask the Actor to return.

**Why are some fields null or empty?** Mozilla may omit optional metadata on an extension, including a homepage, promotion category, or tags. The Actor keeps that distinction visible. It does not create a homepage or infer a license from unrelated text.

**How current are the numbers?** `users`, downloads, and ratings are read when the Actor runs. The API decides when those values change. A scheduled run is a practical way to keep a recurring snapshot, but each run only represents what the API supplied at that time.

**Does it download extension files?** No. It returns the `downloadUrl` and `fileSize` fields from the API. The Actor does not fetch or inspect XPI contents. Permissions are copied from the current file metadata supplied by Mozilla.

**What if a direct URL contains a language prefix?** Standard add-on URLs with or without the locale segment work. The Actor extracts the final add-on slug and asks the API for English localized fields when available.

### Is it legal to scrape Firefox Add-ons?

This Actor reads publicly available Mozilla Add-ons API data without logging in. You are responsible for using the results in line with applicable law and your obligations for personal data, including author names and profile URLs. This Actor is independent and is not affiliated with or endorsed by Mozilla. This paragraph is general information, not legal advice.

### Feedback

If a field is missing, a category behaves unexpectedly, or a public add-on lookup fails, open an issue on the Actor's Issues tab. Include the input you used, the run ID, and the affected `sourceUrl` so the behavior can be reproduced. Avoid putting private information in a public issue. Suggestions for clearer field names and examples are welcome.

# Actor input Schema

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

Keywords to search in the Firefox Add-ons catalog, e.g. \["ad blocker", "dark mode"]. Any language. Supply this, categories, or addonUrls. All targets share maxItems and results are de-duplicated by add-on ID. A term with no matches returns no rows and a status message.

## `categories` (type: `array`):

Mozilla category slugs to browse, e.g. \["privacy-security", "tabs"]. Lowercase letters, digits and hyphens only; other values fail the run. Results follow the sort option. Supply this, searchQueries, or addonUrls.

## `addonUrls` (type: `array`):

Add-ons to fetch directly: page URLs (e.g. https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/), slugs (ublock-origin), numeric IDs (607454) or GUIDs. A non-existent add-on is skipped with a status message. Supply this, searchQueries, or categories.

## `sort` (type: `string`):

Order of search and category results: users (most used, default), rating, updated, created or hotness (trending). Ignored for direct addonUrls.

## `addonType` (type: `string`):

Kind of add-on to search: extension, statictheme (themes), dictionary, language (language packs), or any. Default extension. Direct addonUrls ignore this.

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

Maximum unique add-ons returned across ALL targets combined, 1-10000, default 50. Use 1-5 for a quick test.

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

Apify Proxy settings, e.g. {"useApifyProxy": true}. Default is no proxy, which works for the Mozilla API; enable it only if runs report being blocked.

## Actor input object example

```json
{
  "searchQueries": [
    "ad blocker"
  ],
  "categories": [],
  "addonUrls": [],
  "sort": "users",
  "addonType": "extension",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset with one item per result, in the order found.

# 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 = {
    "searchQueries": [
        "ad blocker"
    ],
    "sort": "users",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/firefox-addons-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 = {
    "searchQueries": ["ad blocker"],
    "sort": "users",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/firefox-addons-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 '{
  "searchQueries": [
    "ad blocker"
  ],
  "sort": "users",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/firefox-addons-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/firefox-addons-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/pBal0PtwQ1qH2Nyks/builds/M2dtWqLPhln8HeaAO/openapi.json
