diff --git a/briar-api/src/org/briarproject/api/contact/ContactManager.java b/briar-api/src/org/briarproject/api/contact/ContactManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..50a4a76a3d7e473a76801d2f33a6af8bca4d5278
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/contact/ContactManager.java
@@ -0,0 +1,27 @@
+package org.briarproject.api.contact;
+
+import org.briarproject.api.Author;
+import org.briarproject.api.AuthorId;
+import org.briarproject.api.Contact;
+import org.briarproject.api.ContactId;
+import org.briarproject.api.db.DbException;
+
+import java.util.Collection;
+
+public interface ContactManager {
+
+	/**
+	 * Stores a contact associated with the given local and remote pseudonyms,
+	 * and returns an ID for the contact.
+	 */
+	ContactId addContact(Author remote, AuthorId local) throws DbException;
+
+	/** Returns the contact with the given ID. */
+	Contact getContact(ContactId c) throws DbException;
+
+	/** Returns all contacts. */
+	Collection<Contact> getContacts() throws DbException;
+
+	/** Removes a contact and all associated state. */
+	void removeContact(ContactId c) throws DbException;
+}
diff --git a/briar-api/src/org/briarproject/api/forum/ForumManager.java b/briar-api/src/org/briarproject/api/forum/ForumManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a380bfc888d0456bddfb49af06ccf360e3b9b15
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/forum/ForumManager.java
@@ -0,0 +1,70 @@
+package org.briarproject.api.forum;
+
+import org.briarproject.api.Contact;
+import org.briarproject.api.ContactId;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageHeader;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+public interface ForumManager {
+
+	/**
+	 * Subscribes to a group, or returns false if the user already has the
+	 * maximum number of public subscriptions.
+	 */
+	boolean addGroup(Group g) throws DbException;
+
+	/** Stores a local message. */
+	void addLocalMessage(Message m) throws DbException;
+
+	/** Returns all groups to which the user could subscribe. */
+	Collection<Group> getAvailableGroups() throws DbException;
+
+	/** Returns the group with the given ID, if the user subscribes to it. */
+	Group getGroup(GroupId g) throws DbException;
+
+	/** Returns all groups to which the user subscribes, excluding inboxes. */
+	Collection<Group> getGroups() throws DbException;
+
+	/** Returns the body of the message with the given ID. */
+	byte[] getMessageBody(MessageId m) throws DbException;
+
+	/** Returns the headers of all messages in the given group. */
+	Collection<MessageHeader> getMessageHeaders(GroupId g)
+			throws DbException;
+
+	/** Returns all contacts who subscribe to the given group. */
+	Collection<Contact> getSubscribers(GroupId g) throws DbException;
+
+	/** Returns the IDs of all contacts to which the given group is visible. */
+	Collection<ContactId> getVisibility(GroupId g) throws DbException;
+
+	/**
+	 * Unsubscribes from a group. Any messages belonging to the group
+	 * are deleted.
+	 */
+	void removeGroup(Group g) throws DbException;
+
+	/**
+	 * Marks a message as read or unread.
+	 */
+	void setReadFlag(MessageId m, boolean read) throws DbException;
+
+	/**
+	 * Makes a group visible to the given set of contacts and invisible to any
+	 * other current or future contacts.
+	 */
+	void setVisibility(GroupId g, Collection<ContactId> visible)
+			throws DbException;
+
+	/**
+	 * Makes a group visible to all current and future contacts, or invisible
+	 * to future contacts.
+	 */
+	void setVisibleToAll(GroupId g, boolean all) throws DbException;
+}
diff --git a/briar-api/src/org/briarproject/api/identity/IdentityManager.java b/briar-api/src/org/briarproject/api/identity/IdentityManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..a657a0851862f84536b3a6dbad436376f3562074
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/identity/IdentityManager.java
@@ -0,0 +1,22 @@
+package org.briarproject.api.identity;
+
+import org.briarproject.api.AuthorId;
+import org.briarproject.api.LocalAuthor;
+import org.briarproject.api.db.DbException;
+
+import java.util.Collection;
+
+public interface IdentityManager {
+
+	/** Stores a local pseudonym. */
+	void addLocalAuthor(LocalAuthor a) throws DbException;
+
+	/** Returns the local pseudonym with the given ID. */
+	LocalAuthor getLocalAuthor(AuthorId a) throws DbException;
+
+	/** Returns all local pseudonyms. */
+	Collection<LocalAuthor> getLocalAuthors() throws DbException;
+
+	/** Removes a local pseudonym and all associated state. */
+	void removeLocalAuthor(AuthorId a) throws DbException;
+}
diff --git a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..4662157624891ceeb756f2fa1029bc3699aa5a31
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java
@@ -0,0 +1,54 @@
+package org.briarproject.api.messaging;
+
+import org.briarproject.api.ContactId;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageHeader;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+public interface MessagingManager {
+
+	/**
+	 * Subscribes to a group, or returns false if the user already has the
+	 * maximum number of public subscriptions.
+	 */
+	boolean addGroup(Group g) throws DbException;
+
+	/** Stores a local message. */
+	void addLocalMessage(Message m) throws DbException;
+
+	/** Returns the group with the given ID, if the user subscribes to it. */
+	Group getGroup(GroupId g) throws DbException;
+
+
+	/**
+	 * Returns the ID of the inbox group for the given contact, or null if no
+	 * inbox group has been set.
+	 */
+	GroupId getInboxGroupId(ContactId c) throws DbException;
+
+	/**
+	 * Returns the headers of all messages in the inbox group for the given
+	 * contact, or null if no inbox group has been set.
+	 */
+	Collection<MessageHeader> getInboxMessageHeaders(ContactId c)
+			throws DbException;
+
+	/** Returns the body of the message with the given ID. */
+	byte[] getMessageBody(MessageId m) throws DbException;
+
+	/**
+	 * Makes a group visible to the given contact, adds it to the contact's
+	 * subscriptions, and sets it as the inbox group for the contact.
+	 */
+	void setInboxGroup(ContactId c, Group g) throws DbException;
+
+	/**
+	 * Marks a message as read or unread.
+	 */
+	void setReadFlag(MessageId m, boolean read) throws DbException;
+}