---
openapi: "3.0.3"
info:
  title: LegalScout Public API
  version: "1.0.0"
  description: "Agent-facing LegalScout HTTP API v1. URL path versioning: /api/v1/ (unversioned /api/ aliases remain). Deprecation: operations marked deprecated:true send Deprecation and Sunset headers at least 180 days before removal. Breaking changes ship as /api/v2/. MCP server version 1.3.0. Authenticated product APIs (dashboard, billing, matters) are not part of this public surface."
  contact:
    name: LegalScout
    email: scout@legalscout.ai
    url: "https://legalscout.net/developers"
x-api-versioning:
  strategy: url-path
  current: v1
  header: API-Version
  deprecation: Deprecated operations are flagged in this spec and send HTTP Deprecation + Sunset headers at least 180 days before removal.
servers:
  - url: "https://legalscout.net"
    description: Production origin — use /api/v1/ paths
  - url: "https://www.legalscout.net"
    description: Production www — use /api/v1/ paths
tags:
  - name: Discovery
    description: Machine-readable files for crawlers and agents
  - name: Directory
    description: Public attorney directory
  - name: MCP
    description: Model Context Protocol (Streamable HTTP)
paths:
  /api/health:
    get:
      tags:
        - Discovery
      operationId: getHealth
      summary: Liveness check
      responses:
        200:
          description: Service is up
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatus"
        404:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
        500:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
  /openapi.json:
    get:
      tags:
        - Discovery
      operationId: getOpenApiJson
      summary: OpenAPI 3 specification (JSON)
      responses:
        200:
          description: OpenAPI document
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenApiDocument"
  /api/openapi.yaml:
    get:
      tags:
        - Discovery
      operationId: getOpenApiYaml
      summary: OpenAPI 3 specification (YAML)
      responses:
        200:
          description: OpenAPI document
          content:
            application/yaml:
              schema:
                type: string
  /llms.txt:
    get:
      tags:
        - Discovery
      operationId: getLlmsTxt
      summary: Agent-oriented site index
      responses:
        200:
          description: Plain-text llms.txt
          content:
            text/plain:
              schema:
                type: string
  /sitemap.xml:
    get:
      tags:
        - Discovery
      operationId: getSitemap
      summary: XML sitemap
      responses:
        200:
          description: Sitemap
          content:
            application/xml:
              schema:
                type: string
  /.well-known/mcp.json:
    get:
      tags:
        - MCP
      operationId: getMcpServerCard
      summary: MCP server card (SEP-1649)
      responses:
        200:
          description: MCP server card
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpServerCard"
  /connect:
    get:
      tags:
        - MCP
      operationId: getConnectPage
      summary: Canonical MCP connection details (HTML or markdown via Accept)
      responses:
        200:
          description: Connection details
          content:
            text/html:
              schema:
                type: string
            text/markdown:
              schema:
                type: string
  /find-a-lawyer:
    get:
      tags:
        - Directory
      operationId: getAttorneyDirectory
      summary: Public discovery-enabled attorney directory
      parameters:
        - name: practice
          in: query
          schema:
            type: string
          description: Practice area filter
      responses:
        200:
          description: Directory page
          content:
            text/html:
              schema:
                type: string
            text/markdown:
              schema:
                type: string
  /api/mcp:
    post:
      tags:
        - MCP
      operationId: postMcp
      summary: LegalScout MCP endpoint (Streamable HTTP / JSON-RPC)
      description: "POST JSON-RPC 2.0 messages. Clients should send Accept: application/json, text/event-stream and MCP-Protocol-Version. Public tools work without auth."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/McpJsonRpcRequest"
      responses:
        200:
          description: JSON-RPC result or SSE stream
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpJsonRpcResponse"
            text/event-stream:
              schema:
                type: string
        400:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
        404:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
    get:
      tags:
        - MCP
      operationId: getMcpDiscover
      summary: "Lightweight MCP discovery document (?discover=1)"
      parameters:
        - name: discover
          in: query
          schema:
            type: string
            example: "1"
      responses:
        200:
          description: Discovery JSON when discover=1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpDiscover"
  /api/deprecation:
    get:
      tags:
        - Discovery
      operationId: getDeprecationPolicy
      summary: LegalScout REST versioning and deprecation policy
      responses:
        200:
          description: Deprecation and Sunset policy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeprecationPolicy"
  /developers:
    get:
      tags:
        - Discovery
      operationId: getLegalScoutDeveloperResources
      summary: "LegalScout developer resources (OpenAPI, MCP, auth, webhooks)"
      responses:
        200:
          description: HTML or markdown index of LegalScout developer resources
          content:
            text/html:
              schema:
                type: string
            text/markdown:
              schema:
                type: string
  /features:
    get:
      tags:
        - Discovery
      operationId: getLegalScoutFeatures
      summary: "LegalScout features — AI associates, briefs, matters, and products"
      responses:
        200:
          description: LegalScout product features
          content:
            text/html:
              schema:
                type: string
            text/markdown:
              schema:
                type: string
  /api/v1/health:
    get:
      tags:
        - Discovery
      operationId: getHealthV1
      summary: Liveness check
      responses:
        200:
          description: Service is up
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatus"
        404:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
        500:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
  /api/v1/mcp:
    post:
      tags:
        - MCP
      operationId: postMcpV1
      summary: LegalScout MCP endpoint (Streamable HTTP / JSON-RPC)
      description: "POST JSON-RPC 2.0 messages. Clients should send Accept: application/json, text/event-stream and MCP-Protocol-Version. Public tools work without auth."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/McpJsonRpcRequest"
      responses:
        200:
          description: JSON-RPC result or SSE stream
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpJsonRpcResponse"
            text/event-stream:
              schema:
                type: string
        400:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
        404:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
    get:
      tags:
        - MCP
      operationId: getMcpDiscoverV1
      summary: "Lightweight MCP discovery document (?discover=1)"
      parameters:
        - name: discover
          in: query
          schema:
            type: string
            example: "1"
      responses:
        200:
          description: Discovery JSON when discover=1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpDiscover"
  /api/v1/openapi.yaml:
    get:
      tags:
        - Discovery
      operationId: getOpenApiYamlV1
      summary: OpenAPI 3 specification (YAML)
      responses:
        200:
          description: OpenAPI document
          content:
            application/yaml:
              schema:
                type: string
  /mcp:
    post:
      tags:
        - MCP
      operationId: postMcpShort
      summary: LegalScout MCP endpoint (Streamable HTTP / JSON-RPC)
      description: "POST JSON-RPC 2.0 messages. Clients should send Accept: application/json, text/event-stream and MCP-Protocol-Version. Public tools work without auth."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/McpJsonRpcRequest"
      responses:
        200:
          description: JSON-RPC result or SSE stream
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpJsonRpcResponse"
            text/event-stream:
              schema:
                type: string
        400:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
        404:
          description: Structured JSON error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JsonError"
    get:
      tags:
        - MCP
      operationId: getMcpDiscoverShort
      summary: "Lightweight MCP discovery document (?discover=1)"
      parameters:
        - name: discover
          in: query
          schema:
            type: string
            example: "1"
      responses:
        200:
          description: Discovery JSON when discover=1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/McpDiscover"
