# Podseeker Agent

Podseeker is a podcast data API. Search a curated database of active, contactable podcasts and get verified contacts, host information, booking difficulty, and guest caliber data. Built for automation.

For full response schemas and example JSON, see the API docs: https://app.podseeker.co/api/docs

For runnable endpoint examples, use the public Postman collection: https://www.postman.com/podseeker-3052715/podseeker-public-api/overview

## Authentication

All requests require a Bearer token in the Authorization header:
```
Authorization: Bearer $PODSEEKER_API_KEY
```

If the user doesn't have an API key, they can sign up at https://app.podseeker.co/auth/registration?product=api.

## Endpoints

Base URL: https://app.podseeker.co/api/v1

### 1. Search Podcasts
```
GET /api/v1/podcasts/search
```

Parameters:
- query (string) -search term like "health", "entrepreneurship", "AI"
- active (boolean) -true to filter active podcasts only
- has_guest (boolean) -true to filter podcasts accepting guests
- has_email (boolean) -true to filter podcasts with verified contact emails
- topic (string, repeatable) -filter by topic, e.g. topic=leadership&topic=coaching
- location (string, repeatable) -usa, uk, au, ca, ie, sg, nz, za
- booking_difficulty (string) -very_low, low, medium, high, very_high
- gender_skew (string) -male, female, neutral
- listener (string, repeatable) -filter by listener range: <100, 100-1k, 1k-10k, 10k-100k, 100k-1m, >1m
- sort (string) -listeners_desc, listeners_asc, latest_episode_desc, latest_episode_asc, youtube_subscribers_desc, instagram_followers_desc
- page (integer) -0-99, 50 results per page

Example:
```bash
curl -H "Authorization: Bearer $PODSEEKER_API_KEY" \
  "https://app.podseeker.co/api/v1/podcasts/search?query=entrepreneurship&active=true&has_guest=true&has_email=true"
```

### 2. Get Podcast Details
```
GET /api/v1/podcasts/:id
```

Returns full podcast profile including verified contacts, enriched contacts (if available), website, RSS feed, host bios, guest caliber requirements, and social stats.

The `contacts.enriched_contacts` field is `null` if not enriched, or contains a `people` array with direct contacts (name, role, email, linkedin, contact_confidence).

Example:
```bash
curl -H "Authorization: Bearer $PODSEEKER_API_KEY" \
  "https://app.podseeker.co/api/v1/podcasts/625373"
```

### 3. Enrich Podcast Contacts
```
POST /api/v1/podcasts/:id/enrich
```

Trigger contact enrichment to find direct contacts (hosts, producers, bookers) with emails. Costs 10 credits. Takes 60-120 seconds. If the enrichment fails or finds no contacts, the 10 credits are automatically refunded. A successful enrichment enters a 30-day cooldown - re-enriching the same podcast before it expires returns a 429.

```bash
curl -X POST -H "Authorization: Bearer $PODSEEKER_API_KEY" \
  "https://app.podseeker.co/api/v1/podcasts/625373/enrich"
```

### 4. Check Enrichment Status
```
GET /api/v1/enrichments/:enrichment_id
```

Poll for enrichment completion. Free, no credit cost. Returns `processing`, `completed`, or `failed`. The response includes a `note` when no contacts were found or the run failed, confirming the 10 credits were refunded.

```bash
curl -H "Authorization: Bearer $PODSEEKER_API_KEY" \
  "https://app.podseeker.co/api/v1/enrichments/enr_123"
```

### 5. Check Usage
```
GET /api/v1/usage
```

Get the current credit balance on demand. Free, no credit cost, strongly consistent (reads the committed ledger). Returns `credits_used`, `credits_included`, `credits_remaining`, `overage_credits`, `overage_charge`, `plan`, `status` (active/trialing), and `period_end` (on a paid plan, when monthly credits reset; null during a trial, since trial credits are a fixed allotment with no scheduled reset). Prefer this over reading the balance off another call's headers.

```bash
curl -H "Authorization: Bearer $PODSEEKER_API_KEY" \
  "https://app.podseeker.co/api/v1/usage"
```

## Workflow

1. **Ask about their topic/niche** if not already clear from context.
2. **Search with filters based on user intent.** No default filters -start broad, then narrow. Apply filters when context calls for them:
   - `has_email=true` when the user needs contact info for outreach
   - `has_guest=true` when the user wants to pitch themselves or others as guests
   - `active=true` only when they want currently-publishing shows
   - `topic`, `location`, `booking_difficulty`, `listener` when specified
3. **Present the shortlist and stop.** Show title, listeners, booking difficulty. Do NOT call /podcasts/:id yet -wait for the user to confirm which podcasts to pursue. Each API call costs 1 credit.
4. **Get details only for confirmed podcasts** -fetch host names, emails, and guest caliber info.
5. **Check enriched_contacts** -if `null`, ask the user if they want to enrich (10 credits). If enriched, use the people array for direct contacts.
6. **Enrich if requested** -POST /podcasts/:id/enrich, then poll GET /enrichments/:id until completed, then re-fetch the podcast.
7. **Hand off contacts and host info to the user.** Pitch drafting and sending is outside this API's scope.

## Key Concepts

- **Booking difficulty**: low = easier to book, high = competitive/selective.
- **Guest caliber**: Shows what kind of guests the podcast typically books. Use this to assess fit.
- **Estimated listeners**: This is an estimate per episode, not exact. Use it for relative sizing, not absolute numbers.
- **Credits**: Search and detail calls cost 1 credit. Enrichment costs 10 credits (auto-refunded if it fails or finds no contacts). 2,000/month included (100 free on trial). Check X-Credits-Remaining in response headers, or GET /api/v1/usage for an authoritative balance.
- **Enriched contacts**: Direct contacts (hosts, producers, bookers) with emails found via automated research. contact_confidence: very_high, high, medium, low, very_low.

## Enrichment Flow

The `enriched_contacts` field in GET /podcasts/:id tells you the state:

- `null` -never enriched. Call POST /podcasts/:id/enrich to trigger (10 credits).
- `{"status": "enriching", "estimated_seconds": 120}` -currently processing. Poll GET /enrichments/:enrichment_id (free, no credit cost) every 15-30 seconds until status is "completed".
- `{"last_updated_at": "2026-05-22", "people": [...]}` -enriched and ready. Check last_updated_at to decide if re-enrichment is needed. Call POST /enrich again to refresh (costs 10 credits each time).

After polling returns "completed", re-fetch GET /podcasts/:id (1 credit) to get the enriched contacts in the response.

Enrichment takes 60-120 seconds. Do not call POST /enrich multiple times for the same podcast -the system prevents duplicate enrichments.

## Rate Limits

60 requests per minute. If you get a 429, wait 60 seconds before retrying.

## Errors

- 401: Invalid API key
- 403: API key is inactive or revoked
- 402: Credits exhausted, or API subscription inactive (reactivate the plan)
- 404: Podcast not found
- 429: Rate limited
