{"openapi":"3.1.0","info":{"title":"Florian Industries Contact API","version":"1.0.0","description":"The public contact-form API for project enquiries. This is not a general-purpose product integration API and does not require authentication.","contact":{"name":"Florian Industries","email":"hi@florian.ie","url":"https://florian.ie/contact"}},"servers":[{"url":"https://florian.ie","description":"Production website"}],"paths":{"/api/contact":{"post":{"operationId":"submitContactMessage","summary":"Submit a project enquiry","description":"Sends a contact message to Florian Industries. Submit only when the person has asked you to send the enquiry. Repeated valid submissions from one client IP are limited to 10 per 60-second window per running application instance.","tags":["Contact"],"requestBody":{"required":true,"description":"Contact details and the message to forward to Florian Industries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactMessageRequest"},"example":{"name":"Alex Example","email":"alex@example.com","company":"Example Ltd","projectType":"custom-website","message":"We are looking for a custom website for our business. Could we discuss scope and timing?"}}}},"responses":{"200":{"description":"The contact message was accepted and sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactMessageSuccess"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}}},"400":{"description":"The request body is malformed or required fields are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}}},"405":{"description":"The requested HTTP method is not supported. Use POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}}},"429":{"description":"The per-client request limit was reached. Wait before retrying.","headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Retry-After":{"description":"Seconds to wait before retrying the request.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"The message could not be sent because of a server configuration or delivery error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}}}}}}},"components":{"headers":{"RateLimitPolicy":{"description":"Fixed request quota policy for one application instance and one client IP.","schema":{"type":"string","example":"\"contact\";q=10;w=60"}},"RateLimit":{"description":"Current service limit: r is the number of requests remaining and t is seconds until the window resets.","schema":{"type":"string","example":"\"contact\";r=9;t=60"}}},"schemas":{"ContactMessageRequest":{"type":"object","required":["name","email","message"],"properties":{"name":{"type":"string","minLength":1,"description":"Name of the person making the enquiry."},"email":{"type":"string","format":"email","description":"Reply-to email address."},"company":{"type":"string","description":"Company or organisation name."},"projectType":{"type":"string","description":"Optional project category, such as custom-website or consulting."},"message":{"type":"string","minLength":10,"description":"Project enquiry, at least 10 characters long."}}},"ContactMessageSuccess":{"type":"object","required":["success","message"],"properties":{"success":{"const":true},"message":{"type":"string","example":"Message sent successfully! I will get back to you soon."}}},"ApiError":{"type":"object","required":["error","code","message","resolution"],"properties":{"error":{"type":"string","description":"Backward-compatible plain-language error string."},"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable explanation."},"resolution":{"type":"string","description":"Suggested next action."}}}}}}