components:
  schemas:
    JsonError:
      type: object
      required:
        - error
        - status
      properties:
        error:
          type: object
          required:
            - code
            - message
            - hint
          properties:
            code:
              type: string
              example: NOT_FOUND
            message:
              type: string
            hint:
              type: string
        status:
          type: integer
          example: 404
        path:
          type: string
          nullable: true
        docs:
          type: string
          example: "https://legalscout.net/openapi.json"
    HealthStatus:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - healthy
            - unhealthy
            - ok
        timestamp:
          type: string
          format: date-time
        serverless:
          type: string
        environment:
          type: object
          properties:
            hasVapiKeys:
              type: boolean
            nodeVersion:
              type: string
    OpenApiDocument:
      type: object
      required:
        - openapi
        - info
        - paths
      properties:
        openapi:
          type: string
        info:
          type: object
        paths:
          type: object
    McpJsonRpcRequest:
      type: object
      required:
        - jsonrpc
        - method
      properties:
        jsonrpc:
          type: string
          enum:
            - "2.0"
        id:
          description: Omit for notifications
          oneOf:
            - type: string
            - type: number
            - type: "null"
        method:
          type: string
          example: initialize
        params:
          type: object
          additionalProperties: true
    McpJsonRpcResponse:
      type: object
      required:
        - jsonrpc
      properties:
        jsonrpc:
          type: string
          enum:
            - "2.0"
        id:
          oneOf:
            - type: string
            - type: number
            - type: "null"
        result:
          type: object
          additionalProperties: true
        error:
          type: object
          properties:
            code:
              type: integer
            message:
              type: string
    McpDiscover:
      type: object
      required:
        - name
        - mcp_url
        - transport
      properties:
        name:
          type: string
        version:
          type: string
        transport:
          type: string
        mcp_url:
          type: string
          format: uri
        public_tools:
          type: array
          items:
            type: string
    McpServerCard:
      type: object
      required:
        - serverInfo
        - transport
      properties:
        protocolVersion:
          type: string
        serverInfo:
          type: object
          properties:
            name:
              type: string
            title:
              type: string
            version:
              type: string
        transport:
          type: object
          properties:
            type:
              type: string
            endpoint:
              type: string
        capabilities:
          type: object
    DeprecationPolicy:
      type: object
      required:
        - strategy
        - current
        - notice_days
      properties:
        name:
          type: string
        strategy:
          type: string
        current:
          type: string
        header:
          type: string
        deprecation_header:
          type: string
        sunset_header:
          type: string
        notice_days:
          type: integer
        description:
          type: string
        docs:
          type: string
          format: uri
