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