---
title: "Merge Anonymous Account"
method: POST
path: "/api/v1/auth/merge"
tags: ["Authentication"]
---

# Merge Anonymous Account

`POST /api/v1/auth/merge`

## Request

- Base URL: `https://www.endlesstravelplans.com`
- URL: `https://www.endlesstravelplans.com/api/v1/auth/merge`
- Auth: HTTP bearer

Converts an anonymous user to a real account, or merges anonymous data
into an existing account if the email is already taken. Names are needed only
for a new account; an existing account needs just its email and password, and
one with two factor sign in on answers the challenge (merge waits for verify-2fa).

## Request body

- object
  - `first_name` string: Required when the email has no account yet.
  - `last_name` string: Required when the email has no account yet.
  - `email` string, required
  - `password` string, required
  - `marketing_consent` boolean
  - `timezone` string, nullable: Must not be greater than 64 characters.
  - `partner_code` string, nullable: A partner code typed in the app, claimed only when the merge creates the account.
  - `password_confirmation` string, required

## Response `200`

- union
  - object: New account
    - `user` object
      - `id` integer
      - `first_name` string
      - `last_name` string
      - `email` string
      - `phone` string, nullable
      - `bio` string, nullable
      - `preferred_language` string, nullable
      - `timezone` string
      - `profile_photo_url` string, nullable
      - `has_pro_access` boolean
      - `subscription_plan` string
      - `can_create_trip` boolean
      - `max_saved_trips` integer
      - `is_anonymous` boolean
      - `marketing_consent` boolean
      - `marketing_consent_source` string
      - `created_at` string
    - `token` string
    - `expires_in` integer
    - `expires_at` string
    - `merged` boolean
  - object: Merged into existing account
    - `user` object
      - `id` integer
      - `first_name` string
      - `last_name` string
      - `email` string
      - `phone` string, nullable
      - `bio` string, nullable
      - `preferred_language` string, nullable
      - `timezone` string
      - `profile_photo_url` string, nullable
      - `has_pro_access` boolean
      - `subscription_plan` string
      - `can_create_trip` boolean
      - `max_saved_trips` integer
      - `is_anonymous` boolean
      - `marketing_consent` boolean
      - `marketing_consent_source` string
      - `created_at` string
    - `token` string
    - `expires_in` integer
    - `expires_at` string
    - `merged` boolean
  - object: Two factor challenge
    - `requires_2fa` boolean
    - `two_factor_token` string
    - `merged` boolean

## Other responses

- `401`
- `403`: guest_required: The action is only for guest accounts (merge).
- `409`: guest_has_staff_rows: The guest account holds staff data and cannot be merged.
- `422`: validation_failed: The request body failed validation; field messages are in `errors`.
- `429`: rate_limited: A throttle or a per-account allowance refused the request; `retry_after` or `remaining` may be present.
- `500`: server_error: Unhandled failure; quote `request_id` to support.

---

[API](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api.md) · [All operations](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api/llms.txt) · [OpenAPI document](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api/revisions/ae82ed3e4a8f?raw)
