{
  "openapi": "3.1.0",
  "info": {
    "title": "Murmur TTS Website and Agent API",
    "version": "1.0.0",
    "summary": "Machine-readable surface for www.murmurtts.com, the site of Murmur, the on-device voice studio for macOS.",
    "description": "This specification documents every machine-readable endpoint published by the Murmur TTS website (murmurtts.com). Murmur is a native macOS application that generates studio-quality text-to-speech entirely on-device using Apple Silicon.\n\nContent pages additionally support Markdown content negotiation following https://acceptmarkdown.com/: send an `Accept: text/markdown` header on any page URL to receive a clean `text/markdown; charset=utf-8` representation. All negotiated responses carry `Vary: Accept`. Unknown paths return a real HTTP 404 whose body follows the request's Accept header (Markdown, JSON error envelope, or HTML). API endpoints return structured JSON errors with `code`, `message`, and `resolution` fields.",
    "contact": {
      "name": "Murmur TTS",
      "url": "https://www.murmurtts.com/"
    },
    "license": {
      "name": "All rights reserved",
      "url": "https://www.murmurtts.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://www.murmurtts.com",
      "description": "Production website"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Discovery",
      "description": "Machine-readable indexes of the Murmur TTS site"
    },
    {
      "name": "Pages",
      "description": "Human-facing content pages with Markdown negotiation"
    },
    {
      "name": "Agent API",
      "description": "Small JSON API surface for automated clients"
    }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getOpenApiSpec",
        "summary": "This OpenAPI specification",
        "description": "Canonical location of the Murmur TTS OpenAPI document. Also available at /api/openapi.json.",
        "responses": {
          "200": {
            "description": "The OpenAPI document itself",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/openapi.json": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getOpenApiSpecAlias",
        "summary": "OpenAPI specification alias",
        "description": "Byte-identical copy of /openapi.json served from the /api namespace.",
        "responses": {
          "200": {
            "description": "The OpenAPI document itself",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/status.json": {
      "get": {
        "tags": ["Agent API"],
        "operationId": "getStatus",
        "summary": "Service status and resource index",
        "description": "Liveness document listing the machine-readable resources published by Murmur TTS. Responds 406 when the client's Accept header cannot accept application/json, and 405 with a JSON envelope for unsupported methods.",
        "responses": {
          "200": {
            "description": "Service status",
            "headers": {
              "Vary": {
                "description": "Always includes Accept because response selection depends on it.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusDocument"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "406": {
            "description": "Accept header cannot be satisfied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getLlmsTxt",
        "summary": "Agent-facing site summary (llms.txt)",
        "description": "Markdown-formatted overview of Murmur TTS with curated links to product pages, developer docs (CLI and MCP), and this API surface.",
        "responses": {
          "200": {
            "description": "llms.txt document",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getSitemap",
        "summary": "XML sitemap of every indexed URL",
        "responses": {
          "200": {
            "description": "Sitemap XML",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getRobots",
        "summary": "Crawler directives",
        "responses": {
          "200": {
            "description": "robots.txt",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "tags": ["Pages"],
        "operationId": "getHomepage",
        "summary": "Murmur TTS homepage",
        "description": "Product overview page. Supports Markdown content negotiation via the Accept header.",
        "responses": {
          "200": {
            "description": "Homepage in the representation selected by content negotiation",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "description": "Accept header matches neither text/html nor text/markdown",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/{pagePath}": {
      "get": {
        "tags": ["Pages"],
        "operationId": "getContentPage",
        "summary": "Any content page with Markdown negotiation",
        "description": "Serves prerendered HTML to browsers and a clean Markdown twin to agents that send Accept: text/markdown. Valid page paths are enumerated in /sitemap.xml and summarized in /llms.txt (for example /voices, /languages, /samples, /docs/automation, /blog/murmur-vs-elevenlabs). Unknown paths return HTTP 404, never a 200 app shell.",
        "parameters": [
          {
            "name": "pagePath",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "voices": {
                "value": "voices",
                "summary": "Voice library"
              },
              "automationDocs": {
                "value": "docs/automation",
                "summary": "CLI and MCP documentation"
              },
              "blogPost": {
                "value": "blog/murmur-vs-elevenlabs",
                "summary": "A blog article"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page content in the representation selected by content negotiation",
            "headers": {
              "Vary": {
                "description": "Set to Accept when the request participates in Markdown negotiation.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No such page. The body format follows the request's Accept header: Markdown for markdown-preferring agents, a JSON ErrorEnvelope when only application/json is acceptable, otherwise a short HTML page pointing back to llms.txt, sitemap.xml, and openapi.json.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "description": "Accept header matches neither text/html nor text/markdown",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "resolution"],
            "properties": {
              "code": {
                "type": "string",
                "examples": ["not_found", "method_not_allowed", "not_acceptable"]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation of what went wrong."
              },
              "resolution": {
                "type": "string",
                "description": "Actionable hint for fixing the request."
              }
            }
          }
        }
      },
      "StatusDocument": {
        "type": "object",
        "required": ["service", "product", "status", "site", "time", "resources"],
        "properties": {
          "service": {
            "const": "Murmur TTS website"
          },
          "product": {
            "const": "Murmur — on-device voice studio for macOS"
          },
          "status": {
            "const": "ok"
          },
          "site": {
            "type": "string",
            "format": "uri"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          },
          "resources": {
            "type": "object",
            "properties": {
              "openapi": {
                "type": "string",
                "format": "uri-reference"
              },
              "llms": {
                "type": "string",
                "format": "uri-reference"
              },
              "sitemap": {
                "type": "string",
                "format": "uri-reference"
              },
              "robots": {
                "type": "string",
                "format": "uri-reference"
              },
              "developerDocs": {
                "type": "string",
                "format": "uri-reference"
              }
            }
          },
          "contentNegotiation": {
            "type": "object",
            "properties": {
              "protocol": {
                "type": "string",
                "const": "https://acceptmarkdown.com/"
              },
              "usage": {
                "type": "string"
              },
              "cacheVary": {
                "type": "string",
                "const": "Accept"
              }
            }
          }
        }
      }
    }
  },
  "x-murmur-agent-surface": {
    "markdownNegotiation": {
      "protocol": "https://acceptmarkdown.com/",
      "request": "Accept: text/markdown",
      "responseContentType": "text/markdown; charset=utf-8",
      "varyHeader": "Accept",
      "markdownTwinSuffix": ".md",
      "unsupportedTypeBehavior": "406 Not Acceptable with a plain-text list of available representations"
    },
    "notFoundBehavior": "Real HTTP 404 status for unknown paths; body format follows the request Accept header."
  }
}
