Skip to content
Reference

Configuration

config.yaml, section by section, and the environment variables.

Behaviour lives in config.yaml; secrets live in .env. The config is committed and contains no secrets;.env is git-ignored. Most values are read live — background jobs pick up a change on their next run; the API needs a restart.

config.yaml, section by section#

outreach — sending#

KeyValueMeaning
send_modegmailLive sending; the alternative writes .eml files to outbox/ (dry run)
daily_send_cap25Emails per day, all kinds
guessed_daily_cap25Of those, to pattern-guessed addresses
send_window / send_days[10, 19] / mon–friLocal hours and days mail may leave
pacingmax_per_run 1 · front_load false · jitter 0.35One per run, spread across the window
warmupfirst 25 · step 5 · every 2Quota = min(cap, first + step × (day ÷ every))
bounce_brakewindow_days 7 · max_bounces 6Pause guessed addresses after too many bounces
per_domain_daily_cap3Cold emails a day into one recipient domain
spam_pause_hours · spam_block_cooldown_days48 · 21After a spam block: no cold mail at all · none into that domain
followup_after_days / max_followups5 / 1One follow-up after five quiet days
asks_per_company · contact/company_cooldown_days2 · 30 / 30Open asks per company; days before asking again
draft_expiry_days7Drafts older than this can’t be approved
gate60–110 words · subject 2–8 wordsReview-flag thresholds
composestructure direct_intro · 80–170 wordsYour template, its wordings and subjects
pattern_approvalfalseEvery email needs its own approval
do_not_contactemails · domains · companiesNever written to, whatever the pipeline finds

targeting — who is worth it#

KeyValueMeaning
fundingpre-seed → Series B · 30 months · ≤ $400MThe funding window
overratedvaluation ≥ $5B or raised ≥ $1BExcluded; plus the named famous lists
india.min_lpa25India pay floor (below → below_pay_bar)
india.citiesBengaluru · HyderabadThe only India targets
stipend_min_inr_month50000Internship stipend bar
ppo_tier1_lpa / ppo_tier2_lpa30 / 30Tier thresholds
priority.weightsfunding 35 · hiring 35 · pay 20 · valuation 10Priority score
people.max_per_company30People kept per company

tick, referrals, actors — the background work#

KeyValueMeaning
tick.scrapers_frozenfalsetrue pauses all scraping: tick install leaves free, paid and audit unloaded
tick.free_referral_jobfalseThe free people-search job; off because referrals are Apify's
actors.apify.tech_titles[engineer, developer, sde, …]People-tab search titles: only people who can refer an engineer
shortlist.pool_order · interval_seconds[Bengaluru, Hyderabad, Remote] · 600The shortlist job: one company every 10 min, in this order
scheduler.daily_scrapefalseThe API’s 08:00 daily cycle is off
tick.free_interval_seconds600Free tick every 10 minutes
tick.budget_seconds · share2400 · leads 0.7 / companies 0.3Time budget per free tick and its split
tick.paid_hour / paid_minute6 / 15Daily paid tick
tick.fill_per_tick · fill_budget_seconds20 · 900Companies filled per tick
tick.people_per_tick · verify_per_tick150 · 120Per-tick limits
referrals.interval_seconds · cycle_seconds900 · 1200Referral job: every 15 min, 20 min each
referrals.only_buckets[Bengaluru, Hyderabad]Cities the referral job works
actors.apify.daily_usd · cache_hours0.60 · 24Apify spend per day — the $19 Starter credit over ~31 days
actors.apify.mode · per_company · companies_per_runfull · 25 · 3People-tab rows with titles, 25 per company, 3 companies a run
actors.apify.interval_seconds · linkedin_backfill_per_run1800 · 30The Apify job every 30 min; homepages read first for LinkedIn pages

decide, mixer — choosing where to spend#

KeyValueMeaning
decide.shortlistBengaluru 100 · Hyderabad 50 · Remote 100Companies kept on each shortlist
decide.me.dsa_level0.35Your interview-DSA level, 0–1. Raise it as you practise; parked companies return
decide.dsaheavy 0.60 · park_always_above 0.80 · margin 0.15 · high_pay_lpa 35When an India company is parked “after DSA”
decide.priors.replyalpha 2 · beta 18Starting belief about a reply: 10%, updated by every send
decide.priors.referral_odds_ratio6.0A referral multiplies the screen’s odds by this
decide.gate.min_info0.55Share of the seven deciding fields needed before deciding (else fill first)
decide.draws · avoid_repeat_days4000 · 30Samples per company · days before a company is picked again
mixer.daily_usd · referral_reserve_usd0.05 · 0.30The mixer’s daily share · what it must leave for referrals
mixer.per_run · refresh_days2 · 14Companies bought per run · days before buying one again
mixer.pay_bands · max_dsapays, deep_pockets, funded · 0.5The pay-power and no-DSA layers
mixer.culture_min · culture_min_reviews3.0 · 10An AmbitionBox rating under this, on enough reviews, is a skip (India)

openrouter, research, scoring#

KeyValueMeaning
openrouter.aliasescheap · judge · writerRanked chains of free models; a call falls through on failure
openrouter caps18 req/min · ₹100/day · ₹2,500/monthChecked before every call
research.exa_daily_cap100Exa searches per day
research.scrapedo_daily / monthly120 / 1000scrape.do budget
research.x_session_enabledfalseLogged-in X search stays off
matching.high_match_threshold65A high match
confidence.bandshigh 65 · medium 48 · low 30Selection bands
scheduler.scrape_hour / reply_poll_minutes8 / 60The API’s own scheduler
api.host / api.port127.0.0.1 / 8000Where the API listens
Note
Some sections are read with built-in defaults and are absent from the file: guardrails (description 60–600 characters, hiring stale after 30 days, 3 referrers per company), audit and fill (refill after 7 days, 30 once complete).

Environment variables#

Read from the process environment, with .env at the repo root folded in first (values already set win). Names only — never commit values.

VariableNeeded for
OPENROUTER_API_KEYEvery model call — required
GMAIL_APP_PASSWORDSending (SMTP) and reading replies (IMAP)
GITHUB_TOKENGitHub API at 5,000 / hour instead of 60
EXA_API_KEYThe metered Exa fallback
APIFY_TOKENBuying People tabs (and the mixer’s job ads) from Apify
HUNTER_API_KEYHunter.io pattern lookups
SCRAPEDO_TOKENscrape.do reads (levels.fyi)
X_AUTH_TOKEN · X_CT0A throwaway X session — only with x_session_enabled
ACTOR_PROXYOptional proxy for actor fetches
ZONULY_PUBLIC · ZONULY_API_KEYRead-only public mode · the operator key that lifts it
ZONULY_DB_PATH · ZONULY_CORS_ORIGINS · ZONULY_HOST · PORTDeployment overrides
A known mismatch
The scrape.do backend's health check looks only for a variable named Scrape_dog, while the reader accepts SCRAPEDO_TOKEN. If scrape.do shows as unavailable in research doctor, that is why.