openapi: 3.0.3 info: title: smokesignal API description: | Event and RSVP management system with comprehensive internationalization support. ## I18n Features smokesignal provides full internationalization support with automatic language detection and locale-aware responses. All endpoints support multiple languages through: - **Accept-Language headers**: Standard HTTP language negotiation - **URL parameters**: `?lang=fr-ca` for explicit language selection - **Locale-aware caching**: Optimized performance with language-specific cache keys - **Translated content**: All user-facing content available in supported locales ## Supported Locales - `en-US`: English (United States) - Default - `fr-CA`: French (Canada) with gender-aware content ## Language Detection Priority 1. URL `lang` parameter 2. Accept-Language header 3. Session preference 4. Default locale (en-US) version: 1.0.0 contact: name: smokesignal Support url: https://github.com/yourusername/smokesignal license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.smokesignal.example.com description: Production server - url: http://localhost:3000 description: Development server paths: /events: get: summary: Filter and search events description: | Retrieve events based on filter criteria with full internationalization support. Facets and event metadata are automatically translated based on the user's language preference. Cache keys include locale information for optimal performance. ## I18n Behavior - Event status and format facets are translated - Date range facets use locale-appropriate formatting - Facet counts include proper pluralization - Error messages are localized parameters: - name: Accept-Language in: header description: | Language preference using standard HTTP Accept-Language header. Examples: - `en-US,en;q=0.9` - English preferred - `fr-CA,fr;q=0.9,en;q=0.8` - French Canadian preferred, French secondary, English fallback - `fr-CA` - French Canadian only schema: type: string example: "fr-CA,fr;q=0.9,en;q=0.8" - name: lang in: query description: | Explicit language override. Takes priority over Accept-Language header. Supported values: - `en-us`: English (United States) - `fr-ca`: French (Canada) schema: type: string enum: [en-us, fr-ca] example: "fr-ca" - name: q in: query description: Search term for event title and description schema: type: string example: "music festival" - name: start_date in: query description: Filter events starting after this date (ISO 8601) schema: type: string format: date example: "2025-06-01" - name: end_date in: query description: Filter events ending before this date (ISO 8601) schema: type: string format: date example: "2025-12-31" - name: lat in: query description: Latitude for location-based filtering schema: type: number format: float example: 45.5017 - name: lng in: query description: Longitude for location-based filtering schema: type: number format: float example: -73.5673 - name: radius in: query description: Search radius in kilometers (requires lat/lng) schema: type: number format: float minimum: 0 maximum: 1000 example: 25 - name: modes in: query description: Filter by event format/mode schema: type: array items: type: string enum: [in_person, virtual, hybrid] example: ["in_person", "hybrid"] - name: statuses in: query description: Filter by event status schema: type: array items: type: string enum: [active, draft, cancelled] example: ["active"] - name: sort in: query description: Sort order for results schema: type: string enum: [start_time, created_at, updated_at, relevance] default: start_time example: "start_time" - name: limit in: query description: Maximum number of events to return schema: type: integer minimum: 1 maximum: 100 default: 20 example: 20 - name: offset in: query description: Number of events to skip (for pagination) schema: type: integer minimum: 0 default: 0 example: 0 responses: '200': description: Successful response with filtered events and facets headers: Content-Language: description: Language of the returned content schema: type: string example: "fr-CA" X-Cache-Key: description: Cache key used (includes locale) schema: type: string example: "filter:abc123:fr-ca" content: application/json: schema: $ref: '#/components/schemas/FilterResults' examples: english_results: summary: English response value: events: - id: "evt_123" title: "Summer Music Festival" description: "Annual outdoor music festival" start_date: "2025-07-15T19:00:00Z" mode: "in_person" status: "active" facets: modes: - value: "in_person" count: 25 i18n_key: "event-mode-in-person" display_name: "In Person" statuses: - value: "active" count: 25 i18n_key: "event-status-active" display_name: "Active" total_count: 25 french_results: summary: French Canadian response value: events: - id: "evt_123" title: "Summer Music Festival" description: "Annual outdoor music festival" start_date: "2025-07-15T19:00:00Z" mode: "in_person" status: "active" facets: modes: - value: "in_person" count: 25 i18n_key: "event-mode-in-person" display_name: "En personne" statuses: - value: "active" count: 25 i18n_key: "event-status-active" display_name: "Actif" total_count: 25 text/html: schema: type: string description: Rendered HTML template with translated content examples: htmx_fragment: summary: HTMX partial response value: |

