# MANUAL-SYNC: the firm counts in this spec (e.g. 23,512 / 16,923 / 6,589) are NOT
# auto-injected (scripts/sync-static-counts.ts deliberately skips YAML — anchors corrupt
# structured specs). On a data bake, update them by hand from public/data/sec-data-meta.json.
openapi: "3.1.0"
info:
  title: Synseus Intelligence API
  description: Public API for RIA practice intelligence, valuation, and succession signal detection — built on SEC IAPD filings and extracted SEC ADV Part 2 brochure data. No authentication required.
  version: "1.0.0"
  contact:
    email: api@synseus.com
  license:
    name: Proprietary
    url: https://synseus.com/terms
servers:
  - url: https://synseus.com

paths:

  /api/public/firm-audit:
    get:
      operationId: getFirmAudit
      security: []
      summary: Look up an RIA firm and get a practice vulnerability audit
      description: Searches 23,512 advisory firms (16,923 SEC-registered RIAs and 6,589 ERA exempt reporting advisers) by name or CRD number. Returns a coarse succession-risk band (insufficient/limited/moderate/elevated, higher = more vulnerable), succession signal count, revenue leakage estimate range, and local acquisition target count. The precise risk score, signal names, reasoning, and target firm names are withheld — only the band and counts are returned.
      parameters:
        - name: query
          in: query
          required: true
          description: Firm name (partial, case-insensitive) or CRD number (digits only for exact match)
          schema:
            type: string
            maxLength: 100
      responses:
        "200":
          description: Firm found
          content:
            application/json:
              schema:
                type: object
                required: [firmName, vulnerabilityBand, signalCount, revenueLeakage, localTargetCount]
                properties:
                  firmName:
                    type: string
                  vulnerabilityBand:
                    type: string
                    enum: [insufficient, limited, moderate, elevated]
                    description: >-
                      Coarse public succession-risk band, higher = more vulnerable
                      (insufficient → limited → moderate → elevated). Derived from public
                      Form ADV firmographics (tenure, AUM band, solo practice); the precise
                      score is withheld. 'insufficient' = no firmographic basis to assess.
                  signalCount:
                    type: integer
                    description: Number of succession signals detected
                  revenueLeakage:
                    type: object
                    properties:
                      low:
                        type: number
                        description: Low estimate of annual revenue leakage in dollars
                      high:
                        type: number
                        description: High estimate of annual revenue leakage in dollars
                  localTargetCount:
                    type: integer
                    description: Number of acquisition-ready practices within 50 miles
        "400":
          description: Missing query parameter
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "404":
          description: Firm not found in database
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "429":
          description: Rate limit exceeded (60 requests per minute per IP)

  /api/public/practice-valuation:
    get:
      operationId: getPracticeValuation
      security: []
      summary: Calculate RIA practice value using four-method weighted average
      description: Returns a valuation range using Revenue Multiple (30% weight), EBITDA Multiple (40%), DCF Analysis (20%), and Client Value (10%). Benchmarked against 23,512 registered advisory firms. All parameters are optional with sensible defaults.
      parameters:
        - name: arr
          in: query
          description: Annual recurring revenue in dollars (default 500000)
          schema:
            type: number
            minimum: 0
        - name: retention
          in: query
          description: Client retention rate 0-100 (default 95)
          schema:
            type: number
            minimum: 0
            maximum: 100
        - name: margin
          in: query
          description: Profit margin percentage 0-100 (default 40)
          schema:
            type: number
            minimum: 0
            maximum: 100
        - name: tenure
          in: query
          description: Years in business (default 9)
          schema:
            type: number
            minimum: 0
      responses:
        "200":
          description: Valuation calculated
          content:
            application/json:
              schema:
                type: object
                required: [lowRange, highRange, weightedAverage, revenueMultiple, ebitdaMultiple, interpretation]
                properties:
                  lowRange:
                    type: number
                    description: Low end of valuation range in dollars
                  highRange:
                    type: number
                    description: High end of valuation range in dollars
                  weightedAverage:
                    type: number
                    description: Blended weighted average valuation in dollars
                  revenueMultiple:
                    type: number
                    description: Revenue multiple applied (e.g. 2.1)
                  ebitdaMultiple:
                    type: number
                    description: EBITDA multiple applied (e.g. 5.0)
                  interpretation:
                    type: string
                    description: Plain-language interpretation of the valuation result
        "400":
          description: Invalid numeric parameters
        "429":
          description: Rate limit exceeded

  /api/public/archetype-assessment:
    get:
      operationId: getArchetypeAssessment
      security: []
      summary: Get the 5-question advisor archetype assessment
      description: Returns the five assessment questions with answer options, and all five advisor archetype profiles. Score each answer +1 to the matching archetypeKey. The archetype with the highest score is the advisor's primary archetype.
      responses:
        "200":
          description: Assessment data returned
          content:
            application/json:
              schema:
                type: object
                properties:
                  questions:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        text:
                          type: string
                        options:
                          type: array
                          items:
                            type: object
                            properties:
                              label:
                                type: string
                              archetypeKey:
                                type: string
                  archetypes:
                    type: object
                    additionalProperties:
                      type: object
                      properties:
                        label:
                          type: string
                        tagline:
                          type: string
                        pitch:
                          type: string
                        topModules:
                          type: array
                          items:
                            type: integer
        "429":
          description: Rate limit exceeded

  /api/public/succession-signals:
    get:
      operationId: getSuccessionSignals
      security: []
      summary: Get aggregated succession signal counts for a geographic area
      description: Returns counts of 7 succession signal types detected across registered advisory firms within the specified radius. Only aggregate counts are returned — no firm names, CRD numbers, or identifying information.
      parameters:
        - name: lat
          in: query
          required: true
          description: Latitude of center point (-90 to 90)
          schema:
            type: number
        - name: lng
          in: query
          required: true
          description: Longitude of center point (-180 to 180)
          schema:
            type: number
        - name: radius_miles
          in: query
          description: Search radius in miles (default 50)
          schema:
            type: number
            minimum: 1
            maximum: 200
      responses:
        "200":
          description: Signal counts returned
          content:
            application/json:
              schema:
                type: object
                properties:
                  firms_analyzed:
                    type: integer
                  radius_miles:
                    type: number
                  signals:
                    type: object
                    properties:
                      NO_SUCCESSION:
                        type: integer
                      LONG_TENURED:
                        type: integer
                      RETIREMENT_PROXIMITY:
                        type: integer
                      REGISTRATION_GAP:
                        type: integer
                      SOLO_PRACTICE:
                        type: integer
                      AUM_TRANSITION_RANGE:
                        type: integer
                      MULTI_STATE_LICENSED:
                        type: integer
                  total_succession_signals:
                    type: integer
        "400":
          description: Missing or invalid lat/lng parameters
        "429":
          description: Rate limit exceeded

  /api/public/platform-stats:
    get:
      operationId: getPlatformStats
      security: []
      summary: Get Synseus platform statistics
      description: Returns current platform statistics including tool count, module count, SEC firm database size, and reported outcome metrics.
      responses:
        "200":
          description: Platform statistics
          content:
            application/json:
              schema:
                type: object
                properties:
                  tools:
                    type: integer
                  modules:
                    type: integer
                  sec_firms:
                    type: object
                    description: SEC IAPD firm universe, derived from the canonical data feed (never hardcoded).
                    properties:
                      firmCount:
                        type: integer
                        description: Total searchable firm universe.
                      secRegistered:
                        type: integer
                        description: SEC-registered RIAs.
                      era:
                        type: integer
                        description: Exempt reporting advisers.
                      asOf:
                        type: string
                        description: Date the firm feed was last refreshed (YYYY-MM-DD).
                  signal_types:
                    type: integer
                  archetypes:
                    type: integer
                  reported_roi:
                    type: string
                  reported_revenue_increase:
                    type: string
                  reported_time_saved:
                    type: string
                  markets:
                    type: array
                    items:
                      type: string
                  integrations:
                    type: integer
        "429":
          description: Rate limit exceeded
