Skip to main content

Official Python client for the Rephonic podcast API.

Project description

rephonic-python

Official Python client for the Rephonic podcast API. Covers 3+ million podcasts with listener estimates, demographics, contact details, chart rankings, episodes, full transcripts, and more.

Thin, typed wrapper around the Rephonic HTTP API. Ships with a rephonic CLI for shell scripts and AI coding agents. If you want Rephonic inside an AI assistant via Model Context Protocol, use the Rephonic MCP Server.

What you can build with it

  • Enrich a CRM with podcast metadata, listener estimates, and contacts
  • Filter podcasts by audience demographics, topic, or reach, then pull verified contact emails in one pass (good for guest pitching and media lists)
  • Monitor brand mentions by polling search.episodes with a rolling threshold
  • Pull age, gender, education, profession, income, interests, and location breakdowns for any show
  • Grab daily Apple, Spotify, and YouTube chart data across countries and categories
  • Audit sponsorships: who's advertising on which shows, with ad copy and promo codes extracted from transcripts
  • Feed full-text, speaker-labelled transcripts into your own LLM pipeline
  • Power a podcast discovery app: search, autocomplete, audience graph, similar podcasts

Install

pip install rephonic            # SDK (and CLI)
pipx install rephonic           # CLI in an isolated venv (recommended for the CLI)

Python 3.8+.

Command line

pip install rephonic also installs a rephonic command. Every method on the Python client has a CLI equivalent. Authentication is via REPHONIC_API_KEY in the environment. Output is JSON on stdout, structured errors on stderr.

export REPHONIC_API_KEY=your_api_key

# Look up a podcast
rephonic podcasts get huberman-lab | jq '.podcast.name'

# Search with Stripe-style filters
rephonic search podcasts \
  --query "marketing" \
  --filters '{"listeners":{"gte":10000},"active":true}'

# Grab a transcript
rephonic episodes transcript kzaca-huberman-lab-dr-brian-keating-charting-the-a \
  | jq '.transcript.segments[].text'

# Check your quota
rephonic account quota

Exit codes: 0 success, 1 API or network error, 2 usage error (bad flags), 4 authentication error, 5 server error (5xx).

Run rephonic --help for the full command tree, or rephonic <group> --help (e.g. rephonic podcasts --help) for commands inside a group. The six groups match the Python client: search, podcasts, episodes, charts, common, account.

Python quickstart

Grab an API key from rephonic.com/developers.

from rephonic import Rephonic

client = Rephonic(api_key="your_api_key")

# Look up a podcast
podcast = client.podcasts.get("huberman-lab")
print(podcast["podcast"]["name"], podcast["podcast"]["downloads_per_episode"])

# Search for podcasts with filters
results = client.search.podcasts(
    query="artificial intelligence",
    filters={"listeners": {"gte": 10000}, "active": True},
    per_page=25,
)
for p in results["podcasts"]:
    print(p["id"], p["name"])

# Get a full transcript
transcript = client.episodes.transcript("kzaca-huberman-lab-dr-brian-keating-charting-the-a")
for segment in transcript["transcript"]["segments"]:
    print(segment["text"])

The client also picks up REPHONIC_API_KEY from the environment:

import os
os.environ["REPHONIC_API_KEY"] = "your_api_key"

from rephonic import Rephonic
client = Rephonic()

Use it as a context manager to release the HTTP connection pool when you're done:

with Rephonic() as client:
    quota = client.account.quota()

Async

AsyncRephonic has the same surface but returns coroutines. Useful when you want to fan out many calls concurrently (enrichment pipelines, media lists, realtime monitoring).

import asyncio
from rephonic import AsyncRephonic

async def main():
    async with AsyncRephonic(api_key="your_api_key") as client:
        podcast = await client.podcasts.get("huberman-lab")

        # These run concurrently.
        podcast_ids = ["huberman-lab", "the-daily", "lex-fridman-podcast"]
        contacts = await asyncio.gather(
            *(client.podcasts.contacts(pid) for pid in podcast_ids)
        )

        # Auto-paginating async iterator.
        async for p in client.search.iter_podcasts(query="ai", limit=500):
            print(p["name"])

asyncio.run(main())

Resources

The API is organised into six resource groups on the client. For the full method reference see api.md.

