openapi: 3.1.0
info:
  title: Ensemble API
  version: 2.0.0
  description: |
    Agent-native design system engine. 11 interconnected tools that generate complete, 
    production-ready design systems from a single hex color. Pure computation — no AI, 
    no external dependencies, deterministic output.
  contact:
    name: HearthByte
    url: https://hearthbyte.dev
  license:
    name: Proprietary
    url: https://hearthbyte.dev/terms

servers:
  - url: https://api.ensemble.hearthbyte.dev
    description: Production

security:
  - BearerAuth: []

tags:
  - name: Design System
    description: Full pipeline generation
  - name: Tools
    description: Individual tool endpoints
  - name: Utility
    description: Health and usage

paths:
  /v2/design-system:
    post:
      tags: [Design System]
      summary: Generate complete design system
      description: |
        Run the full tool chain. One hex color in, complete design system out.
        Returns 15 top-level keys: colors, typography, spacing, shadows, grid, 
        animations, accessibility, dark_mode, components, icons, exports.
      operationId: generateDesignSystem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DesignSystemRequest'
      responses:
        '200':
          description: Complete design system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignSystemResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/harmony:
    post:
      tags: [Tools]
      summary: Color palette generator
      description: |
        Generate an 11-stop shade scale palette in OKLCH perceptual color space.
        Primary, secondary, accent, neutral, and semantic colors.
      operationId: harmony
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Color palette
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HarmonyResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/duet:
    post:
      tags: [Tools]
      summary: Font pairing
      description: |
        Curated font pairing selection with type scale generation. 
        15+ pairings, database-driven.
      operationId: duet
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Typography system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DuetResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/pitch:
    post:
      tags: [Tools]
      summary: Contrast validation
      description: |
        WCAG 2.1 contrast validation. Single pair mode or full palette audit.
      operationId: pitch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/PitchPairRequest'
                - $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Accessibility audit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PitchResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/tempo:
    post:
      tags: [Tools]
      summary: Spacing system
      description: |
        Spacing system based on density preference. Generates a scale from 0 to 16.
      operationId: tempo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Spacing scale
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TempoResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/chord:
    post:
      tags: [Tools]
      summary: Shadows and elevation
      description: |
        Shadow and elevation system. Flat to dramatic, tinted by palette.
      operationId: chord
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Shadow system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChordResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/cadence:
    post:
      tags: [Tools]
      summary: Grid system
      description: |
        Grid, breakpoint, and column system. Responsive-ready.
      operationId: cadence
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Grid system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CadenceResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/riff:
    post:
      tags: [Tools]
      summary: Animation timing
      description: |
        Animation timing, easing curves, and motion presets. CSS-native cubic-bezier.
      operationId: riff
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Animation system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RiffResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/bridge:
    post:
      tags: [Tools]
      summary: Dark mode transformation
      description: |
        Complete dark mode transformation. Inverts palette, adjusts shadows, 
        recalculates contrast. Requires Pro.
      operationId: bridge
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Dark mode tokens
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BridgeResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/motif:
    post:
      tags: [Tools]
      summary: Component patterns
      description: |
        Component patterns generated from your tokens. Buttons, cards, inputs, 
        badges, alerts, modals, navigation. Requires Pro.
      operationId: motif
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Component patterns
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MotifResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/score:
    post:
      tags: [Tools]
      summary: Icon recommendations
      description: |
        Icon library recommendations based on your design style. Requires Pro.
      operationId: score
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SeedRequest'
      responses:
        '200':
          description: Icon recommendations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScoreResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/tools/compose:
    post:
      tags: [Tools]
      summary: Export design system
      description: |
        Export design system as CSS custom properties, JSON tokens, 
        Tailwind config, or SCSS variables.
      operationId: compose
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComposeRequest'
      responses:
        '200':
          description: Exported design system
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComposeResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /v2/health:
    get:
      tags: [Utility]
      summary: Service health
      description: Service status. No auth required.
      operationId: health
      security: []
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  version:
                    type: string
                    example: 2.0.0

  /v2/usage:
    get:
      tags: [Utility]
      summary: Usage stats
      description: Current usage stats for your API key.
      operationId: usage
      responses:
        '200':
          description: Usage statistics
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        API key types:
        - `ens_live_*` - Server keys (full access)
        - `ens_pub_*` - Client keys (origin-locked, 50% rate limits)
        - `ens_test_*` - Test keys (demo endpoint only)

  schemas:
    DesignSystemRequest:
      type: object
      required: [seed]
      properties:
        seed:
          $ref: '#/components/schemas/Seed'
        formats:
          type: array
          items:
            $ref: '#/components/schemas/ExportFormat'
          default: [css, json]

    Seed:
      type: object
      required: [colors]
      properties:
        colors:
          type: array
          items:
            type: string
            pattern: '^#[0-9A-Fa-f]{6}$'
          minItems: 1
          maxItems: 5
          description: 1-5 hex colors
          example: ['#3B82F6']
        mood:
          type: string
          enum: [professional, playful, bold, calm, warm, cool]
        industry:
          type: string
          enum: [healthcare, fintech, saas, ecommerce, creative, education, nonprofit, entertainment]
        preferences:
          $ref: '#/components/schemas/Preferences'
        accessibility:
          $ref: '#/components/schemas/AccessibilityConfig'

    Preferences:
      type: object
      properties:
        color_scheme:
          type: string
          enum: [monochromatic, analogous, complementary, triadic, split-complementary]
          default: analogous
        type_style:
          type: string
          enum: [modern, classical, minimalist, expressive]
          default: modern
        density:
          type: string
          enum: [compact, balanced, airy]
          default: balanced
        corners:
          type: string
          enum: [sharp, rounded, pill]
          default: rounded
        shadow_intensity:
          type: string
          enum: [flat, subtle, pronounced, dramatic]
          default: subtle
        animation_style:
          type: string
          enum: [none, minimal, fluid, energetic]
          default: minimal
        dark_mode:
          type: boolean
          default: true

    AccessibilityConfig:
      type: object
      properties:
        wcag_level:
          type: string
          enum: [AA, AAA]
          default: AA
        min_contrast:
          type: number
          minimum: 1
          maximum: 21
          default: 4.5

    SeedRequest:
      type: object
      required: [seed]
      properties:
        seed:
          $ref: '#/components/schemas/Seed'

    PitchPairRequest:
      type: object
      required: [foreground, background]
      properties:
        foreground:
          type: string
          pattern: '^#[0-9A-Fa-f]{6}$'
          example: '#3B82F6'
        background:
          type: string
          pattern: '^#[0-9A-Fa-f]{6}$'
          example: '#FFFFFF'

    ComposeRequest:
      type: object
      required: [seed, formats]
      properties:
        seed:
          $ref: '#/components/schemas/Seed'
        formats:
          type: array
          items:
            $ref: '#/components/schemas/ExportFormat'

    ExportFormat:
      type: string
      enum: [css, json, tailwind, scss]

    DesignSystemResponse:
      type: object
      properties:
        colors:
          type: object
        typography:
          type: object
        spacing:
          type: object
        shadows:
          type: object
        grid:
          type: object
        animations:
          type: object
        accessibility:
          type: object
        dark_mode:
          type: object
        components:
          type: object
        icons:
          type: object
        exports:
          type: object

    HarmonyResponse:
      type: object
      properties:
        colors:
          type: object
          properties:
            primary:
              $ref: '#/components/schemas/ColorScale'
            secondary:
              $ref: '#/components/schemas/ColorScale'
            accent:
              $ref: '#/components/schemas/ColorScale'
            neutral:
              $ref: '#/components/schemas/ColorScale'
            semantic:
              type: object
              properties:
                success:
                  $ref: '#/components/schemas/ColorScale'
                warning:
                  $ref: '#/components/schemas/ColorScale'
                error:
                  $ref: '#/components/schemas/ColorScale'
                info:
                  $ref: '#/components/schemas/ColorScale'

    ColorScale:
      type: object
      description: 11-stop shade scale (50-950)
      additionalProperties:
        type: string

    DuetResponse:
      type: object
      properties:
        typography:
          type: object
          properties:
            heading:
              type: string
            body:
              type: string
            mono:
              type: string
            scale:
              type: object

    PitchResponse:
      type: object
      properties:
        accessibility:
          type: object
          properties:
            passed:
              type: integer
            failed:
              type: integer
            matrix:
              type: array
              items:
                type: object
            failures:
              type: array
              items:
                type: object

    TempoResponse:
      type: object
      properties:
        spacing:
          type: object
          properties:
            base:
              type: number
            scale:
              type: object

    ChordResponse:
      type: object
      properties:
        shadows:
          type: object
          properties:
            xs:
              type: string
            sm:
              type: string
            md:
              type: string
            lg:
              type: string
            xl:
              type: string
            2xl:
              type: string
            focus:
              type: string
            glow:
              type: string

    CadenceResponse:
      type: object
      properties:
        grid:
          type: object
          properties:
            breakpoints:
              type: object
            columns:
              type: object
            containers:
              type: object
            gutters:
              type: object

    RiffResponse:
      type: object
      properties:
        animations:
          type: object
          properties:
            durations:
              type: object
            easings:
              type: object
            presets:
              type: object

    BridgeResponse:
      type: object
      properties:
        dark_mode:
          type: object
          properties:
            colors:
              type: object
            shadows:
              type: object
            accessibility:
              type: object

    MotifResponse:
      type: object
      properties:
        components:
          type: object
          properties:
            button:
              type: object
            card:
              type: object
            input:
              type: object
            badge:
              type: object
            alert:
              type: object
            modal:
              type: object
            navigation:
              type: object

    ScoreResponse:
      type: object
      properties:
        icons:
          type: object
          properties:
            library:
              type: string
            install:
              type: string
            sizes:
              type: object
            colors:
              type: object

    ComposeResponse:
      type: object
      properties:
        exports:
          type: object
          additionalProperties:
            type: string

    UsageResponse:
      type: object
      properties:
        tier:
          type: string
          example: pro
        period:
          type: object
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time
        calls:
          type: object
          properties:
            used:
              type: integer
            limit:
              type: integer
            remaining:
              type: integer

    Error:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message, status]
          properties:
            code:
              type: string
              enum:
                - invalid_input
                - missing_dependency
                - unauthorized
                - key_expired
                - tier_required
                - origin_denied
                - not_found
                - rate_limit_exceeded
                - internal_error
            message:
              type: string
            status:
              type: integer

  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_input
              message: seed.colors must have at least one color
              status: 400

    Unauthorized:
      description: Authentication failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Missing or invalid API key
              status: 401

    Forbidden:
      description: Access denied
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: tier_required
              message: This feature requires Pro
              status: 403

    RateLimited:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limit_exceeded
              message: Too many requests
              status: 429
