diff --git a/ibis/ibismessage.h b/ibis/ibismessage.h
--- a/ibis/ibismessage.h
+++ b/ibis/ibismessage.h
@@ -253,6 +253,22 @@
 IBIS_AVAILABLE_IN_0_1
 IbisMessage *ibis_message_parse(const char *buffer, GError **error);
 
+/**
+ * ibis_message_get_raw_message:
+ * @message: The instance.
+ *
+ * Gets the `raw-message` that @message was parsed from.
+ *
+ * If @message was not created via [func@Message.parse], then this will be
+ * %NULL.
+ *
+ * Returns: The raw message if available, otherwise %NULL.
+ *
+ * Since: 0.1
+ */
+IBIS_AVAILABLE_IN_0_1
+const char *ibis_message_get_raw_message(IbisMessage *message);
+
 G_END_DECLS
 
 #endif /* IBIS_MESSAGE_H */
# HG changeset patch
# Node ID 012228deb4ef
# Parent  377e1e0c4641
diff --git a/ibis/ibismessage.c b/ibis/ibismessage.c
--- a/ibis/ibismessage.c
+++ b/ibis/ibismessage.c
@@ -31,6 +31,7 @@
 	PROP_COMMAND,
 	PROP_SOURCE,
 	PROP_PARAMS,
+	PROP_RAW_MESSAGE,
 	PROP_TAGS,
 	PROP_ERROR,
 	N_PROPERTIES,
@@ -40,6 +41,8 @@
 struct _IbisMessage {
 	GObject parent;
 
+	char *raw_message;
+
 	char *command;
 	GStrv params;
 	char *source;
@@ -141,6 +144,16 @@
 	}
 }
 
+static void
+ibis_message_set_raw_message(IbisMessage *message, const char *raw_message) {
+	g_return_if_fail(IBIS_IS_MESSAGE(message));
+
+	if(g_set_str(&message->raw_message, raw_message)) {
+		g_object_notify_by_pspec(G_OBJECT(message),
+		                         properties[PROP_RAW_MESSAGE]);
+	}
+}
+
 static guint
 ibis_message_extract_params(GStrvBuilder *builder, const char *str) {
 	char *ptr = NULL;
@@ -215,6 +228,7 @@
 
 	g_clear_pointer(&message->command, g_free);
 	g_clear_pointer(&message->params, g_strfreev);
+	g_clear_pointer(&message->raw_message, g_free);
 	g_clear_pointer(&message->source, g_free);
 	g_clear_object(&message->tags);
 	g_clear_error(&message->error);
@@ -235,6 +249,9 @@
 	case PROP_PARAMS:
 		g_value_set_boxed(value, ibis_message_get_params(message));
 		break;
+	case PROP_RAW_MESSAGE:
+		g_value_set_string(value, ibis_message_get_raw_message(message));
+		break;
 	case PROP_SOURCE:
 		g_value_set_string(value, ibis_message_get_source(message));
 		break;
@@ -263,6 +280,9 @@
 	case PROP_PARAMS:
 		ibis_message_set_paramsv(message, g_value_get_boxed(value));
 		break;
+	case PROP_RAW_MESSAGE:
+		ibis_message_set_raw_message(message, g_value_get_string(value));
+		break;
 	case PROP_SOURCE:
 		ibis_message_set_source(message, g_value_get_string(value));
 		break;
@@ -321,6 +341,22 @@
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
+	 * IbisMessage:raw-message:
+	 *
+	 * The raw message that was parsed.
+	 *
+	 * This property will only be non %NULL if the message was created with
+	 * [func@Message.parse].
+	 *
+	 * Since: 0.1
+	 */
+	properties[PROP_RAW_MESSAGE] = g_param_spec_string(
+		"raw-message", "raw-message",
+		"The raw message that was parsed.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	/**
 	 * IbisMessage:source:
 	 *
 	 * The source of the message.
@@ -545,7 +581,11 @@
 
 	/* Extract the command from the buffer, so we can create the message. */
 	command = g_match_info_fetch_named(info, "command");
-	message = ibis_message_new(command);
+	message = g_object_new(
+		IBIS_TYPE_MESSAGE,
+		"command", command,
+		"raw-message", buffer,
+		NULL);
 
 	tags_string = g_match_info_fetch_named(info, "tags");
 	if(!ibis_str_is_empty(tags_string)) {
@@ -597,3 +637,10 @@
 
 	return message;
 }
+
+const char *
+ibis_message_get_raw_message(IbisMessage *message) {
+	g_return_val_if_fail(IBIS_IS_MESSAGE(message), NULL);
+
+	return message->raw_message;
+}
diff --git a/ibis/tests/test_message.c b/ibis/tests/test_message.c
--- a/ibis/tests/test_message.c
+++ b/ibis/tests/test_message.c
@@ -50,6 +50,7 @@
 	GStrv params1 = NULL;
 	GStrv params2 = NULL;
 	GStrvBuilder *builder = NULL;
+	char *raw_message = NULL;
 	char *source = NULL;
 	char *command = NULL;
 
@@ -68,6 +69,7 @@
 		IBIS_TYPE_MESSAGE,
 		"command", "command",
 		"params", params1,
+		"raw-message", ":source command param1",
 		"source", "source",
 		"tags", tags1,
 		"error", error1,
@@ -79,6 +81,7 @@
 		message,
 		"command", &command,
 		"params", &params2,
+		"raw-message", &raw_message,
 		"source", &source,
 		"tags", &tags2,
 		"error", &error2,
@@ -90,6 +93,9 @@
 	g_assert_cmpstrv(params2, params1);
 	g_clear_pointer(&params2, g_strfreev);
 
+	g_assert_cmpstr(raw_message, ==, ":source command param1");
+	g_clear_pointer(&raw_message, g_free);
+
 	g_assert_cmpstr(source, ==, "source");
 	g_clear_pointer(&source, g_free);
 
diff --git a/ibis/tests/test_parser.c b/ibis/tests/test_parser.c
--- a/ibis/tests/test_parser.c
+++ b/ibis/tests/test_parser.c
@@ -43,6 +43,7 @@
 	GError *error = NULL;
 	GStrv params = NULL;
 	const char *command = NULL;
+	const char *raw_message = NULL;
 	const char *source = NULL;
 	guint n_params = 0;
 
@@ -50,6 +51,9 @@
 	g_assert_no_error(error);
 	g_assert_true(IBIS_IS_MESSAGE(message));
 
+	raw_message = ibis_message_get_raw_message(message);
+	g_assert_cmpstr(raw_message, ==, raw);
+
 	command = ibis_message_get_command(message);
 	g_assert_cmpstr(command, ==, d->command);
 
