Metadata-Version: 2.4
Name: rephonic
Version: 1.2.1
Summary: Official Python client for the Rephonic podcast API.
Project-URL: Homepage, https://rephonic.com
Project-URL: Documentation, https://rephonic.com/developers
Project-URL: Repository, https://github.com/getrephonic/rephonic-python
Project-URL: Issues, https://github.com/getrephonic/rephonic-python/issues
Author-email: Rephonic <support@rephonic.com>
License: MIT License
        
        Copyright (c) 2026 Rephonic
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api,charts,demographics,podcast,podcasts,rephonic,sdk,transcripts
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: httpx<1,>=0.24
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: mypy>=1.5; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=4; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Description-Content-Type: text/markdown

# rephonic-python

Official Python client for the [Rephonic](https://rephonic.com) 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](https://rephonic.com/developers). Ships with a [`rephonic` CLI](#command-line) for shell scripts and AI coding agents. If you want Rephonic inside an AI assistant via Model Context Protocol, use the [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp).

## 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

```bash
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.

```bash
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`.

### Agent skills

The repo also ships [Agent Skills](https://agentskills.io/) for common workflows (setup, search with filters, contact enrichment, similar-podcast discovery, transcript pulls). Install them into your agent's skills directory with the [`skills`](https://skills.sh) CLI:

```bash
npx skills add getrephonic/rephonic-python
```

Auto-detects Claude Code, Cursor, Copilot, Gemini CLI, Goose, and ~40 other agents.

## Python quickstart

Grab an API key from [rephonic.com/developers](https://rephonic.com/developers).

```python
from rephonic import Rephonic

client = Rephonic(api_key="your_api_key")

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

# ... or by an external identifier (Apple, Spotify, YouTube, RSS)
match = client.podcasts.lookup(itunes_id=1545953110)
slug = match["podcasts"][0]["id"] if match["podcasts"] else None

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

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

```python
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).

```python
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](./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:

```python
# 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`:

```python
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):

```python
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](https://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`:

```python
# 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

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

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

See [rephonic.com/developers](https://rephonic.com/developers#pricing) for plan details or [contact us](https://rephonic.com/contact) for higher volume.

## Related resources

- [Rephonic API docs](https://rephonic.com/developers)
- [Markdown API reference for LLMs](https://rephonic.com/llms-full.txt) (feed to any model to generate integration code)
- [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp) for Claude, ChatGPT, and Cursor
- [rephonic.com](https://rephonic.com)

## License

[MIT](./LICENSE)
