swagger: '2.0'
info:
  title: Respectlytics API
  description: |
    Privacy-first mobile analytics API.

    ## Getting Started

    1. [Create an account](/register/) and set up your first app
    2. Copy your **App API Key** (UUID) from the [Dashboard](/dashboard/)
    3. Integrate with our [SDKs](/sdk/) or call the API directly

    ## Authentication

    All API endpoints require the `X-App-Key` header with your App API Key:

    ```
    X-App-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    ```

    ## Core Endpoints

    - **POST /api/v1/events/** — Submit analytics events
    - **GET /api/v1/events/summary/** — Retrieve event summary
    - **GET /api/v1/events/top/** — Top events by count

    ## SDKs

    Official SDKs handle authentication, batching, and RAM-only event queue automatically:
    - [Swift (iOS)](/sdk/swift/)
    - [Kotlin (Android)](/sdk/kotlin/)
    - [Flutter](/sdk/flutter/)
    - [React Native](/sdk/react-native/)

    ## Support

    Questions? Visit our [SDK documentation](/sdk/) or [contact us](/contact/).
  license:
    name: Proprietary
  version: v1
host: respectlytics.com
schemes:
- https
basePath: /api
consumes:
- application/json
produces:
- application/json
securityDefinitions:
  App API Key:
    type: apiKey
    name: X-App-Key
    in: header
    description: |+
      App API Key sent via the X-App-Key header.

      • In Swagger UI: click the Authorize button and paste only the UUID value.
      • In your app or curl: send header X-App-Key: App_API_Key.

security:
- App API Key: []
paths:
  /v1/:
    get:
      operationId: v1_list
      summary: Respectlytics API Root
      description: |-
        Welcome to the Respectlytics API - a privacy-first mobile analytics platform.

        > ⚠️ **AUTHENTICATION REQUIRED:** All endpoints require app_key authentication.

        **Mobile App API Endpoints:**
        - POST /api/v1/events/ - Submit an analytics event
        - GET /api/v1/events/summary/ - Get aggregated analytics data
        - GET /api/v1/events/geo-summary/ - Get geographic distribution
        - GET /api/v1/events/funnel/ - Analyze conversion funnels
        - GET /api/v1/events/event-types/ - List all event types for your app

        **Getting Started:**
        1. Register at /register/ and login at /login/
        2. Create an app via the Dashboard at /dashboard/
        3. Copy your app_key and use it in your mobile app
        4. Send events from your app using the X-App-Key header
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - v1
    parameters: []
  /v1/analytics/conversion-paths/:
    get:
      operationId: v1_analytics_conversion-paths_list
      summary: Discover top conversion paths
      description: |2

        Automatically discover the most common behavior sequences that lead to conversion within sessions.

        **Required Parameter:**
        - `conversion_events`: Comma-separated event names (e.g., "purchase,subscription_start")

        **What This Endpoint Does:**
        1. Finds all sessions that include a conversion event
        2. Extracts the event sequence leading to conversion within each session
        3. Groups common patterns and ranks by frequency
        4. Returns top N paths with timing statistics

        **Session-Based Analysis:**
        - Each session is analyzed independently (no cross-session tracking)
        - Paths show what happens within a single app usage period
        - Maximum session duration is ~2 hours

        **Use Cases:**
        - Discover which in-session journeys lead to purchase
        - Find the most effective onboarding flows
        - Identify hidden conversion patterns within sessions
      parameters:
      - name: conversion_events
        in: query
        description: 'REQUIRED: Comma-separated event names to count as conversions'
        required: true
        type: string
      - name: limit
        in: query
        description: 'Maximum number of paths to return (default: 5, max: 20)'
        required: false
        type: integer
      - name: min_sessions
        in: query
        description: 'Minimum sessions for a path to be included (default: 3)'
        required: false
        type: integer
      - name: max_path_length
        in: query
        description: 'Maximum events in a path before conversion (default: 10)'
        required: false
        type: integer
      - name: start_date
        in: query
        description: Start date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: end_date
        in: query
        description: End date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Top conversion paths with statistics
          examples:
            application/json:
              app:
                id: 1
                name: My App
                slug: my-app
              filters:
                conversion_events:
                - purchase
                start_date: null
                end_date: null
                limit: 5
                min_sessions: 3
                max_path_length: 10
              data_quality:
                total_converting_sessions: 234
                paths_analyzed: 187
                unique_paths_found: 42
              top_conversion_paths:
              - rank: 1
                path:
                - app_open
                - feature_demo
                - pricing_view
                - purchase
                sessions: 89
                conversion_rate: 0.42
                avg_duration_minutes: 15.5
                step_timings:
                - from: app_open
                  to: feature_demo
                  avg_minutes: 2.3
                - from: feature_demo
                  to: pricing_view
                  avg_minutes: 8.1
                - from: pricing_view
                  to: purchase
                  avg_minutes: 5.1
              interpretation: These paths show what sessions do before they convert.
                Each session is analyzed independently.
        '400':
          description: Missing or invalid parameters
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - Analytics
    parameters: []
  /v1/analytics/conversions/:
    get:
      operationId: v1_analytics_conversions_list
      description: |2

        Get conversion summary with flexible time granularity.

        **Required Parameter:**
        The `conversion_events` parameter is **required**. Specify which events to count as conversions.

        **Example:**
        `?conversion_events=purchase,subscription_complete`

        **What is a "conversion rate"?**
        Conversion rate = sessions with conversions / total unique sessions per period.
        A session is a unique app usage period (max 2 hours), identified by session_id.

        **Granularity Options:**
        - `day` (default): Daily conversion data
        - `week`: Weekly conversions - ISO weeks, Mon-Sun
        - `month`: Monthly conversions
        - `quarter`: Quarterly conversions
        - `year`: Yearly conversions

        **Period Labels:**
        | Granularity | Format | Example |
        |-------------|--------|---------|
        | day | YYYY-MM-DD | 2025-11-27 |
        | week | YYYY-Www | 2025-W48 |
        | month | YYYY-MM | 2025-11 |
        | quarter | YYYY-Qn | 2025-Q4 |
        | year | YYYY | 2025 |
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      - name: conversion_events
        in: query
        description: 'REQUIRED: Comma-separated event names to count as conversions
          (e.g., purchase,subscription_complete)'
        required: true
        type: string
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format
        required: false
        type: string
      - name: to
        in: query
        description: End date in YYYY-MM-DD format
        required: false
        type: string
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      - name: granularity
        in: query
        description: 'Time period grouping: day (default), week, month, quarter, year'
        required: false
        type: string
        enum:
        - day
        - week
        - month
        - quarter
        - year
      responses:
        '200':
          description: Conversion summary data by period
          examples:
            application/json:
              app_name: My App
              granularity: month
              conversion_events:
              - purchase
              - subscription_start
              date_range:
                from: '2025-09-01'
                to: '2025-11-27'
              summary:
                total_conversions: 1042
                avg_conversion_rate: 0.0312
              conversions:
              - period: 2025-11
                conversions: 342
                active_sessions: 11793
                conversion_rate: 0.029
              - period: 2025-10
                conversions: 385
                active_sessions: 12419
                conversion_rate: 0.031
              - period: 2025-09
                conversions: 315
                active_sessions: 9265
                conversion_rate: 0.034
              interpretation: Conversion rate shows the percentage of sessions that
                include a conversion event. Each session is analyzed independently.
        '400':
          description: Bad Request - missing conversion_events or invalid parameters
          examples:
            application/json:
              error: conversion_events parameter required
              detail: Please specify which events to count as conversions.
              your_event_types:
              - app_open
              - screen_view
              - button_click
              - checkout_start
              - payment_success
              example: ?conversion_events=payment_success,checkout_start
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/analytics/dau/:
    get:
      operationId: v1_analytics_dau_list
      description: |2

        Get active sessions with flexible time granularity.

        **What is a "session"?**
        A session represents a single app usage period, identified by a unique session_id.
        Sessions automatically rotate every 2 hours and do not persist across app restarts.
        This provides usage metrics without requiring user consent for tracking.

        **Granularity Options:**
        - `day` (default): Daily active sessions
        - `week`: Weekly active sessions - ISO weeks, Mon-Sun
        - `month`: Monthly active sessions
        - `quarter`: Quarterly active sessions
        - `year`: Yearly active sessions

        **Period Labels:**
        | Granularity | Format | Example |
        |-------------|--------|---------|
        | day | YYYY-MM-DD | 2025-11-27 |
        | week | YYYY-Www | 2025-W48 |
        | month | YYYY-MM | 2025-11 |
        | quarter | YYYY-Qn | 2025-Q4 |
        | year | YYYY | 2025 |
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format
        required: false
        type: string
      - name: to
        in: query
        description: End date in YYYY-MM-DD format
        required: false
        type: string
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      - name: granularity
        in: query
        description: 'Time period grouping: day (default), week, month, quarter, year'
        required: false
        type: string
        enum:
        - day
        - week
        - month
        - quarter
        - year
      responses:
        '200':
          description: Active sessions data by period with session length metrics
          examples:
            application/json:
              app_name: My App
              granularity: week
              date_range:
                from: '2025-11-01'
                to: '2025-11-27'
              active_sessions:
              - period: 2025-W48
                unique_sessions: 3456
                total_events: 15234
                avg_session_length_seconds: 245.3
                sessions_with_duration: 2891
              - period: 2025-W47
                unique_sessions: 3189
                total_events: 14102
                avg_session_length_seconds: 238.7
                sessions_with_duration: 2654
              - period: 2025-W46
                unique_sessions: 2987
                total_events: 13456
                avg_session_length_seconds: 251.2
                sessions_with_duration: 2503
              summary:
                total_sessions: 9632
                sessions_with_duration: 8048
                avg_session_length_seconds: 245.1
              top_events_current_period:
              - event_name: app_open
                count: 5341
              - event_name: screen_view
                count: 4876
        '400':
          description: Bad Request - invalid date format or granularity
          examples:
            application/json:
              error: 'Invalid granularity. Must be one of: day, week, month, quarter,
                year'
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/analytics/drop-off/:
    get:
      operationId: v1_analytics_drop-off_list
      summary: Get drop-off diagnostics
      description: |2

        Identify where non-converting sessions end.

        **Required Parameter:**
        - `conversion_events`: Comma-separated event names (e.g., "purchase,subscription_start")

        **What This Endpoint Does:**
        1. Finds all sessions that did NOT include a conversion event
        2. Identifies their "last event before session end" (where they dropped off)
        3. Ranks events by drop-off frequency
        4. Compares non-converting vs converting session behavior patterns
        5. Calculates impact scores to prioritize fixes

        **Session-Based Analysis:**
        - Each session is analyzed independently (no cross-session tracking)
        - Shows where sessions end without converting
        - Maximum session duration is ~2 hours

        **Use Cases:**
        - Find which features are causing sessions to end without converting
        - Identify friction points in the onboarding flow
        - Prioritize UX improvements for conversion impact
        - Compare where converting vs non-converting sessions spend time
      parameters:
      - name: conversion_events
        in: query
        description: 'REQUIRED: Comma-separated event names to count as conversions'
        required: true
        type: string
      - name: min_sessions
        in: query
        description: 'Minimum sessions for a drop-off point to be included (default:
          5)'
        required: false
        type: integer
      - name: limit
        in: query
        description: 'Maximum number of drop-off points to return (default: 10, max:
          50)'
        required: false
        type: integer
      - name: start_date
        in: query
        description: Start date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: end_date
        in: query
        description: End date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Drop-off diagnostics with ranked problem areas
          examples:
            application/json:
              app:
                id: 1
                name: My App
                slug: my-app
              filters:
                conversion_events:
                - purchase
                start_date: null
                end_date: null
                min_sessions: 5
                limit: 10
              data_quality:
                total_sessions: 500
                converting_sessions: 150
                non_converting_sessions: 350
                conversion_rate: 0.3
              drop_off_points:
              - rank: 1
                event: pricing_view
                sessions_dropped: 89
                drop_off_rate: 0.25
                avg_time_before_exit_minutes: 2.5
                impact_score: 0.85
                converter_comparison:
                  converters_with_event: 120
                  converters_event_rate: 0.8
                  non_converters_event_rate: 0.45
                  differential: -0.35
              events_more_common_in_non_converters:
              - event: support_contact
                non_converter_rate: 0.35
                converter_rate: 0.08
                differential: 0.27
              interpretation: Sessions that don't convert - where do they end? Each
                session is analyzed independently.
        '400':
          description: Missing or invalid parameters
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - Analytics
    parameters: []
  /v1/analytics/event-correlation/:
    get:
      operationId: v1_analytics_event-correlation_list
      summary: Get event correlation analysis (Conversion Drivers)
      description: |2

        Identify which events correlate with conversion (positive or negative lift).

        **Required Parameter:**
        - `conversion_events`: Comma-separated event names (e.g., "purchase,subscription_start")

        **What This Endpoint Does:**
        1. For each event type, calculates conversion rate of sessions that include it vs don't
        2. Computes lift score: `(rate_with / rate_without - 1) × 100`
        3. Separates events into positive correlation (boost conversion) and negative correlation (hurt conversion)
        4. Ranks by absolute lift value

        **Lift Score Interpretation:**
        - `+245%` means sessions with this event are 3.45x more likely to convert
        - `-67%` means sessions with this event are 67% less likely to convert
        - `0%` means no correlation with conversion

        **Session-Based Analysis:**
        - Each session is analyzed independently (no cross-session tracking)
        - Minimum 10 sessions per event by default (configurable)
        - Maximum session duration is ~2 hours

        **Use Cases:**
        - Find which in-session behaviors drive conversions
        - Identify features that correlate with session abandonment
        - Prioritize feature development based on conversion impact
        - A/B test validation: does new feature improve conversion?
      parameters:
      - name: conversion_events
        in: query
        description: 'REQUIRED: Comma-separated event names to count as conversions'
        required: true
        type: string
      - name: min_sessions
        in: query
        description: 'Minimum sessions for an event to be included (default: 10)'
        required: false
        type: integer
      - name: limit
        in: query
        description: 'Maximum events per category (default: 10, max: 50)'
        required: false
        type: integer
      - name: start_date
        in: query
        description: Start date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: end_date
        in: query
        description: End date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Event correlation analysis with lift scores
          examples:
            application/json:
              app:
                id: 1
                name: My App
                slug: my-app
              filters:
                conversion_events:
                - purchase
                start_date: null
                end_date: null
                min_sessions: 10
                limit: 10
              data_quality:
                total_sessions: 500
                converting_sessions: 150
                non_converting_sessions: 350
                baseline_conversion_rate: 0.3
                events_analyzed: 15
              positive_correlations:
              - rank: 1
                event: feature_demo
                lift_percent: 245.5
                sessions_with_event: 456
                sessions_without_event: 44
                conversion_rate_with: 0.52
                conversion_rate_without: 0.15
                converts_with: 237
                converts_without: 7
              negative_correlations:
              - rank: 1
                event: error_screen
                lift_percent: -67.3
                sessions_with_event: 123
                sessions_without_event: 377
                conversion_rate_with: 0.11
                conversion_rate_without: 0.34
                converts_with: 14
                converts_without: 128
              neutral_events:
              - app_open
              - screen_view
              interpretation: 'Sessions that include X: correlation with conversion.
                Each session analyzed independently.'
        '400':
          description: Missing or invalid parameters
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - Analytics
    parameters: []
  /v1/analytics/globe-stats/:
    get:
      operationId: v1_analytics_globe-stats_list
      description: |2

        Get country-level analytics optimized for globe visualizations.

        This endpoint provides aggregated statistics by country without period grouping,
        making it significantly faster than segment-comparison for geographic data.
        Results are cached for 15 minutes for optimal performance.
      parameters:
      - name: app_key
        in: query
        description: Your application's API key (required)
        required: true
        type: string
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format (required)
        required: true
        type: string
        format: date
      - name: to
        in: query
        description: End date in YYYY-MM-DD format (required)
        required: true
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      - name: conversion_events
        in: query
        description: Comma-separated list of event names to count as conversions (optional)
        required: false
        type: string
      responses:
        '200':
          description: Country-level statistics
          examples:
            application/json:
              data:
              - country: US
                events: 1234
                sessions: 567
                conversions: 89
                conversion_rate: 15.7
              - country: GB
                events: 890
                sessions: 345
                conversions: 45
                conversion_rate: 13.0
              cached: true
              cache_expires_in: 900
        '400':
          description: Bad request - missing or invalid parameters
        '401':
          description: Unauthorized - invalid or missing API key
        '500':
          description: Internal server error
      tags:
      - v1
    parameters: []
  /v1/analytics/segments/:
    get:
      operationId: v1_analytics_segments_list
      summary: Segment Comparison
      description: |2

        Compare conversion rates across different session segments with flexible time granularity.

        **Session-Based Analysis:**
        All analysis is session-scoped. Each unique session_id is counted once per period.
        This provides privacy-friendly analytics without cross-session tracking.

        **Segment Types:**
        - `platform`: Compare iOS, Android, Web, and Other platforms
        - `country`: Compare by ISO 2-letter country code (US, GB, DE, etc.)
        - `depth`: Compare by session depth (events per session) - buckets: 1, 2, 3, 4, 5, 6-10, 11-20, 21+
        - `hour`: Compare by hour of day (0-23 UTC) - ideal for identifying peak engagement times

        **Granularity Options:**
        - `day` (default): Daily segment data
        - `week`: Weekly segment data - ISO weeks, Mon-Sun
        - `month`: Monthly segment data
        - `quarter`: Quarterly segment data
        - `year`: Yearly segment data

        **Period Labels:**
        | Granularity | Format | Example |
        |-------------|--------|---------|
        | day | YYYY-MM-DD | 2025-11-27 |
        | week | YYYY-Www | 2025-W48 |
        | month | YYYY-MM | 2025-11 |
        | quarter | YYYY-Qn | 2025-Q4 |
        | year | YYYY | 2025 |

        **Privacy Note:**
        All segmentation is done on aggregate data only. No individual user journeys
        are exposed. Country data comes from request headers only - no IP geolocation.
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      - name: conversion_events
        in: query
        description: 'REQUIRED: Comma-separated event names to count as conversions
          (e.g., purchase,subscription_complete)'
        required: true
        type: string
      - name: segment_by
        in: query
        description: 'Segmentation type: platform (default), country, depth (events
          per session), or hour (0-23 UTC)'
        required: false
        type: string
        enum:
        - platform
        - country
        - depth
        - hour
      - name: granularity
        in: query
        description: 'Time period grouping: day (default), week, month, quarter, year'
        required: false
        type: string
        enum:
        - day
        - week
        - month
        - quarter
        - year
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format
        required: false
        type: string
      - name: to
        in: query
        description: End date in YYYY-MM-DD format
        required: false
        type: string
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Segment comparison data
          examples:
            application/json:
              app_name: My App
              granularity: month
              segment_by: platform
              conversion_events:
              - purchase
              date_range:
                from: '2025-09-01'
                to: '2025-11-27'
              summary:
                total_segments: 2
                total_conversions: 570
                total_sessions: 8027
                overall_conversion_rate: 0.068
              interpretation: 'Session-scoped analysis: each unique session_id counted
                once per period'
              segments:
              - segment: iOS
                summary:
                  total_active_sessions: 4497
                  total_conversions: 359
                  conversion_rate: 0.08
                periods:
                - period: 2025-11
                  active_sessions: 2341
                  conversions: 187
                  conversion_rate: 0.08
                - period: 2025-10
                  active_sessions: 2156
                  conversions: 172
                  conversion_rate: 0.08
              - segment: Android
                summary:
                  total_active_sessions: 3530
                  total_conversions: 211
                  conversion_rate: 0.06
                periods:
                - period: 2025-11
                  active_sessions: 1876
                  conversions: 112
                  conversion_rate: 0.06
                - period: 2025-10
                  active_sessions: 1654
                  conversions: 99
                  conversion_rate: 0.06
        '400':
          description: Bad Request - missing conversion_events or invalid parameters
          examples:
            application/json:
              error: conversion_events parameter required
              detail: Please specify which events to count as conversions.
              your_event_types:
              - app_open
              - screen_view
              - button_click
              - checkout_start
              - payment_success
              example: ?conversion_events=payment_success,checkout_start
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/analytics/step-timing/:
    get:
      operationId: v1_analytics_step-timing_list
      summary: Analyze funnel step timing
      description: |2

        Analyze the time between consecutive steps in a user-defined funnel.

        **Session-Based Analysis:**
        This endpoint analyzes events within the **same session_id**. This means:
        - Works for 100% of your sessions (including anonymous visitors)
        - No data quality warnings or exclusions
        - Perfect for in-session funnel analysis

        **Example Use Cases:**
        - How long does onboarding take? (`steps=onboarding_start,onboarding_complete`)
        - Where do sessions slow down in signup? (`steps=signup_start,email_entered,password_set,signup_complete`)
        - How long between pricing view and purchase? (`steps=pricing_view,purchase`)

        **Statistics Provided:**
        - Time between each consecutive step pair (median, mean, p25, p75 in seconds)
        - Number of sessions analyzed per transition
        - Overall funnel completion rate
        - Total funnel duration
      parameters:
      - name: steps
        in: query
        description: Comma-separated list of funnel step event names (required, minimum
          2)
        required: true
        type: string
      - name: start_date
        in: query
        description: Start date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: end_date
        in: query
        description: End date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Funnel step timing analysis
          examples:
            application/json:
              app:
                id: 1
                name: My App
                slug: my-app
              steps:
              - onboarding_start
              - onboarding_complete
              - purchase
              filters:
                start_date: null
                end_date: null
              transitions:
              - from: onboarding_start
                to: onboarding_complete
                sessions_analyzed: 1234
                median_seconds: 45
                mean_seconds: 52
                p25_seconds: 30
                p75_seconds: 65
              - from: onboarding_complete
                to: purchase
                sessions_analyzed: 234
                median_seconds: 120
                mean_seconds: 145
                p25_seconds: 60
                p75_seconds: 180
              funnel_summary:
                sessions_with_first_step: 1234
                sessions_with_all_steps: 234
                completion_rate: 0.19
                median_total_seconds: 165
                mean_total_seconds: 197
        '400':
          description: Missing or invalid steps parameter
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - Analytics
    parameters: []
  /v1/analytics/time-to-conversion/:
    get:
      operationId: v1_analytics_time-to-conversion_list
      summary: Get time-to-conversion analysis
      description: |2

        Analyze how long it takes sessions to complete conversion events after their first
        interaction with the app. This is a session-based analysis.

        **Required Parameters:**
        - `conversion_events`: Comma-separated conversion event names

        **Data Quality:**
        - Minimum 10 sessions with conversions required for meaningful analysis
        - Data quality metrics included in response

        **Statistics Provided:**
        - Median, mean, and percentiles (p25, p75, p90) for time-to-conversion
        - Time buckets: <5min, 5-15min, 15-60min, 1-2h (session-bounded)
      parameters:
      - name: conversion_events
        in: query
        description: Comma-separated list of conversion event names (required)
        required: true
        type: string
      - name: start_date
        in: query
        description: Start date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: end_date
        in: query
        description: End date filter (YYYY-MM-DD)
        required: false
        type: string
        format: date
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      responses:
        '200':
          description: Time-to-conversion analysis
          schema:
            type: object
            properties:
              app:
                type: object
              filters:
                type: object
              data_quality:
                type: object
              time_to_conversion:
                type: object
              time_distribution:
                type: object
        '400':
          description: Missing required parameters or insufficient data
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - Analytics
    parameters: []
  /v1/events/:
    post:
      operationId: v1_events_create
      description: |-
        Submit an analytics event from your mobile app.

        **Privacy-First Validation:**
        Respectlytics enforces strict server-side privacy guards. Your request must:
        - Only include fields from the allowed list (see request body schema)
        - Use properly formatted session_id (16+ random chars, NOT UUID format)

        **Stored Fields:** Only these fields are persisted: event_name, session_id, timestamp, platform, country.

        **Deprecated Fields (accepted but ignored):** For backwards compatibility, these fields are still accepted but are NOT stored: device_type, os_version, app_version, locale, region, screen. Update your SDK to stop sending these fields.

        **Geolocation:** If you don't provide `country`, it will be automatically detected from your IP address. IP addresses are NEVER stored - they are used only for the lookup and immediately discarded.

        **Session Anonymization:** Session IDs are hashed with a daily-rotating salt before storage. This prevents cross-session tracking while enabling same-day funnel analysis.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          required:
          - event_name
          type: object
          properties:
            event_name:
              description: Event name (e.g., "app_open", "purchase")
              type: string
            session_id:
              description: Session identifier - must be 16+ random chars, NOT a UUID
                format. Anonymized with daily rotation.
              type: string
            timestamp:
              description: ISO 8601 timestamp - auto-set to current time if omitted
              type: string
            platform:
              description: 'Platform: ios, android, web, or other'
              type: string
            country:
              description: Country code (e.g., "US") - auto-detected if omitted
              type: string
            region:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
            device_type:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
            os_version:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
            app_version:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
            locale:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
            screen:
              description: 'DEPRECATED: Accepted but not stored'
              type: string
      - name: X-App-Key
        in: header
        description: Your app's API key (UUID)
        required: true
        type: string
      responses:
        '201':
          description: Event created successfully
          examples:
            application/json:
              id: 12345
              event_name: purchase
              timestamp: '2025-11-12T10:30:00Z'
              message: Event created successfully
        '400':
          description: Bad Request - Privacy violation or invalid data
          schema:
            type: object
            properties:
              detail:
                description: Error summary
                type: string
              code:
                description: 'Error code: FORBIDDEN_FIELD, FORBIDDEN_FIELDS, or INVALID_SESSION_ID'
                type: string
                enum:
                - FORBIDDEN_FIELD
                - FORBIDDEN_FIELDS
                - INVALID_SESSION_ID
              reason:
                description: Detailed explanation with fix instructions
                type: string
          examples:
            application/json:
              FORBIDDEN_FIELD:
                detail: Invalid request
                code: FORBIDDEN_FIELD
                reason: 'Field ''device_id'' is not allowed. Respectlytics only accepts:
                  app_key, app_version, country, device_type, event_name, locale,
                  os_version, platform, region, screen, session_id, timestamp.'
              INVALID_SESSION_ID:
                detail: Invalid request
                code: INVALID_SESSION_ID
                reason: session_id appears to be a device identifier or predictable
                  pattern. Use a random string generated fresh for each app session.
        '401':
          description: Unauthorized - missing or invalid app_key
          examples:
            application/json:
              detail: Authentication credentials were not provided.
      tags:
      - v1
    parameters: []
  /v1/events/count/:
    get:
      operationId: v1_events_count_list
      description: |-
        GET /api/v1/events/count/ - Get fast event count for processing status
        Query parameters:
            - from: Start date (YYYY-MM-DD)
            - to: End date (YYYY-MM-DD)

        Returns only the count without expensive aggregations.
        Optimized for showing processing banners with accurate event counts.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - v1
    parameters: []
  /v1/events/delete/:
    post:
      operationId: v1_events_delete_create
      description: |-
        Permanently delete analytics events matching the given filters.

        **This action is irreversible.** All matching events will be permanently removed.

        Date range is required. Platform, country, and event_name are optional additional filters.
        A DeletionLog entry is created for audit purposes.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          required:
          - date_from
          - date_to
          type: object
          properties:
            date_from:
              description: Start date (YYYY-MM-DD)
              type: string
            date_to:
              description: End date (YYYY-MM-DD)
              type: string
            platform:
              description: 'Optional: ios, android, web, other'
              type: string
            country:
              description: 'Optional: ISO country code (e.g., "US")'
              type: string
            event_name:
              description: 'Optional: specific event name'
              type: string
      - name: X-App-Key
        in: header
        description: Your app's API key (UUID)
        required: true
        type: string
      responses:
        '200':
          description: Deletion completed
          examples:
            application/json:
              events_deleted: 1523
              deletion_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        '400':
          description: Invalid request parameters
      tags:
      - v1
    parameters: []
  /v1/events/delete/preview/:
    post:
      operationId: v1_events_delete_preview_create
      description: |-
        Preview the number of events that would be deleted by the given filters.

        Use this endpoint to check how many events match before calling the delete endpoint.
        Date range is required. Platform, country, and event_name are optional additional filters.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          required:
          - date_from
          - date_to
          type: object
          properties:
            date_from:
              description: Start date (YYYY-MM-DD)
              type: string
            date_to:
              description: End date (YYYY-MM-DD)
              type: string
            platform:
              description: 'Optional: ios, android, web, other'
              type: string
            country:
              description: 'Optional: ISO country code (e.g., "US")'
              type: string
            event_name:
              description: 'Optional: specific event name'
              type: string
      - name: X-App-Key
        in: header
        description: Your app's API key (UUID)
        required: true
        type: string
      responses:
        '200':
          description: Count of matching events
          examples:
            application/json:
              events_matching: 1523
        '400':
          description: Invalid request parameters
      tags:
      - v1
    parameters: []
  /v1/events/deletions/:
    get:
      operationId: v1_events_deletions_list
      description: |-
        Retrieve the deletion history for this app.

        Returns a list of all past event deletions with details about what was deleted and when.
        Useful for audit trail and demonstrating deletion request fulfilment.
      parameters:
      - name: X-App-Key
        in: header
        description: Your app's API key (UUID)
        required: true
        type: string
      responses:
        '200':
          description: List of deletion log entries
          examples:
            application/json:
              deletions:
              - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                deleted_at: '2026-02-10T14:30:00Z'
                events_deleted: 1523
                filter_date_from: '2026-01-01'
                filter_date_to: '2026-01-31'
                filter_platform: null
                filter_country: US
                filter_event_name: null
      tags:
      - v1
    parameters: []
  /v1/events/event-types/:
    get:
      operationId: v1_events_event-types_list
      description: Get all distinct event types being tracked for your app
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      responses:
        '200':
          description: List of event types
          examples:
            application/json:
              app_name: My Mobile App
              app_key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
              event_types:
              - app_open
              - product_view
              - purchase
              - share
              - settings_open
              count: 5
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/events/funnel/:
    get:
      operationId: v1_events_funnel_list
      description: Analyze conversion funnel through sequential event steps
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      - name: steps
        in: query
        description: Comma-separated event names in order (e.g., 'app_open,product_view,purchase')
        required: true
        type: string
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format
        required: false
        type: string
      - name: to
        in: query
        description: End date in YYYY-MM-DD format
        required: false
        type: string
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      - name: country
        in: query
        description: Filter by country code (e.g., 'US')
        required: false
        type: string
      - name: platform
        in: query
        description: Filter by platform (ios, android, web, other)
        required: false
        type: string
      - name: window_minutes
        in: query
        description: Step timeout in minutes - max time allowed between consecutive
          funnel steps (e.g., '30' for 30 minutes). Sessions are max 2 hours, so values
          above 120 have no effect. If not specified, no time limit is applied.
        required: false
        type: integer
      responses:
        '200':
          description: Funnel analysis results
          examples:
            application/json:
              app_name: My Mobile App
              app_key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
              funnel:
              - step: app_open
                count: 1000
              - step: product_view
                count: 420
              - step: purchase
                count: 90
              total_sessions_analyzed: 1200
        '400':
          description: Bad request - missing or invalid parameters
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/events/geo-summary/:
    get:
      operationId: v1_events_geo-summary_list
      description: Get geographic distribution of events for map visualizations
      parameters:
      - name: X-App-Key
        in: header
        description: App Key for authentication
        required: true
        type: string
      - name: from
        in: query
        description: Start date in YYYY-MM-DD format
        required: false
        type: string
      - name: to
        in: query
        description: End date in YYYY-MM-DD format
        required: false
        type: string
      - name: tz
        in: query
        description: IANA timezone name (e.g., 'America/New_York', 'Europe/London').
          Dates are interpreted in this timezone. Defaults to UTC.
        required: false
        type: string
        default: UTC
      - name: limit
        in: query
        description: 'Maximum results per category (default: 20)'
        required: false
        type: integer
      responses:
        '200':
          description: Geographic distribution data
          examples:
            application/json:
              app_name: My Mobile App
              app_key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
              total_events: 15420
              countries:
              - country: US
                count: 8500
                percentage: 55.1
              - country: CA
                count: 3200
                percentage: 20.8
              - country: UK
                count: 2100
                percentage: 13.6
        '400':
          description: Bad Request - invalid date format
        '401':
          description: Unauthorized - missing or invalid app_key
      tags:
      - v1
    parameters: []
  /v1/events/summary/:
    get:
      operationId: v1_events_summary_list
      description: |-
        GET /api/v1/events/summary/ - Get aggregated event data (requires authentication)
        Query parameters:
            - from: Start date (YYYY-MM-DD)
            - to: End date (YYYY-MM-DD)

        Returns data for the authenticated app.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - v1
    parameters: []
  /v1/health/:
    get:
      operationId: v1_health_list
      description: |-
        Health check endpoint for load balancers and monitoring.
        Returns 200 if the service is healthy.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - v1
    parameters: []
definitions: {}
