Transfer Code

Create and consume a short-lived account transfer code.

Transfer codes let an existing account session bootstrap a new account session on another device without adding public lookup or full authentication.

Create Request

POST /api/v1/accounts/{accountId}/transfer-codes

The original device must send the runtime key and X-Persistly-Account-Session.

HTTP
POST https://api.persistly.app/api/v1/accounts/acc_01HXYZ/transfer-codes
Authorization: Bearer ps_test_your_runtime_key
X-Persistly-Account-Session: pst_01HSESSION
Content-Type: application/json

{
  "deviceLabel": "Old laptop",
  "ttlSeconds": 600
}

Create Response

201 Created

Show the code once. It is temporary and should not be logged.

JAVASCRIPT
HTTP/1.1 201 Created
Content-Type: application/json

{
  "transferCode": "P7K2D-M9Q4R",
  "expiresAt": "2026-06-01T12:10:00Z",
  "expiresInSeconds": 600
}

Consume Request

POST /api/v1/account-transfer-codes/consume

The new device sends the player-entered code and receives its own account session.

HTTP
POST https://api.persistly.app/api/v1/account-transfer-codes/consume
Authorization: Bearer ps_test_your_runtime_key
Content-Type: application/json

{
  "transferCode": "P7K2D-M9Q4R",
  "deviceLabel": "New tablet"
}

Consume Response

200 OK

The response uses the normal account envelope so SDKs can attach and load slots through the existing account model.

JAVASCRIPT
HTTP/1.1 200 OK
Content-Type: application/json

{
  "accountId": "acc_01HXYZ",
  "accountSessionToken": "pst_01HNEWSESSION",
  "syncPolicy": {
    "minRemoteSyncIntervalSeconds": 60,
    "forceSyncCooldownSeconds": 10,
    "syncOnAppBackground": true,
    "syncOnAppForeground": true,
    "syncOnReconnect": true,
    "maxQueuedLocalSnapshots": 25
  },
  "account": {
    "accountId": "acc_01HXYZ",
    "accountData": {
      "diamonds": 1200
    },
    "slots": [
      {
        "slotId": "autosave",
        "slotInfo": {
          "characterName": "Ayla",
          "level": 6
        },
        "version": 2,
        "status": "active",
        "updatedAt": "2026-06-01T12:01:00Z"
      }
    ],
    "version": 2
  }
}

Rules

Transfer codes are temporary save access, not auth.

Create requires an existing account session on the original device.

Consume requires only the runtime key and the short-lived code.

A consumed or expired code cannot be reused.

The consume response returns a new accountSessionToken for the same account.

Do not use playerRef, externalAccountRef, usernames, or provider subjects as public recovery keys.