openapi: 3.1.0
info:
  title: Fluid Rep APIs
  description: >-
    The **Fluid Rep APIs** provide endpoints for authenticated Reps (Users) to
    access their own data and perform actions on their behalf.


    ## Authentication


    These APIs use **User tokens** for authentication. User tokens are obtained
    through:

    - Magic link authentication

    - JWT exchange (`/api/user_companies/jwt_exchange`)

    - Token exchange (`/api/user_companies/token_exchange`)


    Unlike Company APIs which use Company API tokens for administrative access,
    Rep APIs authenticate the individual user and provide access to their
    personal data, orders, team, and settings.


    For Company-level management APIs, see the Company APIs documentation.
  contact:
    email: support@fluid.app
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: '1.0'
security: []
servers:
  - url: https://{company}.fluid.app
    description: Production server with company subdomain
    variables:
      company:
        default: myco
        description: Company subdomain
  - url: http://fluid.lvh.me:{port}
    description: Local development server
    variables:
      port:
        default: '3000'
        description: The port number for local development
components:
  securitySchemes:
    bearer_auth:
      type: http
      scheme: bearer
      description: >-
        User token obtained from authentication flow (magic link, JWT exchange,
        etc.)
  schemas:
    Meta:
      type: object
      description: Standard response metadata
      properties:
        request_id:
          type: string
          description: Unique identifier for the request
          example: f47ac10b-58cc-4372-a567-0e02b2c3d479
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp of the response
          example: '2025-01-15T10:30:00Z'
      required:
        - request_id
        - timestamp
    OnboardingStep:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - pending
            - completed
            - skipped
        time_estimate:
          type: integer
        allow_manual_completion:
          type: boolean
    OnboardingSection:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        steps:
          type: array
          items:
            $ref: '#/components/schemas/OnboardingStep'
        progress:
          type: object
          properties:
            completed:
              type: integer
            skipped:
              type: integer
            pending:
              type: integer
            total:
              type: integer
            percentage:
              type: integer
            time_remaining:
              type: integer
            all_done:
              type: boolean
    Onboarding:
      type: object
      properties:
        sections:
          type: array
          items:
            $ref: '#/components/schemas/OnboardingSection'
        overall:
          type: object
          properties:
            completed:
              type: integer
            skipped:
              type: integer
            pending:
              type: integer
            total:
              type: integer
            percentage:
              type: integer
            time_remaining:
              type: integer
        completed:
          type: boolean
        show_getting_started:
          type: boolean
    ErrorResponse:
      type: object
      description: Standard error response
      properties:
        error_message:
          type: string
          description: Human-readable error message
          example: Validation failed
        errors:
          type: object
          description: Field-specific validation errors
          additionalProperties:
            type: array
            items:
              type: string
        meta:
          $ref: '#/components/schemas/Meta'
      required:
        - error_message
        - meta
