{"openapi":"3.0.3","info":{"title":"Midsouth Power Washing Authorized Agent Booking API","version":"1.0.0","description":"Book two-hour in-person quote visits, not cleaning appointments. Owner-issued test/live bearer keys, customer approval attestation, idempotent writes and receipt isolation. No cancellations, payments, customer listing or rescheduling."},"servers":[{"url":"https://midsouthpowerwashing.com/api/v1/agent"}],"security":[{"AgentBearer":[]}],"paths":{"/catalog":{"get":{"operationId":"getServiceCatalog","description":"Required scope: catalog:read. Use a server-side client; credentials must never be exposed to the browser.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}},"401":{"description":"Invalid, expired or revoked bearer credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or browser Origin supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input or missing customer approval","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit; Retry-After header supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider unavailable or internal operation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/availability":{"get":{"operationId":"getQuoteAvailability","description":"Required scope: availability:read. Use a server-side client; credentials must never be exposed to the browser.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Availability"}}}},"401":{"description":"Invalid, expired or revoked bearer credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or browser Origin supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input or missing customer approval","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit; Retry-After header supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider unavailable or internal operation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/booking-previews":{"post":{"operationId":"previewQuoteBooking","description":"Required scope: availability:read. Use a server-side client; credentials must never be exposed to the browser.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Preview"}}}},"400":{"description":"Malformed JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid, expired or revoked bearer credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or browser Origin supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"SLOT_TAKEN, REQUEST_CHANGED or IN_PROGRESS. Do not change the idempotency key after an uncertain write.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Body exceeds 64 KB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Content-Type must be application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input or missing customer approval","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit; Retry-After header supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider unavailable or internal operation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewInput"}}}}}},"/bookings":{"post":{"operationId":"createQuoteBooking","description":"Required scope: bookings:write. Use a server-side client; credentials must never be exposed to the browser.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"201":{"description":"Booking created; inspect status before claiming confirmation. Test mode returns simulated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"description":"Malformed JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid, expired or revoked bearer credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or browser Origin supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"SLOT_TAKEN, REQUEST_CHANGED or IN_PROGRESS. Do not change the idempotency key after an uncertain write.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Body exceeds 64 KB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Content-Type must be application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input or missing customer approval","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit; Retry-After header supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider unavailable or internal operation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingInput"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/bookings/{reference}":{"get":{"operationId":"getQuoteBooking","description":"Required scope: bookings:read. Use a server-side client; credentials must never be exposed to the browser.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"401":{"description":"Invalid, expired or revoked bearer credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or browser Origin supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No booking belongs to this credential with that reference."},"422":{"description":"Invalid input or missing customer approval","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit; Retry-After header supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider unavailable or internal operation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}}},"components":{"securitySchemes":{"AgentBearer":{"type":"http","scheme":"bearer","bearerFormat":"Owner-issued MPW agent token"}},"schemas":{"Draft":{"type":"object","required":["type","services","address","city","state","zip","material","size","stories","condition","water","access","timing","name","email","phone"],"properties":{"address":{"type":"string","maxLength":250},"city":{"type":"string","maxLength":250},"state":{"type":"string","enum":["TN","MS","AR"]},"zip":{"type":"string","pattern":"^[0-9]{5}$"},"material":{"type":"string","maxLength":250},"size":{"type":"string","maxLength":250},"stories":{"type":"string","enum":["1","2","3 or more","Unsure"]},"condition":{"type":"string","maxLength":250},"water":{"type":"string","enum":["yes","no","unsure"]},"access":{"type":"string","maxLength":2000},"timing":{"type":"string","maxLength":250},"name":{"type":"string","maxLength":250},"email":{"type":"string","format":"email","maxLength":250},"phone":{"type":"string","maxLength":250},"type":{"type":"string","enum":["residential","commercial","church","equipment"]},"services":{"type":"array","minItems":1,"maxItems":20,"uniqueItems":true,"items":{"type":"string"}}}},"BookingInput":{"type":"object","additionalProperties":false,"required":["draft","appointment","customerApproved"],"properties":{"draft":{"$ref":"#/components/schemas/Draft"},"appointment":{"type":"integer","description":"Unix seconds from an availability slot. Not milliseconds."},"customerApproved":{"type":"boolean","enum":[true],"description":"Agent attests customer approved this quote visit and service-related contact."}}},"PreviewInput":{"type":"object","additionalProperties":false,"required":["draft","appointment"],"properties":{"draft":{"$ref":"#/components/schemas/Draft"},"appointment":{"type":"integer"},"customerApproved":{"type":"boolean"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"Receipt":{"type":"object","required":["reference","status","mode","appointmentStart","timezone","minutes","appointmentType"],"properties":{"reference":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["confirmed","review_required","simulated"]},"mode":{"type":"string","enum":["test","live"]},"appointmentStart":{"type":"integer","description":"Requested Unix start time; only status confirmed proves a live reservation."},"appointment":{"type":"string","description":"Display label; present only for confirmed or simulated bookings."},"timezone":{"type":"string","enum":["America/Chicago"]},"minutes":{"type":"integer","enum":[120]},"appointmentType":{"type":"string","enum":["in_person_quote"]}}},"Availability":{"type":"object","properties":{"mode":{"type":"string","enum":["test","live"]},"timezone":{"type":"string"},"appointmentType":{"type":"string"},"minutes":{"type":"integer"},"slots":{"type":"array","items":{"type":"object","properties":{"start":{"type":"integer"},"minutes":{"type":"integer"},"label":{"type":"string"}}}}}},"Catalog":{"type":"object","properties":{"mode":{"type":"string"},"propertyTypes":{"type":"array","items":{"type":"object"}},"services":{"type":"array","items":{"type":"object"}},"provider":{"type":"string"},"appointmentType":{"type":"string"},"timezone":{"type":"string"},"minutes":{"type":"integer"},"cleaningPrice":{"type":"number","nullable":true},"docs":{"type":"string"}}},"Preview":{"type":"object","properties":{"valid":{"type":"boolean"},"mode":{"type":"string"},"reserved":{"type":"boolean","enum":[false]},"appointment":{"type":"integer"},"appointmentLabel":{"type":"string"},"timezone":{"type":"string"},"minutes":{"type":"integer"},"appointmentType":{"type":"string"},"propertyType":{"type":"string"},"services":{"type":"array","items":{"type":"string"}},"price":{"type":"number","nullable":true},"message":{"type":"string"}}}}}}