Bluesky Community Intelligence
Pricing
$1.50 / 1,000 analyzed accounts
Bluesky Community Intelligence
Discover and compare public Bluesky creators and communities with explainable rankings, bounded activity evidence, and portable snapshots.
Pricing
$1.50 / 1,000 analyzed accounts
Rating
0.0
(0)
Developer
Aung Kyaw Khant
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Bluesky Community Intelligence is a separate Apify Actor for explainable, cost-bounded public Bluesky creator, competitor, and community research. It uses deterministic algorithms rather than an LLM and keeps every useful account tied to its discovery, activity, completeness, and ranking evidence.
The Actor exposes four versioned workflows:
analysisType | Contract | Customer outcome |
|---|---|---|
community_map | 1.0 | Compare selected one-hop following networks and explicit starter packs |
creator_discovery | 2.0 | Find bounded topic/network candidates and rank their observed public activity |
competitor_analysis | 2.0 | Compare the observed public following communities of two or more competitors |
snapshot_compare | 2.0 | Compare two compatible portable snapshots without making a Bluesky request |
Community Map answers three narrow questions:
- Which public accounts are followed by several seed accounts I selected?
- How much do the observed following communities of two seeds overlap?
- Which accounts appear across both selected seed networks and starter packs?
The mature workflows additionally answer who is active around selected topics, which observed accounts connect communities, how competitor source sets differ, and what changed between strictly compatible snapshots. The Actor does not claim to map all of Bluesky or search every post. It analyzes only bounded, public, customer-selected sources.
Community Map v1
The original contract remains supported without schema or methodology changes. It accepts:
- 2–10 seed Bluesky handles or DIDs
- 0–10 explicit
app.bsky.graph.starterpackAT URIs evaluationorscalerun mode- optional lower per-source and unique-account ceilings
It resolves identities to DID, collects bounded one-hop sources, excludes all
resolved seed DIDs, deduplicates by DID, enriches public profiles, calculates
transparent overlap, and uses the published community-consensus-v1 tuple.
Community Map quick start
{"analysisType": "community_map","seedAccounts": ["bsky.app","atproto.com"],"starterPackUris": ["at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.graph.starterpack/3movkm24pzp2d"],"runMode": "evaluation","maxFollowingPerSeed": 100,"maxMembersPerStarterPack": 100,"maxUniqueAccounts": 250}
Runtime validation rejects unknown fields, credential-like fields, malformed pack URIs, invalid limits, and fewer than two distinct normalized seed identifiers before client creation.
After resolution, at least two distinct seed DIDs and at least two usable seed-following source sets must remain. Otherwise the run fails rather than returning fake community overlap.
Mature v2 workflows
Creator discovery quick start
{"contractVersion": "2.0","analysisType": "creator_discovery","topics": ["at protocol", "decentralized social"],"seedAccounts": ["bsky.app"],"languageFilters": ["en"],"recentDays": 30,"runMode": "evaluation","maxSearchAccountsPerTopic": 20,"maxPostsPerAccount": 10,"maxTotalPosts": 300,"maxUniqueAccounts": 30,"rankingLimit": 20}
Creator discovery admits bounded public profile-search results first, followed by optional seed-following and explicit starter-pack sources. It enriches each admitted DID, reads at most one bounded recent author-feed sample, aggregates declared-language and text/activity evidence, and publishes five deterministic ranking views plus clusters and a structured report.
Competitor analysis quick start
{"contractVersion": "2.0","analysisType": "competitor_analysis","competitorAccounts": ["bsky.app", "atproto.com"],"topics": ["at protocol"],"recentDays": 30,"runMode": "evaluation"}
At least two distinct competitor DIDs must resolve. Competitor-following sources have admission priority, followed by topics, optional seed networks, and packs. The comparison describes observed shared/unique sets and containment; it does not infer loyalty, endorsement, intent, or a complete audience.
Every mature network run writes one portable SNAPSHOT key-value record. Pass
two compatible snapshot objects to snapshot_compare; that workflow performs
no AppView request and emits no billable row. A mature network run can also
accept baselineSnapshot and emit a change record against its new snapshot.
Limits
| Limit | Evaluation | Scale |
|---|---|---|
| Seed accounts | 3 | 10 |
| Starter packs | 2 | 10 |
| Following members per seed | 100 | 500 |
| Members per starter pack | 100 | 500 |
| Unique analyzed accounts | 250 | 5,000 |
| Total source memberships | 1,000 | 20,000 |
| Upstream pages | 15 | 100 |
| Graph depth | 1 | 1 |
All limits are ceilings, not delivery guarantees. Results can be smaller because an endpoint ends, a source fails, a global budget is reached, profile enrichment returns fewer records, or an Apify charge limit stops output.
Collection is intentionally sequential by source so admission at a global cap is deterministic. Profile enrichment uses bounded concurrency and batches of at most 25 DIDs, matching the reviewed public AppView contract.
Mature v2 uses a separate, deliberately smaller content-analysis budget:
| Limit | Evaluation | Scale |
|---|---|---|
| Topics | 3 | 10 |
| Competitor accounts | 3 | 10 |
| Profile-search accounts per topic | 25 | 100 |
| Unique analyzed accounts | 50 | 500 |
| Author-feed observations per account | 10 | 25 |
| Total activity observations | 500 | 12,500 |
| Discovery requests | 25 | 150 |
| Content requests | 50 | 500 |
| Recent window | 30 days | 90 days |
| Rows per ranking view | 25 | 100 |
These are hard ceilings, not promises. Mature source admission is sequential and deterministic. Every resolved seed and competitor DID is excluded before candidate admission. Content collection never expands into recursive crawling.
Pricing and spending limits
Planned custom event:
analyzed-account
Planned exact event price:
$0.0015 per unique emitted community_member$1.50 per 1,000 unique emitted community members
A unique DID can trigger at most one analyzed-account event per run, even when it appears in several seed networks and starter packs.
The Actor never charges the custom event for:
- duplicate memberships or graph edges
- seed-account rows
- starter-pack rows
- pair-overlap rows
- source-status rows
- summaries, warnings, or errors
- retries or internal API calls
- observed posts or activity items
- ranking, cluster, competitor-comparison, report, snapshot, or change rows
- failed or malformed identities that never become emitted community members
On hosted Apify runs, the Actor fails before any Bluesky request unless:
- pricing is Pay Per Event
analyzed-accountexists at exactly$0.0015- the default dataset-item event is absent or exactly zero
- the remaining event allowance can be determined
Before collection:
appliedMaxUniqueAccounts = min(input-and-mode maxUniqueAccounts,remaining analyzed-account event allowance)
maximum custom charge = appliedMaxUniqueAccounts × $0.0015
A zero remaining allowance fails before AppView client creation. A late platform charge-limit race stops useful output immediately; the denied row and every remaining member row are not written uncharged.
With the current monetization setting, Apify shows User pays platform usage
costs: No. The customer-facing run price is therefore the confirmed
analyzed-account event total; compute/storage usage is not added to the
customer's bill for this Actor. maximumCustomChargeUsd is still named for the
custom event because that is the runtime allowance the Actor can enforce. Any
future change to the platform-usage setting or addition of another event
requires a pricing and billing-contract re-audit.
Output records
All public records use one default dataset and a shared envelope:
{"recordType": "community_member","analysisType": "community_map","schemaVersion": "1.0","methodologyVersion": "1.0","collectedAt": "2026-07-14T00:00:00Z","runId": "...","analysisId": "sanitized-input-fingerprint","sourceUrl": "https://bsky.app/profile/example.bsky.social","input": {},"data": {},"isBillable": true,"billingCategory": "analyzed_account"}
Community Map v1 record types:
recordType | Purpose | Custom event |
|---|---|---|
community_member | One unique admitted account with source evidence and rank | analyzed-account |
seed_account | Seed resolution result | None |
starter_pack | Pack and backing-list metadata | None |
seed_pair_overlap | Pairwise observed seed-following metrics | None |
starter_pack_pair_overlap | Pairwise observed pack metrics | None |
source_status | Pagination, cap, failure, cursor, and completeness details | None |
analysis_summary | Run, limits, completeness, operational, output, and billing counters | None |
error | Sanitized source/run diagnostics | None |
The dataset schema provides named views for community members, seed accounts, starter packs, seed overlap, starter-pack overlap, source status, summary, errors, and common envelope fields. Views are column presentations; consumers should filter by recordType for type-specific exports.
The compact OUTPUT key-value record contains status, dataset ID, record counts, methodology version, and warnings. It does not duplicate the graph.
Mature v2 keeps the same envelope and adds:
recordType | Purpose | Custom event |
|---|---|---|
community_member | One admitted DID with discovery and bounded activity evidence | analyzed-account |
source_account | Seed/competitor resolution and duplicate/failure evidence | None |
source_status | Search, following, or pack scope and completeness | None |
ranking_entry | One row in a published purpose-specific tuple order | None |
community_cluster | Deterministic cluster membership, evidence labels, and cohesion | None |
competitor_comparison | Shared/unique observed competitor sets and overlap | None |
analysis_report | Deterministic summary assembled from structured evidence | None |
snapshot_change | Strict compatible-snapshot differences and warnings | None |
analysis_summary / error | Reconciled run counters and sanitized diagnostics | None |
Mature rows use schemaVersion=2.0 and methodologyVersion=2.0.
community_map remains 1.0. OUTPUT identifies the SNAPSHOT key and
fingerprint for mature network runs but never embeds the full snapshot.
Mature analysis methods
The five purpose-rankings-v1 views are:
network_connectorsactive_topic_contributorscommunity_engagedbridge_accountsconsistent_contributors
Each row exposes its exact sort tuple, metric version, DID tie-break, and plain-
language reasons. Clusters use dependency-free deterministic weighted label
propagation (1.0), with labels derived from observed terms, hashtags, and
domains. These are bounded evidence summaries—not influence, quality,
authenticity, trust, or lead scores.
Private-run preview
These screenshots document Community Map v1 and mature v2 using small public demonstration targets from successful private runs. Exact, sampled, and source-status fields remain visible so the preview does not imply complete-network coverage.
Safe input

