{
  "openapi": "3.1.0",
  "info": {
    "title": "Journey Health Advisors public website API",
    "description": "The public API surface of journeyhealthadvisors.com: a contact-form intake endpoint (proxied server-side to our CRM) and a health endpoint. Submissions create a sales lead; no protected health information (PHI) is accepted or stored. Documentation: https://journeyhealthadvisors.com/docs/api/",
    "version": "1.0.0",
    "contact": {
      "name": "Journey Health Advisors",
      "url": "https://journeyhealthadvisors.com/contact/"
    }
  },
  "servers": [{ "url": "https://journeyhealthadvisors.com" }],
  "paths": {
    "/api/contact": {
      "post": {
        "operationId": "submitContactForm",
        "summary": "Submit the website contact form",
        "description": "Creates a lead in the Journey Health Advisors CRM. `lastName` is the only required field. If `phone` is provided, `smsConsent: true` is required (TCPA). When CAPTCHA is enabled in production, a Cloudflare Turnstile token is required. Do not send health information of any kind.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ContactSubmission" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lead accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean", "const": true },
                    "leadId": { "type": "string", "description": "CRM lead reference (UUID), when available." }
                  },
                  "required": ["ok"]
                }
              }
            }
          },
          "400": { "description": "Invalid JSON, missing lastName, missing SMS consent for a provided phone, or missing CAPTCHA token.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "403": { "description": "CAPTCHA verification failed.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "502": { "description": "Upstream CRM rejected the lead.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "API liveness check",
        "responses": {
          "200": {
            "description": "Service is up.",
            "content": {
              "application/health+json": {
                "schema": {
                  "type": "object",
                  "properties": { "status": { "type": "string", "const": "ok" } },
                  "required": ["status"]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ContactSubmission": {
        "type": "object",
        "properties": {
          "lastName": { "type": "string", "description": "Required. The only mandatory field." },
          "firstName": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "maxLength": 32, "description": "If provided, smsConsent must be true (TCPA)." },
          "company": { "type": "string" },
          "title": { "type": "string" },
          "state": { "type": "string", "description": "Two-letter US state code." },
          "zip": { "type": "string" },
          "message": { "type": "string", "description": "Free text. Do not include health information." },
          "utmSource": { "type": "string" },
          "utmMedium": { "type": "string" },
          "utmCampaign": { "type": "string" },
          "smsConsent": { "type": "boolean", "description": "Explicit TCPA opt-in. Required when phone is provided. Never pre-checked in UIs." },
          "turnstileToken": { "type": "string", "description": "Cloudflare Turnstile token; required when CAPTCHA is enabled." }
        },
        "required": ["lastName"],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": { "error": { "type": "string" } },
        "required": ["error"]
      }
    }
  }
}
