diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxErrorDialog.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxErrorDialog.kt
index 6f64ae07ccc88a15c4cf35ba3654e5a3a09ea83c..6cdf895cefb2adb7449d91d7335f07be502c8b20 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxErrorDialog.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxErrorDialog.kt
@@ -34,6 +34,8 @@ import androidx.compose.ui.window.WindowPosition
 import androidx.compose.ui.window.rememberDialogState
 import org.briarproject.bramble.api.mailbox.MailboxPairingState
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.OfflineWhenPairing
+import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Pairing
+import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.WasUnpaired
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import java.awt.Dimension
@@ -86,7 +88,7 @@ fun MailboxErrorDialog(
 private fun MailboxPairingUiState.getError(): String = when (this) {
     is OfflineWhenPairing -> i18n("mailbox.setup.offline_error_title") + "\n\n" +
         i18n("mailbox.setup.offline_error_description")
-    is MailboxPairingUiState.Pairing -> when (val s = pairingState) {
+    is Pairing -> when (val s = pairingState) {
         is MailboxPairingState.InvalidQrCode -> i18n("mailbox.setup.link.error")
         is MailboxPairingState.MailboxAlreadyPaired -> i18n("mailbox.setup.already_paired_title") +
             "\n\n" + i18n("mailbox.setup.already_paired_description")
@@ -95,5 +97,7 @@ private fun MailboxPairingUiState.getError(): String = when (this) {
         is MailboxPairingState.UnexpectedError -> i18n("mailbox.setup.assertion_error_description")
         else -> error("Unhandled pairing state: ${s::class.simpleName}")
     }
+    is WasUnpaired -> if (tellUserToWipeMailbox) i18n("mailbox.unlink.no_wipe.title") +
+        "\n\n" + i18n("mailbox.unlink.no_wipe.message") else i18n("mailbox.unlink.no_wipe.title")
     else -> error("Unhandled state: ${this::class.simpleName}")
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt
index 27b2a02a586f9ee9d4dec822a8e62c30b6dae949..c9920763af3bf57a5f1f2c5f089a7debb0da6ab8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxScreen.kt
@@ -32,7 +32,6 @@ import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Pairing
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Unknown
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.WasUnpaired
 import org.briarproject.briar.desktop.ui.Loader
-import org.briarproject.briar.desktop.ui.UiPlaceholder
 import org.briarproject.briar.desktop.viewmodel.viewModel
 
 @Composable
@@ -49,6 +48,8 @@ fun MailboxScreen(viewModel: MailboxViewModel = viewModel()) {
                 status = viewModel.status.value,
                 isCheckingConnection = false, // we just paired, there was no time to trigger a connection check
                 onCheckConnection = viewModel::checkConnection,
+                onWipe = viewModel::unlink,
+                isWiping = false, // same as above, just paired
             )
         }
         OfflineWhenPairing -> MailboxSetupScreen(viewModel, true)
@@ -56,7 +57,10 @@ fun MailboxScreen(viewModel: MailboxViewModel = viewModel()) {
             status = viewModel.status.value,
             isCheckingConnection = state.connectionCheckRunning,
             onCheckConnection = viewModel::checkConnection,
+            onWipe = viewModel::unlink,
+            isWiping = state.isWiping,
         )
-        is WasUnpaired -> UiPlaceholder() // TODO
+        // the unpair success message will be shown like an error dialog
+        is WasUnpaired -> MailboxSetupScreen(viewModel, true)
     }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt
index 7464fa46015f6300d3964207dee5f7b874f9c47e..e23f2ab7d5dbcb2b9fc0bd65a20ea8134fea1d08 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxStatusScreen.kt
@@ -20,12 +20,19 @@ package org.briarproject.briar.desktop.mailbox
 
 import androidx.compose.foundation.layout.Arrangement.spacedBy
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize.Max
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.AlertDialog
 import androidx.compose.material.Button
+import androidx.compose.material.ButtonType.DESTRUCTIVE
+import androidx.compose.material.ButtonType.NEUTRAL
 import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.DialogButton
+import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.material.Icon
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.OutlinedButton
@@ -35,6 +42,8 @@ import androidx.compose.material.icons.filled.CheckCircle
 import androidx.compose.material.icons.filled.Error
 import androidx.compose.material.icons.filled.QuestionMark
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment.Companion.CenterHorizontally
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
@@ -62,6 +71,7 @@ fun main() = preview(
         listOf("error", "problem", "mailbox too old", "briar too old", "ok")
     ),
     "isCheckingConnection" to false,
+    "isWiping" to false,
 ) {
     val now = System.currentTimeMillis()
     val status = when (getStringParameter("status")) {
@@ -71,7 +81,13 @@ fun main() = preview(
         "briar too old" -> MailboxStatus(now, now, 0, listOf(MailboxVersion(42, 0)))
         else -> MailboxStatus(now, now - 18_354, 0, CLIENT_SUPPORTS)
     }
-    MailboxStatusScreen(status, getBooleanParameter("isCheckingConnection")) {}
+    MailboxStatusScreen(
+        status = status,
+        isCheckingConnection = getBooleanParameter("isCheckingConnection"),
+        onCheckConnection = {},
+        isWiping = getBooleanParameter("isWiping"),
+        onWipe = {},
+    )
 }
 
 @Composable
@@ -79,8 +95,11 @@ fun MailboxStatusScreen(
     status: MailboxStatus?,
     isCheckingConnection: Boolean,
     onCheckConnection: () -> Unit,
+    isWiping: Boolean,
+    onWipe: () -> Unit,
 ) {
     if (status == null) return // not expected to happen (for a noticeable amount of time)
+    val deleteGroupDialogVisible = remember { mutableStateOf(false) }
     Column(
         verticalArrangement = spacedBy(16.dp),
         horizontalAlignment = CenterHorizontally,
@@ -129,20 +148,27 @@ fun MailboxStatusScreen(
         }
         if (isCheckingConnection) CircularProgressIndicator()
         else Button(
-            onClick = onCheckConnection
+            onClick = onCheckConnection,
+            enabled = !isWiping,
         ) {
             Text(
                 text = i18n("mailbox.status.check.connection.button"),
             )
         }
         Spacer(modifier = Modifier.weight(1f))
-        OutlinedButton(
-            onClick = { /* TODO */ },
+        if (isWiping) CircularProgressIndicator()
+        else OutlinedButton(
+            onClick = { deleteGroupDialogVisible.value = true },
+            enabled = !isCheckingConnection,
         ) {
             Text(
                 text = i18n("mailbox.status.unlink.button"),
             )
         }
+        if (deleteGroupDialogVisible.value) MailboxWipeDialog(
+            close = { deleteGroupDialogVisible.value = false },
+            onWipe = onWipe,
+        )
     }
 }
 
@@ -174,3 +200,44 @@ private fun MailboxStatusView(
         modifier = Modifier.alpha(0.56f)
     )
 }
+
+@Composable
+@OptIn(ExperimentalMaterialApi::class)
+fun MailboxWipeDialog(
+    close: () -> Unit,
+    onWipe: () -> Unit = {},
+) {
+    AlertDialog(
+        onDismissRequest = close,
+        title = {
+            Text(
+                text = i18n("mailbox.unlink.dialog.title"),
+                modifier = Modifier.width(Max),
+                style = MaterialTheme.typography.h6,
+            )
+        },
+        text = {
+            Column(verticalArrangement = spacedBy(16.dp)) {
+                Text(i18n("mailbox.unlink.dialog.question"))
+                Text(i18n("mailbox.unlink.dialog.warning"))
+            }
+        },
+        dismissButton = {
+            DialogButton(
+                onClick = { close() },
+                text = i18n("cancel"),
+                type = NEUTRAL,
+            )
+        },
+        confirmButton = {
+            DialogButton(
+                onClick = {
+                    close()
+                    onWipe()
+                },
+                text = i18n("mailbox.unlink.dialog.button"),
+                type = DESTRUCTIVE,
+            )
+        },
+    )
+}
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt
index 8e293a210cf0f570ece116259ebf013b305d2ec3..50fd5e3ada166edd63ae8323f48545e68005b1ab 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/mailbox/MailboxViewModel.kt
@@ -40,6 +40,7 @@ import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.NotSetup
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.OfflineWhenPairing
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Pairing
 import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.Unknown
+import org.briarproject.briar.desktop.mailbox.MailboxPairingUiState.WasUnpaired
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import org.briarproject.briar.desktop.utils.KLoggerUtils.i
@@ -53,7 +54,7 @@ sealed class MailboxPairingUiState {
     object NotSetup : MailboxPairingUiState()
     class Pairing(val pairingState: MailboxPairingState) : MailboxPairingUiState()
     object OfflineWhenPairing : MailboxPairingUiState()
-    class IsPaired(val connectionCheckRunning: Boolean) : MailboxPairingUiState()
+    class IsPaired(val connectionCheckRunning: Boolean, val isWiping: Boolean) : MailboxPairingUiState()
     class WasUnpaired(val tellUserToWipeMailbox: Boolean) : MailboxPairingUiState()
 }
 
@@ -93,7 +94,7 @@ class MailboxViewModel @Inject constructor(
             if (isPaired) {
                 val mailboxStatus = mailboxManager.getMailboxStatus(txn)
                 briarExecutors.onUiThread {
-                    _pairingState.value = IsPaired(false)
+                    _pairingState.value = IsPaired(connectionCheckRunning = false, isWiping = false)
                     _status.value = mailboxStatus
                 }
             } else briarExecutors.onUiThread {
@@ -160,16 +161,27 @@ class MailboxViewModel @Inject constructor(
     @UiExecutor
     fun checkConnection() {
         // we can only check the connection when we are already paired (or just finished pairing)
-        _pairingState.value = IsPaired(true)
+        _pairingState.value = IsPaired(connectionCheckRunning = true, isWiping = false)
         briarExecutors.onIoThread {
             // this check updates _status state via an Event
             val success = mailboxManager.checkConnection()
             LOG.i { "Got result from connection check: $success" }
             briarExecutors.onUiThread {
                 val s = pairingState.value
-                if (s is IsPaired) _pairingState.value = IsPaired(false)
+                if (s is IsPaired) _pairingState.value = IsPaired(connectionCheckRunning = false, isWiping = false)
                 else LOG.w { "Unexpected state: ${s::class.simpleName}" }
             }
         }
     }
+
+    @UiExecutor
+    fun unlink() {
+        _pairingState.value = IsPaired(connectionCheckRunning = false, isWiping = true)
+        briarExecutors.onIoThread {
+            val wasWiped = mailboxManager.unPair()
+            briarExecutors.onUiThread {
+                _pairingState.value = WasUnpaired(!wasWiped)
+            }
+        }
+    }
 }
diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
index 58fd1974211169486caa894c92a8b0c79fec231a..a317839da5e585027ed9823345500a69e47444b9 100644
--- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties
+++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
@@ -261,6 +261,12 @@ mailbox.setup.io_error_description=Ensure that both devices are connected to the
 mailbox.setup.assertion_error_description=Please create a bug report if the issue persists.
 mailbox.setup.offline_error_title=Offline
 mailbox.setup.offline_error_description=Ensure that you are online and try again after a while.
+mailbox.unlink.no_wipe.title=Your Mailbox has been unlinked
+mailbox.unlink.no_wipe.message=Next time you have access to your Mailbox device, please open the Mailbox app and tap the "Unlink" button to complete the process.\n\nIf you no longer have access to your Mailbox device, don't worry. Your data is encrypted so it will remain secure even if you don't complete the process.
+mailbox.unlink.dialog.title=Unlink mailbox?
+mailbox.unlink.dialog.question=Are you sure you want to unlink your Mailbox?
+mailbox.unlink.dialog.warning=If you unlink your Mailbox, you won't be able to receive messages while Briar is offline.
+mailbox.unlink.dialog.button=Unlink
 mailbox.status.error=Mailbox is unavailable
 mailbox.status.problem=Briar is having trouble connecting to the Mailbox
 mailbox.status.app_too_old.title=Briar is too old