Pythia Search Bundle — Multi-Source OSINT Fan-Out avatar

Pythia Search Bundle — Multi-Source OSINT Fan-Out

Pricing

Pay per usage

Go to Apify Store
Pythia Search Bundle — Multi-Source OSINT Fan-Out

Pythia Search Bundle — Multi-Source OSINT Fan-Out

One subject in, structured intelligence from many public sources out. Tick the sources you want — jobs boards, SEC filings, news, code repos — and pay only per result returned.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Creator Fusion

Creator Fusion

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 hours ago

Last modified

Share

Pythia Search Bundle — 14-Source OSINT Fan-Out API for AI Agents

One subject in — a company name, domain, GitHub org, or package name — structured intelligence from 14 public sources out, in a single Apify call. This is the account's flagship consolidated intelligence Actor: it replaces 19 single-source Pythia Actors (now deprecated and redirected here) with one typed, agent-friendly fan-out endpoint. Every run returns typed JSON rows — one per source, each holding a list of individually-dated signals — schema below.

Why agents use this actor

  • One call, many sources. Instead of orchestrating 14 separate API integrations, an agent sends one subject and a sources list and gets back a normalized row per source.
  • Deterministic typed output. Every row and every signal matches the published dataset schema, regardless of which source produced it. evidence varies by source but the envelope never does.
  • Per-source failure isolation. One source failing (rate limit, no data, transient error) never breaks the run — it comes back as available: false with an error string, and every other source still returns its data.
  • No auth, no cookies. All 14 sources are public APIs or public pages; this Actor holds any keys it needs internally.
  • Cost-predictable. max_results_per_source hard-caps signals per source, so the maximum possible bill for a run is known before you start it.

Sources

Built as a Rust Cargo workspace: search_bundle (this Actor) fans out via the Apify API to 14 private sibling Actors and aggregates their datasets into one response. subject is sent to each source using the wrapping its input_kind needs (a bare domain vs. a search query vs. a package name).

Source keyInput kindSignal it returns
sec_edgarquerysec_filing — SEC EDGAR full-text search hits
statuspagedomainincident / incident_summary — Atlassian Statuspage vendor incidents
gdeltquerynews_mention — GDELT global news index
google_newsquerynews_mention — Google News RSS
hackernewsquerystory — HackerNews Algolia search
githubdomainorg_summary + repo — GitHub org repo list, languages, activity
greenhousedomainjob_posting — Greenhouse ATS open roles
leverdomainjob_posting — Lever ATS open roles
npmpackagepackage_meta — npm registry package metadata
pypipackagepackage_meta — PyPI package metadata
redditquerypost — Reddit search
stackoverflowqueryquestion — Stack Exchange API
federal_registerqueryfederal_register_doc — Federal Register full-text search
waybackurlsnapshot_summary — Internet Archive Wayback Machine snapshot history

subject is treated literally per source — for github it's matched as an exact org login, for domain-kind sources it's used as-is (no www-stripping). A near-miss (e.g. a decommissioned or unrelated org that happens to share a name) will still return real, live data for the wrong entity, so verify evidence.full_name / the source's own identity fields on the first row before trusting a run at scale.

Known gap — 4 sibling source Actors exist in the codebase but are not yet wired into this Actor's fan-out registry: opencorporates, opensanctions, producthunt, uspto_trademark. Requesting any of these in sources is accepted by the input schema but returns no row for that source — it is recorded as "unknown source: <name>" in the summary row's evidence.failed_sources and nothing is charged for it. Stick to the 14 keys in the table above until these are connected.

Input schema

FieldTypeRequiredDefaultDescription
subjectstringyesCompany slug, domain, GitHub org, package name, or search query. Used for every selected source.
sourcesstring[]yesWhich of the 14 source keys above to fan out to. Unrecognized keys are skipped, not charged.
since_daysintegerno30Lookback window for sources that accept one (news, HackerNews, Reddit, SEC EDGAR, Federal Register, etc). Ignored by sources with no time dimension (npm, PyPI, GitHub org summary).
concurrencyintegerno5How many child Actors to call at once. Higher is faster but heavier on account concurrency.
max_results_per_sourceintegerno25Hard cap on signals returned per source. Caps the maximum possible bill for the run: roughly actor-start + sources × this × per-signal price.

Output schema

One row per requested-and-recognized source, plus one leading search_bundle summary row. All fields nullable.

