{
  "openapi": "3.0.3",
  "info": {
    "title": "Signal Synth API",
    "version": "1.0.0",
    "description": "Quality-ranked scoreboard of learning-focused podcast episodes across 9 categories. Designed for AI agents and developers — every new episode is transcribed, LLM-summarized, and scored on 6 dimensions."
  },
  "servers": [
    {"url": "https://signalsynth.xyz/api/v1"}
  ],
  "paths": {
    "/episodes": {
      "get": {
        "operationId": "queryEpisodes",
        "summary": "Query episodes — returns a ranked list, or a single-episode detail when ?id= is present",
        "description": "Behavior depends on whether the `id` query parameter is set. Without `id`: returns the top-ranked episodes filtered by category/limit/min_score. With `id`: returns full detail for that episode including optional transcript excerpt.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": false,
            "schema": {"type": "string"},
            "description": "If set, return single-episode detail instead of the list."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["all", "tech", "business", "finance", "news", "culture", "science", "health", "education", "sports"]
            }
          },
          {"name": "limit", "in": "query", "schema": {"type": "integer", "default": 20, "maximum": 200}},
          {"name": "min_score", "in": "query", "schema": {"type": "number"}},
          {"name": "include_transcript", "in": "query", "schema": {"type": "boolean", "default": false}, "description": "Only meaningful when `id` is set. Includes the first ~50k chars of the transcript."}
        ],
        "responses": {
          "200": {
            "description": "Ranked list or single-episode detail",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {"$ref": "#/components/schemas/EpisodeListResponse"},
                    {"$ref": "#/components/schemas/EpisodeDetail"}
                  ]
                }
              }
            }
          },
          "404": {"description": "Episode not found (only when ?id= is set)"}
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Episode": {
        "type": "object",
        "properties": {
          "episode_id": {"type": "string"},
          "title": {"type": "string"},
          "podcast": {"type": "string"},
          "podcast_slug": {"type": "string"},
          "category": {"type": "string"},
          "publish_date": {"type": "string", "format": "date-time"},
          "overall_score": {"type": "number"},
          "score_breakdown": {
            "type": "object",
            "properties": {
              "actionability": {"type": "number"},
              "clarity": {"type": "number"},
              "information_density": {"type": "number"},
              "recency_relevance": {"type": "number"},
              "technical_depth": {"type": "number"},
              "originality": {"type": "number"}
            }
          },
          "verdict": {"type": "string", "enum": ["must_listen", "worth_your_time", "skip"]},
          "summary": {"type": "string"},
          "key_takeaways": {"type": "array", "items": {"type": "string"}},
          "best_for": {"type": "array", "items": {"type": "string"}},
          "why_listen": {"type": "string"},
          "audio_url": {"type": "string"},
          "source_link": {"type": "string"},
          "scoring_confidence": {"type": "number"},
          "detail_url": {"type": "string"}
        }
      },
      "EpisodeListResponse": {
        "type": "object",
        "properties": {
          "api_version": {"type": "integer"},
          "snapshot_id": {"type": "string"},
          "generated_at": {"type": "string", "format": "date-time"},
          "category": {"type": "string"},
          "count": {"type": "integer"},
          "episodes": {"type": "array", "items": {"$ref": "#/components/schemas/Episode"}}
        }
      },
      "EpisodeDetail": {
        "type": "object",
        "properties": {
          "api_version": {"type": "integer"},
          "episode_id": {"type": "string"},
          "title": {"type": "string"},
          "podcast": {"type": "string"},
          "podcast_slug": {"type": "string"},
          "category": {"type": "string"},
          "publish_date": {"type": "string", "format": "date-time"},
          "overall_score": {"type": "number"},
          "score_breakdown": {"type": "object"},
          "scoring_confidence": {"type": "number"},
          "summary": {"type": "string"},
          "key_takeaways": {"type": "array", "items": {"type": "string"}},
          "best_for": {"type": "array", "items": {"type": "string"}},
          "why_listen": {"type": "string"},
          "verdict": {"type": "string"},
          "audio_url": {"type": "string"},
          "source_link": {"type": "string"},
          "cover_image_url": {"type": "string"},
          "transcript_available": {"type": "boolean"},
          "transcript_chars": {"type": "integer"},
          "transcript_provider": {"type": "string"},
          "transcript": {"type": "string"}
        }
      }
    }
  }
}
