Quickstart
From an API key to your first search, your first alert and your first signed webhook delivery.
This walks through the Podzone API from a new key to a signed webhook delivery. Each step is one request with curl; the same calls in Python are at the end. Every endpoint links to its entry in the API reference, which lists every parameter, field and error.
1. Create an API key #
In the Podzone app, open API keys and create a key. Copy it when it is shown: the app keeps only its prefix, so it cannot show you the key again.
A new key acts for one team, which is what this guide assumes. Authentication explains account keys, which reach every team in an account.
Keep the key in an environment variable rather than in code:
export PODZONE_API_KEY="pzk_live_..."
2. Check the key #
GET /api/v1/me says which key you are using, the team it acts for, and the account whose limits it counts against:
curl https://api.podzone.fm/api/v1/me \
-H "Authorization: Bearer $PODZONE_API_KEY"
{
"id": "...",
"name": "My integration",
"prefix": "pzk_live_...",
"scope": "team",
"team": { "id": "...", "name": "Marketing" },
"account": { "id": "...", "name": "Acme" }
}
A 401 with the code invalid_credentials means the key is mistyped or has been revoked.
3. Search what was said #
GET /api/v1/episodes/search finds episodes by what was said in them (scope=transcript) or by their titles and descriptions (scope=metadata):
curl -G https://api.podzone.fm/api/v1/episodes/search \
-H "Authorization: Bearer $PODZONE_API_KEY" \
--data-urlencode 'q="brand safety"' \
-d scope=transcript
Quoted words match as a phrase. A search covers the last 30 days unless you pass since, and reaches back up to 18 months. Each result has the episode's id, its podcast, and short excerpts around the match.
To see where in an episode the words were said, ask that episode's transcript with GET /api/v1/episodes/{episode_id}/transcript/excerpts:
curl -G https://api.podzone.fm/api/v1/episodes/EPISODE_ID/transcript/excerpts \
-H "Authorization: Bearer $PODZONE_API_KEY" \
--data-urlencode "q=brand safety"
Each excerpt carries its start and end in seconds from the start of the episode.
4. Create an alert #
An alert watches every new transcript for its keywords. Create one with POST /api/v1/alerts:
curl https://api.podzone.fm/api/v1/alerts \
-H "Authorization: Bearer $PODZONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Our brand", "keywords": ["Acme", "Acme Analytics"]}'
An alert created this way emails nobody: it records its matches, which GET /api/v1/alerts/{alert_id}/matches lists. Add recipient_user_ids to have matches emailed in an hourly digest, or add a webhook to have each one sent to you as it is found.
Keywords so broad that they would match too many episodes a day are refused with a 422 naming keywords.
5. Receive matches by webhook #
A webhook is the URL Podzone POSTs each new match to. Add one with POST /api/v1/webhooks; it must be https on a public host:
curl https://api.podzone.fm/api/v1/webhooks \
-H "Authorization: Bearer $PODZONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/podzone"}'
Save the secret in the response: it is returned only this once, and it is what proves a delivery came from Podzone. Then ask for a test event with POST /api/v1/webhooks/{webhook_id}/test:
curl https://api.podzone.fm/api/v1/webhooks/WEBHOOK_ID/test \
-H "Authorization: Bearer $PODZONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Your endpoint receives a sample match with "test": true. Webhooks shows how to verify its signature, which every receiver should do before trusting a delivery.
The same in Python #
import os
import requests
API = "https://api.podzone.fm/api/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['PODZONE_API_KEY']}"
search = session.get(
f"{API}/episodes/search",
params={"q": '"brand safety"', "scope": "transcript"},
)
search.raise_for_status()
for episode in search.json()["results"]:
print(episode["published_at"], episode["podcast"]["title"], "--", episode["title"])
alert = session.post(f"{API}/alerts", json={"name": "Our brand", "keywords": ["Acme"]})
alert.raise_for_status()
print("Created alert", alert.json()["id"])
Next #
- Authentication: team and account keys, and the
X-Podzone-Teamheader. - Webhooks: the payload, verifying signatures, and retries.
- MCP server: the same data from Claude, Cursor or VS Code.
- The API reference's rate limits, pagination and errors.