openapi: 3.1.0
info:
  title: The Decksmith Public API
  description: >
    Consultation lead intake for The Decksmith — Sydney Eastern Suburbs deck and
    pergola builder (NSW licence 272840C). Browser forms continue to use
    application/x-www-form-urlencoded with 303 redirects. Agents should prefer
    Accept: application/json and/or Content-Type: application/json for JSON
    request/response shapes documented here. No secrets are exposed by this API.
  version: 1.0.0
  contact:
    name: Greg Weinbren — The Decksmith
    email: greg@thedecksmith.com.au
    url: https://www.thedecksmith.com.au/contact/
servers:
  - url: https://www.thedecksmith.com.au
    description: Production
tags:
  - name: Leads
    description: Consultation lead intake and health
paths:
  /api/lead:
    get:
      operationId: getLeadHealth
      tags: [Leads]
      summary: Lead endpoint health check
      description: >
        Returns JSON health status for the Consultation lead intake endpoint.
        Suitable for uptime monitors and agents verifying the API is reachable.
      responses:
        "200":
          description: Endpoint healthy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LeadHealth"
              example:
                status: ok
    post:
      operationId: submitConsultationLead
      tags: [Leads]
      summary: Submit a Consultation lead
      description: >
        Accepts a Consultation request from homeowners (or agents acting for them).
        Supports application/x-www-form-urlencoded (browser forms) and
        application/json (agents). Required fields: name_1, email_1. Optional:
        phone_1, text_1 (postcode), textarea_1 (message), botcheck (honeypot —
        leave empty). When the client wants JSON (Accept prefers application/json,
        or Content-Type is application/json), success is 200 JSON and validation
        failures are 400 JSON. Otherwise browser clients receive 303 redirects to
        /thanks/ (success) or /contact/ (failure).
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: "#/components/schemas/LeadRequest"
          application/json:
            schema:
              $ref: "#/components/schemas/LeadRequest"
      responses:
        "200":
          description: Lead accepted (JSON clients)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LeadSuccess"
              example:
                ok: true
                message: Consultation request received
        "303":
          description: >
            Lead accepted or validation failed (browser form flow).
            Success Location: /thanks/. Failure Location: /contact/.
        "400":
          description: Validation or parse error (JSON clients)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiErrorEnvelope"
              example:
                error:
                  code: VALIDATION_ERROR
                  message: name_1 and a valid email_1 are required
                  resolution: Provide name_1 and a valid email_1. See /openapi.json
components:
  schemas:
    LeadRequest:
      type: object
      required: [name_1, email_1]
      properties:
        name_1:
          type: string
          description: Full name of the person requesting a Consultation
          minLength: 1
        email_1:
          type: string
          format: email
          description: Contact email
        phone_1:
          type: string
          description: Contact phone (optional)
        text_1:
          type: string
          description: Postcode (optional)
        textarea_1:
          type: string
          description: Project message / notes (optional)
        botcheck:
          type: string
          description: >
            Honeypot field for bots — humans and legitimate agents must leave
            this empty or omit it
          default: ""
      additionalProperties: true
    LeadHealth:
      type: object
      required: [status]
      properties:
        status:
          type: string
          const: ok
    LeadSuccess:
      type: object
      required: [ok, message]
      properties:
        ok:
          type: boolean
          const: true
        message:
          type: string
    ApiError:
      type: object
      required: [code, message, resolution]
      properties:
        code:
          type: string
          description: Machine-readable error code, e.g. VALIDATION_ERROR
        message:
          type: string
          description: Human-readable error summary
        resolution:
          type: string
          description: How to fix the request
        details:
          description: Optional structured details
          nullable: true
    ApiErrorEnvelope:
      type: object
      required: [error]
      properties:
        error:
          $ref: "#/components/schemas/ApiError"
