{
  "openapi": "3.1.0",
  "info": {
    "title": "BoutiquePulse Public API",
    "version": "1.0.0",
    "description": "Read-only API for the BoutiquePulse knowledge graph: episodes, atomic answers, the boutique retail glossary, and the weekly Boutique Pulse Index. Free, no auth. Data licensed CC BY 4.0 with attribution to BoutiquePulse (https://theboutiquepulse.com/).",
    "contact": {
      "name": "BoutiquePulse",
      "url": "https://theboutiquepulse.com/developers"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://theboutiquepulse.com",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/episodes": {
      "get": {
        "summary": "List published podcast episodes",
        "operationId": "listEpisodes",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of episodes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EpisodeList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/episodes/{number}": {
      "get": {
        "summary": "Get a single episode by episode number",
        "operationId": "getEpisode",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Episode detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EpisodeDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/answers": {
      "get": {
        "summary": "List atomic answer pages",
        "operationId": "listAnswers",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Free-text search across question and answer."
          },
          {
            "name": "topic",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "inventory",
                "shopify",
                "marketing",
                "social",
                "operations",
                "loyalty"
              ]
            }
          },
          {
            "name": "episode",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of answers",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnswerList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/answers/{slug}": {
      "get": {
        "summary": "Get a single answer page by slug",
        "operationId": "getAnswer",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Answer detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnswerDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/glossary": {
      "get": {
        "summary": "List boutique retail glossary terms",
        "operationId": "listGlossary",
        "parameters": [
          {
            "name": "topic",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of glossary terms",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GlossaryList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/glossary/{slug}": {
      "get": {
        "summary": "Get a single glossary term by slug",
        "operationId": "getGlossaryTerm",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Glossary term detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GlossaryDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/index": {
      "get": {
        "summary": "List weekly Boutique Pulse Index entries",
        "operationId": "listPulseIndex",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 52,
              "default": 26
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of weekly entries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PulseIndexList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/index/latest": {
      "get": {
        "summary": "Get the latest published Boutique Pulse Index entry",
        "operationId": "getLatestPulseIndex",
        "responses": {
          "200": {
            "description": "Latest index entry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PulseIndexDetail"
                }
              }
            }
          },
          "404": {
            "description": "No published entries yet"
          }
        }
      }
    },
    "/api/v1/index/{weekId}": {
      "get": {
        "summary": "Get a Boutique Pulse Index entry by ISO week ID (e.g. 2026-W17)",
        "operationId": "getPulseIndex",
        "parameters": [
          {
            "name": "weekId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-W\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Index entry detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PulseIndexDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/topics": {
      "get": {
        "summary": "List the topic taxonomy",
        "operationId": "listTopics",
        "responses": {
          "200": {
            "description": "Topic list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "summary": "Full-text search across glossary, answers, and episodes",
        "operationId": "search",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResults"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "summary": "MCP JSON-RPC 2.0 endpoint exposing five LLM tools (searchEpisodes, getAnswer, getGlossaryTerm, getLatestIndex, getEpisodeTranscript)",
        "operationId": "mcp",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "jsonrpc": {
                    "type": "string"
                  },
                  "id": {},
                  "method": {
                    "type": "string"
                  },
                  "params": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EpisodeSummary": {
        "type": "object",
        "properties": {
          "episode_number": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "angle": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "scheduled_date": {
            "type": "string",
            "format": "date"
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "EpisodeList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EpisodeSummary"
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "EpisodeDetail": {
        "type": "object",
        "properties": {
          "episode_number": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "angle": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "key_topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "action_steps": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "faq": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "answer_pages": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "AnswerSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "question": {
            "type": "string"
          },
          "short_answer": {
            "type": "string"
          },
          "episode_number": {
            "type": "integer",
            "nullable": true
          },
          "topic": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "AnswerList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnswerSummary"
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "AnswerDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "question": {
            "type": "string"
          },
          "short_answer": {
            "type": "string"
          },
          "long_answer": {
            "type": "string"
          },
          "episode_number": {
            "type": "integer",
            "nullable": true
          },
          "topic": {
            "type": "string",
            "nullable": true
          },
          "citation": {
            "type": "object",
            "nullable": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "GlossarySummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "term": {
            "type": "string"
          },
          "short_definition": {
            "type": "string"
          },
          "topic": {
            "type": "string",
            "nullable": true
          },
          "audience": {
            "type": "string",
            "enum": [
              "single_store",
              "multi_location",
              "both"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "GlossaryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GlossarySummary"
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "GlossaryDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "term": {
            "type": "string"
          },
          "short_definition": {
            "type": "string"
          },
          "long_definition": {
            "type": "string"
          },
          "audience": {
            "type": "string",
            "enum": [
              "single_store",
              "multi_location",
              "both"
            ]
          },
          "examples": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "topic": {
            "type": "string",
            "nullable": true
          },
          "related_episode_numbers": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "PulseIndexSummary": {
        "type": "object",
        "properties": {
          "week_id": {
            "type": "string"
          },
          "week_start": {
            "type": "string",
            "format": "date"
          },
          "week_end": {
            "type": "string",
            "format": "date"
          },
          "headline": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "scout_findings_count": {
            "type": "integer"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "PulseIndexList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PulseIndexSummary"
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "PulseIndexDetail": {
        "type": "object",
        "properties": {
          "week_id": {
            "type": "string"
          },
          "week_start": {
            "type": "string",
            "format": "date"
          },
          "week_end": {
            "type": "string",
            "format": "date"
          },
          "headline": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "trending_products": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "platform_changes": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "community_pulse": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "listener_signals": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "bot_traffic_signals": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "scout_findings_count": {
            "type": "integer"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "license": {
            "type": "string",
            "format": "uri"
          },
          "attribution": {
            "type": "string"
          }
        }
      },
      "SearchResults": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "glossary": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GlossarySummary"
            }
          },
          "answers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnswerSummary"
            }
          },
          "episodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EpisodeSummary"
            }
          }
        }
      }
    }
  }
}