paths:
  /api/analytics:
    get:
      summary: Get analytics summary
      tags:
        - Analytics
      operationId: getAnalyticsSummary
      description: |
        Returns analytics summary for the current user.

        When the user has affiliate data, returns metrics including:
        - Unique visitors
        - Total views
        - Total leads
        - Total shares
        - Conversion rates
        - Top performing content

        Returns an empty object if no analytics data is available.
      security:
        - bearer_auth: []
      parameters:
        - name: start_date
          in: query
          required: false
          description: Start date for analytics period (ISO 8601 format)
          schema:
            type: string
        - name: end_date
          in: query
          required: false
          description: End date for analytics period (ISO 8601 format)
          schema:
            type: string
      responses:
        '200':
          description: analytics retrieved
          content:
            application/json:
              schema:
                type: object
                example:
                  unique_visitors: 1247
                  total_views: 3892
                  total_leads: 89
                  total_shares: 156
                  total_orders: 23
                  total_revenue: 4523.5
                  conversion_rate: 7.14
                  mysite_views: 1523
                  mysite_leads: 47
                  top_media:
                    - id: 42
                      title: The Importance of Paper Quality
                      views: 892
                      shares: 34
                      leads: 12
                    - id: 87
                      title: How to Choose the Right Paper Weight
                      views: 654
                      shares: 28
                      leads: 8
                    - id: 23
                      title: Sustainability in Paper Production
                      views: 521
                      shares: 19
                      leads: 6
                  leads_by_source:
                    mysite: 34
                    media: 28
                    referral: 15
                    organic: 12
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/authentication/send_mfa:
    post:
      summary: Send MFA Passcode
      description: Send MFA Passcode via email
      tags:
        - Authentication
      operationId: sendMultiFactorAuthentication
      parameters:
        - name: email
          in: query
          required: true
          description: Email address of the user
          schema:
            type: string
        - name: fluid_shop
          in: query
          required: false
          description: 'Shop name, eg: company.fluid.app'
          schema:
            type: string
      responses:
        '201':
          description: generic success response
          content:
            application/json:
              schema:
                type: object
                properties:
                  multi_factor_authentication:
                    title: MultiFactorAuthentication
                    type: object
                    properties:
                      uuid:
                        type: string
                      authenticated:
                        type: boolean
                      verification_channel:
                        type: string
                      verification_code_expires_at:
                        type: string
                    required:
                      - uuid
                      - verification_channel
                      - authenticated
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: 123e4567-e89b-12d3-a456-426614174000
                      timestamp:
                        type: string
                        example: '2021-01-01T00:00:00Z'
                required:
                  - multi_factor_authentication
  /api/authentication/confirm_mfa:
    post:
      summary: Confirm MFA passcode
      description: Confirm MFA Passcode
      tags:
        - Authentication
      operationId: confirmMultiFactorAuthentication
      parameters: []
      responses:
        '200':
          description: MFA code confirmed
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                    example: true
                  auth_type:
                    type: string
                    example: rep
                  companies:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        name:
                          type: string
                          example: John Doe
                        shop_name:
                          type: string
                          example: myco.fluid.app
                        logo_url:
                          type:
                            - string
                            - 'null'
                          example: https://example.com/logo.png
                        jwt:
                          type: string
                          example: eyJhbGciOiJIUzI1NiJ9.eyJhdXRoX3R5cGUiOiJjdX...
                        primary_domain_hostname:
                          type: string
                          example: myco.fluid.app
                      required:
                        - id
                        - name
                        - shop_name
                        - jwt
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
                required:
                  - authenticated
                  - auth_type
                  - companies
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                uuid:
                  type: string
                  example: drp_p4r9jsl305iduqrsl0ujdth35jhuy2al
                multi_factor_authentication:
                  type: object
                  properties:
                    verification_code:
                      type: string
                      example: '543432'
                  required:
                    - verification_code
              required:
                - uuid
                - multi_factor_authentication
  /api/authentication/me:
    get:
      summary: Fetch user details from JWT
      tags:
        - Authentication
      operationId: userDetailsViaMultiFactorAuthentication
      parameters:
        - name: jwt
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          description: user details given
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      first_name:
                        type:
                          - string
                          - 'null'
                        example: Mike
                      last_name:
                        type:
                          - string
                          - 'null'
                        example: Tingey
                      email:
                        type: string
                        example: mike@example.com
                      avatar_url:
                        type:
                          - string
                          - 'null'
                        example: >-
                          https://d1r16g5m5p3ba7.cloudfront.net/uploads/user/avatar/980190962/avatar.png
                      root_admin:
                        type: boolean
                        example: true
                  user_company:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      company_id:
                        type: integer
                        example: 226157151
                      company_name:
                        type: string
                        example: Fluid
                      roles:
                        type:
                          - array
                          - 'null'
                        example: '["admin", "developer"]'
                      user_type:
                        type:
                          - string
                          - 'null'
                        example: admin
                      logo_url:
                        type:
                          - string
                          - 'null'
                        example: https://cdn.filestackcontent.com/1Rnqia44T2mLcXuFZCTV
                      icon_url:
                        type:
                          - string
                          - 'null'
                        example: https://cdn.filestackcontent.com/1Rnqia44T2mLcXuFZCTV
                      fluid_shop:
                        type:
                          - string
                          - 'null'
                        example: myco.fluid.app
                      company_colors:
                        type:
                          - object
                          - 'null'
                        properties:
                          primary_color:
                            type:
                              - string
                              - 'null'
                            example: 0C7CF6
                          secondary_color:
                            type:
                              - string
                              - 'null'
                            example: 0C7CF6
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: 72591788-c981-47d1-8dd5-1cc0e1612815
                      timestamp:
                        type: string
                        format: date-time
                        example: '2025-05-08T06:18:09Z'
        '404':
          description: user not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: object
                    properties:
                      user:
                        type: array
                  error_message:
                    type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
  /api/authentication/resend_mfa:
    post:
      summary: Resend code via email
      tags:
        - Authentication
      operationId: resendMultiFactorAuthentication
      parameters:
        - name: uuid
          in: query
          required: true
          description: Current MFA uuid
          schema:
            type: string
      responses:
        '201':
          description: verification code resent
          content:
            application/json:
              schema:
                type: object
                properties:
                  multi_factor_authentication:
                    title: MultiFactorAuthentication
                    type: object
                    properties:
                      uuid:
                        type: string
                      verification_channel:
                        example: test@example.com
                        type: string
                      verification_code_expires_at:
                        example: '2025-02-17T08:00:01Z'
                        type:
                          - string
                          - 'null'
                        format: date-time
                      authenticated:
                        example: 'false'
                        type: boolean
                        default: false
                    required:
                      - uuid
                      - verification_channel
                      - authenticated
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: 123e4567-e89b-12d3-a456-426614174000
                      timestamp:
                        type: string
                        example: '2021-01-01T00:00:00Z'
                required:
                  - multi_factor_authentication
        '422':
          description: resend before 30 seconds
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: object
                    properties:
                      multi_factor_authentication:
                        type: array
                  error_message:
                    type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
  /api/authentication/company/{fluid_shop}:
    get:
      summary: Fetch company details from Fluid Shop name
      tags:
        - Authentication
      operationId: companyDetailsViaMultiFactorAuthentication
      parameters:
        - name: fluid_shop
          in: path
          required: true
          description: Fluid shop name
          example: myco
          schema:
            type: string
      responses:
        '200':
          description: company details given
          content:
            application/json:
              schema:
                type: object
                properties:
                  company:
                    type: object
                    properties:
                      name:
                        type: string
                      logo_url:
                        type:
                          - string
                          - 'null'
                        example: https://example.com/logo.png
                      color:
                        type: string
                        example: '#000000'
                      fluid_shop:
                        type: string
                        example: myco.fluid.app
                      primary_domain_hostname:
                        type: string
                        example: myco.com
                      support_email:
                        type:
                          - string
                          - 'null'
                        example: support@example.com
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
  /api/authentication/company/{company_id}/switch:
    put:
      summary: Switch company
      tags:
        - Authentication
      security:
        - bearer_auth: []
      operationId: switchCompany
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company id
          example: '980190965'
          schema:
            type: integer
      responses:
        '200':
          description: New company details with jwt given
          content:
            application/json:
              schema:
                type: object
                properties:
                  company:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      name:
                        type: string
                        example: fluid
                      fluid_shop:
                        type: string
                        example: myco.fluid.app
                      logo_url:
                        type:
                          - string
                          - 'null'
                        example: https://example.com/logo.png
                      jwt:
                        type: string
                        example: eyJhbGciOiJIUzI1NiJ9.eyJhdXRoX3R5cGUiOiJjdX...
                      redirect_path:
                        type: string
                        example: /admin/dashboard
                    required:
                      - id
                      - name
                      - fluid_shop
                      - logo_url
                      - jwt
                      - redirect_path
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
                required:
                  - company
                  - meta
        '404':
          description: Company not found or not associated with current user
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: object
                    properties:
                      company:
                        type: array
                  error_message:
                    type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                        example: f5473a8c-8a86-4e0e-b3e8-95392003921b
                      timestamp:
                        type: string
                        example: '2025-02-03T08:04:10Z'
  /api/contacts:
    get:
      summary: List contacts
      tags:
        - Contacts
      operationId: listContacts
      description: >
        Returns all contacts for the current user.


        Contacts include leads, customers, and prospects captured through
        various channels

        including MySite forms, shared media, and manual entry.
      security:
        - bearer_auth: []
      parameters:
        - name: filter
          in: query
          required: false
          description: >-
            Filter by status: `all`, `leads`, `customers`, `prospects`,
            `archived`
          schema:
            type: string
        - name: search
          in: query
          required: false
          description: Search by name, email, or phone
          schema:
            type: string
        - name: page
          in: query
          required: false
          description: Page number for pagination
          schema:
            type: integer
        - name: per_page
          in: query
          required: false
          description: Number of results per page (max 100)
          schema:
            type: integer
      responses:
        '200':
          description: contacts retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 4829
                    token: ct_8f3a2b1c9d7e
                    first_name: Michael
                    last_name: Scott
                    full_name: Michael Scott
                    email: m.scott@dundermifflin.com
                    phone: +1-570-555-0100
                    avatar_url: https://cdn.dundermifflin.com/contacts/michael-scott.jpg
                    status: lead
                    lead_type: organic
                    city: Scranton
                    state: PA
                  - id: 4830
                    token: ct_2c4d6e8f0a1b
                    first_name: Jim
                    last_name: Halpert
                    full_name: Jim Halpert
                    email: j.halpert@dundermifflin.com
                    phone: +1-570-555-0101
                    status: customer
                    city: Scranton
                    state: PA
                  - id: 4831
                    token: ct_3d5e7f9a1b2c
                    first_name: Pam
                    last_name: Beesly
                    full_name: Pam Beesly
                    email: p.beesly@dundermifflin.com
                    phone: +1-570-555-0102
                    status: customer
                    city: Scranton
                    state: PA
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
    post:
      summary: Create a contact
      tags:
        - Contacts
      operationId: createContact
      description: |
        Creates a new contact for the current user.

        This can be used to manually add leads, customers, or prospects.
        The contact will be associated with the authenticated user's account.
      security:
        - bearer_auth: []
      parameters: []
      responses:
        '201':
          description: contact created
          content:
            application/json:
              schema:
                type: object
                example:
                  id: 4832
                  token: ct_4e6f8a0b2c3d
                  first_name: Stanley
                  last_name: Hudson
                  full_name: Stanley Hudson
                  email: s.hudson@dundermifflin.com
                  status: prospect
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                first_name:
                  type: string
                  example: Stanley
                last_name:
                  type: string
                  example: Hudson
                email:
                  type: string
                  example: s.hudson@dundermifflin.com
                phone:
                  type: string
                  example: +1-570-555-0103
                status:
                  type: string
                  example: prospect
                  enum:
                    - lead
                    - customer
                    - prospect
                address:
                  type: string
                  example: 1725 Slough Avenue
                city:
                  type: string
                  example: Scranton
                state:
                  type: string
                  example: PA
                postal_code:
                  type: string
                  example: '18505'
                reason:
                  type: string
                  example: Interested in crossword puzzle paper
              required:
                - first_name
                - last_name
              example:
                first_name: Stanley
                last_name: Hudson
                email: s.hudson@dundermifflin.com
                phone: +1-570-555-0103
                status: prospect
                address: 1725 Slough Avenue
                city: Scranton
                state: PA
                postal_code: '18505'
                reason: Interested in crossword puzzle paper
  /api/events:
    get:
      summary: List events
      tags:
        - Events
      operationId: listEvents
      description: >
        Returns all events available for the current user.


        Events include company-wide events, trainings, webinars, and regional
        meetups.

        Results can be filtered by date range and event type.
      security:
        - bearer_auth: []
      parameters:
        - name: upcoming
          in: query
          required: false
          description: Filter to show only upcoming events
          schema:
            type: boolean
        - name: type
          in: query
          required: false
          description: 'Filter by event type: webinar, training, meetup, conference'
          schema:
            type: string
      responses:
        '200':
          description: events retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 127
                    title: Quarterly Sales Training - The Art of the Sale
                    description: >-
                      Learn Michael Scott's legendary sales techniques that have
                      made Dunder Mifflin Scranton the top branch.
                    event_type: training
                    start_time: '2024-01-15T14:00:00Z'
                    end_time: '2024-01-15T16:00:00Z'
                    time_zone: America/New_York
                    location: Dunder Mifflin Scranton Conference Room
                    host:
                      id: 1
                      name: Michael Scott
                    attendee_count: 45
                    is_registered: true
                    image_url: https://cdn.dundermifflin.com/events/sales-training.jpg
                  - id: 128
                    title: Dundie Awards Ceremony
                    description: Annual celebration of excellence at Dunder Mifflin.
                    event_type: meetup
                    start_time: '2024-02-14T18:00:00Z'
                    end_time: '2024-02-14T22:00:00Z'
                    time_zone: America/New_York
                    location: Chili's Scranton
                    host:
                      id: 1
                      name: Michael Scott
                    attendee_count: 28
                    is_registered: true
                  - id: 129
                    title: Safety Training Webinar
                    description: >-
                      Important workplace safety guidelines presented by Dwight
                      Schrute.
                    event_type: webinar
                    start_time: '2024-01-20T10:00:00Z'
                    end_time: '2024-01-20T11:00:00Z'
                    time_zone: America/New_York
                    virtual_url: https://meet.dundermifflin.com/safety
                    host:
                      id: 2
                      name: Dwight Schrute
                    attendee_count: 67
                    is_registered: false
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/libraries:
    get:
      summary: List libraries
      tags:
        - Libraries
      operationId: listLibraries
      description: >
        Returns all libraries (playlists) for the current user.


        Libraries are curated collections of media content that can be shared
        with contacts.

        Each library contains media items, products, and enrollment packs
        organized by theme or purpose.
      security:
        - bearer_auth: []
      responses:
        '200':
          description: libraries retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 42
                    slug: paper-sales-101
                    custom_slug: null
                    title: Paper Sales 101 - The Basics
                    items_count: 8
                    library_items:
                      - id: 1
                        position: 1
                        relateable_type: Medium
                        relateable_id: 101
                      - id: 2
                        position: 2
                        relateable_type: Medium
                        relateable_id: 102
                    products: []
                  - id: 43
                    slug: client-success-stories
                    custom_slug: success
                    title: Client Success Stories
                    items_count: 5
                    library_items: []
                    products: []
                  - id: 44
                    slug: the-dundies-collection
                    custom_slug: null
                    title: The Dundies Collection - Award Winning Content
                    items_count: 12
                    library_items: []
                    products: []
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/media:
    get:
      summary: List media
      tags:
        - Media
      operationId: listMedia
      description: >
        Returns all media available to the current user.


        Media includes videos, PDFs, presentations, and other content that can
        be

        shared with contacts. Results can be filtered by type, category, or
        search term.
      security:
        - bearer_auth: []
      parameters:
        - name: kind
          in: query
          required: false
          description: 'Filter by media kind: `video`, `pdf`, `presentation`, `image`'
          schema:
            type: string
        - name: category
          in: query
          required: false
          description: Filter by category slug
          schema:
            type: string
        - name: search
          in: query
          required: false
          description: Search by title or description
          schema:
            type: string
        - name: tag
          in: query
          required: false
          description: Filter by tag
          schema:
            type: string
      responses:
        '200':
          description: media retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 101
                    slug: paper-quality-matters
                    title: Why Paper Quality Matters
                    description: >-
                      Discover the difference premium paper makes in your
                      business communications.
                    kind: video
                    media_type: video
                    media_format: mp4
                    image_url: https://cdn.dundermifflin.com/thumbnails/paper-quality.jpg
                    video_url: https://cdn.dundermifflin.com/videos/paper-quality.mp4
                    duration: 342
                    active: true
                    comments_count: 12
                    share_url: https://share.dundermifflin.com/dwight/paper-quality
                  - id: 102
                    slug: choosing-paper-weight
                    title: How to Choose the Right Paper Weight
                    description: A guide to paper weights for every business need.
                    kind: video
                    media_type: video
                    image_url: https://cdn.dundermifflin.com/thumbnails/paper-weight.jpg
                    video_url: https://cdn.dundermifflin.com/videos/paper-weight.mp4
                    duration: 287
                    active: true
                    comments_count: 8
                  - id: 103
                    slug: product-catalog-2024
                    title: Dunder Mifflin Product Catalog 2024
                    description: Complete catalog of our paper products and pricing.
                    kind: pdf
                    media_type: document
                    image_url: https://cdn.dundermifflin.com/thumbnails/catalog-2024.jpg
                    pdf_url: https://cdn.dundermifflin.com/docs/catalog-2024.pdf
                    active: true
                    comments_count: 3
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/mysite/leads:
    get:
      summary: Get MySite leads
      tags:
        - MySite
      operationId: getMySiteLeads
      description: |
        Returns leads captured through the user's MySite.

        These are contacts who submitted their information through
        forms on the user's personal website.
      security:
        - bearer_auth: []
      parameters:
        - name: page
          in: query
          required: false
          description: Page number for pagination
          schema:
            type: integer
        - name: per_page
          in: query
          required: false
          description: Number of results per page
          schema:
            type: integer
      responses:
        '200':
          description: MySite leads retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 4829
                    first_name: Michael
                    last_name: Scott
                    email: m.scott@dundermifflin.com
                    phone: +1-570-555-0100
                    source: mysite
                    page: Home
                    created_at: '2024-01-15T10:30:00Z'
                  - id: 4830
                    first_name: Jim
                    last_name: Halpert
                    email: j.halpert@dundermifflin.com
                    source: mysite
                    page: Products
                    created_at: '2024-01-14T14:20:00Z'
  /api/mysite/themes:
    get:
      summary: Get available MySite themes
      tags:
        - MySite
      operationId: getMySiteThemes
      description: |
        Returns available themes for customizing the user's MySite.

        Themes control the visual appearance including colors, fonts,
        and layout of the personal website.
      security:
        - bearer_auth: []
      responses:
        '200':
          description: MySite themes retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 1
                    name: Modern Professional
                    description: Clean, modern design perfect for business professionals
                    preview_url: https://cdn.dundermifflin.com/themes/modern-pro.jpg
                    is_default: true
                    primary_color: '#2563eb'
                  - id: 2
                    name: Classic Elegance
                    description: Timeless design with elegant typography
                    preview_url: https://cdn.dundermifflin.com/themes/classic.jpg
                    is_default: false
                    primary_color: '#1e293b'
                  - id: 3
                    name: Bold & Vibrant
                    description: Stand out with bold colors and dynamic layouts
                    preview_url: https://cdn.dundermifflin.com/themes/bold.jpg
                    is_default: false
                    primary_color: '#dc2626'
  /api/v1/onboardings:
    get:
      summary: Get onboarding status
      tags:
        - Onboarding
      operationId: getOnboardingStatus
      security:
        - bearer_auth: []
      responses:
        '200':
          description: onboarding status retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  onboarding:
                    type: object
                    properties:
                      sections:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            steps:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  name:
                                    type: string
                                  description:
                                    type:
                                      - string
                                      - 'null'
                                  status:
                                    type: string
                                    enum:
                                      - pending
                                      - completed
                                      - skipped
                                  time_estimate:
                                    type: integer
                                  allow_manual_completion:
                                    type: boolean
                            progress:
                              type: object
                              properties:
                                completed:
                                  type: integer
                                skipped:
                                  type: integer
                                pending:
                                  type: integer
                                total:
                                  type: integer
                                percentage:
                                  type: integer
                                time_remaining:
                                  type: integer
                                all_done:
                                  type: boolean
                      overall:
                        type: object
                        properties:
                          completed:
                            type: integer
                          skipped:
                            type: integer
                          pending:
                            type: integer
                          total:
                            type: integer
                          percentage:
                            type: integer
                          time_remaining:
                            type: integer
                      completed:
                        type: boolean
                      show_getting_started:
                        type: boolean
                  company_status:
                    type:
                      - string
                      - 'null'
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - onboarding
                  - company_status
                  - meta
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Invalid credentials.
  /api/v1/onboardings/check_step:
    patch:
      summary: Check onboarding step
      tags:
        - Onboarding
      operationId: checkOnboardingStep
      description: >-
        Check if an onboarding step meets completion criteria and automatically
        complete it if eligible. This endpoint modifies state by marking steps
        as completed when they meet their defined criteria.
      security:
        - bearer_auth: []
      parameters:
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  step:
                    type: object
                    properties:
                      section:
                        type: string
                      step_id:
                        type: string
                      step_status:
                        type: string
                        enum:
                          - pending
                          - completed
                          - skipped
                      is_step_complete:
                        type: boolean
                    required:
                      - section
                      - step_id
                      - step_status
                      - is_step_complete
                  onboarding:
                    type: object
                    properties:
                      sections:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            steps:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  name:
                                    type: string
                                  description:
                                    type:
                                      - string
                                      - 'null'
                                  status:
                                    type: string
                                    enum:
                                      - pending
                                      - completed
                                      - skipped
                                  time_estimate:
                                    type: integer
                                  allow_manual_completion:
                                    type: boolean
                            progress:
                              type: object
                              properties:
                                completed:
                                  type: integer
                                skipped:
                                  type: integer
                                pending:
                                  type: integer
                                total:
                                  type: integer
                                percentage:
                                  type: integer
                                time_remaining:
                                  type: integer
                                all_done:
                                  type: boolean
                      overall:
                        type: object
                        properties:
                          completed:
                            type: integer
                          skipped:
                            type: integer
                          pending:
                            type: integer
                          total:
                            type: integer
                          percentage:
                            type: integer
                          time_remaining:
                            type: integer
                      completed:
                        type: boolean
                      show_getting_started:
                        type: boolean
                  company_status:
                    type:
                      - string
                      - 'null'
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - step
                  - onboarding
                  - company_status
                  - meta
        '422':
          description: unprocessable entity - invalid step_id
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_message:
                    type: string
                  errors:
                    type: object
                    properties:
                      section:
                        type: array
                        items:
                          type: string
                      step_id:
                        type: array
                        items:
                          type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - error_message
                  - errors
                  - meta
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                section:
                  type: string
                  example: account
                step_id:
                  type: string
                  example: setup_user_roles
              required:
                - section
                - step_id
  /api/v1/onboardings/complete_step:
    patch:
      summary: Complete onboarding step manually
      tags:
        - Onboarding
      operationId: completeOnboardingStep
      description: >-
        Manually complete an onboarding step. This endpoint can only be used for
        steps that have 'allow_manual_completion' set to true. Steps without
        this flag will return a 403 Forbidden error.
      security:
        - bearer_auth: []
      parameters:
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      responses:
        '200':
          description: step completed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  step:
                    type: object
                    properties:
                      section:
                        type: string
                      step_id:
                        type: string
                      step_status:
                        type: string
                        enum:
                          - pending
                          - completed
                          - skipped
                    required:
                      - section
                      - step_id
                      - step_status
                  onboarding:
                    type: object
                    properties:
                      sections:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            steps:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  name:
                                    type: string
                                  description:
                                    type:
                                      - string
                                      - 'null'
                                  status:
                                    type: string
                                    enum:
                                      - pending
                                      - completed
                                      - skipped
                                  time_estimate:
                                    type: integer
                                  allow_manual_completion:
                                    type: boolean
                            progress:
                              type: object
                              properties:
                                completed:
                                  type: integer
                                skipped:
                                  type: integer
                                pending:
                                  type: integer
                                total:
                                  type: integer
                                percentage:
                                  type: integer
                                time_remaining:
                                  type: integer
                                all_done:
                                  type: boolean
                      overall:
                        type: object
                        properties:
                          completed:
                            type: integer
                          skipped:
                            type: integer
                          pending:
                            type: integer
                          total:
                            type: integer
                          percentage:
                            type: integer
                          time_remaining:
                            type: integer
                      completed:
                        type: boolean
                      show_getting_started:
                        type: boolean
                  company_status:
                    type:
                      - string
                      - 'null'
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - step
                  - onboarding
                  - company_status
                  - meta
        '403':
          description: forbidden - manual completion not allowed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_message:
                    type: string
                  errors:
                    type: object
                    properties:
                      base:
                        type: array
                        items:
                          type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - error_message
                  - errors
                  - meta
        '422':
          description: unprocessable entity - invalid step_id
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_message:
                    type: string
                  errors:
                    type: object
                    properties:
                      section:
                        type: array
                        items:
                          type: string
                      step_id:
                        type: array
                        items:
                          type: string
                  meta:
                    type: object
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                required:
                  - error_message
                  - errors
                  - meta
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                section:
                  type: string
                  example: data_sync
                step_id:
                  type: string
                  example: connect_data_source
              required:
                - section
                - step_id
  /api/orders:
    get:
      summary: List orders
      tags:
        - Orders
      operationId: listUserOrders
      description: >
        Returns all orders associated with the current user.


        This includes orders placed by the user's contacts and customers,

        as well as the user's own purchases. Orders are sorted by date
        descending.
      security:
        - bearer_auth: []
      parameters:
        - name: status
          in: query
          required: false
          description: >-
            Filter by order status: `pending`, `processing`, `shipped`,
            `delivered`, `cancelled`
          schema:
            type: string
        - name: from_date
          in: query
          required: false
          description: Filter orders from this date (ISO 8601)
          schema:
            type: string
        - name: to_date
          in: query
          required: false
          description: Filter orders to this date (ISO 8601)
          schema:
            type: string
      responses:
        '200':
          description: orders retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 78234
                    order_number: DM-2024-78234
                    status: shipped
                    total: 249.99
                    subtotal: 224.99
                    tax: 15
                    shipping: 10
                    currency: USD
                    items_count: 3
                    created_at: '2024-01-15T14:30:00Z'
                    shipped_at: '2024-01-16T09:00:00Z'
                    tracking_number: 1Z999AA10123456784
                    tracking_url: https://ups.com/track?num=1Z999AA10123456784
                    customer:
                      id: 4829
                      full_name: Michael Scott
                      email: m.scott@dundermifflin.com
                    shipping_address:
                      address1: 1725 Slough Avenue
                      address2: Suite 200
                      city: Scranton
                      state: PA
                      postal_code: '18505'
                      country: US
                  - id: 78235
                    order_number: DM-2024-78235
                    status: delivered
                    total: 89.97
                    subtotal: 79.97
                    tax: 5
                    shipping: 5
                    currency: USD
                    items_count: 1
                    created_at: '2024-01-14T10:00:00Z'
                    shipped_at: '2024-01-15T08:00:00Z'
                    delivered_at: '2024-01-17T14:30:00Z'
                    customer:
                      id: 4830
                      full_name: Jim Halpert
                      email: j.halpert@dundermifflin.com
                  - id: 78236
                    order_number: DM-2024-78236
                    status: pending
                    total: 524.95
                    subtotal: 499.95
                    tax: 25
                    shipping: 0
                    currency: USD
                    items_count: 5
                    created_at: '2024-01-18T16:45:00Z'
                    customer:
                      id: 4831
                      full_name: Pam Beesly
                      email: p.beesly@dundermifflin.com
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/tasks:
    get:
      summary: List tasks
      tags:
        - Tasks
      operationId: listTasks
      description: |
        Returns all tasks for the current user.

        Tasks can be associated with contacts, orders, or general follow-ups.
        They help track action items and deadlines for the user's workflow.
      security:
        - bearer_auth: []
      parameters:
        - name: status
          in: query
          required: false
          description: 'Filter by status: `pending`, `completed`, `overdue`'
          schema:
            type: string
        - name: contact_id
          in: query
          required: false
          description: Filter tasks by contact ID
          schema:
            type: integer
      responses:
        '200':
          description: tasks retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 891
                    title: Follow up with Michael about paper order
                    description: >-
                      He needs 50 reams of premium copy paper for the holiday
                      party invitations.
                    status: pending
                    priority: high
                    due_date: '2024-01-20'
                    contact:
                      id: 4829
                      full_name: Michael Scott
                      email: m.scott@dundermifflin.com
                    created_at: '2024-01-15T09:30:00Z'
                  - id: 892
                    title: Send product catalog to Pam
                    description: She's interested in our new recycled paper line.
                    status: pending
                    priority: medium
                    due_date: '2024-01-22'
                    contact:
                      id: 4831
                      full_name: Pam Beesly
                      email: p.beesly@dundermifflin.com
                    created_at: '2024-01-16T11:00:00Z'
                  - id: 893
                    title: Call Jim about the Stamford account
                    description: null
                    status: completed
                    priority: low
                    due_date: '2024-01-18'
                    completed_at: '2024-01-18T15:45:00Z'
                    contact:
                      id: 4830
                      full_name: Jim Halpert
                      email: j.halpert@dundermifflin.com
                    created_at: '2024-01-14T08:00:00Z'
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/trainings:
    get:
      summary: List trainings
      tags:
        - Training
      operationId: listTrainings
      description: >
        Returns all training content for the current user.


        Training includes educational videos, courses, certifications, and
        skill-building

        content provided by the company. Users can track their progress through
        training modules.
      security:
        - bearer_auth: []
      parameters:
        - name: category
          in: query
          required: false
          description: Filter by training category
          schema:
            type: string
        - name: completed
          in: query
          required: false
          description: Filter by completion status
          schema:
            type: boolean
      responses:
        '200':
          description: trainings retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 201
                    title: Sales Fundamentals - The Michael Scott Method
                    description: >-
                      Learn the core principles of relationship-based selling
                      from the World's Best Boss.
                    category: sales
                    duration_minutes: 45
                    image_url: >-
                      https://cdn.dundermifflin.com/training/sales-fundamentals.jpg
                    progress_percent: 75
                    completed: false
                    modules:
                      - id: 1
                        title: Introduction to Sales
                        completed: true
                      - id: 2
                        title: Building Rapport
                        completed: true
                      - id: 3
                        title: Closing the Deal
                        completed: false
                  - id: 202
                    title: Product Knowledge - Paper Types and Uses
                    description: >-
                      Become an expert on paper weights, finishes, and
                      applications.
                    category: product
                    duration_minutes: 30
                    image_url: https://cdn.dundermifflin.com/training/paper-types.jpg
                    progress_percent: 100
                    completed: true
                    completed_at: '2024-01-10T16:30:00Z'
                  - id: 203
                    title: Safety Training with Dwight Schrute
                    description: >-
                      Essential workplace safety guidelines and emergency
                      procedures.
                    category: compliance
                    duration_minutes: 60
                    image_url: https://cdn.dundermifflin.com/training/safety.jpg
                    progress_percent: 0
                    completed: false
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
  /api/announcements:
    get:
      summary: List announcements
      tags:
        - Training
      operationId: listAnnouncements
      description: |
        Returns company announcements for the current user.

        Announcements are company-wide messages, updates, and notifications.
        They can include text, images, and videos.
      security:
        - bearer_auth: []
      responses:
        '200':
          description: announcements retrieved
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                example:
                  - id: 501
                    title: Q4 Sales Competition - Win a Dundie!
                    description: >-
                      The annual sales competition is here! Top performers will
                      receive the prestigious Dundie Award at our ceremony.
                    kind: announcement
                    media_type: text
                    image_url: >-
                      https://cdn.dundermifflin.com/announcements/dundie-competition.jpg
                    active: true
                    read: false
                    created_at: '2024-01-02T09:00:00Z'
                    author:
                      id: 1
                      name: Michael Scott
                  - id: 502
                    title: 'New Product Launch: Dunder Mifflin Infinity Paper'
                    description: >-
                      Introducing our most advanced paper yet - now with 20%
                      more whiteness.
                    kind: announcement
                    media_type: video
                    video_url: >-
                      https://cdn.dundermifflin.com/announcements/infinity-launch.mp4
                    active: true
                    read: true
                    created_at: '2024-01-01T12:00:00Z'
                    author:
                      id: 10
                      name: Ryan Howard
  /api/me:
    get:
      summary: Get current user profile
      tags:
        - User Profile
      operationId: getCurrentUser
      description: >
        Returns the profile and settings for the currently authenticated user.


        This endpoint requires a **User token** obtained through:

        - Magic link authentication

        - JWT exchange (`/api/user_companies/jwt_exchange`)

        - Login endpoints


        The response includes the user's profile information, company
        association,

        and various settings like notification preferences.
      security:
        - bearer_auth: []
      responses:
        '200':
          description: user profile retrieved
          content:
            application/json:
              schema:
                type: object
                example:
                  id: 1847
                  email: d.schrute@dundermifflin.com
                  first_name: Dwight
                  last_name: Schrute
                  full_name: Dwight Schrute
                  phone: +1-570-555-0142
                  bio: >-
                    Assistant to the Regional Manager. Beet farmer. Volunteer
                    Sheriff's Deputy.
                  image_url: https://cdn.dundermifflin.com/avatars/dwight-schrute.jpg
                  language: en
                  time_zone: America/New_York
                  share_link: https://shop.dundermifflin.com/dwight
                  mysite_url: https://dwight.dundermifflin.com
                  affiliate_shop_url: https://shop.dundermifflin.com/dwight
                  affiliate_id: SCHRUTE2023
                  role: rep
                  active: true
                  rank:
                    id: 5
                    name: Assistant Regional Manager
                    external_id: ARM
                  total_points: 15000
                  fantasy_points: 2500
                  leads_remaining: 47
                  leads_recurring: 10
                  open_task_count: 3
                  unread_messages_count: 12
                  mysite_views: 1523
                  mysite_leads: 89
                  facebook: https://facebook.com/dwightschrute
                  instagram: '@dwight_schrute_farms'
                  twitter: '@schaboretum'
                  linkedin: https://linkedin.com/in/dwight-schrute
                  youtube: null
                  tiktok: null
                  push_notifications: true
                  email_notifications: true
                  sms_notifications: false
                  activity_notifications: true
                  profile_notifications: true
                  created_at: '2019-03-24T08:00:00Z'
                  company:
                    id: 1
                    name: Dunder Mifflin Paper Company
                    slug: dunder-mifflin
        '401':
          description: unauthorized - invalid or missing token
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
    put:
      summary: Update current user profile
      tags:
        - User Profile
      operationId: updateCurrentUser
      description: |
        Updates the profile information for the currently authenticated user.

        Only the fields provided in the request body will be updated.
        Omitted fields will retain their current values.
      security:
        - bearer_auth: []
      parameters: []
      responses:
        '200':
          description: profile updated successfully
          content:
            application/json:
              schema:
                type: object
                example:
                  id: 1847
                  email: d.schrute@dundermifflin.com
                  first_name: Dwight
                  last_name: Schrute
                  full_name: Dwight Schrute
                  bio: Assistant Regional Manager. Beet farmer.
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                example:
                  message: Invalid or expired token
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                first_name:
                  type: string
                  example: Dwight
                last_name:
                  type: string
                  example: Schrute
                phone:
                  type: string
                  example: +1-570-555-0142
                bio:
                  type: string
                  example: Assistant to the Regional Manager. Beet farmer.
                language:
                  type: string
                  example: en
                time_zone:
                  type: string
                  example: America/New_York
                facebook:
                  type: string
                  example: https://facebook.com/dwightschrute
                instagram:
                  type: string
                  example: '@dwight_schrute_farms'
                linkedin:
                  type: string
                  example: https://linkedin.com/in/dwight-schrute
                twitter:
                  type: string
                  example: '@schaboretum'
                push_notifications:
                  type: boolean
                  example: true
                email_notifications:
                  type: boolean
                  example: true
                sms_notifications:
                  type: boolean
                  example: false
                activity_notifications:
                  type: boolean
                  example: true
              example:
                first_name: Dwight
                last_name: Schrute
                bio: >-
                  Assistant Regional Manager. Beet farmer. Volunteer Sheriff's
                  Deputy.
                time_zone: America/New_York
tags: []
x-tagGroups:
  - name: Authentication
    tags:
      - Authentication
      - User Sessions
  - name: User Profile
    tags:
      - User Profile
      - Profile
      - Me
      - Settings
  - name: Contacts & CRM
    tags:
      - Contacts
      - Groups
      - Notes
      - Tasks
  - name: Media & Content
    tags:
      - Media
      - Libraries
      - Comments
  - name: Orders & Commerce
    tags:
      - Orders
      - Payments
      - Addresses
  - name: MySite
    tags:
      - MySite
      - Pages
      - Themes
  - name: Activities & Training
    tags:
      - Activities
      - Analytics
      - Announcements
      - Events
      - Explore
      - Training
