{"openapi":"3.1.0","info":{"title":"Amzy — Amzy agent API","version":"1.0.0","description":"Centralized adapters for the existing Amzy estimator, live availability and explicit booking-confirmation workflow. Example ZIPs and requests are illustrative, not claims of coverage or price."},"servers":[{"url":"https://amzy.me"}],"externalDocs":{"url":"https://amzy.me/ai"},"paths":{"/api/agent/check_service_area":{"post":{"operationId":"check_service_area","summary":"Check service area","description":"Validate a pickup ZIP and material profile against live Amzy coverage. Coverage does not reserve a contractor or slot. Public operation. ","tags":["read-only"],"security":[],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"zip_code":{"type":"string","pattern":"^\\d{5}$"},"material_profile":{"type":"string","minLength":1,"maxLength":300},"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["zip_code","material_profile"],"additionalProperties":false},"example":{"zip_code":"98003","material_profile":"household furniture"}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"covered":{"value":{"status":"serviceable","supported":true,"zip_code":"98003","conversation_token":"<retain-this-token>"}},"uncovered":{"value":{"supported":false,"status":"unsupported","zip_code":"98003"}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/get_business_hours":{"post":{"operationId":"get_business_hours","summary":"Get business hours","description":"Read configured business hours; missing hours are explicitly unconfigured. Appointment windows are checked separately. Public operation. ","tags":["read-only"],"security":[],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"example":{}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"hours":{"value":{"provider":"amzy","configured":false,"hours":[]}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/get_service_information":{"post":{"operationId":"get_service_information","summary":"Get service information","description":"Read the service provider, contact information, configured service areas, and enabled capabilities. Public operation. ","tags":["read-only"],"security":[],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"example":{}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"information":{"value":{"provider":{"id":"amzy","name":"Amzy","url":"https://amzy.me","description":"Junk-removal estimates, appointment availability, and booking powered by Amzy.","bookingUrl":"https://amzy.me/","telephone":"+12532347078","email":"contact@amzy.me","serviceZipCodes":[],"hours":[],"capabilities":["check_service_area","get_business_hours","get_service_information","get_estimate","check_availability","book_junk_removal"]},"capabilities":["check_service_area","get_business_hours","get_service_information","get_estimate","check_availability","book_junk_removal"],"fulfillment":"Amzy network routing; contractor assignment is not guaranteed"}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/get_estimate":{"post":{"operationId":"get_estimate","summary":"Get estimate","description":"Continue the existing Amzy estimator using pickup ZIP and junk items. Follow-up questions may be required. Estimates are approximate. Requires the latest conversation_token from a successful coverage/estimate/preparation response as Authorization: Bearer. Tokens are scoped to ZIP and provider. ","tags":["read-only"],"security":[{"conversation":[]}],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"zip_code":{"type":"string","pattern":"^\\d{5}$"},"items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"message":{"default":"","type":"string","maxLength":4000}},"required":["zip_code","items"],"additionalProperties":false},"example":{"zip_code":"98003","items":["one sofa"],"message":"The sofa is curbside. What else do you need for an estimate?"}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"quoted":{"summary":"Illustrative backend result; never a published service price","value":{"route":"quote_ready","quote":{"amount":237.19,"low":200,"high":275,"confidence":0.8,"rationale":"Example only: real prices come from the backend."},"job_size_id":2,"slot_held":false,"conversation_token":"<replacement-token>"}},"incomplete":{"value":{"route":"ask_items","quote":null,"reply":"More information is required.","conversation_token":"<replacement-token>"}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/check_availability":{"post":{"operationId":"check_availability","summary":"Check availability","description":"Read live appointment options for an existing quoted conversation and date. Returned options do not hold a slot. Requires the latest conversation_token from a successful coverage/estimate/preparation response as Authorization: Bearer. Tokens are scoped to ZIP and provider. ","tags":["read-only"],"security":[{"conversation":[]}],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"zip_code":{"type":"string","pattern":"^\\d{5}$"},"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["zip_code","date"],"additionalProperties":false},"example":{"zip_code":"98003","date":"2026-11-02"}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"available":{"value":{"options":[{"scheduled_time":"2026-11-02T10:00:00-08:00","label":"Example appointment time","availability_percent":100}],"conversation_token":"<replacement-token>"}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/book_junk_removal":{"post":{"operationId":"book_junk_removal","summary":"Book junk removal","description":"Prepare customer details and the selected appointment in the existing booking conversation; submit only after explicit approval of its final summary. Fulfillment follows Amzy network routing; named contractor assignment is not guaranteed. Requires the latest conversation_token from a successful coverage/estimate/preparation response as Authorization: Bearer. Tokens are scoped to ZIP and provider. Call with customer_approved=false until ready_for_confirmation=true. Display confirmation_summary, then resend identical preparation fields with customer_approved=true, the exact confirmation_summary, and the replacement token. Backend validation remains authoritative.","tags":["booking-mutation"],"security":[{"conversation":[]}],"parameters":[{"in":"query","name":"provider","required":false,"schema":{"type":"string","default":"amzy"},"description":"Registered provider ID. Default: amzy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"zip_code":{"type":"string","pattern":"^\\d{5}$"},"items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"customer":{"type":"object","properties":{"firstname":{"type":"string","minLength":1,"maxLength":100},"lastname":{"type":"string","minLength":1,"maxLength":100},"phone_number":{"type":"string","pattern":"^\\+?[1-9][0-9]{9,14}$"},"house":{"type":"string","minLength":1,"maxLength":200},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"type":"string","pattern":"^[A-Z]{2}$"}},"required":["firstname","lastname","phone_number","house","city","state"],"additionalProperties":false},"selected_scheduled_time":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"customer_approved":{"type":"boolean"},"confirmation_summary":{"type":"string","minLength":1,"maxLength":8000},"message":{"default":"","type":"string","maxLength":4000}},"required":["zip_code","items","customer","selected_scheduled_time","customer_approved"],"additionalProperties":false},"example":{"zip_code":"98003","customer":{"firstname":"Example","lastname":"Customer","phone_number":"+12065550100","house":"123 Example Street","city":"Example City","state":"WA"},"items":["one sofa"],"selected_scheduled_time":"2026-11-02T10:00:00-08:00","customer_approved":false}}}},"responses":{"200":{"description":"Illustrative backend results. Estimates may require more information; availability does not reserve a slot. Only the backend booking field establishes submission.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"prepared":{"value":{"route":"final_confirmation","customer_approval_required":true,"ready_for_confirmation":true,"confirmation_summary":"<exact-backend-summary-displayed-to-customer>","conversation_token":"<replacement-token>","booking":null}},"submitted":{"value":{"route":"booking_confirmed","booking":{"appointment_id":123},"conversation_token":"<replacement-token>"}}}}}},"400":{"description":"Invalid ZIP, fields, or JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, expired, or invalid conversation token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Capability disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown operation or provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Coverage, quote, or confirmation not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Expected application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Backend unavailable or rejected request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Server configuration required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"conversation":{"type":"http","scheme":"bearer","description":"Scoped conversation_token returned by check_service_area and replaced on later responses. Expires one hour after the initial coverage check; replacement tokens retain that original expiry. On expiry, start a new coverage check, obtain a fresh estimate, and prepare a new summary for approval."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}},"additionalProperties":false}},"additionalProperties":false}}}}