{
 "openapi": "3.1.0",
 "info": {
  "title": "Balcostics Research quote request",
  "version": "1.0.0",
  "description": "Ask Balcostics Research for a costed fieldwork plan. See https://balcostics.com/quote.md."
 },
 "servers": [
  {
   "url": "https://balcostics.com"
  }
 ],
 "paths": {
  "/api/contact": {
   "post": {
    "operationId": "requestQuote",
    "summary": "Send a quote request to Balcostics Research",
    "description": "Rate limit 3 submissions per hour per IP address. Body limit 32 KB.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "email",
         "service"
        ],
        "properties": {
         "firstName": {
          "type": "string",
          "maxLength": 80
         },
         "lastName": {
          "type": "string",
          "maxLength": 80
         },
         "email": {
          "type": "string",
          "format": "email",
          "maxLength": 200
         },
         "service": {
          "type": "string",
          "enum": [
           "Research \u2014 CAPI / CATI Surveys",
           "Research \u2014 Data Collection & Analysis",
           "Research \u2014 Baseline / Endline Studies",
           "Research \u2014 Monitoring & Evaluation",
           "Legal Services \u2014 Balcostics Law",
           "MyVoice Platform",
           "Other"
          ]
         },
         "message": {
          "type": "string",
          "maxLength": 5000,
          "description": "Required unless sampleSize, mode, parishes or timeline is given."
         },
         "sampleSize": {
          "type": "string",
          "maxLength": 120,
          "example": "1,200 households"
         },
         "mode": {
          "type": "string",
          "maxLength": 60,
          "examples": [
           "CAPI (face to face)",
           "CATI (phone)",
           "Mixed",
           "myVoice panel",
           "Not sure yet"
          ]
         },
         "parishes": {
          "type": "string",
          "maxLength": 300,
          "example": "St. Mary, St. Ann"
         },
         "timeline": {
          "type": "string",
          "maxLength": 200,
          "example": "Fieldwork in March 2027"
         },
         "website": {
          "type": "string",
          "description": "Honeypot. Leave empty."
         },
         "_loadedAt": {
          "type": "string",
          "description": "Milliseconds since epoch when the form was shown. Submissions less than 3 seconds after this are discarded."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Accepted",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Missing or invalid field"
     },
     "413": {
      "description": "Body too large"
     },
     "429": {
      "description": "More than 3 submissions in an hour"
     },
     "500": {
      "description": "Email delivery failed"
     }
    }
   }
  }
 }
}