openapi: 3.1.0
info:
  title: Whoila API
  version: 0.1.0
  description: Make a blog, jacket, and 6×9 PDF, then publish them to a connected site.
servers:
  - url: https://whoila.com
paths:
  /waitlist:
    post:
      summary: Join the beta waitlist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email: { type: string, format: email }
      responses:
        "201": { description: Queued }
  /v1/make:
    post:
      summary: Compose a piece
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required: [brief]
              properties:
                site: { type: string }
                kind: { type: string, enum: [blog, article, pdf] }
                brief: { type: string }
                title: { type: string }
                publish: { type: boolean }
                formats:
                  type: array
                  items: { type: string, enum: [pdf, html, png] }
                wait: { type: boolean }
      responses:
        "200": { description: Finished }
        "202": { description: Queued }
  /v1/jobs/{id}:
    get:
      summary: Job status + artifact URLs
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
  /v1/jobs/{id}/publish:
    post:
      summary: Push article, thumbnail, and PDF
  /v1/widgets:
    get:
      summary: DesignForever journal widget catalog
      description: |
        Lists the 10 journal widget kinds Whoila can render via DesignForever when
        VAE_SERVICE_KEY is configured: hbarChart, pieChart, dotTimeline, chart,
        quoteCard, factSheet, table, linearTimeline, colorType, imageGrid.
        Widgets are optional (0–2 typical). Use only when data in the brief clarifies
        scanning — pieChart for % splits, hbarChart for ranked comparisons, etc.
      responses:
        "200":
          description: Catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  enabled: { type: boolean }
                  catalog:
                    type: array
                    items: { type: string }
                  kinds:
                    type: array
                    items:
                      type: object
                      properties:
                        kind: { type: string }
                        molecule: { type: string }
  /v1/sites:
    get: { summary: List sites }
    post: { summary: Create a site }
  /v1/sites/request:
    post: { summary: Request a host-site integration }
  /v1/sites/{id}:
    get: { summary: One site }
    patch: { summary: Update hooks / origin / service key }
  /v1/sites/{id}/verify:
    get: { summary: Verification token and instructions }
    post: { summary: Prove domain ownership }
  /v1/sites/{id}/checkout:
    post: { summary: Stripe Checkout for this site }
  /v1/sites/{id}/portal:
    post: { summary: Stripe customer portal }
  /stripe/webhook:
    post: { summary: Stripe billing webhook }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Whoila API key (whl_live_…)