Resource Methods
client.search podcasts, iter_podcasts, episodes, iter_episodes, autocomplete
client.podcasts get, people, demographics, promotions, contacts, social, feedback, reviews, trends, similar_graph
client.episodes list, iter_list, get, transcript
client.charts index, rankings
client.common categories, countries, languages, sponsors, professions, interests
client.account quota

Pagination

Search endpoints and episodes.list return one page at a time. Each resource also exposes an iter_* helper that fetches subsequent pages for you:

# Manual paging
page1 = client.search.podcasts(query="ai", per_page=50, page=1)
page2 = client.search.podcasts(query="ai", per_page=50, page=2)

# Auto-paging
for podcast in client.search.iter_podcasts(query="ai", limit=500):
    print(podcast["name"])

Error handling

Every non-2xx response is raised as a subclass of RephonicError:

from rephonic import (
    Rephonic,
    APIConnectionError,
    AuthenticationError,
    BadRequestError,
    RateLimitError,
    InternalServerError,
)

client = Rephonic()

try:
    client.podcasts.get("does-not-exist")
except BadRequestError as exc:
    # Rephonic returns 400 for missing resources too, so inspect exc.message.
    print(exc.status_code, exc.message)
except RateLimitError:
    # Back off and retry later.
    ...
except APIConnectionError:
    # Network-level problem (DNS, timeout, TLS).
    ...

The Rephonic API returns 400 Bad Request for missing resources, not 404. Catch BadRequestError and check .message (e.g. "Podcast not found.", "Unknown episode.") to distinguish them.

The client retries automatically on 429 and 5xx responses with exponential backoff (max_retries=2 by default). Pass max_retries=0 to disable.

Filters

Pass filters as a dict. Booleans are plain values; numeric ops use gte / lte; multi-value ops use any (union) / in (intersection):

client.search.podcasts(
    query="marketing",
    filters={
        "listeners": {"gte": 5000},
        "active": True,
        "categories": {"any": [1482, 1406]},
        "locations": {"any": ["us"]},
        "professions": {"any": ["Doctor", "Lawyer"]},
        "founded": {"gte": 1517270400, "lte": 1589932800},
    },
)

Reserved characters (-, ,, :, \) inside values are escaped automatically, so "Harley-Davidson" just works.

Rephonic's in means the field must contain all of the listed values (intersection), not SQL-style set membership. Use any for OR semantics.

Full list of filters and operators at rephonic.com/developers/search-filters. Use client.common.categories(), countries(), languages(), sponsors(), professions(), and interests() to look up valid IDs.

Other accepted shapes for filters:

# List of raw clauses
filters=["listeners:gte:5000", "active:is:true"]

# Legacy comma-separated string (still supported)
filters="listeners:gte:5000,active:is:true"

Advanced configuration

import httpx
from rephonic import Rephonic, AsyncRephonic

client = Rephonic(
    api_key="...",
    timeout=60.0,
    max_retries=3,
    # Bring your own httpx.Client for proxies, mTLS, custom transports.
    http_client=httpx.Client(
        proxies="http://corp-proxy:8080",
        verify="/path/to/custom-ca.pem",
    ),
)

# For async, pass an httpx.AsyncClient.
async_client = AsyncRephonic(
    api_key="...",
    http_client=httpx.AsyncClient(proxies="http://corp-proxy:8080"),
)

Rate limits and quota

Check your current monthly usage:

client.account.quota()
# {"usage": 292, "quota": 10000}

See rephonic.com/developers for plan details or contact us for higher volume.

Related resources

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rephonic-1.2.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rephonic-1.2.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file rephonic-1.2.0.tar.gz.

File metadata

  • Download URL: rephonic-1.2.0.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for rephonic-1.2.0.tar.gz
Algorithm Hash digest
SHA256 25c55d412f24de4e41fc6a34fa3a8259e57867af76e83dcf33c27decf6521ccd
MD5 024c02b6ab06286a8586a44c681430af
BLAKE2b-256 ee1ef85c1f8881aecc4e3cd63f38f7fde15a5c77a19ee7131604ed01bf1de88f

See more details on using hashes here.

File details

Details for the file rephonic-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: rephonic-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for rephonic-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2a4d65393d442286e9c15961eee4da14adbf9971f2738add27169ccce89a6fb7
MD5 08f51f178a0a7b3aadee8d2e80ded12a
BLAKE2b-256 f666881308ae8c244c5c3b4de0df6fd568177191b75c932aeb6c96bfd3171f38

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page