{"openapi":"3.1.0","info":{"title":"Jolly Raleigh Grokbot Quote Request API","version":"1.0.0","description":"Customer-authorized, email-only submissions that start the existing Christmas lighting quote workflow. A request acknowledgement is not a booking. Rolling limits: 60 API attempts/minute per shared network bucket and 600/minute globally; 5 requests/hour per shared network bucket; 3 requests/24 hours per reply inbox; 1/24 hours per property; 50/24 hours globally; at most 20 pending jobs. Malformed and unauthorized attempts count toward API ceilings. Honor Retry-After on 429 and 503."},"servers":[{"url":"https://jollyraleigh.com/api/grokbot/v1"}],"paths":{"/requests":{"post":{"operationId":"createQuoteRequest","summary":"Start an email-only Christmas lighting quote","description":"Starts the existing quote generation workflow. There is no separate status endpoint. Reuse the same key and exact payload for retries. The returned quoteUrl is the supported way to view job progress and results. A 409 processing or needs_support response must not be worked around by creating a second request.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^[a-zA-Z0-9_-]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["schemaVersion","customer","property","options","communication","authorization"],"properties":{"schemaVersion":{"const":"1"},"customer":{"type":"object","additionalProperties":false,"required":["name","replyEmail"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"replyEmail":{"type":"string","format":"email","maxLength":254}}},"property":{"type":"object","additionalProperties":false,"required":["addressLine1","city","state","postalCode"],"properties":{"addressLine1":{"type":"string","minLength":1,"maxLength":180},"city":{"type":"string","minLength":1,"maxLength":80},"state":{"type":"string","pattern":"^[A-Z]{2}$"},"postalCode":{"type":"string","pattern":"^\\d{5}(-\\d{4})?$"}}},"options":{"description":"Option A requests roofline only. Option B requests roofline, ridges, and front-facing gable. Trees and bushes are separate optional requests applied to selected options. Option IDs and scopes must each be unique.","type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"object","additionalProperties":false,"required":["id","scope"],"properties":{"id":{"type":"string","pattern":"^[A-Z0-9_-]{1,20}$"},"scope":{"description":"Use roofline_only for A or roofline_ridges_front_gable for B. roofline_trees_bushes is accepted only for compatibility with older callers; new requests use the separate landscape object.","enum":["roofline_only","roofline_ridges_front_gable","roofline_trees_bushes"]}}}},"landscape":{"type":"object","additionalProperties":false,"required":["trees","bushes"],"properties":{"trees":{"type":"boolean"},"bushes":{"type":"boolean"}},"description":"Optional tree and bush requests applied to each selected option."},"questions":{"type":"array","uniqueItems":true,"maxItems":6,"description":"Optional question categories; standard service answers are included in the 202 response.","items":{"enum":["purchase_or_lease","installation_dates","takedown_dates","storage","warranty","in_season_service"]}},"communication":{"type":"object","additionalProperties":false,"required":["channel","allowCalls","allowSms"],"properties":{"channel":{"const":"email"},"allowCalls":{"const":false},"allowSms":{"const":false}}},"authorization":{"type":"object","additionalProperties":false,"required":["authorizedToRequestQuote"],"properties":{"authorizedToRequestQuote":{"const":true}}},"notes":{"type":"string","minLength":1,"maxLength":2000}}},"example":{"schemaVersion":"1","customer":{"name":"Example Customer","replyEmail":"customer@example.com"},"property":{"addressLine1":"123 Example Lane","city":"Raleigh","state":"NC","postalCode":"27615"},"options":[{"id":"A","scope":"roofline_only"},{"id":"B","scope":"roofline_ridges_front_gable"}],"landscape":{"trees":true,"bushes":true},"communication":{"channel":"email","allowCalls":false,"allowSms":false},"authorization":{"authorizedToRequestQuote":true},"notes":"Please consider the selected roofline and landscaping scopes."}}}},"responses":{"202":{"description":"The existing quote workflow accepted the job. It may still be processing. New responses include shared servicePolicies; older responses may omit them.","content":{"application/json":{"example":{"requestId":"example-request-id","jobId":"example-job-id","publicToken":"<keep-private>","quoteUrl":"/property/example-job-id?t=<keep-private>","status":"processing","servicePolicies":{"lights":"Lights are leased.","storage":"Storage is included.","installation":"Available installation weeks are shown at checkout. Choose an available week; we guarantee installation during that week.","takedown":"Takedown scheduling is dynamic. We guarantee takedown by January 21.","service":"Bulb outages or storm damage are repaired within 48 hours at no extra charge.","policyUrl":"https://jollyraleigh.com/christmas-lights/"}},"schema":{"type":"object","required":["requestId","jobId","publicToken","quoteUrl","status"],"properties":{"requestId":{"type":"string"},"jobId":{"type":"string"},"publicToken":{"type":"string"},"quoteUrl":{"type":"string"},"status":{"type":"string"},"servicePolicies":{"description":"Shared service answers; absent on legacy responses.","type":"object","additionalProperties":false,"required":["lights","storage","installation","takedown","service","policyUrl"],"properties":{"lights":{"type":"string"},"storage":{"type":"string"},"installation":{"type":"string"},"takedown":{"type":"string"},"service":{"type":"string"},"policyUrl":{"type":"string","format":"uri"}}}}}}}},"400":{"description":"Invalid JSON or missing/invalid Idempotency-Key.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"409":{"description":"The key conflicts or the original job outcome is unresolved. Reuse the same key; contact written support if needed.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"413":{"description":"Request body exceeds 16 KiB.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"415":{"description":"Content-Type must be application/json.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"422":{"description":"Request fields do not match the v1 schema.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"429":{"description":"A request limit was reached; honor Retry-After.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}},"503":{"description":"Intake or a required dependency is unavailable; honor Retry-After.","content":{"application/json":{"schema":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"retryAfterSeconds":{"type":"integer","minimum":0}}},"requestId":{"type":"string"}}}}}}}}}}}