{"openapi":"3.1.0","info":{"title":"Houston Marketing Pros Public API","version":"0.1.0","description":"Houston Marketing Pros public API for read-only service and service-area discovery. Canonical public routes use the /api/v1/ major-version prefix. Breaking changes require a new major version; backward-compatible additions may be introduced within the same major version. When an endpoint or version is scheduled for retirement, responses may include Deprecation and, where applicable, Sunset headers. Nothing in the current canonical API is deprecated.","x-api-versioning":{"strategy":"URL path","canonicalPrefix":"/api/v1/","breakingChanges":"New major version required","compatibleChanges":"Allowed within the same major version"},"x-deprecation-policy":{"currentDeprecatedEndpoints":[],"headers":["Deprecation","Sunset"]}},"servers":[{"url":"https://houstonmarketingpros.com/api","description":"Houston Marketing Pros API base path; canonical public operations use the /v1 prefix."}],"paths":{"/v1/services":{"get":{"operationId":"listPublicServices","tags":["public"],"security":[],"summary":"List available marketing services","description":"Returns the public Houston Marketing Pros service catalog. The response contains display content and public website links only.","responses":{"200":{"description":"Public services","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicService"}}}}},"400":{"$ref":"#/components/responses/PublicBadRequest"},"404":{"$ref":"#/components/responses/PublicNotFound"},"429":{"$ref":"#/components/responses/PublicRateLimited"},"500":{"$ref":"#/components/responses/PublicUnexpectedError"}}}},"/v1/service-areas":{"get":{"operationId":"listPublicServiceAreas","tags":["public"],"security":[],"summary":"List served Houston-area markets","description":"Returns public geographic coverage information for Houston Marketing Pros without internal planning, scoring, priority, or publication data.","responses":{"200":{"description":"Public service areas","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicServiceArea"}}}}},"400":{"$ref":"#/components/responses/PublicBadRequest"},"404":{"$ref":"#/components/responses/PublicNotFound"},"429":{"$ref":"#/components/responses/PublicRateLimited"},"500":{"$ref":"#/components/responses/PublicUnexpectedError"}}}}},"components":{"headers":{"RateLimitLimit":{"description":"Maximum requests permitted in the current public API rate-limit window.","schema":{"type":"integer","minimum":1}},"RateLimitRemaining":{"description":"Requests remaining in the current public API rate-limit window.","schema":{"type":"integer","minimum":0}},"RateLimitReset":{"description":"Seconds until the current public API rate-limit window resets.","schema":{"type":"integer","minimum":0}},"RetryAfter":{"description":"Seconds until a rate-limited request may be retried.","schema":{"type":"integer","minimum":0}}},"schemas":{"PublicService":{"type":"object","additionalProperties":false,"required":["slug","name","description","url"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"}}},"PublicErrorResponse":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"$ref":"#/components/schemas/PublicError"}}},"PublicError":{"type":"object","additionalProperties":false,"required":["code","message","resolution"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"description":"Safe structured issues that can help correct the request.","type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}},"resolution":{"type":"string"}}},"ValidationIssue":{"type":"object","additionalProperties":false,"required":["field","message"],"properties":{"field":{"type":"string"},"message":{"type":"string"}}},"PublicServiceArea":{"type":"object","additionalProperties":false,"required":["slug","name","areaType","region","url"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"areaType":{"type":"string","enum":["city","community","submarket"]},"region":{"type":"string"},"url":{"type":"string"}}}},"responses":{"PublicBadRequest":{"description":"The request could not be validated.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicErrorResponse"}}}},"PublicNotFound":{"description":"The public API operation was not found.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicErrorResponse"}}}},"PublicRateLimited":{"description":"The public API request quota has been exceeded.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicErrorResponse"}}}},"PublicUnexpectedError":{"description":"An unexpected server failure occurred.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicErrorResponse"}}}}}}}