Account export format
GET /api/account/export (companion: Account → Your data → Download my data) returns everything
a server keeps about one account as one JSON document. It is meant for people leaving a server
and, later, for moving an account to another server while keeping its connections.
Version 1
Section titled “Version 1”{ "format": "openloungephone-export", "version": 1, "exportedAt": "2026-09-28T12:00:00.000Z", "server": "hub.openloungephone.app", "account": { "id": "acc_…", "handle": "jesse", "name": "Jesse", "address": "jesse@hub.openloungephone.app", "createdAt": "2026-09-01T09:30:00.000Z", "sharePresence": false }, "connections": [ { "address": "bob@phone.example.org", "peerId": "acc_…", "name": "Bob", "state": "active", "since": "2026-09-10T18:00:00.000Z" } ], "blockedServers": ["spam.example"], "spaces": [ { "id": "hh_…", "name": "Jesse's home", "type": "home", "timeZone": "Europe/Amsterdam", "role": "guardian", "nameThere": "Jesse", "phones": [{ "id": "dev_…", "name": "Kid phone", "kind": "kids", "own": false }], "quietHours": [{ "days": [0, 1, 2, 3, 4], "start": "19:30", "end": "07:00" }] } ], "calls": [ { "peer": "bob@phone.example.org", "peerLabel": "Bob", "direction": "out", "startedAt": "2026-09-12T17:00:00.000Z", "answered": true, "durationMs": 420000, "endReason": "hangup" }, { "peer": "bob@phone.example.org", "peerLabel": "Bob", "direction": "in", "startedAt": "2026-09-13T08:00:00.000Z", "answered": false, "durationMs": 0, "endReason": "timeout", "voicemailId": "vm_…", "voicemail": "/api/voicemails/vm_…/audio" }, { "peer": "user:usr_…", "peerLabel": "Ben", "direction": "out", "startedAt": "2026-09-14T09:00:00.000Z", "answered": true, "durationMs": 180000, "endReason": "hangup", "recordingId": "rec_…", "recording": "/api/recordings/rec_…/audio" } ], "missedCalls": [ { "peer": "bob@phone.example.org", "peerLabel": "Bob", "at": "2026-09-15T18:00:00.000Z", "seenAt": "2026-09-15T19:30:00.000Z" } ], "missedCallbacks": [ { "line": "help@acme.example", "name": "Acme help", "at": "2026-09-14T10:00:00.000Z" } ], "recordings": [ { "id": "rec_…", "kind": "call", "peerLabel": "Ben", "startedAt": "2026-09-14T09:00:00.000Z", "durationMs": 180000, "transcript": "…", "audio": "/api/recordings/rec_…/audio" } ], "addons": [ { "name": "seat", "address": "jesse+seat@hub.openloungephone.app", "space": "Jesse's home", "createdAt": "2026-10-01T09:00:00.000Z", "shares": [ { "label": "Book club", "address": "jesse+seat+bookclub@hub.openloungephone.app", "holders": [{ "name": "Ana", "address": "ana@hub.openloungephone.app" }] } ] } ], "addonSharesHeld": [ { "owner": "jo@hub.openloungephone.app", "addon": "echo", "share": "Garden", "address": "jo+echo+garden@hub.openloungephone.app" } ]}connectionsholdsactiveandblockedpeople (pending knocks and declines are not exported).peerIdis the other person’s stable id on their server;addresstheir current address. Whole-server blocks are inblockedServers.spaceslists every space the account is in. Phones are listed for guardians (all of the space’s phones) and for owners (their own phone). Quiet hours are included for guardians of homes.callsis the account’s call log (newest first, up to 1,000).peerishandle@hostfor someone on another server or connected across households,user:<id>/device:<id>inside a space. A missed call that ended in a voicemail for you carriesvoicemailIdandvoicemail, the path of its audio on this server (signed-inGET, the same audio as the Voicemail tab); the transcript is in the inbox. A call its space recorded (always announced to everyone on it) carriesrecordingIdandrecording, the path of its audio.recordingslists the recordings of calls and rooms you were in or recorded (up to 1,000), with their transcripts where the space transcribes; the audio is ataudio(signed-inGET).addonslists the add-ons linked to your account (docs/add-ons.md): name, address, the space it was linked in, and each share with who holds it.addonSharesHeldlists the shares of other people’s add-ons on this server that you hold (shares from another server come with that connection, on that server).missedCallslists calls that rang you (any of your phones and apps, in any space) that nobody answered and that left no message: who (peer,peerLabel, named as incalls) and when (at), withseenAtonce you cleared them. Kept as long as the space’s history setting keeps calls.missedCallbackslists public lines’ call backs you didn’t take and haven’t cleared (lineaddress,name,at), up to 100.- Not included: passkeys (they’re bound to the old server’s name), sessions, the recovery code (only its hash is kept, and never exported), voicemail audio (download it from the Voicemail tab), other people’s data.
Readers must reject documents whose format differs, and should accept any version they know;
new fields may be added within a version.
Moving an account (design, not built yet)
Section titled “Moving an account (design, not built yet)”- On the new server, create an account and choose Import with the export file.
- The new server re-creates spaces and settings (phones must be re-paired: their keys are bound to their pairing).
- For each
activeconnection, the new server sends a signedPOST /fed/v1/connections/movedto the peer’s server with{from: <new party>, previous: <old address>, peerId}; the old server co-signs the move (a signed statement from the old server thatpreviousmoved to the new address), so a peer can update the connection without a new knock. - The old account can then be deleted; its handle stays reserved for 90 days so nobody else can take it in the meantime.