Scraper Workers

Twitter angel scraper

The Ultron Twitter Angel Scraper hits the official Twitter v2 search API with a broad set of angel and indie-hacker queries, filters the resulting authors by bio keywords, and returns a deduplicated set of profiles likely to be active angel investors. Designed for the 7-day recent-search window the v2 API enforces on most app contexts.

Updated today

Overview

At a glance
Worker
ultron-twitter-angels
Runtime
Python 3.13 (apify/actor-python image)
API
Twitter v2 /search/recent with Bearer token
Query count
~30 tuned angel queries
Bio inclusion
angel, investor, writing checks, seed, scout, etc.
Bio exclusion
crypto scam, dm for promo, nft giveaway, airdrop
Default window
7 days

The angel scraper is the entry point to a downstream qualification flow. The Specter persona uses it to build a candidate pool, then the platform's enrichment skills add email finder results, LinkedIn cross-references, and warm-intro paths. The actor itself stays narrow: it produces a list of plausible angel-investor Twitter handles, no more.

Authentication

OAuth 2.0 app-only Bearer token, derived from the caller's app credentials.

apify-actors/twitter/src/__main__.pypython
1def get_bearer(consumer_key: str, consumer_secret: str) -> str:
2 """Generate Bearer Token from consumer credentials."""
3 creds = base64.b64encode(f"{consumer_key}:{consumer_secret}".encode()).decode()
4 req = urllib.request.Request(
5 "https://api.x.com/oauth2/token",
6 data=b"grant_type=client_credentials",
7 headers={
8 "Authorization": f"Basic {creds}",
9 "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
10 },
11 )
12 resp = urllib.request.urlopen(req, timeout=15)
13 data = json.loads(resp.read().decode("utf-8"))
14 return data.get("access_token", "")
Note
App-only authentication is enough for the recent-search endpoint. User-context auth would unlock the full archive search, but no app credential available to the platform's free or paid Twitter tier reaches that endpoint reliably.

Query strategy

Broad rather than precise. The 7-day window penalises narrow queries.

apify-actors/twitter/src/__main__.pypython
1ANGEL_QUERIES = [
2 "angel investor", "angel investing", "angel investor AI", "angel investor SaaS",
3 "seed investor", "pre-seed investor", "writing checks startup", "angel portfolio",
4 "invest in founders", "backing founders", "angel round", "first check investor",
5 "micro VC", "solo GP", "emerging fund manager", "syndicate lead",
6 "indie hacker investor", "bootstrapped founder angel", "operator investor",
7 "founder angel", "angel check size",
8 "just invested seed", "excited to announce investment", "proud to invest",
9 "joined cap table", "new angel investment", "backed my first startup",
10 "led the round", "participated in round",
11 "angel group", "angel network", "angel syndicate", "scout program",
12 "venture scout", "invest AI startup", "AI seed funding", "AI angel",
13]

Queries are designed to match many tweets each in any 7-day window so the pipeline finds a useful number of distinct authors. The bio filter does the precision work afterwards.

Bio filters

Inclusion set and exclusion set applied to the author's bio after dedup.

apify-actors/twitter/src/__main__.pypython
1ANGEL_BIO_KEYWORDS = {
2 "angel", "investor", "writing checks", "backing founders",
3 "angel portfolio", "seed investor", "pre-seed", "invest in founders",
4 "angel investing", "check writer", "startup investor", "scout",
5 "micro fund", "indie", "bootstrapped", "founder", "operator",
6 "venture", "vc", "fund", "portfolio", "syndicate", "gp",
7 "capital", "invest", "backed", "seed", "series a",
8}
9
10EXCLUDE_BIO_KEYWORDS = {
11 "venture capital firm", "institutional investor", "fund of funds",
12 "crypto scam", "dm for promo", "nft giveaway", "airdrop",
13}
Tip
The exclusion list is the noise filter for the angel persona specifically. Institutional investors are intentionally excluded because the Specter persona's outreach approach for institutional funds is a different skill with a different cadence.

The 7-day window

The recent-search endpoint only sees the last 7 days.

App-only auth is capped at v2's search/recent, which only indexes the last 7 days. The actor is designed around that constraint: queries are broad enough to find many matches inside a week, the bio filter does the qualifying, and the workflow assumes the user will run the actor on a schedule rather than as a one-shot.

Output shape

One row per unique author who passed the filters.

dataset-row.jsonjson
1{
2 "username": "mariaschultz",
3 "user_id": "1234567890",
4 "name": "Maria Schultz",
5 "bio": "Angel @ ... backing AI founders. Writing $25-50k checks.",
6 "location": "Berlin",
7 "followers": 18500,
8 "following": 820,
9 "tweet_count": 1240,
10 "matched_query": "angel investor AI",
11 "sample_tweet_id": "1789...",
12 "sample_tweet_text": "Proud to invest in ...",
13 "scraped_at": "2026-05-11T18:42:00Z"
14}

How to trigger it

From a skill, through the Apify HTTP API.

invocationtext
1POST https://api.apify.com/v2/acts/ultron-twitter-angels/runs?token=<APIFY_TOKEN>
2Content-Type: application/json
3
4{
5 "consumer_key": "<from the connected Twitter integration>",
6 "consumer_secret": "<from the connected Twitter integration>"
7}

File map

apify-actors/twitter (deployed only)
Dockerfile
requirements.txt
src
__main__.pyqueries + bio filters + Bearer derivation
__init__.py
Note
This actor is deployed but does not have a local source folder in the repo at the time of writing. The source shown above was pulled from the deployed version. Bring the source into the repo if you plan to evolve it; the workflow for the other scrapers is the canonical path.