### OP3 Prefix URL Example
Source: https://github.com/skymethod/op3/blob/master/README.md
This example shows the URL prefix that podcasters or podcast hosting companies can prepend to their podcast episode URLs to participate in the OP3 service and start sending data for analytics. This prefix is the entry point for tracking listener requests.
```url
https://op3.dev/e/
```
--------------------------------
### Example API Response (200 OK)
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Sample JSON structure for a successful API response, including fields like 'asof', 'showDownloadCounts', and 'queryTime'.
```json
{
"asof": "string",
"showDownloadCounts": { },
"queryTime": 0
}
```
--------------------------------
### Example API Response Structure
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Illustrates the structure of a typical JSON response from the OP3 API, including fields like 'asof', 'showDownloadCounts', and 'queryTime'.
```json
{
"asof": "string",
"showDownloadCounts": { },
"queryTime": 0
}
```
--------------------------------
### URL Prefixing for Podcast Enclosures
Source: https://github.com/skymethod/op3/blob/master/worker/static/setup.htm
Demonstrates how skymethod/op3 prefixes podcast enclosure URLs with a base origin, handling different protocols and optional parameters. The `pg` parameter allows specifying a Podcast GUID for attribution.
```APIDOC
URL Prefixing Rules:
This system prefixes podcast enclosure URLs with a base origin, typically in the format `${origin}/e/...`.
1. **HTTPS URLs**:
* **From**: ``
* **To**: ``
2. **HTTP URLs**:
* **From**: ``
* **To**: ``
* Note: Including the full protocol after the prefix is only necessary when the target is `http`.
3. **With Optional `pg` Parameter (Podcast GUID)**:
* Optional arguments are passed as comma-delimited `name=value` pairs between `e` and `/`.
* The `pg` parameter specifies the Podcast GUID for attribution.
* **From**: ``
* **To**: ``
* Example GUID lookup: [Podcast namespace GUID](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid)
```
--------------------------------
### Initialize Redoc Viewer
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
This snippet shows how to get a DOM element and hydrate it with the Redoc viewer using a predefined state object. The state object contains configuration and data for the documentation.
```javascript
var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container);
```
--------------------------------
### Query Top Apps for Show (GET)
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Lists all applications downloading a given show over the last three calendar months. Results are returned in reverse order, from most downloads to fewest. Requires specifying the show by UUID, GUID, or base64 feed URL.
```APIDOC
/queries/top-apps-for-show:
get:
tags:
- queries
summary: Query the top apps for a given show
description: 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:
GET [${ORIGIN}/api/1/queries/top-apps-for-show?showUuid=DEMO_SHOW_UUID_TEMPLATE&token=PREVIEW_TOKEN_TEMPLATE](${ORIGIN}/api/1/queries/top-apps-for-show?showUuid=DEMO_SHOW_UUID_TEMPLATE&token=PREVIEW_TOKEN_TEMPLATE)
operationId: queryTopAppsForShow
parameters:
- name: token
in: query
description: Pass your bearer token either:
- as an authorization header: `Authorization: Bearer mytoken`
- or using this query param: `?token=mytoken`
See the [Authentication](#section/Authentication) section above for how to obtain a token.
required: false
schema:
type: string
- name: showUuid
in: query
description: Specify the show by OP3 show uuid.
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: 32-character hex
- name: podcastGuid
in: query
description: Specify the show by [`podcast:guid`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid).
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: 32-character hex
- name: feedUrlbase64
in: query
description: Specify the show by podcast feed url (as [urlsafe base-64](https://www.base64url.com/)).
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: urlsafe base-64
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/QueryTopAppsForShowResponse"
security:
- bearer_token_or_token_query_param: []
```
--------------------------------
### Query Show Downloads API Endpoint
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
This entry documents the 'Query show downloads' operation for the Skymethod OP3 API. It details the GET request, path parameters, query parameters, and expected response structure for retrieving download data.
```APIDOC
GET /api/1/downloads/show/{showUuid}
Perform a query of show [downloads](${ORIGIN}/download-calculation).
Results are returned in ascending order by time.
Example:
GET ${ORIGIN}/api/1/downloads/show/DEMO_SHOW_UUID_TEMPLATE?start=2023-02&end=2023-03&limit=10&format=json&token=PREVIEW_TOKEN_TEMPLATE
Authorizations:
_bearer_token_or_token_query_param
Path Parameters:
showUuid
required
string <32-character hex>
Example: 3299ee267635404e9cd660088a755b34
Filter by the OP3 show uuid
Query Parameters:
token
string
Pass your bearer token either:
* as an authorization header: `Authorization: Bearer mytoken`
* or using this query param: `?token=mytoken`
See the [Authentication](#section/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 (`tsv`), but also supports a object-based `json` format (aka `json-o`) or a more compact array-based `json-a` format.
limit
integer [ 0 .. 20000 ]
Default: 100
Maximum number of rows to return
start
string
Example: start=2023-02-23T21:01:45.797Z
Filter by start time (inclusive) using a timestamp, date, or relative time (e.g. `-24h`)
You can specify either `start` or `startAfter`, not both
startAfter
string
Example: startAfter=2023-02-23T21:01:45.797Z
Filter by start time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)
You can specify either `start` or `startAfter`, not both
end
string
Example: end=2023-02-23T21:01:45.797Z
Filter by end time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)
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
Continue a prior query if necessary
Responses:
200
successful operation
get/downloads/show/{showUuid}
${ORIGIN}/api/1/downloads/show/{showUuid}
```
```json
{
"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
}
```
--------------------------------
### Query Show Downloads API Endpoint
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
This entry documents the 'Query show downloads' operation for the Skymethod OP3 API. It details the GET request, path parameters, query parameters, and expected response structure for retrieving download data.
```APIDOC
GET /api/1/downloads/show/{showUuid}
Perform a query of show [downloads](${ORIGIN}/download-calculation).
Results are returned in ascending order by time.
Example:
GET ${ORIGIN}/api/1/downloads/show/DEMO_SHOW_UUID_TEMPLATE?start=2023-02&end=2023-03&limit=10&format=json&token=PREVIEW_TOKEN_TEMPLATE
Authorizations:
_bearer_token_or_token_query_param
Path Parameters:
showUuid
required
string <32-character hex>
Example: 3299ee267635404e9cd660088a755b34
Filter by the OP3 show uuid
Query Parameters:
token
string
Pass your bearer token either:
* as an authorization header: `Authorization: Bearer mytoken`
* or using this query param: `?token=mytoken`
See the [Authentication](#section/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 (`tsv`), but also supports a object-based `json` format (aka `json-o`) or a more compact array-based `json-a` format.
limit
integer [ 0 .. 20000 ]
Default: 100
Maximum number of rows to return
start
string
Example: start=2023-02-23T21:01:45.797Z
Filter by start time (inclusive) using a timestamp, date, or relative time (e.g. `-24h`)
You can specify either `start` or `startAfter`, not both
startAfter
string
Example: startAfter=2023-02-23T21:01:45.797Z
Filter by start time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)
You can specify either `start` or `startAfter`, not both
end
string
Example: end=2023-02-23T21:01:45.797Z
Filter by end time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)
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
Continue a prior query if necessary
Responses:
200
successful operation
get/downloads/show/{showUuid}
${ORIGIN}/api/1/downloads/show/{showUuid}
```
```json
{
"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
}
```
--------------------------------
### GET /queries/show-download-counts
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Queries monthly and weekly download counts for one or more shows. Provides total monthly downloads, a 30-day download activity string, average weekly downloads, and weekly download figures. Excludes bots and updates daily.
```APIDOC
GET /queries/show-download-counts
Summary: Query monthly/weekly download counts for one or more shows
Description: 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 days
- `days` (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 shows
- `weeklyAvgDownloads` (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` (array of numbers): 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:
GET ${ORIGIN}/api/1/queries/show-download-counts?showUuid=DEMO_SHOW_UUID_TEMPLATE&token=PREVIEW_TOKEN_TEMPLATE
Parameters:
- token (string, optional): Pass your bearer token either as an authorization header ('Authorization: Bearer mytoken') or using this query param ('?token=mytoken'). See the Authentication section for how to obtain a token.
- showUuid (array of strings, required): Specify one or more shows by OP3 show uuid. Each uuid must be a 32-character hex string. Minimum of 1 item, unique items.
Responses:
200 (successful operation): Returns a QueryShowDownloadCountsResponse object.
Security:
bearer_token_or_token_query_param
```
--------------------------------
### ViewShowResponse Schema
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Defines the structure for a response containing details about a specific podcast show. Includes show identifiers, title, podcast GUID, stats page URL, and an optional list of episodes.
```APIDOC
ViewShowResponse:
description: Response object for viewing show details.
properties:
showUuid:
type: string
description: Unique OP3 uuid for the show (32-character hex).
title:
type: string
description: Title of the show.
podcastGuid:
type: string
description: "[podcast:guid](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid)" associated with the show (guid format).
statsPageUrl:
type: string
description: Canonical public stats page url for the show (url format).
episodes:
type: array
items: { $ref: "#/components/schemas/ViewShowResponse.Episode" }
description: If included, all episodes for the show (from newest to oldest).
required:
- showUuid
- statsPageUrl
```
--------------------------------
### Query Top Apps for Show API
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Lists the top applications downloading a specific show over the last three months. Results are ordered by download count, from most to fewest. Requires specifying the show via UUID, GUID, or feed URL. Authentication is mandatory.
```APIDOC
GET /api/1/queries/top-apps-for-show
Operation ID: queryTopAppsForShow
Summary: Query the top apps for a given show
Description: 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:
GET [${ORIGIN}/api/1/queries/top-apps-for-show?showUuid=DEMO_SHOW_UUID_TEMPLATE&token=PREVIEW_TOKEN_TEMPLATE](${ORIGIN}/api/1/queries/top-apps-for-show?showUuid=DEMO_SHOW_UUID_TEMPLATE&token=PREVIEW_TOKEN_TEMPLATE)
Parameters:
- name: token
in: query
description: Pass your bearer token either:
- as an authorization header: `Authorization: Bearer mytoken`
- or using this query param: `?token=mytoken`
See the [Authentication](#section/Authentication) section above for how to obtain a token.
required: false
schema:
type: string
- name: showUuid
in: query
description: Specify the show by OP3 show uuid.
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: 32-character hex
- name: podcastGuid
in: query
description: Specify the show by [`podcast:guid`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid).
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: 32-character hex
- name: feedUrlbase64
in: query
description: Specify the show by podcast feed url (as [urlsafe base-64](https://www.base64url.com/)).
Must provide either `showUuid`, `podcastGuid` or `feedUrlBase64`.
required: false
schema:
type: string
format: urlsafe base-64
Responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/c
```
--------------------------------
### Get Recent Episodes with Transcripts
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Retrieves a list of recent podcast episodes that have associated transcripts. The response includes metadata like publication date, podcast GUID, episode GUID, and transcript availability.
```APIDOC
GET /api/1/queries/recent-episodes-with-transcripts
Description:
successful operation
Response Sample (200):
Content type: application/json
{
"asof": "string",
"episodes": [
{
"pubdate": "string",
"podcastGuid": "string",
"episodeItemGuid": "string",
"hasTranscripts": true,
"dailyDownloads": { }
}
],
"queryTime": 0
}
```
--------------------------------
### Get Recent Episodes with Transcripts
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Retrieves a list of recent podcast episodes that have associated transcripts. The response includes metadata like publication date, podcast GUID, episode GUID, and transcript availability.
```APIDOC
GET /api/1/queries/recent-episodes-with-transcripts
Description:
successful operation
Response Sample (200):
Content type: application/json
{
"asof": "string",
"episodes": [
{
"pubdate": "string",
"podcastGuid": "string",
"episodeItemGuid": "string",
"hasTranscripts": true,
"dailyDownloads": { }
}
],
"queryTime": 0
}
```
--------------------------------
### View Show Information (GET)
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Retrieves the canonical OP3 stats page for a given show. The stats page URL is provided in the `statsPageUrl` response field. Supports lookup by show UUID, podcast GUID, or base64 encoded feed URL.
```APIDOC
/viewShowInformation:
get:
tags:
- shows
summary: View show stats pages
operationId: viewShowInformation
parameters:
- name: showUuidOrPodcastGuidOrFeedUrlBase64
in: path
description: A given OP3 show uuid, [podcast:guid](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid), or podcast feed url (as [urlsafe base-64](https://www.base64url.com/)).
required: true
schema:
type: string
format: 32-character hex, guid, or urlsafe base-64
example: 3299ee267635404e9cd660088a755b34
- name: token
in: query
description: Pass your bearer token either:
- as an authorization header: `Authorization: Bearer mytoken`
- or using this query param: `?token=mytoken`
See the [Authentication](#section/Authentication) section above for how to obtain a token.
required: false
schema:
type: string
- name: episodes
in: query
description: Whether or not to include episode information as well.
required: false
schema:
type: enum
enum:
- include
- exclude
default: exclude
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/ViewShowResponse"
security:
- bearer_token_or_token_query_param: []
```
--------------------------------
### Redoc State Initialization
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
JavaScript code snippet showing the initialization of the Redoc state, which likely configures the documentation UI, including the API specification URL.
```javascript
const __redoc_state = {
"menu": {
"activeItemIdx": -1
},
"spec": {
"url": "${ORIGIN}/api/docs/swagger.json&instance=prod",
"data": {
"openapi": "3.0.0",
"info": {
"description": "The [Open Podcast Prefix Project](${ORIGIN}) is an open-source [podcast prefix analytics service](https://soundsprofitable.com/update/prefix-analytics) committed to open data and listener privacy.\n\nThis API serves as an interface to access the data collected in a privacy-preserving way.\n\n# Endpoint\n\nBase url for all API calls: `${ORIGIN}/api/1`\n\n# Authentication\n\nEvery call to the OP3 API requires a bearer token associated with a valid API Key.\n\n> [Manage your API Keys and bearer tokens →](/api/keys)\n\nPass your bearer token either: \n - as an authorization header: `Authorization: Bearer mytoken`\n - or using this query param: `?token=mytoken`\n\n\n\nYou can also use the sample bearer token `PREVIEW_TOKEN_TEMPLATE` to preview API access on this instance.",
"version": "API_VERSION_TEMPLATE",
"title": "OP3 API",
"termsOfService": "${ORIGIN}/terms/",
"contact": {
"email": "john@op3.dev"
},
"license": {
"name": "MIT",
"url": "https://github.com/skymethod/op3/blob/master/LICENSE"
}
},
"tags": [
{
"name": "hits",
"description": "Lowest-level log records saved for every prefix redirect processed.\n\nThis is the raw material on which higher-level metrics like [downloads](#tag/downloads) can be [derived](${ORIGIN}/download-calculation)."
}
],
"paths": {
"/hits": {
"get": {
"tags": [
"hits"
],
"summary": "Query hits",
"description": "Perform a query of every request (\"hit\") logged using the redirect.\n\nThis can be used to verify that requests are stored properly in the system.\n\nResults 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.\n\nYou can filter by a time range and one additional optional dimension (\`url\` or \`hashedIpAddress\`, which only have data for the last 90 days).\n\nFor example, to view hits starting 24 hours ago in json format:\n\nGET [${ORIGIN}/api/1/hits?start=-24h&format=json&token=PREVIEW_TOKEN_TEMPLATE](${ORIGIN}/api/1/hits?start=-24h&format=json&token=PREVIEW_TOKEN_TEMPLATE)",
"operationId": "queryHits",
"parameters": [
{
"name": "token",
"in": "query",
"description": "Pass your bearer token either: \n - as an authorization header: `Authorization: Bearer mytoken`\n - or using this query param: `?token=mytoken`\n\nSee the [Authentication](#section/Authentication) section above for how to obtain a token.",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "format",
"in": "query",
"description": "Output format\n\nDefaults to tab-separated text (\`tsv\`), but also supports a object-based \`json\` format (aka \`json-o\`) or a more compact array-based \`json-a\` format.",
"required": false,
"schema": {
"type": "string",
"enum": [
"tsv",
"json",
"json-o",
"json-a"
],
"default": "tsv"
}
},
{
"name": "limit",
"in": "query",
"description": "Maximum number of rows to return",
"required": false,
"schema": {
"type": "integer",
"minimum": 0,
"maximum": 1000,
"default": 100
}
},
{
"name": "start",
"in": "query",
"description": "Filter by start time (inclusive) using a timestamp, date, or relative time (e.g. `-24h`)\n\nYou can specify either `start` or `startAfter`, not both",
"example": "2022-09-15T14:00:52.709Z",
"required": false,
"schema": {
"type": "string",
"format": "ISO 8601 timestamp, date, or relative duration"
}
},
{
"name": "startAfter",
"in": "query",
"description": "Filter by start time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)\n\nYou can specify either `start` or `startAfter`, not both",
"example": "2022-09-15T14:00:52.709Z",
"required": false,
"schema": {
"type": "string",
"format": "ISO 8601 timestamp, date, or relative duration"
}
},
{
"name": "end",
"in": "query",
"description": "Filter by end time (exclusive) using a timestamp, date, or relative time (e.g. `-24h`)",
"example": "2022-09-15T14:00:52.709Z",
"required": false,
"schema": {
"type": "string",
"format": "ISO 8601 timestamp, date, or relative duration"
}
},
{
"name": "url",
"in": "query",
"description": "Filter by a specific episode url\n\nAlso supports trailing wildcards, i.e. \"starts with\" queries.\n\nExample: `url=${ORIGIN}/e/example.com/path/`",
"example": "${ORIGIN}/e/example.com/path/to/episode.mp3",
"required": false,
"schema": {
"type": "string",
"format": "url"
}
},
{
"name": "hashedIpAddress",
"in": "query",
"description": "Filter by a specific IP address secure hash\n\nRaw IP addresses are never stored, only their secure hash, using rotating keys\n\nYou can specify `hashedIpAddress=current` to use the value corresponding to your current IP address",
"example": "a3f1b92bc53ff9512253be45bc9c60047bddad55",
"required": false,
"schema": {
"type": "40-character hex"
}
},
{
"name": "desc",
"in": "query",
"description": "If true, results are returned in descending order by time.",
"required": false,
"schema": {
"type": "boolean"
}
}
]
}
}
}
}
}
}
```
--------------------------------
### QueryRecentEpisodesWithTranscriptsResponse.Episode Schema
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Defines the structure for a single episode in the recent episodes list. Includes publication date, show GUID, episode item GUID, transcript status, and daily download counts.
```APIDOC
QueryRecentEpisodesWithTranscriptsResponse.Episode:
description: Represents a single episode with transcript information.
properties:
pubdate:
type: string
description: Publication time of the episode (ISO 8601 timestamp).
podcastGuid:
type: string
description: The "[podcast:guid](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid)" of the associated show.
episodeItemGuid:
type: string
description: The episode's item-level `` tag value.
hasTranscripts:
type: boolean
description: Whether or not the episode has a "[podcast:transcript](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#transcript)" tag (always true for this query).
dailyDownloads:
type: object
description: Number of downloads (object value) per day (object key) (format: { "yyyy-mm-dd": number }).
additionalProperties: true
required:
- pubdate
- podcastGuid
- episodeItemGuid
- hasTranscripts
- dailyDownloads
```
--------------------------------
### OP3 API Specification (OpenAPI 3.0)
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Comprehensive API documentation for the Open Podcast Prefix Project (OP3), detailing endpoints, authentication, parameters, and response formats. Includes details for querying hits.
```APIDOC
OpenAPI Version: 3.0.0
Info:
Title: OP3 API
Version: API_VERSION_TEMPLATE
Description: The [Open Podcast Prefix Project](${ORIGIN}) is an open-source [podcast prefix analytics service](https://soundsprofitable.com/update/prefix-analytics) committed to open data and listener privacy.
This API serves as an interface to access the data collected in a privacy-preserving way.
Base url for all API calls: `${ORIGIN}/api/1`
Terms of Service: ${ORIGIN}/terms/
Contact: john@op3.dev
License: MIT (https://github.com/skymethod/op3/blob/master/LICENSE)
Authentication:
Requires a bearer token associated with a valid API Key.
Obtain tokens via: /api/keys
Pass token as:
- Authorization header: `Authorization: Bearer mytoken`
- Query parameter: `?token=mytoken`
Preview token available: `PREVIEW_TOKEN_TEMPLATE`
Note: This is a non-production instance and may be redeployed often for testing.
Tags:
- Name: hits
Description: Lowest-level log records saved for every prefix redirect processed. Used to derive higher-level metrics like downloads.
Paths:
/hits:
GET:
Tags: [hits]
Summary: Query hits
OperationId: queryHits
Description: Perform a query of every request ("hit") logged using the redirect. Used to verify data storage. Results are returned in ascending order by time (plus uuid to break ties) unless `desc` is specified. Filter by time range and optionally by `url` or `hashedIpAddress` (data available for last 90 days).
Example Usage:
GET ${ORIGIN}/api/1/hits?start=-24h&format=json&token=PREVIEW_TOKEN_TEMPLATE
Parameters:
token:
Name: token
In: query
Description: Bearer token for authentication. See Authentication section.
Required: false
Schema:
Type: string
format:
Name: format
In: query
Description: Output format. Supports `tsv` (default), `json` (object-based), or `json-a` (array-based).
Required: false
Schema:
Type: string
Enum: [tsv, json, json-o, json-a]
Default: tsv
limit:
Name: limit
In: query
Description: Maximum number of rows to return.
Required: false
Schema:
Type: integer
Minimum: 0
Maximum: 1000
Default: 100
start:
Name: start
In: query
Description: Filter by start time (inclusive). Use timestamp, date, or relative duration (e.g., `-24h`). Specify either `start` or `startAfter`, not both.
Required: false
Schema:
Type: string
Format: ISO 8601 timestamp, date, or relative duration
Example: 2022-09-15T14:00:52.709Z
startAfter:
Name: startAfter
In: query
Description: Filter by start time (exclusive). Use timestamp, date, or relative duration (e.g., `-24h`). Specify either `start` or `startAfter`, not both.
Required: false
Schema:
Type: string
Format: ISO 8601 timestamp, date, or relative duration
Example: 2022-09-15T14:00:52.709Z
end:
Name: end
In: query
Description: Filter by end time (exclusive). Use timestamp, date, or relative duration (e.g., `-24h`).
Required: false
Schema:
Type: string
Format: ISO 8601 timestamp, date, or relative duration
Example: 2022-09-15T14:00:52.709Z
url:
Name: url
In: query
Description: Filter by a specific episode URL. Supports trailing wildcards (e.g., `starts with` queries).
Required: false
Schema:
Type: string
Format: url
Example: ${ORIGIN}/e/example.com/path/to/episode.mp3
hashedIpAddress:
Name: hashedIpAddress
In: query
Description: Filter by a specific IP address secure hash. Raw IPs are not stored. Use `hashedIpAddress=current` to filter by the IP of the current request.
Required: false
Schema:
Type: string
```
--------------------------------
### OP3 API Documentation
Source: https://github.com/skymethod/op3/blob/master/worker/static/home.htm
Access publicly available podcast download metrics, detailed breakdowns, and spreadsheet data exports through the OP3 API. This API provides open data for developers and companies to build services and products related to podcast analytics.
```APIDOC
OP3 API Reference:
Provides access to podcast download metrics and listener data.
Endpoints:
- /api/docs: Documentation for the OP3 API.
- /api/v1/stats: Endpoint for retrieving podcast statistics.
Data Availability:
- Publicly accessible podcast download metrics.
- Detailed breakdowns of listener data.
- Spreadsheet data exports with full history.
Usage:
Developers can integrate with the OP3 API to build applications and services leveraging open podcast data. The API is designed to be auditable and transparent, aligning with OP3's commitment to open data and listener privacy.
Example Data Points (Conceptual):
- Total downloads per episode.
- Geographic distribution of listeners.
- Client application usage.
Note:
Specific endpoint details, request parameters, and response formats are available via the /api/docs link mentioned in the project content.
```
--------------------------------
### CSS for Component Readiness and Transitions
Source: https://github.com/skymethod/op3/blob/master/worker/static/shoelace_common.htm
Defines CSS rules for elements with the '.wait' class, initially hiding them, and then applying opacity and transitions when the '.ready' class is added. This facilitates smooth appearance animations.
```css
.wait {
opacity: 0;
}
.wait.ready {
opacity: 1;
transition: 0.25s opacity;
}
```
--------------------------------
### Query Top Apps for a Show
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Lists the top applications downloading a specific podcast show over the last three calendar months. Results are ordered by download count in descending order. Requires authentication.
```APIDOC
GET /api/1/queries/top-apps-for-show
Description:
Query the top apps for a given show. Lists all apps downloading a given show over the last three calendar months. Results are returned in reverse order (most downloads to fewest).
Authorizations:
bearer_token_or_token_query_param
Query Parameters:
token (string):
Pass your bearer token either as an authorization header (Authorization: Bearer mytoken) or using this query param (?token=mytoken).
See the [Authentication](#section/Authentication) section for how to obtain a token.
showUuid (string <32-character hex>):
Specify the show by OP3 show uuid. Must provide either showUuid, podcastGuid or feedUrlBase64.
podcastGuid (string <32-character hex>):
Specify the show by [podcast:guid](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid).
Must provide either showUuid, podcastGuid or feedUrlBase64.
feedUrlbase64 (string ):
Specify the show by podcast feed url (as [urlsafe base-64](https://www.base64url.com/)).
Must provide either showUuid, podcastGuid or feedUrlBase64.
Response Sample (200):
Content type: application/json
{
"showUuid": "string",
"appDownloads": { },
"queryTime": 0
}
```
--------------------------------
### Query Recent Episodes with Transcripts (GET)
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html_prod.htm
Lists all episodes that include the `podcast:transcript` tag. Results are returned in reverse chronological order (newest to oldest). Supports limiting the number of results.
```APIDOC
/queries/recent-episodes-with-transcripts:
get:
tags:
- queries
summary: Query recent episodes with transcripts
description: List all episodes with [`podcast:transcript`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#transcript) tags.
Results are returned in reverse chronological order (newest to oldest).
For example, to find the last five episodes with transcripts:
GET [${ORIGIN}/api/1/queries/recent-episodes-with-transcripts?limit=5&token=PREVIEW_TOKEN_TEMPLATE](${ORIGIN}/api/1/queries/recent-episodes-with-transcripts?limit=5&token=PREVIEW_TOKEN_TEMPLATE)
operationId: queryRecentEpisodesWithTranscripts
parameters:
- name: token
in: query
description: Pass your bearer token either:
- as an authorization header: `Authorization: Bearer mytoken`
- or using this query param: `?token=mytoken`
See the [Authentication](#section/Authentication) section above for how to obtain a token.
required: false
schema:
type: string
- name: limit
in: query
description: Maximum number of rows to return
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 100
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/QueryRecentEpisodesWithTranscriptsResponse"
security:
- bearer_token_or_token_query_param: []
```
--------------------------------
### QueryRecentEpisodesWithTranscriptsResponse
Source: https://github.com/skymethod/op3/blob/master/worker/static/api_docs_html.htm
Defines the structure for API responses listing recent episodes that include transcript information. Includes a timestamp for data currency and details for each episode, such as publication date, GUIDs, and daily download counts.
```APIDOC
QueryRecentEpisodesWithTranscriptsResponse:
type: object
properties:
asof:
type: string
description: "Data current as of this time, usually the start of the current UTC day"
format: "ISO 8601 timestamp"
episodes:
type: array
items:
$ref: "#/components/schemas/QueryRecentEpisodesWithTranscriptsResponse.Episode"
description: "All episodes using OP3 with a [\`podcast:transcript\`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#transcript) tag, from newest to oldest"
queryTime:
type: integer
description: "Query server processing time, in milliseconds"
required:
- asof
- episodes
- queryTime
QueryRecentEpisodesWithTranscriptsResponse.Episode:
type: object
properties:
pubdate:
type: string
description: "Publication time of the episode"
format: "ISO 8601 timestamp"
podcastGuid:
type: string
description: "The [\`podcast:guid\`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid) of the associated show"
episodeItemGuid:
type: string
description: "The episode's item-level \`\` tag value"
hasTranscripts:
type: boolean
description: "Whether or not the episode has a [\`podcast:transcript\`](https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#transcript) tag (always true for this query)"
dailyDownloads:
type: object
description: "Number of downloads (object value) per day (object key)"
additionalProperties: true
format: "{ \"yyyy-mm-dd\": number }"
required:
- pubdate
- podcastGuid
- episodeItemGuid
- hasTranscripts
- dailyDownloads
```