# Amrico's Lead Limiter 🌟Delete # leads in the same company (`amr-mando/lead-limiter`) Actor

Upload a CSV of leads, set a max number of leads per domain, and the actor removes the excess, starting from the lowest job-title seniority and prioritizing tech-sector titles. 🌟Private use for Amrico's partners (amr@amrico.net)

- **URL**: https://apify.com/amr-mando/lead-limiter.md
- **Developed by:** [Mando](https://apify.com/amr-mando) (community)
- **Categories:** Lead generation
- **Stats:** 3 total users, 3 monthly users, 40.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## 🎯 Domain Lead Limiter

Limit the number of leads (rows) per company domain in your CSV. When leads must be removed, the actor keeps the most senior people and **prioritises technology-sector job titles**.

---

### 📌 What it does

You upload a CSV containing leads scraped from various sources. Many of those leads share the same company domain - for example, 7 employees from one company. You only need 2 or 3 contacts per company, not all 7.

This actor:

1. Groups all leads by their company domain
2. For any domain that exceeds your configured limit, removes the lowest-priority leads
3. Outputs the remaining leads with **every column preserved in the exact same order as the input**

---

### 🏆 How leads are prioritised (what gets kept vs removed)

#### Seniority hierarchy (highest to lowest)

| Level | Examples |
|-------|---------|
| 10 - C-Suite | CEO, CTO, CIO, CISO, COO, CFO, CMO, Chief Technology Officer |
| 9 - President / Owner / Founder | President, Owner, Founder, Co-Founder |
| 8 - Vice President | VP of IT, SVP, EVP, Vice President of Engineering |
| 7 - Director | Managing Director, IT Director, Director of Technology, Technical Director |
| 6 - Head / Group Lead | Head of IT, Head of Engineering, Group Lead |
| 5 - Manager / Partner | IT Manager, Managing Partner, General Manager, Principal |
| 4 - Architect / Lead / Staff | Systems Architect, Lead Engineer, Staff Engineer, Principal Consultant |
| 3 - Senior | Senior Engineer, Senior Consultant, Senior Analyst |
| 2 - Mid-level | Engineer, Specialist, Consultant, Analyst, Administrator |
| 1 - Junior / Entry | Junior Developer, Intern, Trainee, Associate, Assistant |
| 0 - Unknown | Any title not matching the above - removed first |

#### Tech-sector priority (tiebreaker)

**This actor is built to prioritise technology-sector job titles.**

When two leads have the **same seniority level**, the tech-related title is kept and the non-tech title is removed. For example:

- Director of Technology (level 7, tech) is kept over Director of Sales (level 7, non-tech)
- IT Manager (level 5, tech) is kept over Marketing Manager (level 5, non-tech)
- CTO (level 10, tech) is kept over CFO (level 10, non-tech)

Tech-related titles are identified by keywords such as: IT, technology, engineering, software, infrastructure, cloud, security, cyber, data, DevOps, systems, network, CTO, CIO, CISO, and many more.

#### When titles are unrecognised

If a job title does not match any known seniority pattern, it is assigned level 0 and will be the first to be removed. Among multiple unknown titles, the original CSV row order is preserved (earlier rows are kept).

---

### 🚀 How to use it

1. **Upload your CSV file** - the file must contain at least a domain column and a job title column
2. **Specify the domain column name** (e.g. `domain`, `website`, `company_domain`) - or leave blank to auto-detect
3. **Specify the job title column name** (e.g. `title`, `job_title`, `position`) - or leave blank to auto-detect
4. **Set the max leads per domain** - for example, `2` means keep at most 2 leads per company
5. **Run the actor**
6. **Export the results** - the output has the same columns in the same order as your input, minus the removed leads

> Column name matching is **not case-sensitive**. `Domain`, `DOMAIN`, and `domain` all work.

---

### 📤 Output

The output dataset contains exactly the same columns as your input CSV, in the same order. The only difference is that excess leads have been removed. No columns are added or modified.

---

### 📋 Example

**Input CSV (5 leads, 2 domains):**

| domain | name | title |
|--------|------|-------|
| acme.com | Alice | CEO |
| acme.com | Bob | CTO |
| acme.com | Carol | Junior Developer |
| acme.com | Dave | Sales Director |
| acme.com | Eve | IT Manager |
| globex.com | Frank | Managing Director |
| globex.com | Grace | Intern |

**Settings:** max 2 leads per domain

**Output (4 leads):**

| domain | name | title |
|--------|------|-------|
| acme.com | Alice | CEO |
| acme.com | Bob | CTO |
| globex.com | Frank | Managing Director |
| globex.com | Grace | Intern |

From acme.com, Carol (Junior, level 1), Dave (Sales Director, level 7 non-tech), and Eve (IT Manager, level 5 tech) were candidates for removal. Carol is removed first (lowest level), then between Dave and Eve - Dave is removed because Eve has a tech title. Alice (CEO) and Bob (CTO) are kept as the top 2.

---

### 📊 Log output

The actor logs a clear summary:

````

📄 CSV loaded: 1,250 total leads
🌐 Domain column: "domain"
💼 Job title column: "title"
🔢 Max leads per domain: 2

📊 Found 340 unique domains
⚠️ 85 domains have more than 2 leads (430 leads total in those domains)

✂️ Trimming to 2 lead(s) per domain (keeping highest seniority, prioritising tech titles)...

acme.com: 5 leads -> kept 2, removed 3
globex.com: 4 leads -> kept 2, removed 2
...

✅ Done!

Total leads in input:     1,250
Unique domains:           340
Max leads per domain:     2
Domains trimmed:          85
Leads removed:            260
Leads kept (output):      990

````

# Actor input Schema

## `password` (type: `string`):

Enter the password to use this actor. Contact the actor owner if you don't have one.
## `csvFile` (type: `string`):

Upload a CSV file containing your leads. The actor will read the domain and job title columns, then remove excess leads per domain based on job title seniority.
## `maxLeadsPerDomain` (type: `integer`):

The maximum number of leads (rows) to keep per unique domain. Any excess leads will be removed, starting from the lowest job-title seniority. For example, if set to 2 and a domain has 5 leads, the 3 lowest-seniority leads are removed.
## `domainColumn` (type: `string`):

The name of the CSV column that contains the company domain or website (e.g. domain, website, url). Leave blank to auto-detect. Column matching is not case-sensitive.
## `jobTitleColumn` (type: `string`):

The name of the CSV column that contains the job title or position (e.g. title, job_title, position). Leave blank to auto-detect. Column matching is not case-sensitive.

## Actor input object example

```json
{
  "maxLeadsPerDomain": 3,
  "domainColumn": "Domain",
  "jobTitleColumn": "job_title"
}
````

# Actor output Schema

## `csvOutput` (type: `string`):

No description

## `results` (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 = {
    "maxLeadsPerDomain": 3,
    "domainColumn": "Domain",
    "jobTitleColumn": "job_title"
};

// Run the Actor and wait for it to finish
const run = await client.actor("amr-mando/lead-limiter").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 = {
    "maxLeadsPerDomain": 3,
    "domainColumn": "Domain",
    "jobTitleColumn": "job_title",
}

# Run the Actor and wait for it to finish
run = client.actor("amr-mando/lead-limiter").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxLeadsPerDomain": 3,
  "domainColumn": "Domain",
  "jobTitleColumn": "job_title"
}' |
apify call amr-mando/lead-limiter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=amr-mando/lead-limiter",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Amrico's Lead Limiter 🌟Delete # leads in the same company",
        "description": "Upload a CSV of leads, set a max number of leads per domain, and the actor removes the excess, starting from the lowest job-title seniority and prioritizing tech-sector titles. 🌟Private use for Amrico's partners (amr@amrico.net)",
        "version": "0.1",
        "x-build-id": "uTDbAZTXaAO8DSjC9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/amr-mando~lead-limiter/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-amr-mando-lead-limiter",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/amr-mando~lead-limiter/runs": {
            "post": {
                "operationId": "runs-sync-amr-mando-lead-limiter",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/amr-mando~lead-limiter/run-sync": {
            "post": {
                "operationId": "run-sync-amr-mando-lead-limiter",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "password",
                    "csvFile",
                    "maxLeadsPerDomain"
                ],
                "properties": {
                    "password": {
                        "title": "🔑 Password",
                        "type": "string",
                        "description": "Enter the password to use this actor. Contact the actor owner if you don't have one."
                    },
                    "csvFile": {
                        "title": "📄 CSV File",
                        "type": "string",
                        "description": "Upload a CSV file containing your leads. The actor will read the domain and job title columns, then remove excess leads per domain based on job title seniority."
                    },
                    "maxLeadsPerDomain": {
                        "title": "🔢 Max Leads Per Domain",
                        "minimum": 1,
                        "type": "integer",
                        "description": "The maximum number of leads (rows) to keep per unique domain. Any excess leads will be removed, starting from the lowest job-title seniority. For example, if set to 2 and a domain has 5 leads, the 3 lowest-seniority leads are removed.",
                        "default": 3
                    },
                    "domainColumn": {
                        "title": "🌐 Domain Column Name",
                        "type": "string",
                        "description": "The name of the CSV column that contains the company domain or website (e.g. domain, website, url). Leave blank to auto-detect. Column matching is not case-sensitive.",
                        "default": ""
                    },
                    "jobTitleColumn": {
                        "title": "💼 Job Title Column Name",
                        "type": "string",
                        "description": "The name of the CSV column that contains the job title or position (e.g. title, job_title, position). Leave blank to auto-detect. Column matching is not case-sensitive.",
                        "default": ""
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
