diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
index 0c09880dfb743245b6f34749801c5c52fa4afe6a..c73d7ca4a7d70154e59ec0dd78b0bbac5518a6d9 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
@@ -339,6 +339,11 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, size_t addressed_index);
 	public:
 		IPAACA_HEADER_EXPORT size_t size();
+		IPAACA_HEADER_EXPORT bool is_null();
+		IPAACA_HEADER_EXPORT bool is_string();
+		IPAACA_HEADER_EXPORT bool is_number();
+		IPAACA_HEADER_EXPORT bool is_list();
+		IPAACA_HEADER_EXPORT bool is_map();
 	public:
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](size_t index); // array-style navigation
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](int index); // int is UNFORTUNATELY required to catch
diff --git a/ipaacalib/cpp/src/ipaaca-json.cc b/ipaacalib/cpp/src/ipaaca-json.cc
index 4124d3994f702e26c643398d522d1f8e01976de4..857c67aab5cf2e96b36135686025c8744fec141a 100644
--- a/ipaacalib/cpp/src/ipaaca-json.cc
+++ b/ipaacalib/cpp/src/ipaaca-json.cc
@@ -57,6 +57,7 @@ int iterators_main(int argc, char** argv)//{{{
 	std::cout << "Using this JSON document as initial payload entry 'a':" << std::endl << json_source << std::endl;
 	ipaaca::PayloadDocumentEntry::ptr entry = ipaaca::PayloadDocumentEntry::from_json_string_representation(json_source);
 	
+	std::cout << std::endl << "Setting up payload by adding some additional values" << std::endl;
 	ipaaca::FakeIU::ptr iu = ipaaca::FakeIU::create();
 	iu->add_fake_payload_item("a", entry);
 	iu->payload()["b"] = "simpleString";
@@ -64,6 +65,7 @@ int iterators_main(int argc, char** argv)//{{{
 	iu->payload()["c"] = "anotherSimpleString";
 	iu->payload()["d"] = 100;
 	iu->payload()["e"] = 3l;
+	iu->payload()["f"] = "12.5000";
 	
 	std::cout << std::endl << "Iterate over payload" << std::endl;
 	for (auto it = iu->payload().begin(); it != iu->payload().end(); ++it) {
@@ -89,6 +91,19 @@ int iterators_main(int argc, char** argv)//{{{
 	eq = iu->payload()["a"][2] == iu->payload()["e"];
 	std::cout << "  a[2]==e ? : " << (eq?"true":"false") << std::endl;
 	
+	std::cout << std::endl << "Type checks" << std::endl;
+	std::cout << "  a[3] is_null() ? : " << ((iu->payload()["a"][3].is_null())?"true":"false") << std::endl;
+	std::cout << "  a[3] is_string() ? : " << ((iu->payload()["a"][3].is_string())?"true":"false") << std::endl;
+	std::cout << "  a[3] is_number() ? : " << ((iu->payload()["a"][3].is_number())?"true":"false") << std::endl;
+	std::cout << "  a[3] is_list() ? : " << ((iu->payload()["a"][3].is_list())?"true":"false") << std::endl;
+	std::cout << "  a[3] is_map() ? : " << ((iu->payload()["a"][3].is_map())?"true":"false") << std::endl;
+	std::cout << std::endl;
+	std::cout << "  f is_null() ? : " << ((iu->payload()["f"].is_null())?"true":"false") << std::endl;
+	std::cout << "  f is_string() ? : " << ((iu->payload()["f"].is_string())?"true":"false") << std::endl;
+	std::cout << "  f is_number() ? : " << ((iu->payload()["f"].is_number())?"true":"false") << std::endl;
+	std::cout << "  f is_list() ? : " << ((iu->payload()["f"].is_list())?"true":"false") << std::endl;
+	std::cout << "  f is_map() ? : " << ((iu->payload()["f"].is_map())?"true":"false") << std::endl;
+	
 	std::cout << std::endl << "Inner iterators, map (printing values as strings)" << std::endl;
 	try {
 		auto inner = iu->payload()["a"][3];
diff --git a/ipaacalib/cpp/src/ipaaca-payload.cc b/ipaacalib/cpp/src/ipaaca-payload.cc
index 99117e08cb87f44466e7bf69f708582c1b3aeb37..02da62124b26456288b4ce75cbd4f9a41adc50a5 100644
--- a/ipaacalib/cpp/src/ipaaca-payload.cc
+++ b/ipaacalib/cpp/src/ipaaca-payload.cc
@@ -586,6 +586,34 @@ IPAACA_EXPORT size_t PayloadEntryProxy::size()
 	if (json_value->IsObject()) return json_value->MemberCount();
 	return 0;
 }
+IPAACA_EXPORT bool PayloadEntryProxy::is_null()
+{
+	return (!json_value) || json_value->IsNull();
+}
+IPAACA_EXPORT bool PayloadEntryProxy::is_string()
+{
+	return json_value && json_value->IsString();
+}
+/// is_number => whether it is *interpretable* as
+/// a numerical value (i.e. including conversions)
+IPAACA_EXPORT bool PayloadEntryProxy::is_number()
+{
+	if (!json_value) return false;
+	try {
+		double dummy = json_value_cast<double>(*json_value);
+		return true;
+	} catch (PayloadTypeConversionError& ex) {
+		return false;
+	}
+}
+IPAACA_EXPORT bool PayloadEntryProxy::is_list()
+{
+	return json_value && json_value->IsArray();
+}
+IPAACA_EXPORT bool PayloadEntryProxy::is_map()
+{
+	return json_value && json_value->IsObject();
+}
 
 //
 // new stuff for protocol v2