Download OpenAPI specification:Download
The Open Podcast Prefix Project is an open-source podcast prefix analytics service committed to open data and listener privacy.
This API serves as an interface to access the data collected in a privacy-preserving way.
Every call to the OP3 API requires a bearer token associated with a valid API Key.
Pass your bearer token either:
Authorization: Bearer mytoken
?token=mytoken
You can also use the sample bearer token preview07ce
to preview API access on this instance.
Perform a query of every request ("hit") logged using the redirect.
This can be used to verify that requests are stored properly in the system.
Results are returned in ascending order by time (plus uuid to break ties for multiple requests in the same millisecond) unless the desc
param is specified.
You can filter by a time range and one additional optional dimension (url
or hashedIpAddress
, which only have data for the last 90 days).
For example, to view hits starting 24 hours ago in json format:
GET https://op3.dev/api/1/hits?start=-24h&format=json&token=preview07ce
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
format | string Default: "tsv" Enum: "tsv" "json" "json-o" "json-a" Output format Defaults to tab-separated text ( |
limit | integer [ 0 .. 1000 ] Default: 100 Maximum number of rows to return |
start | string <ISO 8601 timestamp, date, or relative duration> Example: start=2022-09-15T14:00:52.709Z Filter by start time (inclusive) using a timestamp, date, or relative time (e.g. You can specify either |
startAfter | string <ISO 8601 timestamp, date, or relative duration> Example: startAfter=2022-09-15T14:00:52.709Z Filter by start time (exclusive) using a timestamp, date, or relative time (e.g. You can specify either |
end | string <ISO 8601 timestamp, date, or relative duration> Example: end=2022-09-15T14:00:52.709Z Filter by end time (exclusive) using a timestamp, date, or relative time (e.g. |
url | string <url> Example: url=https://op3.dev/e/example.com/path/to/episode.mp3 Filter by a specific episode url Also supports trailing wildcards, i.e. "starts with" queries. Example: |
hashedIpAddress | 40-character hex Example: hashedIpAddress=a3f1b92bc53ff9512253be45bc9c60047bddad55 Filter by a specific IP address secure hash Raw IP addresses are never stored, only their secure hash, using rotating keys You can specify |
desc | boolean If provided, sorts the results in time-descending order (most recent first) |
{- "rows": [
- {
- "time": "string",
- "uuid": "string",
- "hashedIpAddress": "string",
- "method": "string",
- "url": "string",
- "userAgent": "string",
- "referer": "string",
- "range": "string",
- "xpsId": "string",
- "ulid": "string",
- "edgeColo": "string",
- "continent": "string",
- "country": "string",
- "timezone": "string",
- "regionCode": "string",
- "region": "string",
- "metroCode": "string"
}
], - "count": 0,
- "queryTime": 0
}
Perform a query of show downloads.
Results are returned in ascending order by time.
For example, to view the first ten downloads for show a18389b8a52d4112a782b32f40f73df6
in the month of February 2023 in json format:
showUuid required | string <32-character hex> Example: 3299ee267635404e9cd660088a755b34 Filter by the OP3 show uuid |
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
format | string Default: "tsv" Enum: "tsv" "json" "json-o" "json-a" Output format Defaults to tab-separated text ( |
limit | integer [ 0 .. 20000 ] Default: 100 Maximum number of rows to return |
start | string <ISO 8601 timestamp, date, or relative duration> Example: start=2023-02-23T21:01:45.797Z Filter by start time (inclusive) using a timestamp, date, or relative time (e.g. You can specify either |
startAfter | string <ISO 8601 timestamp, date, or relative duration> Example: startAfter=2023-02-23T21:01:45.797Z Filter by start time (exclusive) using a timestamp, date, or relative time (e.g. You can specify either |
end | string <ISO 8601 timestamp, date, or relative duration> Example: end=2023-02-23T21:01:45.797Z Filter by end time (exclusive) using a timestamp, date, or relative time (e.g. |
episodeId | string <64-character hex> Example: episodeId=6e3c647698c647939f479e6e0b822ec7a2eaa30b4ca5488d8eeb8b08ac22cdf7 Filter by the OP3 episode id |
bots | string Default: "exclude" Enum: "include" "exclude" Whether or not to include downloads from known bots |
skip | string Value: "headers" Whether or not to skip specific response metadata like TSV headers |
continuationToken | string <Opaque token from a prior query response> Continue a prior query if necessary |
{- "rows": [
- {
- "time": "string",
- "url": "string",
- "audienceId": "string",
- "showUuid": "string",
- "episodeId": "string",
- "hashedIpAddress": "string",
- "agentType": "string",
- "agentName": "string",
- "deviceType": "string",
- "deviceName": "string",
- "referrerType": "string",
- "referrerName": "string",
- "botType": "string",
- "countryCode": "string",
- "continentCode": "string",
- "regionCode": "string",
- "regionName": "string",
- "timezone": "string",
- "metroCode": "string"
}
], - "count": 0,
- "queryTime": 0,
- "continuationToken": "string"
}
Look up show-level information for a given OP3 show uuid, podcast:guid
or podcast feed url (as urlsafe base-64).
If an HTTP 404 response code is returned, OP3 doesn't know about the show.
Episode information is not included by default, but can be included with episodes=include
.
Example call (without episodes):
GET https://op3.dev/api/1/shows/a18389b8a52d4112a782b32f40f73df6?token=preview07ce
Public show stats pages
The canonical OP3 stats page for the show is returned in the
statsPageUrl
response field, but in general are available athttps://op3.dev/show/<show-uuid-or-podcast-guid>
showUuidOrPodcastGuidOrFeedUrlBase64 required | string <32-character hex, guid, or urlsafe base-64> Example: 3299ee267635404e9cd660088a755b34 A given OP3 show uuid, |
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
episodes | enum Default: "exclude" Enum: "include" "exclude" Whether or not to include episode information as well. |
{- "showUuid": "string",
- "title": "string",
- "podcastGuid": "string",
- "statsPageUrl": "string",
- "episodes": [
- {
- "id": "string",
- "title": "string",
- "pubdate": "string"
}
]
}
List all episodes with podcast:transcript
tags.
Results are returned in reverse chronological order (newest to oldest).
For example, to find the last five episodes with transcripts:
GET https://op3.dev/api/1/queries/recent-episodes-with-transcripts?limit=5&token=preview07ce
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
limit | integer [ 1 .. 100 ] Default: 100 Maximum number of rows to return |
{- "asof": "string",
- "episodes": [
- {
- "pubdate": "string",
- "podcastGuid": "string",
- "episodeItemGuid": "string",
- "hasTranscripts": true,
- "dailyDownloads": { }
}
], - "queryTime": 0
}
List all apps downloading a given show over the last three calendar months.
Results are returned in reverse order (most downloads to fewest).
For example:
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
showUuid | string <32-character hex> Specify the show by OP3 show uuid. Must provide either |
podcastGuid | string <32-character hex> Specify the show by Must provide either |
feedUrlbase64 | string <urlsafe base-64> Specify the show by podcast feed url (as urlsafe base-64). Must provide either |
{- "showUuid": "string",
- "appDownloads": { },
- "queryTime": 0
}
List global app share over the last thirty days.
Results are returned in reverse order (most downloads to fewest).
For example:
GET https://op3.dev/api/1/queries/top-apps?token=preview07ce
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
deviceName | string If specified, constrains the results to a single device (e.g. Device names can be found in the opawg/user-agents-v2 device list. Bear in mind not all user-agents contain enough info to derive the device, so this may be of limited utility. |
userAgent | string If specified, constrains the results to a single device (e.g. Bear in mind not all user-agents contain enough info to derive the device, so this may be of limited utility. |
{- "appShares": { },
- "deviceName": "string",
- "minDate": "string",
- "maxDate": "string",
- "queryTime": 0
}
Get number of monthly downloads (last 30 days) and average weekly downloads over the last four weeks.
Excludes bots. Updated daily.
You can pass in one or more OP3 show uuids, and the results in showDownloadCounts
will be keyed by show, with the following data points for each show:
monthlyDownloads
(number): total number of non-bot downloads for the show in the last 30 daysdays
(string): 30-character string, each character identifying whether (1
) or not (0
) the show had at least one-bot download in each of the last 30 days (ascending in time), useful in determining how to interpret monthlyDownloads
for new showsweeklyAvgDownloads
(number): average number of non-bot downloads per week over the last four weeks (or at least the last few full weeks if new to OP3)weeklyDownloads
([ number, number, number, number]): non-bot downloads per week over the last four weeks (ascending in time)numWeeks
(number): number of recent weeks with full data on OP3, denominator used in weeklyAvgDownloads
. Usually 4
, but can be less for new shows (e.g. 1
if we only have data for the last 10 days)For example:
token | string Pass your bearer token either:
See the Authentication section above for how to obtain a token. |
showUuid required | Array of strings <32-character hex> non-empty unique [ items <32-character hex > ] Specify one or more shows by OP3 show uuid. |
{- "asof": "string",
- "showDownloadCounts": { },
- "queryTime": 0
}