buzzabout docs
API reference

Run your first analysis

End-to-end in Python — scrape posts, collect audience profiles, then hand the dataset to the AI assistant.

This is the API / SDK walkthrough. Prefer the no-code path? Run your first research covers the same flow inside the app.

This tutorial assumes you've finished the quickstart and have an API key. We'll chain five steps into a single workflow, all in Python:

  1. Create a dataset and trigger a Reddit run.
  2. Wait for it to complete.
  3. Create an audience dataset, kick off a profile-collection run from the source dataset, and wait for it.
  4. Read the audience profiles.
  5. (Optional) Hand the dataset to the AI assistant.

The whole flow takes 5–15 minutes depending on platform speed.

Setup

export BUZZABOUT_KEY="bz_live_abcdef1234567890abcdef1234567890"
pip install httpx
first_analysis.py
import os
import time
import httpx

BUZZABOUT_KEY = os.environ["BUZZABOUT_KEY"]
client = httpx.Client(
    base_url="https://api.buzzabout.ai",
    headers={"x-api-key": BUZZABOUT_KEY},
    timeout=30.0,
)


def wait_for_run(url: str, interval: float = 10.0) -> dict:
    """Poll a run resource until it transitions out of pending/working."""
    while True:
        body = client.get(url).raise_for_status().json()["data"]
        status_type = body["status"]["type"]
        print(f"  {url}  status: {status_type}")
        if status_type in ("completed", "failed"):
            return body
        time.sleep(interval)

Walkthrough

Create the source dataset

dataset = client.post(
    "/v1/datasets",
    json={"name": "cold brew"},
).raise_for_status().json()["data"]
dataset_id = dataset["id"]

Trigger a run

run = client.post(
    f"/v1/datasets/{dataset_id}/runs",
    json={
        "search_query": {
            "type": "prompt",
            "sources": ["reddit"],
            "search_query": "cold brew",
        },
        "count": 200,
        "num_comments_per_post": 5,
        "content_analysis_actions": ["sentiment", "hook", "cta"],
    },
).raise_for_status().json()["data"]
run_id = run["id"]

Wait for the dataset run to complete

wait_for_run(f"/v1/datasets/{dataset_id}/runs/{run_id}")

A 200-post Reddit run with sentiment + hook + CTA analysis typically finishes in 1–3 minutes.

List the top mentions

top = client.post(
    "/v1/mentions",
    json={
        "dataset_ids": [dataset_id],
        "limit": 5,
        "sort": "engagement_rate",
        "order": "desc",
        "filters": [[{"type": "sentiment", "values": ["positive"]}]],
    },
).raise_for_status().json()["data"]

for m in top:
    print(f"{m['num_likes']:6,} likes  {m['url']}\n  {m['text'][:100]}")

Each row has text, url, the author block, engagement counts, and the analysis fields you opted in to.

Create an audience dataset

audience = client.post(
    "/v1/audience_datasets",
    json={"name": "cold brew creators"},
).raise_for_status().json()["data"]
audience_dataset_id = audience["id"]

Kick off the audience run

audience_run = client.post(
    f"/v1/audience_datasets/{audience_dataset_id}/runs",
    json={
        "source_dataset_id": dataset_id,
        "total_profile_count": 200,
    },
).raise_for_status().json()["data"]
audience_run_id = audience_run["id"]

The audience pipeline reads the source dataset's posts (across every completed run, deduped, top by created_at DESC), walks authors plus commenters, and stops when 200 profiles are collected.

Wait for the audience run

wait_for_run(
    f"/v1/audience_datasets/{audience_dataset_id}/runs/{audience_run_id}",
    interval=15.0,
)

Audience runs are slower than dataset runs because each profile is scraped + LLM-enriched. A 200-profile run typically takes 5–10 minutes.

Read the audience profiles

profiles = client.post(
    "/v1/audience_profiles",
    json={
        "audience_dataset_ids": [audience_dataset_id],
        "sort": "follower_count",
        "order": "desc",
        "limit": 10,
    },
).raise_for_status().json()["data"]

for p in profiles:
    print(
        f"{p['follower_count']:8,}  @{p['handle']:24}  {p['creator_tier']}"
    )

Each row is a creator/commenter profile with platform metadata, audience metrics, and an LLM-derived layer (creator_tier, content_niche, interest_clusters, summary, etc.).

Hand it to the AI assistant

The assistant returns markdown plus a typed references[] list. The turn is asynchronous: the POST returns 202, then you poll until status == "completed".

ask = client.post(
    "/v1/ask",
    json={
        "message": (
            "In this dataset, what are the top three hooks pulling "
            "on Reddit? Cite specific posts."
        ),
        "context": {"dataset_ids": [dataset_id]},
    },
).raise_for_status().json()["data"]

chat_id = ask["chat_id"]
message_id = ask["message_id"]

while True:
    msg = client.get(
        f"/v1/chats/{chat_id}/messages/{message_id}",
    ).raise_for_status().json()["data"]
    if msg["status"] in ("completed", "failed"):
        break
    time.sleep(2)

print(msg["text"])
for ref in msg["references"]:
    print(f"  -> {ref['type']} {ref['id']}")

Citations appear inline in text as [label](post:reddit:t3_...) markdown links. See Reference types for the resolution scheme.

Already wired buzzabout into Claude / Cursor / ChatGPT? Use the MCP path instead — your assistant calls buzzabout__ask directly and you skip the polling boilerplate.

Audience datasets persist independently of the source dataset. Once the audience run completes, the profiles stay accessible even if you later soft-delete the source dataset (though new audience runs can no longer target it).

Next steps

On this page