diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index dc979d71253f15f55077ef554f87331e0fa4dd8e..c1397f41b5bd587ffab37f78fc55b96e8756f46b 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -419,6 +419,11 @@ int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out);
 int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out);
 
 // TODO(fspreck) getters for value and datatypes
+int caosdb_entity_datatype_is_atomic(caosdb_entity_datatype *datatype, bool *out);
+int caosdb_entity_datatype_is_reference(caosdb_entity_datatype *datatype, bool *out);
+int caosdb_entity_datatype_is_list_of_atomic(caosdb_entity_datatype *datatype, bool *out);
+int caosdb_entity_datatype_is_list_of_refernce(caosdb_entity_datatype *datatype, bool *out);
+
 int caosdb_entity_value_is_null(caosdb_entity_value *value, bool *out);
 int caosdb_entity_value_is_string(caosdb_entity_value *value, bool *out);
 int caosdb_entity_value_is_double(caosdb_entity_value *value, bool *out);
@@ -440,13 +445,14 @@ int caosdb_entity_create_property(caosdb_entity_property *out);
 int caosdb_entity_delete_property(caosdb_entity_property *out);
 int caosdb_entity_create_parent(caosdb_entity_parent *out);
 int caosdb_entity_delete_parent(caosdb_entity_parent *out);
-// TODO(fspreck) implementations, also list_datatypes, list_values...
+
 // DATATYPE CONSTRUCTORS for atomic and reference datatypes and lists thereof
 int caosdb_entity_create_atomic_datatype(caosdb_entity_datatype *out, const char *name);
 int caosdb_entity_create_reference_datatype(caosdb_entity_datatype *out, const char *name);
 int caosdb_entity_create_atomic_list_datatype(caosdb_entity_datatype *out, const char *name);
 int caosdb_entity_create_reference_list_datatype(caosdb_entity_datatype *out, const char *name);
 int caosdb_entity_delete_datatype(caosdb_entity_datatype *out);
+
 // VALUE CONSTRUCTORS (resolve overloaded constructors)
 int caosdb_entity_create_int_value(caosdb_entity_value *out, const int64_t value);
 int caosdb_entity_create_string_value(caosdb_entity_value *out, const char *value);
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index 5079f119efdba1eff3f4c42705e08dc616d3a113..1e2b62fb233c2beeae7e19c4b903e35206032e54 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -719,9 +719,8 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out)
                     try {
                       auto enum_value = ENUM_VALUE_FROM_NAME(std::string(name), AtomicDataType);
-                      out->wrapped_datatype = new caosdb::entity::DataType();
-                      auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(out);
-                      wrapped_datatype->ListOf(enum_value);
+                      out->wrapped_datatype =
+                        new caosdb::entity::DataType(caosdb::entity::DataType::ListOf(enum_value));
                       out->_deletable = true;
                       return 0;
                     } catch (const std::out_of_range &exc) {
@@ -734,9 +733,8 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                                                                    const char *name),
                   {
                     RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out)
-                    out->wrapped_datatype = new caosdb::entity::DataType();
-                    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(out);
-                    wrapped_datatype->ListOf(std::string(name));
+                    out->wrapped_datatype = new caosdb::entity::DataType(
+                      caosdb::entity::DataType::ListOf(std::string(name)));
                     out->_deletable = true;
                     return 0;
                   })
@@ -1025,6 +1023,48 @@ ERROR_RETURN_CODE(
     return 0;
   })
 
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_datatype_is_atomic(caosdb_entity_datatype *datatype, bool *out),
+                  {
+                    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype);
+                    *out = wrapped_datatype->IsAtomic();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_datatype_is_reference(caosdb_entity_datatype *datatype,
+                                                          bool *out),
+                  {
+                    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype);
+                    *out = wrapped_datatype->IsReference();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_datatype_is_list_of_atomic(caosdb_entity_datatype *datatype,
+                                                               bool *out),
+                  {
+                    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype);
+                    if (wrapped_datatype->IsList()) {
+                      const auto &list_datatype = wrapped_datatype->GetAsList();
+                      *out = list_datatype.IsListOfAtomic();
+                    } else {
+                      *out = false;
+                    }
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_datatype_is_list_of_refernce(caosdb_entity_datatype *datatype,
+                                                                 bool *out),
+                  {
+                    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype);
+                    if (wrapped_datatype->IsList()) {
+                      const auto &list_datatype = wrapped_datatype->GetAsList();
+                      *out = list_datatype.IsListOfReference();
+                    } else {
+                      *out = false;
+                    }
+                    return 0;
+                  })
+
 VALUE_IS(null, IsNull)
 VALUE_IS(string, IsString)
 VALUE_IS(double, IsDouble)
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index ac01dd0a96d696a1f9ba2bf3aebc10d8028194ad..cb84419bfcea7e864b635b868633c7f9529cc1c0 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -142,13 +142,66 @@ TEST_F(test_ccaosdb, test_datatype) {
   EXPECT_EQ(return_code, 0);
 
   caosdb_entity_datatype list_of_atomics;
-  return_code = caosdb_entity_create_reference_datatype(&list_of_atomics, "DATETIME");
+  return_code = caosdb_entity_create_atomic_list_datatype(&list_of_atomics, "DATETIME");
   EXPECT_EQ(return_code, 0);
 
   caosdb_entity_datatype list_of_references;
-  return_code = caosdb_entity_create_reference_datatype(&list_of_references, "MyType");
+  return_code = caosdb_entity_create_reference_list_datatype(&list_of_references, "MyType");
   EXPECT_EQ(return_code, 0);
 
+  bool is_a(false);
+  return_code = caosdb_entity_datatype_is_atomic(&atomic, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_TRUE(is_a);
+  return_code = caosdb_entity_datatype_is_reference(&atomic, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_atomic(&atomic, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_refernce(&atomic, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+
+  return_code = caosdb_entity_datatype_is_atomic(&reference, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_reference(&reference, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_TRUE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_atomic(&reference, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_refernce(&reference, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+
+  return_code = caosdb_entity_datatype_is_atomic(&list_of_atomics, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_reference(&list_of_atomics, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_atomic(&list_of_atomics, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_TRUE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_refernce(&list_of_atomics, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+
+  return_code = caosdb_entity_datatype_is_atomic(&list_of_references, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_reference(&list_of_references, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_atomic(&list_of_references, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_FALSE(is_a);
+  return_code = caosdb_entity_datatype_is_list_of_refernce(&list_of_references, &is_a);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_TRUE(is_a);
+
   return_code = caosdb_entity_delete_datatype(&atomic);
   EXPECT_EQ(return_code, 0);
   return_code = caosdb_entity_delete_datatype(&reference);