OSINT workflow example
Every lead, sourced
and verified.
OSINT is one workflow a universal autonomous worker can run: plan subtasks, inspect configured public sources, preserve evidence in memory, and ask for review before saving or contacting anyone. Connectors and integrations are optional, not guaranteed.
Data sources
Where a configured worker can look
Business registries
When configured, registry connectors can provide public company records, identifiers, founders and executives for a worker to inspect.
Maps & directories
Optional map and directory connectors can add public addresses, phones and opening hours; availability depends on operator setup and source limits.
Corporate sites
Workers can parse fetched team, about, contact and press pages, including Schema.org and JSON-LD where present.
Social networks
Configured public LinkedIn, X/Twitter or Telegram access can add context; blocked or unavailable sources remain explicit.
News & mentions
An enabled news connector can provide press, funding, hiring or launch context for the investigation.
Pipeline
A worker loop from plan to report
Plan
A universal worker scopes the question, selects configured tools and delegates source-specific subtasks.
Extract
extract_contacts gathers public emails, phones, social profiles and entities while retaining provenance.
Verify
verify_email, verify_phone and verify_social_profile apply available checks and label confidence without guessing.
Enrich
enrich_company and enrich_person add context from matching evidence; missing fields stay marked as gaps.
Persist
SQLite or PostgreSQL can store worker findings, memory and review receipts with normalized deduplication.
Govern
Policy and approval gates can pause side effects such as CRM writes, outreach or notifications.
Report
The worker synthesizes a cited report and can export findings or hand off to configured integrations.
Verification
Make uncertainty visible before saving
A worker can apply MX, disposable-domain and role-based checks when those network lookups are available. Obfuscated addresses such as name [at] domain [dot] com may be decoded and marked lower confidence; governance can require review before persistence or outreach.
verify_email("[email protected]")
→ 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"
→ [email protected] # confidence 0.70
"[email protected]" # plain → confidence 0.95Phones & patterns
Normalize phones, propose candidates
Phones can be normalized to E.164 via libphonenumber when the tool is available. When only a name and domain are known, suggest_emails proposes candidates from observed naming patterns for a worker or human to review and 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")
→ [email protected]
→ [email protected]
→ [email protected] …
→ additional candidates follow the observed
domain pattern and require reviewStorage
Persist findings with memory and review
Workers can persist findings in SQLite or PostgreSQL, depending on configuration. Normalized emails and phones support deduplication, while tags, notes, evidence and approval receipts keep context queryable across runs.
save_contacts · db_path = "./contacts.db" · pg_url = "postgres://…"
| Table | Columns |
|---|---|
| contacts | id, email, phone, name, title, company, source, timestamps |
| social_profiles | contact_id, platform, url, username |
| companies | name, website, industry, size, location |
| tags | contact_id, tag |
| notes | contact_id, note |
Query examples
Prompt examples for a governed workflow
fathom 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)fathom run \
"Map SaaS companies in Berlin,
collect public evidence and
identify founders or CTOs where
sources support the match." \
--output ./berlin-saas/
# → cited company and contact findings
# with confidence, gaps and review
# status; export only after approvalfathom run \
"Research the Dubai fintech
startup market and identify
decision-maker evidence where
public sources support it." \
--output ./dubai-fintech/
# → market overview with cited evidence,
# contact hypotheses, gaps and review
# status; export or hand off when allowedEthics & compliance
Responsible by default
GDPR & Law 152-FZ
Personal data is processed in line with GDPR and Russia's Federal Law 152-FZ on Personal Data: 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.