{"openapi":"3.1.0","info":{"title":"Hoverstate API","version":"1.0.0","x-api-version":"1","description":"Public utility endpoints for the Hoverstate website design gallery. The gallery catalog is available via sitemap.xml and llms.txt; these endpoints cover search, newsletter subscription, and username validation.\n\n**Versioning:** The current API version is v1. The version is indicated by the `API-Version` response header. Breaking changes will be released under a new version prefix (e.g. `/api/v2/`).\n\n**Deprecation:** Deprecated endpoints will include a `Sunset` response header with the retirement date at least 6 months in advance.\n\n**Rate limits:** 60 requests per 60-second window (unauthenticated). Headers: `RateLimit-Limit`, `RateLimit-Window`, `RateLimit-Policy`. A `429` response includes `Retry-After`.","contact":{"url":"https://www.hoverstate.design/contact"}},"servers":[{"url":"https://www.hoverstate.design","description":"Production"}],"paths":{"/api/v1/search":{"get":{"operationId":"searchGalleryV1","summary":"Search the Hoverstate gallery (v1)","description":"Full-text search across designs, tools, fonts, and OG images. Versioned stable endpoint.","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","example":"dark mode"}},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["website","tool","font","og-image"]}}],"responses":{"200":{"description":"Search results","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"type":"object","required":["groups","total"],"properties":{"groups":{"type":"array","items":{"type":"object"}},"total":{"type":"integer"}}}}}}}}},"/api/v1/subscribe":{"post":{"operationId":"subscribeNewsletterV1","summary":"Subscribe to the Hoverstate newsletter (v1)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Subscribed","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"description":"Invalid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/username/check":{"get":{"operationId":"checkUsernameAvailabilityV1","summary":"Check username availability (v1)","parameters":[{"name":"username","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Availability result","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"}},"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["available","unavailable","invalid"]}}}}}}}}},"/api/search":{"get":{"operationId":"searchGallery","summary":"Search the Hoverstate gallery","description":"Full-text search across designs, tools, fonts, and OG images. Returns grouped results capped at 5 items per group.","parameters":[{"name":"q","in":"query","required":false,"description":"Search query. Supports filter syntax: `tag:`, `tool:`, `type:`.","schema":{"type":"string","example":"dark mode"}},{"name":"type","in":"query","required":false,"description":"Comma-separated list of result types to include.","schema":{"type":"string","enum":["website","tool","font","og-image"],"example":"website,tool"}}],"responses":{"200":{"description":"Search results grouped by type","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}},"content":{"application/json":{"schema":{"type":"object","required":["groups","total"],"properties":{"groups":{"type":"array","items":{"type":"object","required":["type","items"],"properties":{"type":{"type":"string"},"items":{"type":"array","items":{"type":"object"}}}}},"total":{"type":"integer","description":"Total matched items across all groups"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/subscribe":{"post":{"operationId":"subscribeNewsletter","summary":"Subscribe to the Hoverstate newsletter","description":"Add an email address to the Hoverstate newsletter mailing list.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","example":"hello@example.com"}}}}}},"responses":{"200":{"description":"Subscription confirmed","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"}},"content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","example":true}}}}}},"400":{"description":"Invalid email address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream newsletter service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/username/check":{"get":{"operationId":"checkUsernameAvailability","summary":"Check whether a username is available","description":"Returns availability status for a given username string.","parameters":[{"name":"username","in":"query","required":true,"description":"Username to check (lowercase alphanumeric, 3–30 chars).","schema":{"type":"string","example":"alice"}}],"responses":{"200":{"description":"Username availability result","headers":{"API-Version":{"$ref":"#/components/headers/APIVersion"}},"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["available","unavailable","invalid"]},"username":{"type":"string"},"error":{"type":"string"}}}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}}},"headers":{"RateLimitLimit":{"description":"Maximum requests allowed per window","schema":{"type":"integer","example":60}},"RateLimitWindow":{"description":"Rate limit window in seconds","schema":{"type":"integer","example":60}},"RateLimitPolicy":{"description":"RFC RateLimit policy string","schema":{"type":"string","example":"60;w=60"}},"APIVersion":{"description":"Current API version","schema":{"type":"string","example":"1"}}}}}