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

# tRPC User Onboarding API

> Authenticated user-onboarding profile generation for the welcome flow.

The `userOnboarding` namespace currently exposes the AI-assisted profile
generation procedure used by the `/welcome/preferences` step in `webapp-v2`.

* Base endpoint: `POST /v1/trpc`
* Namespace: `userOnboarding.*`
* Auth: wallet-authenticated

## Procedure

* `userOnboarding.generateInvestingProfile`
  * Purpose: convert a structured onboarding quiz plus optional notes into a
    normalized `InvestingProfileV1` payload and narrative copy
  * Used by:
    * `/welcome/preferences`
    * future settings-based profile editing flows
  * Response shape:
    * `headline`
    * `summary`
    * `profile`

## Input Contract

`generateInvestingProfile` accepts:

* `avatarId`: string
* `quiz`
  * `primaryGoal`: `growth | balanced | income | preservation | exploration`
  * `timeHorizon`: `lt_1y | 1_3y | 3_5y | 5y_plus`
  * `riskTolerance`: `conservative | moderate | aggressive`
  * `automationStyle`: `hands_on | guided | delegated`
  * `strategyInterests`: string\[] from:
    * `core_large_cap`
    * `yield_income`
    * `index_like`
    * `defi`
    * `thematic`
    * `experimental`
* `notes`: `string | null`
* `existingProfile?`: optional prior `InvestingProfileV1` payload used when the
  user regenerates summary copy from an already-edited board

## Output Contract

The returned `profile` is normalized and ready to persist as the user-scoped
generic preference `investing_profile_v1`.

`InvestingProfileV1` fields:

* `version`
* `completionMode`
* `avatarId`
* `primaryGoal`
* `timeHorizon`
* `riskTolerance`
* `automationStyle`
* `strategyInterests`
* `preferredChains`
* `guardrails`
* `notes`
* `headline`
* `summary`
* `updatedAt`

## Persistence Notes

This procedure generates the profile, but does not persist it directly.

`webapp-v2` now saves the confirmed profile through the dedicated builder
surface:

* `v2.portfolio.builder.saveProfile`
* `profile: InvestingProfileV1`

The saved profile is then read back through `v2.portfolio.builder.getProfile`
and used to drive the onboarding handoff into `/start`.

## Generation Behavior

* Deterministic normalization always runs first and is the source of truth for
  the structured profile fields.
* Vertex AI is used only for the narrative `headline` and `summary`.
* If model output is unavailable or invalid, the backend falls back to
  deterministic copy and still returns a valid `InvestingProfileV1`.
* “Use balanced defaults” maps to `completionMode: "balanced_defaults"` when
  the request matches the built-in default quiz and omits notes.

## Example Call

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.glider.fi/v1/trpc/userOnboarding.generateInvestingProfile' \
    --header 'Content-Type: application/json' \
    --data '{
      "input": {
        "avatarId": "blue",
        "quiz": {
          "primaryGoal": "growth",
          "timeHorizon": "5y_plus",
          "riskTolerance": "moderate",
          "automationStyle": "guided",
          "strategyInterests": ["core_large_cap", "index_like"]
        },
        "notes": "Prefer a boring core portfolio with room for one experimental sleeve."
      }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "result": {
      "data": {
        "headline": "Steady growth with room for selective upside",
        "summary": "You want a long-horizon portfolio that compounds through diversified core exposure while keeping automation helpful rather than fully delegated.",
        "profile": {
          "version": 1,
          "completionMode": "generated",
          "avatarId": "blue",
          "primaryGoal": "growth",
          "timeHorizon": "5y_plus",
          "riskTolerance": "moderate",
          "automationStyle": "guided",
          "strategyInterests": ["core_large_cap", "index_like"],
          "preferredChains": ["base", "ethereum"],
          "guardrails": ["keep_stable_buffer"],
          "notes": "Prefer a boring core portfolio with room for one experimental sleeve.",
          "headline": "Steady growth with room for selective upside",
          "summary": "You want a long-horizon portfolio that compounds through diversified core exposure while keeping automation helpful rather than fully delegated.",
          "updatedAt": "2026-03-26T16:00:00.000Z"
        }
      }
    }
  }
  ```
</ResponseExample>
