# Bluesky Community Intelligence (`xcalibur/bluesky-community-intelligence`) Actor

Discover and compare public Bluesky creators and communities with explainable rankings, bounded activity evidence, and portable snapshots.

- **URL**: https://apify.com/xcalibur/bluesky-community-intelligence.md
- **Developed by:** [Aung Kyaw Khant](https://apify.com/xcalibur) (community)
- **Categories:** Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 analyzed accounts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Bluesky Community Intelligence

**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:

1. Which public accounts are followed by several seed accounts I selected?
2. How much do the observed following communities of two seeds overlap?
3. 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.starterpack` AT URIs
- `evaluation` or `scale` run 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

```json
{
  "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

```json
{
  "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

```json
{
  "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:

```text
analyzed-account
```

Planned exact event price:

```text
$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-account` exists at exactly `$0.0015`
- the default dataset-item event is absent or exactly zero
- the remaining event allowance can be determined

Before collection:

```text
appliedMaxUniqueAccounts = min(
  input-and-mode maxUniqueAccounts,
  remaining analyzed-account event allowance
)
```

```text
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:

```json
{
  "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:

```text
network_connectors
active_topic_contributors
community_engaged
bridge_accounts
consistent_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

![Community Map input with two public seeds and one public starter pack](docs/store-assets/01-safe-input.jpg)

#### Ranked community members

![Community members with billable flag, deterministic rank, DID, and public profile fields](docs/store-assets/02-community-members.jpg)

#### Transparent seed overlap

![Seed overlap view with flattened source identity and completeness fields](docs/store-assets/03-seed-overlap.jpg)

![Seed overlap coefficients including intersection, union, and Jaccard](docs/store-assets/03b-seed-overlap-coefficients.jpg)

![Seed containment columns and sampled metric status](docs/store-assets/03c-seed-overlap-containment.jpg)

#### Source completeness

![Source status view for seed following and starter pack sources](docs/store-assets/04-source-status.jpg)

#### Analysis and billing summary

![Analysis summary view with applied caps and reconciliation fields](docs/store-assets/05-summary.jpg)

#### Creator-discovery input and cost boundary

![Creator-discovery evaluation input with public-data, account-cap, pricing, and methodology boundaries](docs/store-assets/06-creator-input.png)

#### Mature analyzed accounts

![Creator-discovery members with billable DID, public profile, purpose rank, and workflow evidence](docs/store-assets/07-mature-members.png)

#### Explainable purpose ranking

![Active-topic-contributor ranking, one of five deterministic tuple-ranked views](docs/store-assets/08-explainable-rankings.png)

#### Observed community clusters

![Deterministic community clusters derived only from emitted public DIDs](docs/store-assets/09-community-clusters.png)

#### Competitor observed-set comparison

![Competitor-following set comparison with explicit observed counts and transparent metrics](docs/store-assets/10-competitor-comparison.png)

#### Portable snapshot comparison

![Compatible snapshot comparison with matching fingerprints and zero Bluesky requests or billed events](docs/store-assets/11-snapshot-comparison.png)

### Ranking

The Actor emits no synthetic influence score. Candidate order is the published lexicographic tuple:

```text
1. seedMembershipCount descending
2. starterPackMembershipCount descending
3. followersCount descending, null last
4. postsCount descending, null last
5. 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`:

```text
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`](docs/METHODOLOGY.md) and [`docs/COMPLETENESS.md`](docs/COMPLETENESS.md).

### Completeness and run status

Source completeness:

- `exact`: endpoint exhaustion was observed before a cap or failure
- `lower_bound`: at least one validated page was collected, but a cap, repeated cursor, or later failure stopped the source
- `unavailable`: 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 stop
- `partial`: 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 output
- `failed`: 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`](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

```bash
python3.11 -m venv .venv
.venv/bin/pip install -r requirements.lock.txt
.venv/bin/python -m pytest -q
apify 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:

```bash
docker build -t bluesky-community-intelligence:local .
```

Release-gate commands and expected evidence are documented in [`docs/RELEASE_VALIDATION.md`](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.

# Actor input Schema

## `contractVersion` (type: `string`):

Optional explicit contract pin. community\_map requires 1.0; mature workflows require 2.0. When omitted, runtime selects the required version from analysisType.

## `analysisType` (type: `string`):

Choose one explicit workflow. All network workflows remain anonymous, public, bounded, one-hop, DID-keyed, deterministic, and AI-free. Snapshot comparison makes no Bluesky request.

## `seedAccounts` (type: `array`):

Public handles or DIDs. Community Map requires 2–10 under mode caps. Mature network workflows accept optional seed-following evidence. Resolved source DIDs are excluded from member results.

## `competitorAccounts` (type: `array`):

Two or more public handles or DIDs for competitor\_analysis only. Outputs describe observed public set relationships and never infer loyalty, intent, endorsement, or private affiliation.

## `topics` (type: `array`):

Creator discovery requires at least one explicit topic. Public profile search admits bounded candidates; recent post text is matched by published token and phrase rules, not an LLM.

## `languageFilters` (type: `array`):

Optional BCP 47-style tags such as en or fr. Matching uses only public post language declarations; missing language is excluded when a filter is active and is counted rather than inferred.

## `starterPackUris` (type: `array`):

Explicit at:// URIs for public app.bsky.graph.starterpack records. The Actor resolves each public backing list and never searches for packs.

## `recentDays` (type: `integer`):

Mature workflows only. Evaluation clamps to 30 days and Scale to 90 days. Activity outside the explicit run window is not analyzed.

## `runMode` (type: `string`):

Evaluation uses smaller discovery/content caps. Scale raises reviewed ceilings. Community Map retains its v1 250/5,000 account ceilings; mature workflows use 50/500 accounts plus separate request and post-observation budgets.

## `maxFollowingPerSeed` (type: `integer`):

Per-seed collection ceiling. Evaluation clamps to 100; Scale clamps to 500. The source is lower-bound only when the limit is reached and AppView exposes an unconsumed next cursor; exact exhaustion at the limit remains exact.

## `maxMembersPerStarterPack` (type: `integer`):

Per-pack backing-list ceiling. Evaluation clamps to 100; Scale clamps to 500. The source is lower-bound only when the limit is reached and AppView exposes an unconsumed next cursor; exact exhaustion at the limit remains exact.

## `maxSearchAccountsPerTopic` (type: `integer`):

Mature workflows only. One public profile-search page per topic; Evaluation clamps to 25 and Scale to 100.

## `maxPostsPerAccount` (type: `integer`):

Mature workflows only. One public author-feed page per admitted DID; Evaluation clamps to 10 and Scale to 25.

## `maxTotalPosts` (type: `integer`):

Mature workflows only. Separate global observation budget; Evaluation clamps to 500 and Scale to 12,500.

## `maxUniqueAccounts` (type: `integer`):

Hard ceiling shared by admitted DIDs, enrichment, member rows, and analyzed-account events. Community Map clamps to 250/5,000; mature workflows to 50/500. Remaining hosted event allowance can reduce it before client creation.

## `rankingLimit` (type: `integer`):

Mature workflows only. Caps public rows in each explainable ranking view; snapshots retain full emitted-account positions. Evaluation clamps to 25 and Scale to 100.

## `baselineSnapshot` (type: `object`):

Versioned portable snapshot from a comparable mature run. Required with currentSnapshot for snapshot\_compare; optional on network workflows to emit observed changes.

## `currentSnapshot` (type: `object`):

Versioned portable snapshot required only by snapshot\_compare. Snapshot bodies are validated, fingerprinted, bounded to 2 MB each, and never copied into dataset input metadata.

## Actor input object example

```json
{
  "analysisType": "community_map",
  "runMode": "evaluation"
}
```

# Actor output Schema

## `results` (type: `string`):

Filter by recordType and analysisType. Mature rows include purpose rankings, clusters, observed competitor comparisons, deterministic reports, and snapshot changes. Derived and control rows are non-billable.

## `runOutput` (type: `string`):

Analysis status, dataset ID, record counts, methodology version, and warnings. The full graph remains in the dataset.

## `snapshot` (type: `string`):

Present for creator\_discovery and competitor\_analysis runs. Contains bounded normalized emitted-account evidence for strict later comparison; absent for Community Map and pure snapshot comparison.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("xcalibur/bluesky-community-intelligence").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("xcalibur/bluesky-community-intelligence").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call xcalibur/bluesky-community-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=xcalibur/bluesky-community-intelligence",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bluesky Community Intelligence",
        "description": "Discover and compare public Bluesky creators and communities with explainable rankings, bounded activity evidence, and portable snapshots.",
        "version": "0.1",
        "x-build-id": "WAILA7AHyNplhAWcF"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/xcalibur~bluesky-community-intelligence/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-xcalibur-bluesky-community-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/xcalibur~bluesky-community-intelligence/runs": {
            "post": {
                "operationId": "runs-sync-xcalibur-bluesky-community-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/xcalibur~bluesky-community-intelligence/run-sync": {
            "post": {
                "operationId": "run-sync-xcalibur-bluesky-community-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "contractVersion": {
                        "title": "Contract version",
                        "enum": [
                            "1.0",
                            "2.0"
                        ],
                        "type": "string",
                        "description": "Optional explicit contract pin. community_map requires 1.0; mature workflows require 2.0. When omitted, runtime selects the required version from analysisType."
                    },
                    "analysisType": {
                        "title": "Analysis type",
                        "enum": [
                            "community_map",
                            "creator_discovery",
                            "competitor_analysis",
                            "snapshot_compare"
                        ],
                        "type": "string",
                        "description": "Choose one explicit workflow. All network workflows remain anonymous, public, bounded, one-hop, DID-keyed, deterministic, and AI-free. Snapshot comparison makes no Bluesky request.",
                        "default": "community_map"
                    },
                    "seedAccounts": {
                        "title": "Seed accounts",
                        "maxItems": 10,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Public handles or DIDs. Community Map requires 2–10 under mode caps. Mature network workflows accept optional seed-following evidence. Resolved source DIDs are excluded from member results.",
                        "items": {
                            "type": "string",
                            "minLength": 3,
                            "maxLength": 253
                        }
                    },
                    "competitorAccounts": {
                        "title": "Competitor accounts",
                        "maxItems": 10,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Two or more public handles or DIDs for competitor_analysis only. Outputs describe observed public set relationships and never infer loyalty, intent, endorsement, or private affiliation.",
                        "items": {
                            "type": "string",
                            "minLength": 3,
                            "maxLength": 253
                        }
                    },
                    "topics": {
                        "title": "Topics",
                        "maxItems": 10,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Creator discovery requires at least one explicit topic. Public profile search admits bounded candidates; recent post text is matched by published token and phrase rules, not an LLM.",
                        "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    },
                    "languageFilters": {
                        "title": "Declared language filters",
                        "maxItems": 20,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional BCP 47-style tags such as en or fr. Matching uses only public post language declarations; missing language is excluded when a filter is active and is counted rather than inferred.",
                        "items": {
                            "type": "string",
                            "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
                        }
                    },
                    "starterPackUris": {
                        "title": "Optional starter-pack AT URIs",
                        "maxItems": 10,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Explicit at:// URIs for public app.bsky.graph.starterpack records. The Actor resolves each public backing list and never searches for packs.",
                        "items": {
                            "type": "string",
                            "maxLength": 2048,
                            "pattern": "^at://did:[a-z0-9]+:[A-Za-z0-9._:%-]+(?::[A-Za-z0-9._:%-]+)*/app\\.bsky\\.graph\\.starterpack/[A-Za-z0-9._~:-]{1,512}$"
                        }
                    },
                    "recentDays": {
                        "title": "Recent activity window in days",
                        "type": "integer",
                        "description": "Mature workflows only. Evaluation clamps to 30 days and Scale to 90 days. Activity outside the explicit run window is not analyzed."
                    },
                    "runMode": {
                        "title": "Run scale",
                        "enum": [
                            "evaluation",
                            "scale"
                        ],
                        "type": "string",
                        "description": "Evaluation uses smaller discovery/content caps. Scale raises reviewed ceilings. Community Map retains its v1 250/5,000 account ceilings; mature workflows use 50/500 accounts plus separate request and post-observation budgets.",
                        "default": "evaluation"
                    },
                    "maxFollowingPerSeed": {
                        "title": "Maximum following members per seed",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Per-seed collection ceiling. Evaluation clamps to 100; Scale clamps to 500. The source is lower-bound only when the limit is reached and AppView exposes an unconsumed next cursor; exact exhaustion at the limit remains exact."
                    },
                    "maxMembersPerStarterPack": {
                        "title": "Maximum members per starter pack",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Per-pack backing-list ceiling. Evaluation clamps to 100; Scale clamps to 500. The source is lower-bound only when the limit is reached and AppView exposes an unconsumed next cursor; exact exhaustion at the limit remains exact."
                    },
                    "maxSearchAccountsPerTopic": {
                        "title": "Maximum searched accounts per topic",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Mature workflows only. One public profile-search page per topic; Evaluation clamps to 25 and Scale to 100."
                    },
                    "maxPostsPerAccount": {
                        "title": "Maximum recent activities per account",
                        "minimum": 1,
                        "maximum": 25,
                        "type": "integer",
                        "description": "Mature workflows only. One public author-feed page per admitted DID; Evaluation clamps to 10 and Scale to 25."
                    },
                    "maxTotalPosts": {
                        "title": "Maximum total post observations",
                        "minimum": 1,
                        "maximum": 12500,
                        "type": "integer",
                        "description": "Mature workflows only. Separate global observation budget; Evaluation clamps to 500 and Scale to 12,500."
                    },
                    "maxUniqueAccounts": {
                        "title": "Maximum unique analyzed accounts",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Hard ceiling shared by admitted DIDs, enrichment, member rows, and analyzed-account events. Community Map clamps to 250/5,000; mature workflows to 50/500. Remaining hosted event allowance can reduce it before client creation."
                    },
                    "rankingLimit": {
                        "title": "Rows per ranking view",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Mature workflows only. Caps public rows in each explainable ranking view; snapshots retain full emitted-account positions. Evaluation clamps to 25 and Scale to 100."
                    },
                    "baselineSnapshot": {
                        "title": "Optional baseline snapshot",
                        "type": "object",
                        "description": "Versioned portable snapshot from a comparable mature run. Required with currentSnapshot for snapshot_compare; optional on network workflows to emit observed changes."
                    },
                    "currentSnapshot": {
                        "title": "Current snapshot",
                        "type": "object",
                        "description": "Versioned portable snapshot required only by snapshot_compare. Snapshot bodies are validated, fingerprinted, bounded to 2 MB each, and never copied into dataset input metadata."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
