---
title: "Upgrade Guest Account"
method: POST
path: "/api/v1/auth/upgrade"
tags: ["auth"]
---

# Upgrade Guest Account

`POST /api/v1/auth/upgrade`

## Request

- Base URL: `https://yondry.app` (the document declares no server; this is the origin it was published from)
- URL: `https://yondry.app/api/v1/auth/upgrade`
- Auth: HTTP bearer

Attach a verified Apple or Google identity to the caller's guest account.

This exists because ``POST /auth/social`` cannot do it. That endpoint takes
no current user: it calls ``find_or_create_user()``, which matches on the
provider id, then on a verified email, and otherwise creates a **new row**.
A guest who signs in there keeps nothing — their saved places and plans stay
on the account they just walked away from, orphaned at the exact moment they
decided to commit.

Here the row is mutated in place, so the id never changes and every place,
plan, collection and visit stays attached. The caller's existing tokens
remain valid for the same reason.

A provider identity already in use is **refused, never merged**. Merging two
populated accounts means choosing which home location, which collections and
which history survive, and getting that wrong destroys data silently. The
friction of "sign in instead" is recoverable; a bad merge is not.

## Request body

- SocialAuthRequest
  - `provider` 'apple' | 'google', required
  - `id_token` string, required
  - `display_name` string, nullable

## Response `200`

Successful Response

- GuestUpgradeResponse: Result of attaching a real identity to the caller's guest account. No token pair: the row keeps its id, so the caller's existing tokens stay valid and re-issuing would only invalidate a session that is still correct.
  - `user` UserAuthInfo, required: Minimal user representation returned inside SocialAuthResponse.
    - `id` string, uuid, required
    - `email` string, required
    - `display_name` string, nullable, required
    - `avatar_url` string, nullable, required
    - `onboarding_completed` boolean, required
    - `auth_provider` string, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/yondry/apis/yondry-api.md) · [All operations](https://skmtc.dev/yondry/apis/yondry-api/llms.txt) · [OpenAPI document](https://skmtc.dev/yondry/apis/yondry-api/revisions/d2c213cea95b?raw)
