{
    "openapi": "3.1.0",
    "info": {
        "title": "Pocket Casts Search API",
        "version": "1.0.1",
        "description": "Public search endpoints for podcast search, episode search, and combined search."
    },
    "servers": [
        {
            "url": "https://podcast-api.pocketcasts.com",
            "description": "Pocket Casts Search API"
        }
    ],
    "tags": [
        {
            "name": "Search"
        }
    ],
    "paths": {
        "/discover/search": {
            "post": {
                "tags": ["Search"],
                "summary": "Search podcasts",
                "description": "Returns an array of podcast matches. If `term` is empty, returns an empty array.",
                "operationId": "searchPodcasts",
                "parameters": [
                    {
                        "name": "x-app-language",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Optional app language/locale. When present, this takes precedence over `language` in the request body (e.g. `fr-CA` -> `fr`)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SearchRequest"
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "term": "daily news",
                                        "language": "en"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Podcast search results",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/PodcastSearchResult"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request (missing/invalid JSON body)"
                    }
                }
            }
        },
        "/episode/search": {
            "post": {
                "tags": ["Search"],
                "summary": "Search episodes",
                "description": "Returns episode matches inside `{ \"episodes\": [...] }`. If `term` is empty, returns `{ \"episodes\": [] }`.",
                "operationId": "searchEpisodes",
                "parameters": [
                    {
                        "name": "x-app-language",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Optional app language/locale. When present, this takes precedence over `language` in the request body (e.g. `es-MX` -> `es`)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SearchRequest"
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "term": "open source",
                                        "language": "en"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Episode search results",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EpisodeSearchResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request (missing/invalid JSON body)"
                    }
                }
            }
        },
        "/search/combined": {
            "post": {
                "tags": ["Search"],
                "summary": "Search podcasts and episodes together",
                "description": "Returns mixed podcast and episode results in `{ \"results\": [...] }`, ranked by score. If `term` is empty, returns `{ \"results\": [] }`.",
                "operationId": "searchCombined",
                "parameters": [
                    {
                        "name": "x-app-language",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Optional app language/locale. When present, this takes precedence over `language` in the request body."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SearchRequest"
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "term": "machine learning",
                                        "language": "en"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Combined search results",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CombinedSearchResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request (missing/invalid JSON body)"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "SearchRequest": {
                "type": "object",
                "required": ["term"],
                "properties": {
                    "term": {
                        "type": "string",
                        "description": "Search query text. An empty string is allowed and returns an empty result set."
                    },
                    "language": {
                        "type": "string",
                        "description": "Optional language code. Ignored when `x-app-language` header is provided."
                    }
                },
                "additionalProperties": false
            },
            "PodcastSearchResult": {
                "type": "object",
                "required": ["uuid", "_score"],
                "properties": {
                    "uuid": {
                        "type": "string"
                    },
                    "title": {
                        "type": ["string", "null"]
                    },
                    "author": {
                        "type": ["string", "null"]
                    },
                    "slug": {
                        "type": ["string", "null"]
                    },
                    "_score": {
                        "type": "number"
                    }
                },
                "additionalProperties": false
            },
            "EpisodeSearchResult": {
                "type": "object",
                "required": [
                    "uuid",
                    "title",
                    "published_date",
                    "published",
                    "url",
                    "podcast_uuid",
                    "podcast_title",
                    "podcast_slug",
                    "_score"
                ],
                "properties": {
                    "uuid": {
                        "type": "string"
                    },
                    "title": {
                        "type": "string"
                    },
                    "published_date": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "published": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "duration": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Present when known."
                    },
                    "podcast_uuid": {
                        "type": "string"
                    },
                    "podcast_title": {
                        "type": "string"
                    },
                    "podcast_slug": {
                        "type": "string"
                    },
                    "_score": {
                        "type": "number"
                    }
                },
                "additionalProperties": false
            },
            "EpisodeSearchResponse": {
                "type": "object",
                "required": ["episodes"],
                "properties": {
                    "episodes": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/EpisodeSearchResult"
                        }
                    }
                },
                "additionalProperties": false
            },
            "CombinedPodcastResult": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/PodcastSearchResult"
                    },
                    {
                        "type": "object",
                        "required": ["type", "_weighted_score"],
                        "properties": {
                            "type": {
                                "type": "string",
                                "const": "podcast"
                            },
                            "_weighted_score": {
                                "type": "number"
                            }
                        }
                    }
                ]
            },
            "CombinedEpisodeResult": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/EpisodeSearchResult"
                    },
                    {
                        "type": "object",
                        "required": ["type", "_weighted_score"],
                        "properties": {
                            "type": {
                                "type": "string",
                                "const": "episode"
                            },
                            "_weighted_score": {
                                "type": "number"
                            }
                        }
                    }
                ]
            },
            "CombinedSearchResult": {
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/CombinedPodcastResult"
                    },
                    {
                        "$ref": "#/components/schemas/CombinedEpisodeResult"
                    }
                ],
                "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                        "podcast": "#/components/schemas/CombinedPodcastResult",
                        "episode": "#/components/schemas/CombinedEpisodeResult"
                    }
                }
            },
            "CombinedSearchResponse": {
                "type": "object",
                "required": ["results"],
                "properties": {
                    "results": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/CombinedSearchResult"
                        }
                    }
                },
                "additionalProperties": false
            }
        }
    }
}
