> ## Documentation Index
> Fetch the complete documentation index at: https://docs.handauncle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# App Launch

> Resolves the caller to a user (if possible), updates device metadata, and returns onboarding, usage, auth state, and link information required to render the home screen. Supports optional Authorization header to return token expiry info and validate device-user mapping for silent refresh flows.

Use this endpoint whenever the Handa Uncle mobile app boots. The backend will
associate the provided device information with an existing user (if one can be
identified) or create a lightweight record and respond with everything the app
needs to decide whether to show onboarding, what limits apply, and which system
links to surface.

### Required headers

* `x-device-id`: Stable device identifier or installation ID
* `x-platform`: One of `android`, `ios`, `web`

### Optional headers

* `x-user-id`: Known user identifier (Auth0 / Mongo ID)
* `x-user-email`: Known email address
* `x-user-phone`: E.164‑formatted phone number

Providing user hints dramatically improves the chance of mapping the device to
an existing account before falling back to device-based upsert logic.

### Example request

```bash theme={null}
curl -X GET https://api.handauncle.com/app/launch \
  -H 'x-device-id=ios-device-3f92' \
  -H 'x-platform=ios' \
  -H 'x-user-email=investor@example.com'
```

### Response highlights

* `data.appLaunchResponseData.userData` mirrors the canonical user profile,
  including verification, platform, and timestamps.
* `isOnboardingRequired` flips to `false` once either an email or phone is
  attached to the user.
* `freeThreshold` is derived from the `FREE_MESSAGE_THRESHOLD` environment value
  and the user's current message count.
* `socialMediaUrls` and `systemUrls` are dynamically loaded from the database,
  so no hard-coded URLs are required in clients. Administrators can update these
  URLs via the [configuration endpoints](/api-reference/endpoint/app-config) without
  requiring app updates.

See the full schema in the OpenAPI reference panel on the right.

### Configuration URLs

The `socialMediaUrls` and `systemUrls` returned in this response are centrally
managed and can be updated by administrators. For more information:

* [Get App Configuration](/api-reference/endpoint/app-config) - View current configuration
* [Update System URLs](/api-reference/endpoint/app-config-update-system-urls) - Modify legal/support URLs
* [Update Social Media URLs](/api-reference/endpoint/app-config-update-social-urls) - Modify social media links


## OpenAPI

````yaml GET /app/launch
openapi: 3.1.0
info:
  title: Handa Uncle API
  version: 1.0.0
  description: Public specification for the Handa Uncle web and mobile APIs.
  contact:
    name: Handa Uncle Engineering
    email: hello@handauncle.com
servers:
  - url: https://handauncle-backend-prod-205012263523.asia-south1.run.app
    description: Prod API base (Cloud Run)
  - url: https://api.handauncle.com
    description: Production
  - url: https://staging-api.handauncle.com
    description: Staging
  - url: http://localhost:8080
    description: Local development
security: []
tags:
  - name: Mobile App
    description: Endpoints used by the native Handa Uncle app.
  - name: Platform
    description: Cross-service operational endpoints.
  - name: Auth
    description: Authentication endpoints handled by the backend adapter.
  - name: AI
    description: LLM chat endpoints supporting streaming and device-auth guests.
  - name: OTP
    description: Phone OTP lifecycle powered by Exotel.
  - name: Webhooks
    description: Server-to-server hooks invoked by Auth0.
  - name: Conversations
    description: Authenticated user conversation management.
  - name: Chat Share
    description: Create, manage, and consume shared conversations.
  - name: Files
    description: Upload, list, and delete user files.
  - name: Prompt management
    description: Admin and public APIs for managing masked pre-prompts.
  - name: User Profile
    description: Profile card collection and user data for personalized AI responses.
  - name: Visual Embeds
    description: Manage visual embed images that attach to AI chat responses.
  - name: Second Opinion
    description: Admin and public APIs for Second Opinion suggestion cards.
  - name: Profile Cards
    description: >-
      APIs for managing profile card questions used in onboarding and
      personalization.
