diff --git a/substrate/core/rpc/src/state/tests.rs b/substrate/core/rpc/src/state/tests.rs
index 6b4ddc9b920bc9b0dbf9eb0c219e9c4cb3a4aef7..0bb6d40e24c69e9a151de3064a3fd5da329911f5 100644
--- a/substrate/core/rpc/src/state/tests.rs
+++ b/substrate/core/rpc/src/state/tests.rs
@@ -262,10 +262,12 @@ fn should_return_runtime_version() {
 		[\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\
 		[\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}";
 
-	assert_eq!(
-		serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(),
-		result,
-	);
+	let runtime_version = api.runtime_version(None.into()).unwrap();
+	let serialized = serde_json::to_string(&runtime_version).unwrap();
+	assert_eq!(serialized, result);
+
+	let deserialized: RuntimeVersion = serde_json::from_str(result).unwrap();
+	assert_eq!(deserialized, runtime_version);
 }
 
 #[test]
diff --git a/substrate/core/sr-version/src/lib.rs b/substrate/core/sr-version/src/lib.rs
index 731c5b63c7137cf9d00c3253c9021d0e4af35e1d..f787d8dd7ebfb112b64442eea53f0adbfa46f63a 100644
--- a/substrate/core/sr-version/src/lib.rs
+++ b/substrate/core/sr-version/src/lib.rs
@@ -96,7 +96,13 @@ pub struct RuntimeVersion {
 	pub impl_version: u32,
 
 	/// List of supported API "features" along with their versions.
-	#[cfg_attr(feature = "std", serde(serialize_with = "apis_serialize::serialize"))]
+	#[cfg_attr(
+		feature = "std",
+		serde(
+			serialize_with = "apis_serialize::serialize",
+			deserialize_with = "apis_serialize::deserialize",
+		)
+	)]
 	pub apis: ApisVec,
 }
 
@@ -163,7 +169,7 @@ impl NativeVersion {
 mod apis_serialize {
 	use super::*;
 	use impl_serde::serialize as bytes;
-	use serde::{Serializer, ser::SerializeTuple};
+	use serde::{Serializer, de, ser::SerializeTuple};
 
 	#[derive(Serialize)]
 	struct ApiId<'a>(
@@ -187,4 +193,44 @@ mod apis_serialize {
 	{
 		bytes::serialize(*apis, ser)
 	}
+
+	#[derive(Deserialize)]
+	struct ApiIdOwned(
+		#[serde(deserialize_with="deserialize_bytes")]
+		super::ApiId,
+		u32,
+	);
+
+	pub fn deserialize<'de, D>(deserializer: D) -> Result<ApisVec, D::Error> where
+		D: de::Deserializer<'de>,
+	{
+		struct Visitor;
+		impl<'de> de::Visitor<'de> for Visitor {
+			type Value = ApisVec;
+
+			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+				formatter.write_str("a sequence of api id and version tuples")
+			}
+
+			fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> where
+				V: de::SeqAccess<'de>,
+			{
+				let mut apis = Vec::new();
+				while let Some(value) = visitor.next_element::<ApiIdOwned>()? {
+					apis.push((value.0, value.1));
+				}
+				Ok(apis.into())
+			}
+		}
+		deserializer.deserialize_seq(Visitor)
+	}
+
+	pub fn deserialize_bytes<'de, D>(d: D) -> Result<super::ApiId, D::Error> where
+		D: de::Deserializer<'de>
+	{
+		let bytes = bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(8))?;
+		let mut arr = [0; 8];
+		arr.copy_from_slice(&bytes);
+		Ok(arr)
+	}
 }