Ranked community members

Transparent seed overlap



Source completeness

Analysis and billing summary

Creator-discovery input and cost boundary

Mature analyzed accounts

Explainable purpose ranking

Observed community clusters

Competitor observed-set comparison

Portable snapshot comparison

Ranking
The Actor emits no synthetic influence score. Candidate order is the published lexicographic tuple:
1. seedMembershipCount descending2. starterPackMembershipCount descending3. followersCount descending, null last4. postsCount descending, null last5. DID ascending
Each member includes the exact seed and pack memberships, every sort component, rankBasisVersion, and plain-language rank reasons.
A high rank means only that the account has stronger evidence under this observed source tuple. It does not mean the account is objectively influential, trustworthy, authentic, high quality, or commercially valuable.
Overlap metrics
For observed source sets A and B:
intersectionCount = |A ∩ B|unionCount = |A ∪ B|Jaccard = |A ∩ B| / |A ∪ B|overlapCoefficient = |A ∩ B| / min(|A|, |B|)aContainedInB = |A ∩ B| / |A|bContainedInA = |A ∩ B| / |B|
A zero denominator produces null, not zero.
If either source is unavailable, all pair metrics are null. If either source is truncated, the ratios are labeled sampled_from_truncated_sources. Jaccard from two truncated samples is not described as a mathematical lower bound.
See docs/METHODOLOGY.md and docs/COMPLETENESS.md.
Completeness and run status
Source completeness:
exact: endpoint exhaustion was observed before a cap or failurelower_bound: at least one validated page was collected, but a cap, repeated cursor, or later failure stopped the sourceunavailable: no validated source set was collected
Run status:
complete: all requested sources are exact, all seeds are distinct/usable, enrichment succeeds, and billing reaches no late stoppartial: enough source data exists for analysis, but a source is truncated/failed, a requested seed is duplicate/unavailable, enrichment is partial, or a late charge boundary stops outputfailed: input or pricing preflight fails, fewer than two distinct usable seeds remain, fewer than two seed sources produce trustworthy sets, or safe persistence cannot be established
A customer-selected cap is not an operational error, but it makes the result incomplete.
Public-data and privacy boundary
The Actor uses only anonymous reads from the public Bluesky AppView service. It does not accept Bluesky passwords, app passwords, tokens, or account sessions.
It does not provide:
- global keyword/post search
- follower collection
- recursive or whole-network crawling
- schedules, continuous monitoring, or developer-owned cross-run storage
- sentiment, intent, authenticity, influence, lead-quality, demographic, or political scores
- contact, email, or website enrichment
- private messages or private data
- deleted, blocked, or access-controlled content recovery
- browser automation
See docs/PRIVACY_AND_ACCEPTABLE_USE.md.
Support and responsible disclosure
Use the Actor's Apify Issues tab for product support, billing questions,
privacy concerns, or misuse reports. Include the Apify run ID and a sanitized
description of the problem; for billing questions, also include the dataset ID
and the analysis_summary row. Never post API tokens, credentials, private
targets, or unredacted customer data in an issue.
The target response window is two business days. Schema-breaking changes will use a new schema version and will be announced before deprecation of the prior contract.
Local validation
python3.11 -m venv .venv.venv/bin/pip install -r requirements.lock.txt.venv/bin/python -m pytest -qapify validate-schema.venv/bin/python scripts/live_smoke.py
The live smoke uses small public limits and validates endpoint shape/invariants, not fixed account counts.
Docker validation:
$docker build -t bluesky-community-intelligence:local .
Release-gate commands and expected evidence are documented in docs/RELEASE_VALIDATION.md.
Current validation boundary
On 2026-07-21 the Community Map and mature runtime passed 263 tests, schema and
contract checks, all seven anonymous AppView wrapper checks, local Actor
lifecycle tests, and Docker lifecycle tests. The mature smoke emitted three
unique account rows, all five ranking views, one cluster, one report, and a
reconciled SNAPSHOT. A reproducible dense analysis benchmark processed 500
DIDs, 5,000 memberships, and 12,500 activity observations in 12.99 seconds with
about 302 MiB maximum process RSS; the Actor minimum is therefore 512 MiB.
The prior v1 runtime passed a nine-case private hosted billing matrix on
2026-07-16. That is not deployed-SHA proof for v2. A fresh private build must
reconfirm exact price preflight, allowance-derived v2 caps, account/event
reconciliation, SNAPSHOT, named mature views, and hosted resource behavior
before release approval. The Actor has not been published.