25 événements trouvés

'400': description: Bad request - Invalid parameters content: application/json: schema: $ref: '#/components/schemas/Error' examples: invalid_locale: summary: Invalid locale parameter value: error: "invalid_locale" message: "Unsupported locale 'es-ES'. Supported locales: en-us, fr-ca" details: supported_locales: ["en-us", "fr-ca"] '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /events/{id}: get: summary: Get event details description: | Retrieve detailed information for a specific event with localized content. ## I18n Features - Event metadata translated based on user language - Date/time formatting according to locale conventions - RSVP status and form labels localized parameters: - name: id in: path required: true description: Event ID schema: type: string example: "evt_123" - name: Accept-Language in: header description: Language preference schema: type: string example: "fr-CA,fr;q=0.9,en;q=0.8" - name: lang in: query description: Explicit language override schema: type: string enum: [en-us, fr-ca] responses: '200': description: Event details content: application/json: schema: $ref: '#/components/schemas/Event' text/html: schema: type: string description: Rendered event detail page '404': description: Event not found content: application/json: schema: $ref: '#/components/schemas/Error' /facets: get: summary: Get available facets for filtering description: | Retrieve facet counts for the current filter context with translated display names. This endpoint is optimized for autocomplete and filter UI updates. Facets include pre-calculated display names in the user's preferred language. parameters: - name: Accept-Language in: header description: Language preference for facet translations schema: type: string example: "fr-CA" - name: context in: query description: Current filter context to calculate facets against schema: type: string example: "search=music&location=montreal" responses: '200': description: Available facets with counts and translations content: application/json: schema: $ref: '#/components/schemas/EventFacets' /health/translations: get: summary: Health check for translation system description: | Verify that translation system is working correctly for all supported locales. Returns status of translation loading, cache connectivity, and sample translations. responses: '200': description: Translation system healthy content: application/json: schema: type: object properties: status: type: string example: "healthy" locales: type: array items: type: object properties: locale: type: string loaded: type: boolean translation_count: type: integer example: - locale: "en-us" loaded: true translation_count: 245 - locale: "fr-ca" loaded: true translation_count: 243 cache: type: object properties: connected: type: boolean hit_rate: type: number components: schemas: FilterResults: type: object properties: events: type: array items: $ref: '#/components/schemas/Event' facets: $ref: '#/components/schemas/EventFacets' total_count: type: integer description: Total number of events matching criteria Event: type: object properties: id: type: string description: Unique event identifier title: type: string description: Event title description: type: string description: Event description start_date: type: string format: date-time description: Event start date and time (ISO 8601) end_date: type: string format: date-time description: Event end date and time (ISO 8601) mode: type: string enum: [in_person, virtual, hybrid] description: Event format/mode status: type: string enum: [active, draft, cancelled] description: Event status location: $ref: '#/components/schemas/Location' created_at: type: string format: date-time updated_at: type: string format: date-time EventFacets: type: object description: Available facets for filtering with translated display names properties: modes: type: array items: $ref: '#/components/schemas/FacetValue' description: Event format facets statuses: type: array items: $ref: '#/components/schemas/FacetValue' description: Event status facets date_ranges: type: array items: $ref: '#/components/schemas/FacetValue' description: Date range facets (Today, This Week, etc.) creators: type: array items: $ref: '#/components/schemas/FacetValue' description: Event creator facets total_count: type: integer description: Total events matching current criteria FacetValue: type: object description: A single facet value with count and i18n support properties: value: type: string description: The actual filter value (e.g., "in_person") example: "in_person" count: type: integer description: Number of events matching this facet example: 15 i18n_key: type: string description: Translation key for the display name example: "event-mode-in-person" display_name: type: string description: Pre-calculated display name in user's locale example: "En personne" Location: type: object properties: latitude: type: number format: float longitude: type: number format: float address: type: string city: type: string country: type: string Error: type: object properties: error: type: string description: Error code message: type: string description: Human-readable error message (localized) details: type: object description: Additional error context required: - error - message securitySchemes: BearerAuth: type: http scheme: bearer description: JWT token authentication security: - BearerAuth: [] tags: - name: Events description: Event management and filtering - name: I18n description: Internationalization and localization - name: Health description: System health and status checks