---
title: "POST /v2/setup/switch-space"
method: POST
path: "/v2/setup/switch-space"
tags: ["setup-v2"]
---

# POST /v2/setup/switch-space

`POST /v2/setup/switch-space`

## Request body

- SwitchSpaceRequest — Request body for `POST /v2/setup/switch-space`. Maps to `SpaceSetupFacade::switch_space(SwitchSpaceInput)`. Pre-conditions (setup completed + session unlocked + no pending migration) are checked inside the facade and surface as 409 / 423 / 423 respectively.
  - `code` string, required
  - `newPassphrase` string, required
  - `preserveUnreadableHistory` boolean

## Response `200`

Switched space

- SetupSwitchSpaceEnvelope — Canonical success envelope: `{ "data": T, "ts": <unix millis i64> }`. `ts` is `chrono::Utc::now().timestamp_millis()`, set in the webserver handler via [`ApiEnvelope::now`] (the contract carries only the type + the clock helper, not a hard dependency on when the handler reads the clock). `rename_all = "camelCase"` is a no-op for the single-word fields here but is declared for forward-compat. IMPORTANT (utoipa v4): every concrete `ApiEnvelope<X>` that needs a named OpenAPI component is declared in the `#[aliases(...)]` block below. Add a new alias line whenever a new payload type needs enveloping. NEVER register the bare `ApiEnvelope` in `components(schemas(...))` — utoipa errors on a bare generic, and an un-aliased generic inlines an anonymous schema.
  - `data` union, required — Stable outcome of a durable space admission.
    - object
      - `joinId` string, required
      - `joinedSpace` JoinedSpaceResponse, required
        - `migratedRecords` integer, nullable
        - `preservedUnreadableRecords` integer, nullable
        - `selfDeviceId` string, required
        - `selfIdentityFingerprint` string, required
        - `spaceId` string, required
        - `sponsorDeviceId` string, required
        - `sponsorIdentityFingerprint` string, required
      - `status` 'active', required
    - object
      - `cancelRequested` boolean, required
      - `joinId` string, required
      - `sponsorDeviceId` string, nullable
      - `sponsorIdentityFingerprint` string, nullable
      - `status` 'pending', required
      - `targetSpaceId` string, nullable
    - object
      - `joinId` string, required
      - `reason` 'invitation_unavailable' | 'authentication_rejected' | 'identity_conflict' | 'base_history_changed' | 'joiner_history_ahead' | 'history_conflict' | 'peer_upgrade_required' | 'cancelled' | 'removed_before_activation', required
      - `status` 'rejected', required
  - `ts` integer, required — Server time when the response was built (unix epoch milliseconds).

## Other responses

- `400` — Wrong passphrase / device name missing
- `404` — Invitation not found / expired
- `409` — Not setup, pending migration, sponsor rejected, or session locked
- `500` — Internal error / corrupted ciphertext / storage failure
- `503` — Sponsor unreachable / service unavailable

---

[API](https://skmtc.net/uniclipboard/apis/uniclipboard-daemon-api.md) · [All operations](https://skmtc.net/uniclipboard/apis/uniclipboard-daemon-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/uniclipboard/uniclipboard-daemon-api/revisions/291e4c2346eb/schema)