paths:
  /app/launch:
    get:
      tags:
        - Mobile App
      summary: Bootstrap the mobile app session
      description: >-
        Resolves the caller to a user (if possible), updates device metadata,
        and returns onboarding, usage, auth state, and link information required
        to render the home screen. Supports optional Authorization header to
        return token expiry info and validate device-user mapping for silent
        refresh flows.
      operationId: getAppLaunch
      parameters:
        - name: x-device-id
          in: header
          required: true
          description: Unique identifier for the physical device or installation.
          schema:
            type: string
            minLength: 1
        - name: x-platform
          in: header
          required: true
          description: Platform the client is running on.
          schema:
            type: string
            enum:
              - android
              - ios
              - web
        - name: x-user-id
          in: header
          required: false
          description: Known user identifier (Auth0 or Mongo ID) if available.
          schema:
            type: string
        - name: x-user-email
          in: header
          required: false
          description: Known user email address.
          schema:
            type: string
            format: email
        - name: x-user-phone
          in: header
          required: false
          description: Known phone number in E.164 format.
          schema:
            type: string
            pattern: ^\+?[1-9]\d{7,14}$
        - name: Authorization
          in: header
          required: false
          description: >-
            Optional Bearer token for authenticated users. When provided, the
            response includes `accessTokenExpiry` in userData and validates
            device-user mapping. This enables silent refresh flows without
            blocking the UI.
          schema:
            type: string
            pattern: ^Bearer .+$
      responses:
        '200':
          description: App launch payload returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AppLaunchResponseEnvelope'
        '400':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    AppLaunchResponseEnvelope:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          $ref: '#/components/schemas/AppLaunchPayload'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
      required:
        - success
        - data
        - meta
    AppLaunchPayload:
      type: object
      properties:
        appLaunchResponseData:
          $ref: '#/components/schemas/AppLaunchResponseData'
      required:
        - appLaunchResponseData
    ResponseMeta:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        requestId:
          type: string
          description: Server generated correlation identifier.
      required:
        - timestamp
        - requestId
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          $ref: '#/components/schemas/ErrorObject'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
      required:
        - success
        - error
        - meta
    AppLaunchResponseData:
      type: object
      properties:
        userData:
          $ref: '#/components/schemas/AppLaunchUserData'
        auth:
          $ref: '#/components/schemas/AppLaunchAuthInfo'
        isOnboardingRequired:
          type: boolean
        freeThreshold:
          $ref: '#/components/schemas/FreeThreshold'
        socialMediaUrls:
          $ref: '#/components/schemas/SocialMediaUrls'
        systemUrls:
          $ref: '#/components/schemas/SystemUrls'
      required:
        - userData
        - auth
        - isOnboardingRequired
        - freeThreshold
        - socialMediaUrls
        - systemUrls
    ErrorObject:
      type: object
      properties:
        message:
          type: string
          description: Human-readable error message describing the issue.
          example: Please enter a valid 10-digit phone number (e.g., 9876543210)
        code:
          type: string
          description: Error code for programmatic handling.
          example: VALIDATION_ERROR
        details:
          type: array
          description: >-
            Array of field-specific validation errors (for VALIDATION_ERROR
            responses).
          items:
            type: object
            properties:
              field:
                type: string
                description: Field name that failed validation.
                example: phone
              message:
                type: string
                description: Specific validation error message for this field.
                example: Please enter a valid 10-digit phone number (e.g., 9876543210)
            required:
              - field
              - message
      required:
        - message
    AppLaunchUserData:
      type: object
      properties:
        userId:
          type: string
          description: Internal user identifier.
        email:
          type: string
          format: email
          nullable: true
        phoneNumber:
          type: string
          nullable: true
        name:
          type: string
        avatarUrl:
          type: string
          format: uri
          description: URL of the user's avatar image.
        deviceId:
          type: string
        platform:
          type: string
          enum:
            - android
            - ios
            - web
        authProvider:
          type: string
        isLoggedIn:
          type: boolean
        isVerified:
          type: boolean
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        accessTokenExpiry:
          type: string
          format: date-time
          description: >-
            ISO timestamp of when the access token expires. Only present when
            Authorization header is provided in the request.
      required:
        - userId
        - name
        - deviceId
        - platform
        - authProvider
        - isLoggedIn
        - isVerified
        - createdAt
        - updatedAt
    AppLaunchAuthInfo:
      type: object
      description: Authentication state information for silent refresh support.
      properties:
        sessionExists:
          type: boolean
          description: Whether the server knows a session for this device/user.
        refreshAllowed:
          type: boolean
          description: Whether silent refresh can be performed for this device.
        graceWindowSeconds:
          type: integer
          description: >-
            Server-side grace window in seconds for token refresh (e.g., 300 for
            5 minutes).
      required:
        - sessionExists
        - refreshAllowed
        - graceWindowSeconds
    FreeThreshold:
      type: object
      properties:
        total:
          type: integer
        used:
          type: integer
        remaining:
          type: integer
        percentUsed:
          type: integer
          minimum: 0
          maximum: 100
      required:
        - total
        - used
        - remaining
        - percentUsed
    SocialMediaUrls:
      type: object
      properties:
        facebook:
          type: string
          format: uri
        instagram:
          type: string
          format: uri
        linkedin:
          type: string
          format: uri
        twitter:
          type: string
          format: uri
      required:
        - facebook
        - instagram
        - linkedin
        - twitter
      example:
        facebook: https://www.facebook.com/handauncle
        instagram: https://www.instagram.com/handauncle
        linkedin: https://www.linkedin.com/company/handauncle
        twitter: https://twitter.com/handauncle
    SystemUrls:
      type: object
      properties:
        termsAndConditions:
          type: string
          format: uri
        privacyPolicy:
          type: string
          format: uri
        faqs:
          type: string
          format: uri
        supportEmail:
          type: string
          format: email
      required:
        - termsAndConditions
        - privacyPolicy
        - faqs
        - supportEmail
      example:
        termsAndConditions: https://www.handauncle.com/terms
        privacyPolicy: https://www.handauncle.com/privacy
        faqs: https://www.handauncle.com/faqs
        supportEmail: hello@handauncle.com
  responses:
    ValidationError:
      description: The request payload or headers were invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

````