FieldTypeDescription
sourcestring | nullsearch_bundle for the summary row, otherwise the source key, e.g. hackernews, github.
subjectstring | nullSubject as sent to this source.
signalsarray | nullThe signals this source returned. Empty when unavailable or nothing found.
signals[].signal_idstring | nullStable ID, typically {source}:{subject}:{event_type}:{id-or-date}.
signals[].sourcestring | nullSource key for this individual signal.
signals[].event_typestring | nulle.g. story, org_summary, repo, job_posting, sec_filing, news_mention, post, question, incident, package_meta, snapshot_summary, federal_register_doc, bundle_summary.
signals[].subjectstring | nullSubject this signal is about.
signals[].summarystring | nullOne-line, public-record-style description. No advice, no editorial framing.
signals[].severitystring | nullcritical, high, notable, or info. Every source Actor currently emits only notable/info; critical/high are reserved for a future synthesis layer.
signals[].source_confidencestring | nullhigh, medium, or low.
signals[].deltastring | nullnew, changed, resolved, or info. Currently always info — no cross-run diffing yet.
signals[].observed_atstring | nullISO 8601 timestamp of the underlying event (not the run time).
signals[].evidenceobject | nullFree-form, source-specific structured data. Never contains raw PII or credentials — a redaction guard runs before every push and fails the run if it finds any.
availableboolean | nullTrue if the source ran and returned data (even zero signals). False if it errored.
errorstring | nullSet when available is false, e.g. "reddit status 403 Forbidden".
fetched_atstring | nullISO 8601 timestamp this row was produced.
actor_versionstring | nullSemver of the Actor (bundle or child) that produced this row.

Example — summary row (real output, subject: "Anthropic", sources: ["hackernews","github"])

{
"source": "search_bundle",
"subject": "Anthropic",
"signals": [{
"signal_id": "search_bundle:TQifrPdkrzhIbsxfq:summary",
"source": "search_bundle",
"event_type": "bundle_summary",
"subject": "Anthropic",
"summary": "2 sources requested, 2 succeeded, 0 failed; 20 signals total",
"severity": "info",
"source_confidence": "high",
"delta": "info",
"observed_at": "2026-08-15T11:41:51.049Z",
"evidence": {
"bundle_run_id": "TQifrPdkrzhIbsxfq",
"requested_sources": ["hackernews", "github"],
"successful_sources": ["hackernews", "github"],
"failed_sources": [],
"failures_detail": [],
"total_signals": 20,
"total_billable_results": 20,
"estimated_gross_cost_usd": 0.7
}
}],
"available": true,
"error": null,
"fetched_at": "2026-08-15T11:41:51.049Z",
"actor_version": "0.1.10"
}

Example — hackernews source row (real output)

{
"source": "hackernews",
"subject": "Anthropic",
"signals": [{
"signal_id": "hackernews:Anthropic:story:49308395",
"source": "hackernews",
"event_type": "story",
"subject": "Anthropic",
"summary": "OpenAI and Anthropic in price war as Chinese AI rivals gain ground (↑3)",
"severity": "info",
"source_confidence": "high",
"delta": "info",
"observed_at": "2026-08-15T07:01:41Z",
"evidence": {
"object_id": "49308395",
"title": "OpenAI and Anthropic in price war as Chinese AI rivals gain ground",
"url": "https://arstechnica.com/ai/2026/08/openai-and-anthropic-in-price-war-as-chinese-ai-rivals-gain-ground/",
"author": "joozio",
"points": 3,
"num_comments": 1
}
}],
"available": true,
"error": null,
"fetched_at": "2026-08-15T11:41:47.887Z",
"actor_version": "0.1.0"
}

Example — github source row (real output; org_summary + one repo signal)

{
"source": "github",
"subject": "anthropic",
"signals": [
{
"signal_id": "github:anthropic:summary",
"source": "github",
"event_type": "org_summary",
"subject": "anthropic",
"summary": "18 repos · 0 created in 30d · top lang: JavaScript",
"severity": "info",
"source_confidence": "high",
"delta": "info",
"observed_at": "2026-08-15T11:41:50.710Z",
"evidence": { "total_public_repos": 18, "new_repos_30d": 0, "top_language": "JavaScript", "language_counts": { "JavaScript": 9, "TypeScript": 2, "HTML": 3, "Makefile": 1, "Unknown": 3 } }
},
{
"signal_id": "github:anthropic:repo:302289032",
"source": "github",
"event_type": "repo",
"subject": "anthropic",
"summary": "react (★1) — —",
"severity": "info",
"source_confidence": "high",
"delta": "info",
"observed_at": "2026-08-15T11:41:50.710Z",
"evidence": { "full_name": "Anthropic/react", "id": 302289032, "stargazers_count": 1, "forks_count": 1, "language": null, "fork": true, "archived": false, "created_at": "2020-10-08T09:18:29Z", "pushed_at": "2020-10-08T06:10:24Z", "description": "A declarative, efficient, and flexible JavaScript library for building user interfaces." }
}
],
"available": true,
"error": null,
"fetched_at": "2026-08-15T11:41:50.710Z",
"actor_version": "0.1.0"
}

Example — unavailable source row (real output; reddit on a 403)

{
"source": "reddit",
"subject": "Anthropic",
"signals": [],
"available": false,
"error": "reddit status 403 Forbidden",
"fetched_at": "2026-08-15T11:42:43.031Z",
"actor_version": "0.1.0"
}

