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:
- Create a dataset and trigger a Reddit run.
- Wait for it to complete.
- Create an audience dataset, kick off a profile-collection run from the source dataset, and wait for it.
- Read the audience profiles.
- (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 httpximport 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
- API / Datasets — the full parameter reference for the dataset run.
- API / Mentions — every filter and sort option for the mentions read.
- MCP / Tools reference — every tool the host
LLM can call, including
buzzabout__ask.