# URL Normalizer & Tracking Cleaner (`grounded_goldeneye/url-normalizer-tracking-cleaner`) Actor

Normalize inline HTTP(S) URLs, remove known tracking parameters and fragments, and deduplicate results. Preserve signed URLs, encoded paths, identifiers and query order by default. No URL fetching.

- **URL**: https://apify.com/grounded_goldeneye/url-normalizer-tracking-cleaner.md
- **Developed by:** [david tan](https://apify.com/grounded_goldeneye) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.02 / completed url normalizer & tracking cleaner

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

## URL Normalizer & Tracking Cleaner

Normalize inline HTTP(S) URLs, remove known tracking parameters and fragments, and deduplicate results. Preserve signed URLs, encoded paths, identifiers and query order by default. No URL fetching.

### When to use it

Clean URL lists before deduplication, reporting or later fetching in your own workflow.

### Price

**$0.02 per completed report**, for supported paying Apify users. One `report-generated` event, after files and a summary are stored. No per-row, per-URL or dataset-item charge. Invalid input and processor timeouts do not trigger the report event. Apify’s free-user rules and any separately applicable platform charges are governed by Apify.

Use a maximum charge limit that covers at least one report. Keep a smaller diagnostic `detailLimit` for large inputs; all output records and counts remain complete. No external AI models or API keys are needed.

### Example input

```json
{
  "urls": [
    "HTTPS://Example.COM:443/Products/001?utm_source=ads&id=001#top",
    "https://example.com/Products/001?id=001",
    "https://example.com/A%2Fb?q=a+b",
    "https://example.com/file?X-Amz-Signature=demo&utm_source=keep"
  ],
  "dropTracking": true,
  "sortQuery": false,
  "removeFragment": true,
  "deduplicate": true,
  "detailLimit": 100
}
```

### Results

- `REPORT.json`: complete `summary`, full `records` and bounded `details`.
- `RECORDS.csv`: all output records. Formula-like cells are escaped for spreadsheets; JSON is the authoritative typed result.
- `REPORT.html`: self-contained escaped report, with at most 20 output records in the preview.

The default dataset contains a single operational summary; it is not the records export. A low detail limit truncates diagnostics only. Download JSON or CSV for full output.

### Limits and behavior

5 MiB input envelope; 10,000 URLs; 32,768 UTF-8 bytes per URL. Only HTTP(S). No requests or DNS lookups are performed. URLs with recognized signature or token parameters are preserved verbatim; detection cannot identify every proprietary signature scheme. Unicode hosts are lowercased without IDNA conversion. Query sorting is disabled by default. Paths, encoded slashes, duplicate query values and leading-zero identifiers are preserved.

All products have a 25-second processor deadline, 256 MiB container memory, a 60-second run timeout and a combined 10 MiB export limit. Large or wide inputs may hit the export limit before the row limit. Failed exports do not charge the report event. No automatic restarts are enabled.

### Privacy and operation

Use only data you are authorized to process. Inline data and outputs are stored in your run’s Apify storage under its configured access and retention settings. This Actor does not fetch external resources or invoke a model, and does not log source values. Review your own storage sharing and retention settings for sensitive inputs.

Billing uses a durable checkpoint. If a charge response is uncertain, the same run stops for ledger review instead of retrying payment automatically. Start a new run only after inspecting the earlier attempt. Report a problem through Apify’s Actor issue tracker with sanitized examples; do not post private records or tokens.

# Actor input Schema

## `urls` (type: `array`):

HTTP(S) URLs only. At most 10,000 URLs. URLs containing credentials, controls, spaces, invalid escapes or ports are rejected.

## `dropTracking` (type: `boolean`):

Removes utm\_\* and explicitly recognized tracking keys, retaining ordinary application parameters.

## `sortQuery` (type: `boolean`):

Opt-in stable sorting. Query order can affect endpoints; a warning is returned.

## `removeFragment` (type: `boolean`):

Drops # fragments from ordinary URLs.

## `deduplicate` (type: `boolean`):

Keep the first occurrence and record duplicate provenance.

## `detailLimit` (type: `integer`):

Caps warning or diagnostic samples only. Complete counts and output records are retained.

## Actor input object example

```json
{
  "urls": [],
  "dropTracking": true,
  "sortQuery": false,
  "removeFragment": true,
  "deduplicate": true,
  "detailLimit": 100
}
```

# Actor output Schema

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

One summary row; no source values.

## `file0` (type: `string`):

Full records are in JSON and CSV. HTML previews at most 20 output rows. Markdown and text files, when present, are complete.

## `file1` (type: `string`):

Full records are in JSON and CSV. HTML previews at most 20 output rows. Markdown and text files, when present, are complete.

## `file2` (type: `string`):

Full records are in JSON and CSV. HTML previews at most 20 output rows. Markdown and text files, when present, are complete.

# 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("grounded_goldeneye/url-normalizer-tracking-cleaner").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("grounded_goldeneye/url-normalizer-tracking-cleaner").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 grounded_goldeneye/url-normalizer-tracking-cleaner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,grounded_goldeneye/url-normalizer-tracking-cleaner"
        }
    }
}
```

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/iaoccY2U6eTuqbaxn/builds/wjzG8L3fyQoVFeJrE/openapi.json