Error semantics

  • Empty subject or empty sources — the run fails immediately (exit code 1) with a descriptive message.
  • A source fails at the HTTP/parse level (rate limit, timeout, upstream error) — its row is still pushed, with available: false and error set. The rest of the run continues. It is also listed in the search_bundle summary row's evidence.failed_sources / evidence.failures_detail.
  • An unrecognized source key (not one of the 14 wired sources) — no row is pushed for it at all. It is dropped silently from the dataset and recorded only in the summary row's evidence.failed_sources as "unknown source: <name>". Nothing is charged for it. Check evidence.successful_sources against your requested sources if you need to detect this.
  • estimated_gross_cost_usd in the summary row's evidence is the Actor's own internal per-signal cost model (used for max_results_per_source capping), not necessarily the platform's live configured pricing — see Pricing below.
  • Rows are pushed as each source finishes, so a run that ends early for any reason still leaves every completed source's row in the dataset.

Use from AI agents (MCP)

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=apricot_blackberry/pythia-search-bundle",
"headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
}
}
}

Works in Claude, Cursor, ChatGPT deep research connectors, and any MCP client; the input schema above is the tool's parameter schema.

Use from code

curl

curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~pythia-search-bundle/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"subject":"Anthropic","sources":["hackernews","github"],"since_days":14,"max_results_per_source":10}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('apricot_blackberry/pythia-search-bundle').call({
subject: 'Anthropic',
sources: ['hackernews', 'github', 'sec_edgar'],
since_days: 30,
max_results_per_source: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((row) => row.available === false));

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("apricot_blackberry/pythia-search-bundle").call(run_input={
"subject": "Anthropic",
"sources": ["hackernews", "github", "gdelt", "google_news"],
"since_days": 30,
"max_results_per_source": 25,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["source"], row["available"], len(row.get("signals", [])))

Use from automation platforms

  • n8n / Make / Zapier — use the native Apify integration, pick "Run Actor", and choose pythia-search-bundle by name.
  • LangChain / LlamaIndex — wrap it with the Apify Actor tool wrappers (apricot_blackberry/pythia-search-bundle); the input schema becomes the tool signature.
  • Webhooks — Apify webhooks can fire on run completion, so a downstream pipeline can pick up a finished intelligence sweep without polling.

Pricing

Not yet monetized on the Apify Console at time of writing — runs are free while this listing is finalized. The code itself carries an internal per-source cost model (used to cap max_results_per_source and reported as estimated_gross_cost_usd in every summary row) that reflects the intended pricing shape:

SourceInternal price per signal
sec_edgar, federal_register$0.10
reddit, stackoverflow, github, statuspage, wayback$0.05
greenhouse, lever, hackernews, gdelt, npm, pypi, google_news$0.02

Check the Apify Console for this Actor's live configured pricing before relying on these figures for a production budget.

FAQ

What is this actor, really? One Apify call that fans out to 14 separate public-data source Actors for the same subject and returns their results as normalized rows. It replaces 19 single-source Pythia Actors that were deprecated and redirected here.

Does subject need to be a domain, a company name, or something else? It depends on the source — see the Sources table's "Input kind" column. The same literal subject string is sent to every selected source, wrapped appropriately (a bare login for github, a search query for hackernews/gdelt/google_news/reddit/stackoverflow, a package name for npm/pypi, a URL for wayback).

Why did I get a GitHub org I didn't expect? github matches subject as an exact org login. If the exact-name org isn't the company you meant (a decommissioned shell org, a name squat, etc.), you'll get real data for the wrong entity. Check evidence.full_name on the first repo signal to confirm identity before trusting results at scale.

Can I request opencorporates, opensanctions, producthunt, or uspto_trademark? The input schema accepts them, but they aren't wired into this Actor's fan-out registry yet. You'll get no row for that source and a "unknown source" entry in the summary — see Error semantics.

How do I keep a run's cost predictable? Set max_results_per_source — the summary row's evidence.estimated_gross_cost_usd shows what the run would cost against the internal per-signal price table, before you scale up.

Does this work for private companies or people who don't file with the SEC? Yes — hackernews, gdelt, google_news, reddit, stackoverflow, github, npm, pypi, greenhouse, lever, statuspage, and wayback all cover subjects with no SEC presence. Only sec_edgar and federal_register are limited to entities that file with US federal bodies.

Changelog

0.1 — Consolidated fan-out Actor covering 14 wired sources (SEC EDGAR, Statuspage, GDELT, Google News, HackerNews, GitHub, Greenhouse, Lever, npm, PyPI, Reddit, Stack Overflow, Federal Register, Wayback). Typed dataset schema, per-source failure isolation, redaction guard on every push, internal per-signal cost model for predictable-bill capping. Supersedes 19 deprecated single-source Pythia Actors.