{"openapi":"3.1.0","info":{"title":"Api","version":"0.1.0","description":"API specification"},"servers":[{"url":"/api","description":"Base API path"}],"tags":[{"name":"health","description":"Health operations"},{"name":"agent","description":"Programmatic front door for AI agents acting on behalf of contractors. Requests are received and stored; a human confirms by email within 1 business day. Nothing is auto-provisioned."}],"paths":{"/agent/demo-request":{"post":{"operationId":"submitAgentDemoRequest","tags":["agent"],"summary":"Request a product demo","description":"Ask for a Punch demo on behalf of a contractor. The request is stored and Punch's founder is notified; a human replies to the contact email to schedule. Agents can also book directly via Calendly: https://calendly.com/taylor-punch/30min","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestInput"}}}},"responses":{"202":{"description":"Request received (not yet confirmed — a human follows up by email)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestReceipt"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}},"503":{"description":"Persistence unavailable — the request was NOT saved. The response is honest about that and points at the direct Calendly booking URL so the agent can still move the contractor forward.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}}}}},"/agent/account-request":{"post":{"operationId":"submitAgentAccountRequest","tags":["agent"],"summary":"Request a Punch account","description":"Ask for a Punch account on behalf of a contractor. No account is created automatically — the request is stored, Punch's founder is notified, and a human confirms next steps by email within 1 business day.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestInput"}}}},"responses":{"202":{"description":"Request received (no account exists yet — a human confirms by email)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestReceipt"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}},"503":{"description":"Persistence unavailable — the request was NOT saved. The response is honest about that and points at the direct Calendly booking URL so the agent can still move the contractor forward.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequestErrors"}}}}}}},"/healthz":{"get":{"operationId":"healthCheck","tags":["health"],"summary":"Health check","description":"Returns server health status","responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatus"}}}}}}}},"components":{"schemas":{"AgentRequestInput":{"type":"object","description":"Details an agent submits on behalf of a contractor.","properties":{"companyWebsite":{"type":"string","format":"uri","description":"The contractor's company website (http/https URL)","examples":["https://example-contractor.com"]},"contactName":{"type":"string","minLength":2,"maxLength":200,"description":"Human contact at the company"},"contactEmail":{"type":"string","format":"email","description":"Email a human at Punch will reply to"},"notes":{"type":["string","null"],"maxLength":2000,"description":"Optional free-form context — anything that helps a human prepare"},"trade":{"type":["string","null"],"maxLength":120,"description":"Optional: the contractor's trade, e.g. \"drywall\", \"electrical\", \"self-performing GC\""},"teamSize":{"type":["string","null"],"maxLength":120,"description":"Optional: rough size, e.g. \"40 field crew, 3 PMs\""},"interestedFeatures":{"type":["array","null"],"maxItems":20,"items":{"type":"string","maxLength":120},"description":"Optional: product areas the contractor cares about, e.g. [\"daily-reports\", \"purchase-orders\", \"invoices\", \"job-costing\", \"scheduling\"]. Free-form strings are fine — a human reads them."},"sampleDocumentUrls":{"type":["array","null"],"maxItems":10,"items":{"type":"string","format":"uri"},"description":"Optional: links to existing documents (a daily report, a purchase order, a pay app) the contractor is willing to share. A human at Punch reviews them before the demo so the working session can run on the contractor's real paperwork. Only share links the contractor has approved sharing."},"preferredTimes":{"type":["string","null"],"maxLength":300,"description":"Optional (demo requests): preferred days/times with timezone, e.g. \"weekday mornings, US Eastern\""}},"required":["companyWebsite","contactName","contactEmail"]},"AgentRequestReceipt":{"type":"object","properties":{"status":{"type":"string","description":"Always \"received\""},"requestId":{"type":"integer","description":"Reference id for the stored request"},"message":{"type":"string","description":"Honest status: the request was received and a human will confirm by email within 1 business day. No demo is scheduled and no account exists until that confirmation."},"nextSteps":{"type":"array","items":{"type":"string"}}},"required":["status","requestId","message","nextSteps"]},"AgentRequestErrors":{"type":"object","properties":{"error":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error"]},"HealthStatus":{"type":"object","properties":{"status":{"type":"string"}},"required":["status"]}}}}