Python SDK

The official Python SDK wraps the BrightBean REST API. Sync and async clients, typed dataclass responses, every endpoint covered. Requires Python 3.10+.

Install

pip install brightbean

Quickstart (sync)

from brightbean import BrightBean

with BrightBean(api_key="bb_...") as client:
    result = client.score(
        title="10 Tips to Boost Your Coding Productivity",
        thumbnail_url="https://i.ytimg.com/vi/abc123/maxresdefault.jpg",
    )
    print(f"score={result.score:.2f} percentile={result.percentile}")

The constructor reads BRIGHTBEAN_API_KEY from the environment if api_key= is omitted. The context manager closes the underlying HTTP session on exit.

Async

import asyncio
from brightbean import AsyncBrightBean

async def main():
    async with AsyncBrightBean(api_key="bb_...") as client:
        return await client.score(title="My epic video")

asyncio.run(main())

Every method documented below has the same signature on AsyncBrightBean; just await the call.

Methods

Method REST endpoint Cost
client.score(...) POST /v1/score/packaging 1 / 2 / 3 credits
client.video_hook(...) POST /v1/score/video-hook 10 credits
client.benchmark_channel(...) POST /v1/benchmark/channel 5 credits
client.benchmark_video(...) POST /v1/benchmark/video 3 credits
client.niches(...) GET /v1/research/niches 1 credit
client.content_gaps(...) GET /v1/research/content-gaps 5 credits
client.me() GET /v1/me/ free
client.usage() GET /v1/usage/ free

client.score(title=, thumbnail_url=, thumbnail_base64=)

Packaging score (title and/or thumbnail). At least one input is required. The server auto-detects the mode and charges accordingly: 1 credit title-only, 2 thumbnail-only, 3 combined.

Returns PackagingScoreResponse with: score_id, score (0–1), percentile (0–100), raw_score, mode, niche_slug, niche_label, niche_confidence.

client.video_hook(youtube_url=)

Score the first ~6 s of a YouTube video. Returns VideoHookScoreResponse with primary_archetype (one of 13), scores (clarity, specificity, tension, visual_energy, pace — each 0–10), overall_score (0–100), strengths, weaknesses, suggestions, and delta_vs_niche_top. Cost: 10 credits.

client.benchmark_channel(url=)

Channel vs. niche. Returns nested channel and niche objects with engagement percentiles, title patterns, and up to 5 exemplar channels. Cost: 5 credits.

client.benchmark_video(url=)

Single video vs. niche. Returns video and niche objects with engagement percentiles and title patterns. Cost: 3 credits.

client.niches() and client.content_gaps(niche=, gap_type=, limit=, min_score=)

niches() lists every catalogued niche slug with its gap_count. content_gaps(...) returns ranked opportunities for a given niche, optionally filtered by gap_type — any subset of ["underserved", "stale", "competitive"]. Default is ["underserved", "stale"]; competitive is opt-in.

client.me() and client.usage()

me() returns account info and plan details. usage() returns the live credit balance and a recent-activity tail.

Error handling

from brightbean import (
    BrightBean,
    AuthenticationError,
    InsufficientCreditsError,
    RateLimitError,
    ServiceUnavailableError,
)

try:
    with BrightBean() as client:
        client.score(title="…")
except InsufficientCreditsError as e:
    print(f"out of credits: {e}")
except RateLimitError as e:
    print(f"slow down, retry after {e.retry_after}s")
except (AuthenticationError, ServiceUnavailableError) as e:
    print(f"transport/server error: {e}")

All errors carry request_id, status_code, and the parsed error envelope. See Errors for the full taxonomy.

Retries

The sync and async clients retry 429 and 5xx responses up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s, capped at 60s, honouring Retry-After). Disable via retries=0 in the constructor.

Configuration reference

Option Env var Default Notes
api_key BRIGHTBEAN_API_KEY Required.
api_url BRIGHTBEAN_API_URL https://api.brightbean.xyz Override for staging or testing.
timeout 60s Per-request timeout.
retries 5 Set to 0 to disable.