# Git Email Extractor (`rl1987/git-email-extractor`) Actor

Shallow-clones git repositories and extracts contributor emails (author & committer) from commit history. Give it a list of repo URLs, get back a flat dataset of names and emails per repo.

- **URL**: https://apify.com/rl1987/git-email-extractor.md
- **Developed by:** [R.L.](https://apify.com/rl1987) (community)
- **Categories:** Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 89.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 output rows

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

### What does Git Email Extractor do?

**Git Email Extractor** takes a list of git repository URLs, performs a shallow clone of each one, and scans the commit history for author and committer emails (including addresses mentioned in commit message trailers like `Co-authored-by`). Useful for mapping out contributors to open source projects, OSINT research on a target's engineering footprint, or lead-gen research on maintainers of a codebase.

### Why use Git Email Extractor?

- Quickly identify all contributors to a repository without cloning and grepping manually.
- OSINT/recon: enumerate real names and emails tied to a person's, company's, or project's public repos to build a contact or attribution picture.
- Run against many repositories in one go via the Apify platform's API, scheduler, and integrations.
- Get structured, downloadable results (JSON/CSV/Excel) instead of parsing `git log` output by hand.

### How to use Git Email Extractor

1. Open the Actor's **Input** tab.
2. Add one or more git repository URLs (HTTPS clone URLs, e.g. `https://github.com/user/repo.git`).
3. Optionally adjust the **shallow clone depth** (how many recent commits to scan per repo).
4. Run the Actor and check the **Dataset** tab for results.

### Input

| Field | Type | Description |
|---|---|---|
| `repoUrls` | array of strings | Git repository URLs to clone and scan. |
| `cloneDepth` | integer | Number of most recent commits to fetch per repo (default `100`). Only commits within this depth are scanned. |

### Output

Example dataset items — one flat row per name/email pair found:

```json
[
  { "repoUrl": "https://github.com/apify/apify-sdk-python.git", "name": "Jane Doe", "email": "jane@example.com" },
  { "repoUrl": "https://github.com/apify/apify-sdk-python.git", "name": "John Smith", "email": "john@example.com" }
]
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data table

| Field | Description |
|---|---|
| `repoUrl` | The repository URL the row was found in. Rows are de-duplicated by (repository, address), so one person appearing in two repositories is two rows. |
| `name` | Display name attached to the address in the commit history, where the history carries one. Empty when the address was found only inside a commit-message body, which carries no name. |
| `email` | The extracted address. Not verified, not deliverability-checked, and not filtered to business domains - see **What the addresses actually are** below. |

#### What the addresses actually are

A git history is a mix of work and personal addresses, and this Actor returns the
mix rather than pretending otherwise. Measured on an 8-row result for a flagship
open-source repository (2026-11-03): **3 corporate addresses, 3 personal Gmail
addresses tied to a full real name, 1 personal domain**, and 1 placeholder
(`webmaster@registry.example.com`) that a commit body had pasted in from a config
sample. Placeholders like that one are now dropped - addresses on domains reserved
for documentation or testing (`example.com`, `.test`, `.invalid`, `.localhost`,
`.local`) are not returned and not charged.

Only scrape and process addresses you have a lawful basis to use. Roughly half of
a typical result is a private individual's personal address rather than a business
contact.

### Pricing / Cost estimation

Cost scales with the number of repositories and the clone depth you set - cloning is the dominant cost, since email extraction itself is cheap local text processing. Use a smaller `cloneDepth` if you only need recent contributors.

Note that cost and output size are indexed to **different things**: what the run
spends tracks the *bytes cloned per repository*, while what it returns tracks the
*addresses per repository*. Measured: a 66-row run cost less than a 27-row one,
because the 27-row repository had far more history to fetch. So estimate by
repository, not per row. The price per 1,000 rows for your Apify plan is shown on
the Pricing tab.

### Tips

- Only public (or otherwise accessible) HTTPS repo URLs are supported — private repos requiring auth aren't handled.
- `noreply` addresses (e.g. GitHub's privacy emails) are filtered out automatically. Most modern GitHub contributors commit under a `users.noreply.github.com` privacy address, so a repository with dozens of contributors can legitimately yield only a handful of rows - a thin result is usually that, not a broken run.
- Increase `cloneDepth` if a repo has many contributors further back in history you want to catch.

### FAQ, disclaimers, and support

Only scrape repositories you have the right to access and process. Respect the license and any usage terms of the target repositories. Found a bug or have a feature request? Open an issue on the Actor's Issues tab.

### Cyber recon toolkit

Part of the **Cyber recon toolkit** — OSINT, attack-surface recon, and vulnerability-intel data collection for security research:

- [Bugcrowd Scraper](https://apify.com/rl1987/bugcrowd-scraper) — Scrapes public Bugcrowd data: disclosed submissions, program directory, leaderboard.
- [HackerOne Scraper](https://apify.com/rl1987/hackerone-scraper) — Scrapes public HackerOne data: Hacktivity disclosed reports, program directory, researcher leaderboard.
- [Intigriti Scraper](https://apify.com/rl1987/intigriti-scraper) — Scrapes public Intigriti data: bug bounty/VDP program directory, researcher leaderboard and profiles.
- [CVE Scraper](https://apify.com/rl1987/cve-scraper) — CVE.org vulnerability info scraper.
- [TLSX - TLS Data Gathering and Analysis](https://apify.com/rl1987/pd-tlsx) — Fast, configurable TLS grabber for TLS-based data collection and analysis.
- [BGP.HE.NET Recon Scraper](https://apify.com/rl1987/bgphenet-scraper) — Scrapes ASN, prefix, IP, and DNS recon data from bgp.he.net.
- [gau - Get All URLs](https://apify.com/rl1987/gau-wrapper) — Fetch known URLs from Wayback Machine, Common Crawl, AlienVault OTX, and URLScan.
- [Wappalyzer Technology Lookup](https://apify.com/rl1987/wappalyzer-tech-lookup) — Detect the technology stack behind any website using Wappalyzer.
- [Meta Tags Scraper](https://apify.com/rl1987/meta-tags-scraper) — Web page metadata scraper (meta tags, Open Graph, Twitter Card).
- [Universal Contact Extractor](https://apify.com/rl1987/universal-contact-extractor) — Extract phone numbers, emails and social media URLs from web pages.
- [Web Text Extractor](https://apify.com/rl1987/web-text-extractor) — Extract clean text or Markdown content from web pages.

### Did you find this useful?

Rate this actor on Apify! Your feedback helps other users find it and helps us keep improving it.

# Actor input Schema

## `repoUrls` (type: `array`):

List of git repository URLs to clone and scan for commit author/committer emails.

## `cloneDepth` (type: `integer`):

Number of most recent commits to fetch per repository (shallow clone). Only commits within this depth are scanned for emails.

## Actor input object example

```json
{
  "repoUrls": [
    "https://github.com/apify/apify-sdk-python.git"
  ],
  "cloneDepth": 100
}
```

# Actor output Schema

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

One row per unique email found per repository, with the associated display name.

# 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 = {
    "repoUrls": [
        "https://github.com/apify/apify-sdk-python.git"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rl1987/git-email-extractor").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 = { "repoUrls": ["https://github.com/apify/apify-sdk-python.git"] }

# Run the Actor and wait for it to finish
run = client.actor("rl1987/git-email-extractor").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 '{
  "repoUrls": [
    "https://github.com/apify/apify-sdk-python.git"
  ]
}' |
apify call rl1987/git-email-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rl1987/git-email-extractor"
        }
    }
}
```

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/5OiraI1lXn3aLEMmF/builds/xLJuLzgQjdrQQsget/openapi.json
