{"openapi":"3.1.0","info":{"title":"Plenum Public API","version":"1.0.0","summary":"Unauthenticated public surface for AI agents, WordPress widgets, and tenant marketing sites.","description":"Plenum is a multi-tenant field-service platform. This spec describes the public, unauthenticated routes that power tenant websites and are wrapped by Plenum MCP tools. For write-scoped actions (lead submission), agents may authenticate via OAuth 2.1 (see /.well-known/oauth-authorization-server) to bypass reCAPTCHA.","contact":{"name":"Plenum","url":"https://plenum.pro"},"license":{"name":"Proprietary"},"x-mcp-server":"/.well-known/mcp.json"},"servers":[{"url":"https://app.plenum.pro","description":"Plenum production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"OAuth 2.1 access token","description":"Required for write-scoped operations (e.g. POST /forms/submit with leads:write). Obtain via client_credentials or authorization_code grant at /api/oauth/token."}},"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","const":false},"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}},"ServiceAreaValidation":{"type":"object","properties":{"isValid":{"type":"boolean"},"matchedAreaId":{"type":"string","nullable":true},"surchargeCents":{"type":"integer","minimum":0,"nullable":true}}},"PricerTemplate":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"inputs":{"type":"array","items":{"type":"object"}}}},"PricerCalculation":{"type":"object","properties":{"total":{"type":"string","description":"Decimal as string"},"lineItems":{"type":"array","items":{"type":"object"}}}},"Brand":{"type":"object","required":["name","slug","preferred","excluded"],"properties":{"name":{"type":"string"},"slug":{"type":"string"},"preferred":{"type":"boolean"},"excluded":{"type":"boolean"}}},"Service":{"type":"object","required":["id","name","basePrice"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","nullable":true},"basePrice":{"type":"string","description":"Decimal as string"},"estimatedDuration":{"type":"integer","description":"Minutes","nullable":true},"isPopular":{"type":"boolean"},"isHearEligible":{"type":"boolean"}}},"LeadSubmission":{"type":"object","required":["formId","firstName","lastName","email"],"properties":{"companyId":{"type":"string"},"formId":{"type":"string"},"formName":{"type":"string","maxLength":255},"firstName":{"type":"string","maxLength":100},"lastName":{"type":"string","maxLength":100},"email":{"type":"string","format":"email"},"phone":{"type":"string","pattern":"^\\+?[0-9()\\-\\s]{7,30}$"},"serviceId":{"type":"string"},"fields":{"type":"object","additionalProperties":true},"recaptchaToken":{"type":"string"},"honeypotValue":{"type":"string"},"formLoadTime":{"type":"integer"},"submitTime":{"type":"integer"},"pageUrl":{"type":"string","maxLength":2000},"referrer":{"type":"string","maxLength":2000},"utmSource":{"type":"string"},"utmMedium":{"type":"string"},"utmCampaign":{"type":"string"},"utmTerm":{"type":"string"},"utmContent":{"type":"string"},"visitorId":{"type":"string","format":"uuid"}}},"LeadSubmissionResponse":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"submissionId":{"type":"string"},"message":{"type":"string"}}},"CompanyPublic":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"logoUrl":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"hours":{"type":"object","additionalProperties":true,"nullable":true}}},"WidgetConfig":{"type":"object","additionalProperties":true},"RebateCheckRequest":{"type":"object","required":["companyId","zipCode"],"properties":{"companyId":{"type":"string"},"zipCode":{"type":"string","pattern":"^\\d{5}$"},"householdSize":{"type":"integer","minimum":1,"maximum":12},"annualIncome":{"type":"number","minimum":0},"equipmentType":{"type":"string"},"programIds":{"type":"array","items":{"type":"string"}}}},"RebateCheckResponse":{"type":"object","properties":{"programs":{"type":"array","items":{"type":"object","required":["programId","qualifies"],"properties":{"programId":{"type":"string"},"name":{"type":"string"},"qualifies":{"type":"boolean"},"status":{"type":"string","enum":["active","paused","expired"]},"amount":{"type":"string","description":"Decimal as string"},"tier":{"type":"string"},"reason":{"type":"string"}}}}}}}},"paths":{"/api/public/service-area/validate":{"get":{"operationId":"validateServiceArea","summary":"Check if a ZIP or address is inside the company service area","tags":["service-area"],"x-mcp-tool":"check_service_area","parameters":[{"name":"companyId","in":"query","required":true,"schema":{"type":"string"}},{"name":"zip","in":"query","schema":{"type":"string","pattern":"^\\d{5}$"}},{"name":"address","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAreaValidation"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/quick-pricer/templates":{"get":{"operationId":"listPricerTemplates","summary":"List Quick Pricer templates available for a company","tags":["pricing"],"x-mcp-tool":"get_pricer_templates","parameters":[{"name":"companyId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Template list","content":{"application/json":{"schema":{"type":"object","properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/PricerTemplate"}}}}}}}}}},"/api/public/quick-pricer/templates/{slug}":{"get":{"operationId":"getPricerTemplate","summary":"Fetch a single Quick Pricer template by slug","tags":["pricing"],"x-mcp-tool":"get_pricer_templates","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"companyId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Template detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricerTemplate"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/quick-pricer/calculate":{"post":{"operationId":"calculatePricing","summary":"Calculate a price estimate from a template + inputs","tags":["pricing"],"x-mcp-tool":"calculate_pricing","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["companyId","templateSlug","inputs"],"properties":{"companyId":{"type":"string"},"templateSlug":{"type":"string"},"inputs":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Calculation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricerCalculation"}}}}}}},"/api/public/forms/submit":{"post":{"operationId":"submitLead","summary":"Submit a contact-form lead (WordPress widget + MCP submit_lead)","description":"Accepts EITHER a valid reCAPTCHA v3 token (anonymous) OR an OAuth 2.1 Bearer with the `leads:write` scope (AI agents). Agent-source is automatically detected from User-Agent and `x-agent-source`/`x-agent-intent` request headers.","tags":["leads"],"x-mcp-tool":"submit_lead","security":[{},{"bearerAuth":["leads:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadSubmission"}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/LeadSubmission"},{"type":"object","properties":{"attachments":{"type":"array","items":{"type":"string","format":"binary"},"maxItems":12}}}]}}}},"responses":{"200":{"description":"Submission accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadSubmissionResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Bearer token invalid (if Authorization header was supplied)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/subscribe/confirm":{"post":{"operationId":"confirmSubscription","summary":"Confirm an email subscription token","tags":["email"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"email":{"type":"string"}}}}}}}}},"/api/public/company/{companyId}":{"get":{"operationId":"getCompanyPublic","summary":"Get public company info (name, logo, hours, contact)","tags":["company"],"x-mcp-tool":"get_business_hours","parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Company info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyPublic"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/companies/{companyId}/services":{"get":{"operationId":"listCompanyServices","summary":"List bookable services for a company","tags":["services"],"x-mcp-tool":"list_services","parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/Service"}},"count":{"type":"integer"}}}}}}}}}}},"/api/public/companies/{companyId}/brands":{"get":{"operationId":"listCompanyBrands","summary":"List equipment brands the company installs (with preferred/excluded flags)","tags":["services"],"x-mcp-tool":"list_brands","parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Brand list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"brands":{"type":"array","items":{"$ref":"#/components/schemas/Brand"}},"count":{"type":"integer"}}}}}}}}}}},"/api/public/companies/{companyId}/widget-config":{"get":{"operationId":"getWidgetConfig","summary":"Get WordPress widget configuration for a company","tags":["widget"],"parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Widget config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetConfig"}}}}}}},"/api/public/rebates/check-eligibility":{"post":{"operationId":"checkRebateEligibility","summary":"Check rebate-program eligibility for a prospective customer","description":"Evaluates the QualificationGateService for each program the company runs. Returns per-program status: active/paused/expired + qualifying amount. Agent-facing; anonymous.","tags":["rebates"],"x-mcp-tool":"check_rebate_eligibility","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebateCheckRequest"}}}},"responses":{"200":{"description":"Eligibility result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebateCheckResponse"}}}}}}}},"x-agent-rate-limits":{"anonymous":{"requests":30,"windowSeconds":600,"scope":"per-IP"},"authenticated":{"requests":300,"windowSeconds":600,"scope":"per-oauth-client","notes":"Tunable per-tenant; write scopes may have lower caps."}}}