diff --git a/libpurple/purplecontactinfo.h b/libpurple/purplecontactinfo.h
--- a/libpurple/purplecontactinfo.h
+++ b/libpurple/purplecontactinfo.h
@@ -231,6 +231,98 @@
 void purple_contact_info_set_color(PurpleContactInfo *info, const char *color);
 
 /**
+ * purple_contact_info_get_email:
+ * @info: The instance.
+ *
+ * Gets the primary email address from @info.
+ *
+ * Returns: (nullable): The primary email address or %NULL if not set.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_contact_info_get_email(PurpleContactInfo *info);
+
+/**
+ * purple_contact_info_set_email:
+ * @info: The instance.
+ * @email: (nullable): The new email address.
+ *
+ * Sets the primary email address for @info.
+ *
+ * Since: 3.0.0
+ */
+void purple_contact_info_set_email(PurpleContactInfo *info, const char *email);
+
+/**
+ * purple_contact_info_get_phone_number:
+ * @info: The instance:
+ *
+ * Gets the primary phone number for the contact.
+ *
+ * Returns: (nullable): The primary phone number for the contact.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_contact_info_get_phone_number(PurpleContactInfo *info);
+
+/**
+ * purple_contact_info_set_phone_number:
+ * @info: The instance.
+ * @phone_number: (nullable): The new phone number to set.
+ *
+ * Sets the primary phone number for @info.
+ *
+ * Since: 3.0.0
+ */
+void purple_contact_info_set_phone_number(PurpleContactInfo *info, const char *phone_number);
+
+/**
+ * purple_contact_info_get_time_zone:
+ * @info: The instance.
+ *
+ * Gets the [struct@GTimeZone] for @info.
+ *
+ * Returns: (nullable): The time zone if set, otherwise %NULL.
+ *
+ * Since: 3.0.0
+ */
+GTimeZone *purple_contact_info_get_time_zone(PurpleContactInfo *info);
+
+/**
+ * purple_contact_info-set_time_zone:
+ * @info: The instance.
+ * @time_zone: (nullable): The new time zone.
+ *
+ * Sets the time zone of @info to @time_zone.
+ *
+ * Since: 3.0.0
+ */
+void purple_contact_info_set_time_zone(PurpleContactInfo *info, GTimeZone *timezone);
+
+/**
+ * purple_contact_info_get_note:
+ * @info: The instance.
+ *
+ * Gets the "note" for and @info.
+ *
+ * Returns: The note.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_contact_info_get_note(PurpleContactInfo *info);
+
+/**
+ * purple_contact_info_set_note:
+ * @info: The instance.
+ * @note: (nullable): The new note.
+ *
+ * Sets the note for @info to @note.
+ *
+ * Since: 3.0.0
+ */
+void purple_contact_info_set_note(PurpleContactInfo *info, const char *note);
+
+/**
  * purple_contact_info_get_avatar:
  * @info: The instance.
  *
# HG changeset patch
# Node ID b229c2a100eb
# Parent  63639da06cbd
diff --git a/libpurple/purplecontactinfo.c b/libpurple/purplecontactinfo.c
--- a/libpurple/purplecontactinfo.c
+++ b/libpurple/purplecontactinfo.c
@@ -28,6 +28,10 @@
 	char *display_name;
 	char *alias;
 	char *color;
+	char *email;
+	char *phone_number;
+	GTimeZone *time_zone;
+	char *note;
 
 	char *name_for_display;
 
@@ -49,6 +53,10 @@
 	PROP_DISPLAY_NAME,
 	PROP_ALIAS,
 	PROP_COLOR,
+	PROP_EMAIL,
+	PROP_PHONE_NUMBER,
+	PROP_TIME_ZONE,
+	PROP_NOTE,
 	PROP_AVATAR,
 	PROP_PRESENCE,
 	PROP_TAGS,
@@ -171,6 +179,19 @@
 		case PROP_COLOR:
 			g_value_set_string(value, purple_contact_info_get_color(info));
 			break;
+		case PROP_EMAIL:
+			g_value_set_string(value, purple_contact_info_get_email(info));
+			break;
+		case PROP_PHONE_NUMBER:
+			g_value_set_string(value,
+			                   purple_contact_info_get_phone_number(info));
+			break;
+		case PROP_TIME_ZONE:
+			g_value_set_boxed(value, purple_contact_info_get_time_zone(info));
+			break;
+		case PROP_NOTE:
+			g_value_set_string(value, purple_contact_info_get_note(info));
+			break;
 		case PROP_AVATAR:
 			g_value_set_object(value, purple_contact_info_get_avatar(info));
 			break;
@@ -219,6 +240,19 @@
 		case PROP_COLOR:
 			purple_contact_info_set_color(info, g_value_get_string(value));
 			break;
+		case PROP_EMAIL:
+			purple_contact_info_set_email(info, g_value_get_string(value));
+			break;
+		case PROP_PHONE_NUMBER:
+			purple_contact_info_set_phone_number(info,
+			                                     g_value_get_string(value));
+			break;
+		case PROP_TIME_ZONE:
+			purple_contact_info_set_time_zone(info, g_value_get_boxed(value));
+			break;
+		case PROP_NOTE:
+			purple_contact_info_set_note(info, g_value_get_string(value));
+			break;
 		case PROP_AVATAR:
 			purple_contact_info_set_avatar(info, g_value_get_object(value));
 			break;
@@ -261,6 +295,10 @@
 	g_clear_pointer(&priv->display_name, g_free);
 	g_clear_pointer(&priv->alias, g_free);
 	g_clear_pointer(&priv->color, g_free);
+	g_clear_pointer(&priv->email, g_free);
+	g_clear_pointer(&priv->phone_number, g_free);
+	g_clear_pointer(&priv->time_zone, g_time_zone_unref);
+	g_clear_pointer(&priv->note, g_free);
 	g_clear_pointer(&priv->name_for_display, g_free);
 
 	G_OBJECT_CLASS(purple_contact_info_parent_class)->finalize(obj);
@@ -379,10 +417,67 @@
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
+	 * PurpleContactInfo:email:
+	 *
+	 * The primary email address for the contact. This may also be controlled
+	 * via a protocol plugin in the event that the protocol makes it available.
+	 *
+	 * Since: 3.0.0
+	 */
+	properties[PROP_EMAIL] = g_param_spec_string(
+		"email", "email",
+		"The primary email address for the contact.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
+	 * PurpleContactInfo:phone-number:
+	 *
+	 * The primary phone number for the contact. This may also be set via a
+	 * protocol plugin in the event that the protocol knows it.
+	 *
+	 * Since: 3.0.0
+	 */
+	properties[PROP_PHONE_NUMBER] = g_param_spec_string(
+		"phone-number", "phone-number",
+		"The primary phone number for the contact.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
+	 * PurpleContactInfo:time-zone:
+	 *
+	 * The time zone for this contact. This is typically controlled by the
+	 * protocol and should only be read by others.
+	 *
+	 * Since: 3.0.0
+	 */
+	properties[PROP_TIME_ZONE] = g_param_spec_boxed(
+		"time-zone", "time-zone",
+		"The time zone for the contact.",
+		G_TYPE_TIME_ZONE,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
+	 * PurpleContactInfo:note:
+	 *
+	 * A note for this contact. Many protocols will allow you to set a note on
+	 * a contact and store it server side. This property is where that is kept
+	 * track of.
+	 *
+	 * Since: 3.0.0
+	 */
+	properties[PROP_NOTE] = g_param_spec_string(
+		"note", "note",
+		"A note for the contact.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
 	 * PurpleContactInfo:avatar:
 	 *
-	 * The avatar for this contact. This is typically controlled by the protocol
-	 * and should only be read by others.
+	 * The avatar for this contact. This is typically controlled by the
+	 * protocol and should only be read by others.
 	 *
 	 * Since: 3.0.0
 	 */
@@ -690,6 +785,125 @@
 	}
 }
 
+const char *
+purple_contact_info_get_email(PurpleContactInfo *info) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL);
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	return priv->email;
+}
+
+void
+purple_contact_info_set_email(PurpleContactInfo *info, const char *email) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_CONTACT_INFO(info));
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	if(!purple_strequal(priv->email, email)) {
+		g_free(priv->email);
+		priv->email = g_strdup(email);
+
+		g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_EMAIL]);
+	}
+}
+
+const char *
+purple_contact_info_get_phone_number(PurpleContactInfo *info) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL);
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	return priv->phone_number;
+}
+
+void
+purple_contact_info_set_phone_number(PurpleContactInfo *info,
+                                     const char *phone_number)
+{
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_CONTACT_INFO(info));
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	if(!purple_strequal(priv->phone_number, phone_number)) {
+		g_free(priv->phone_number);
+		priv->phone_number = g_strdup(phone_number);
+
+		g_object_notify_by_pspec(G_OBJECT(info),
+		                         properties[PROP_PHONE_NUMBER]);
+	}
+}
+
+GTimeZone *
+purple_contact_info_get_time_zone(PurpleContactInfo *info) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL);
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	return priv->time_zone;
+}
+
+void
+purple_contact_info_set_time_zone(PurpleContactInfo *info,
+                                  GTimeZone *time_zone)
+{
+	PurpleContactInfoPrivate *priv = NULL;
+	GTimeZone *old = NULL;
+
+	g_return_if_fail(PURPLE_IS_CONTACT_INFO(info));
+
+	priv = purple_contact_info_get_instance_private(info);
+	old = priv->time_zone;
+
+	priv->time_zone = NULL;
+	if(time_zone != NULL) {
+		priv->time_zone = g_time_zone_ref(time_zone);
+	}
+
+	if(old != NULL) {
+		g_time_zone_unref(old);
+	}
+
+	g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_TIME_ZONE]);
+}
+
+const char *
+purple_contact_info_get_note(PurpleContactInfo *info) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL);
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	return priv->note;
+}
+
+void
+purple_contact_info_set_note(PurpleContactInfo *info, const char *note) {
+	PurpleContactInfoPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_CONTACT_INFO(info));
+
+	priv = purple_contact_info_get_instance_private(info);
+
+	if(!purple_strequal(priv->note, note)) {
+		g_free(priv->note);
+		priv->note = g_strdup(note);
+
+		g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_NOTE]);
+	}
+}
+
 GdkPixbuf *
 purple_contact_info_get_avatar(PurpleContactInfo *info) {
 	PurpleContactInfoPrivate *priv = NULL;
diff --git a/libpurple/tests/test_contact_info.c b/libpurple/tests/test_contact_info.c
--- a/libpurple/tests/test_contact_info.c
+++ b/libpurple/tests/test_contact_info.c
@@ -46,16 +46,23 @@
 	PurpleTags *tags = NULL;
 	GdkPixbuf *avatar = NULL;
 	GdkPixbuf *avatar1 = NULL;
+	GTimeZone *time_zone = NULL;
+	GTimeZone *time_zone1 = NULL;
 	char *id = NULL;
 	char *username = NULL;
 	char *display_name = NULL;
 	char *alias = NULL;
 	char *color = NULL;
+	char *email = NULL;
+	char *phone_number = NULL;
+	char *note = NULL;
 	char *name_for_display = NULL;
 
 	avatar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
 	person = purple_person_new();
 
+	time_zone = g_time_zone_new_utc();
+
 	/* Use g_object_new so we can test setting properties by name. All of them
 	 * call the setter methods, so by doing it this way we exercise more of the
 	 * code.
@@ -67,6 +74,10 @@
 		"display-name", "display-name",
 		"alias", "alias",
 		"color", "#e9c636",
+		"email", "pidgin@example.com",
+		"phone-number", "+10123456789",
+		"time-zone", time_zone,
+		"note", "message in a bottle",
 		"avatar", avatar,
 		"person", person,
 		"permission", PURPLE_CONTACT_INFO_PERMISSION_ALLOW,
@@ -79,6 +90,10 @@
 		"display-name", &display_name,
 		"alias", &alias,
 		"color", &color,
+		"email", &email,
+		"phone-number", &phone_number,
+		"time-zone", &time_zone1,
+		"note", &note,
 		"avatar", &avatar1,
 		"presence", &presence1,
 		"tags", &tags,
@@ -93,6 +108,11 @@
 	g_assert_cmpstr(display_name, ==, "display-name");
 	g_assert_cmpstr(alias, ==, "alias");
 	g_assert_cmpstr(color, ==, "#e9c636");
+	g_assert_cmpstr(email, ==, "pidgin@example.com");
+	g_assert_cmpstr(phone_number, ==, "+10123456789");
+	g_assert_cmpstr(g_time_zone_get_identifier(time_zone1), ==,
+	                g_time_zone_get_identifier(time_zone));
+	g_assert_cmpstr(note, ==, "message in a bottle");
 	g_assert_cmpstr(name_for_display, ==, "alias");
 	g_assert_true(avatar1 == avatar);
 	g_assert_nonnull(presence1);
@@ -106,6 +126,10 @@
 	g_clear_pointer(&display_name, g_free);
 	g_clear_pointer(&alias, g_free);
 	g_clear_pointer(&color, g_free);
+	g_clear_pointer(&email, g_free);
+	g_clear_pointer(&phone_number, g_free);
+	g_clear_pointer(&time_zone, g_time_zone_unref);
+	g_clear_pointer(&note, g_free);
 	g_clear_pointer(&name_for_display, g_free);
 	g_clear_object(&avatar1);
 	g_clear_object(&presence1);
