Change language
Get Started

OSINT Playbook

Every lead, sourced
and verified.

An automated OSINT pipeline: parallel agents source companies and people across registries, maps, corporate sites and social networks, extract and verify every email and phone, then merge it all into one clean contact database — synced straight to your CRM.

Data sources

Where the leads come from

search_business_directory

Business registries

ЕГРЮЛ aggregators — rusprofile.ru, list-org.com, sbis.ru, companies.rbc.ru: registry data, INN/OGRN, founders and executives.

find_leads

Maps & directories

2GIS (CIS), Yandex Maps (Russia/CIS), Yellow Pages (international) — companies with addresses, phones and opening hours.

parse_corporate_site

Corporate sites

Team and about pages, contacts, press releases — plus Schema.org markup and JSON-LD blocks structured for extraction.

search_social

Social networks

LinkedIn profiles and company pages, X/Twitter search, Telegram channels and users — with anti-bot limits handled honestly.

search_news

News & mentions

Serper News API and Google News RSS — funding rounds, hires and launches that tell you who to contact next.

Pipeline

Seven stages, one query

01

Plan

The coordinator decomposes the query into parallel subtasks: registries, socials, corporate sites, databases.

02

Extract

extract_contacts pulls emails, phones, socials, persons and companies from every fetched page.

03

Verify

verify_email, verify_phone and verify_social_profile filter the noise and score confidence.

04

Enrich

enrich_company and enrich_person add industry, size, location, role and buying signals.

05

ContactDb

SQLite or PostgreSQL store; dedup and merge on normalized emails and phones.

06

CRM

Sync into amoCRM, Bitrix24 or HubSpot — dedup by crm_id, no duplicates on re-runs.

07

Report

summary.md plus a contact table, exported to CSV, vCard, JSON or Excel.

Verification

Nothing unverified gets saved

Bounced emails and dead numbers burn outreach budget. Every candidate passes MX checks, disposable-domain and role-based filters before it earns a confidence score — and obfuscated addresses like name [at] domain [dot] com are decoded automatically, with a lower score than plain ones.

verify_email("info@company.com")
→ is_valid_syntax: true
→ domain_exists:   true
→ mx_records:      ["mx1.company.com"]
→ is_disposable:   false
→ is_role_based:   true      # info@ admin@ support@
→ confidence:      0.85

# deobfuscation
"name [at] company [dot] com"
→ info@company.com           # confidence 0.70
"info@company.com"           # plain → confidence 0.95

Phones & patterns

E.164 phones, inferred emails

Phones are normalized to E.164 via libphonenumber with country and mobile/landline detection. When only a name and a domain are known, suggest_emails builds candidate addresses from name permutations and the domain's existing pattern — up to 9 variants to verify.

verify_phone("+7 (495) 710-75-80")
→ normalized:   "+74957107580"    # E.164
→ country_code: "RU"
→ is_valid:     true
→ is_mobile:    false             # landline

suggest_emails("John Doe", "acme.com")
→ john.doe@acme.com
→ j.doe@acme.com
→ john@acme.com  …
→ up to 9 candidates: name permutations
  × observed domain pattern

Storage

ContactDb — one canonical record

Contacts land in SQLite out of the box — or PostgreSQL for large bases, same interface. Dedup and merge run on normalized emails and phones, so re-runs and overlapping sources never create double records. Tags and notes attach per contact; the whole schema is yours to query.

save_contacts · db_path = "./contacts.db" · pg_url = "postgres://…"

TableColumns
contactsid, email, phone, name, title, company, source, timestamps
social_profilescontact_id, platform, url, username
companiesname, website, industry, size, location
tagscontact_id, tag
notescontact_id, note

Query examples

One command, a folder of leads

Moscow — IT CEOs
parallel-research run \
  "Find contacts of CEOs and CTOs at
   small IT companies in Moscow.
   Extract emails, phones and
   LinkedIn profiles." \
  --output ./leads/

# agents fan out over rusprofile,
# list-org and sbis, parse corporate
# sites, enrich persons
# → INN/OGRN table + emails + phones
#   + LinkedIn candidates (CSV, md)
Berlin — SaaS Series A–B
parallel-research run \
  "Find 20 SaaS companies,
   Series A–B, Berlin. Collect
   emails and LinkedIn of founders
   and CTOs." \
  --output ./berlin-saas/

# → 20 companies × founder/CTO
#   contacts, verified emails +
#   LinkedIn URLs, exported to
#   CSV / vCard
Dubai — fintech market
parallel-research run \
  "Research the Dubai fintech
   startup market. For the top-10
   companies find decision-maker
   contacts." \
  --output ./dubai-fintech/

# → market overview + top-10
#   companies with decision-maker
#   contacts, CSV / vCard export

Ethics & compliance

Responsible by default

GDPR & 152-ФЗ

Personal data is processed in line with GDPR and Russia's 152-ФЗ: lawful basis, scoped purpose, deletion on request.

Public data only

Agents read open, publicly available sources — nothing scraped behind logins, paywalls or private APIs.

robots.txt & rate limits

Crawling respects robots.txt and built-in throttling; bot-blocked pages (403) are skipped gracefully, never hammered.

Honest statuses

Uncertainty is explicit: "requires verification", "not found", "HTTP 999", "low-confidence match" — never silent guesses.

LinkedIn HTTP 999

LinkedIn answers bots with HTTP 999. Stable parsing needs proxies/cookies; agents surface the block instead of inventing data.

No spam

Extracted contacts are for qualified outreach and research — not bulk unsolicited mailings. Confidence scores help you filter.

See the full lead-generation workflow

Lead generation →