diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java
index 430f2c274b0890863255be18ddc03fcfeaae7851..7ddb31a3661c175cd50cc277542aeb1959103854 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java
@@ -2,28 +2,44 @@ package org.briarproject.bramble.mailbox;
 
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.mailbox.MailboxConstants;
 import org.briarproject.bramble.api.mailbox.MailboxInfo;
 import org.briarproject.bramble.api.sync.SyncSessionFactory;
 import org.briarproject.bramble.api.transport.KeyManager;
+import org.briarproject.bramble.api.transport.StreamContext;
 import org.briarproject.bramble.api.transport.StreamReaderFactory;
 import org.briarproject.bramble.api.transport.StreamWriterFactory;
 import org.briarproject.bramble.mailbox.protocol.MailboxMessage;
 import org.briarproject.bramble.mailbox.protocol.MailboxProtocol;
 import org.briarproject.bramble.mailbox.protocol.MailboxRequest;
+import org.briarproject.bramble.mailbox.protocol.MailboxRequestHandler;
 import org.briarproject.bramble.mailbox.protocol.MailboxRequestStore;
+import org.briarproject.bramble.mailbox.protocol.MailboxRequestTake;
 
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.ProtocolException;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
+import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
+import static org.briarproject.bramble.mailbox.protocol.MailboxMessage.TYPE.TAKE;
 import static org.briarproject.bramble.util.LogUtils.logException;
 
-class PrivateMailboxSession extends AbstractMailboxSession {
+/**
+ * This session represents an Owner (of a private mailbox) connecting
+ * to their mailbox
+ */
+public class PrivateMailboxSession extends AbstractMailboxSession {
 	private static final Logger LOG =
 			Logger.getLogger(PrivateMailboxSession.class.getName());
+	private final KeyManager keyManager;
+	private final SyncSessionFactory syncSessionFactory;
+	private final StreamReaderFactory streamReaderFactory;
 	private MailboxProtocol mailboxProtocol;
 
 	public PrivateMailboxSession(ContactId contactId, Executor ioExecutor,
@@ -37,16 +53,22 @@ class PrivateMailboxSession extends AbstractMailboxSession {
 		super(ioExecutor, keyManager, syncSessionFactory, streamWriterFactory,
 				streamReaderFactory, mailboxProtocol, transportMaxLatency,
 				transportMaxIdleTime, contactId);
+		this.keyManager = keyManager;
+		this.syncSessionFactory = syncSessionFactory;
+		this.streamReaderFactory = streamReaderFactory;
 		this.mailboxProtocol = mailboxProtocol;
 
-		registerSupportedRequest(MailboxMessage.TYPE.SYNC);
+		mailboxProtocol.registerRequestHandler(new TAKEHandler());
+		// Register SYNC handler and run outgoing SYNC session
+		enableSYNCHandling();
+		mailboxProtocol.enableRequestHandling();
 	}
 
 	/**
 	 * Stores messages on the private mailbox for a contact
-	 * who does not have a mailbox
+	 * who does not own a mailbox
 	 */
-	public void handleOwnerContact(MailboxInfo mailboxInfo) {
+	public void handleContactWithoutPrivateMailbox(MailboxInfo mailboxInfo) {
 		byte[] encryptedStream;
 		try {
 			encryptedStream =
@@ -71,12 +93,65 @@ class PrivateMailboxSession extends AbstractMailboxSession {
 	}
 
 	@Override
-	public void run()  {
+	public void run() {
 		try {
-			waitForHandlersToFinish();
+			awaitSYNCHandlerFinished();
 		} catch (InterruptedException e) {
-			if (LOG.isLoggable(INFO))
-				LOG.info(e.toString());
+			logException(LOG, WARNING, e);
+		}
+	}
+
+	/**
+	 * Handles an incoming TAKE request. The request contains an encrypted BSP
+	 * stream. From this stream, the tag is read and a StreamReader is created.
+	 * A BSP IncomingSession is created for the stream
+	 */
+	private class TAKEHandler implements MailboxRequestHandler {
+		@Override
+		public void handleRequest(MailboxRequest request)
+				throws ProtocolException {
+			MailboxRequestTake takeRequest = (MailboxRequestTake) request;
+			InputStream in = new ByteArrayInputStream(
+					takeRequest.getEncryptedSyncStream());
+			byte[] tag = new byte[TAG_LENGTH];
+			StreamContext ctx;
+
+			try {
+				// read tag from input stream
+				int offset = 0;
+				while (offset < tag.length) {
+					int read = in.read(tag, offset, tag.length - offset);
+					if (read == -1) throw new EOFException();
+					offset += read;
+				}
+
+				ctx =
+						keyManager.getStreamContext(MailboxConstants.ID, tag);
+
+				if (ctx == null) {
+					throw new ProtocolException(
+							"Received stream with unrecognisable tag");
+				}
+
+				InputStream reader =
+						streamReaderFactory.createStreamReader(in, ctx);
+
+				syncSessionFactory
+						.createIncomingSession(ctx.getContactId(), reader)
+						.run();
+			} catch (DbException | IOException e) {
+				logException(LOG, WARNING, e);
+				throw new ProtocolException("Received invalid stream");
+			}
+		}
+
+		@Override
+		public MailboxMessage.TYPE getType() {
+			return TAKE;
+		}
+
+		@Override
+		public void protocolFinished() {
 		}
 	}
 }