diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index 9a70ab5a8f4abbc70d5089cdcce816025a913a92..40a47227c5d146a97583e5068b033896e17b1cfe 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -552,9 +552,37 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                   })
 CAOSDB_ENTITY_GET(name, GetName())
 CAOSDB_ENTITY_GET(description, GetDescription())
-// TODO(fspreck)
-// CAOSDB_ENTITY_GET(datatype, strcpy(out,
-// wrapped_entity->GetDatatype().c_str());)
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name,
+                                                        bool *is_ref, bool *is_list),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    const auto &datatype = wrapped_entity->GetDataType();
+                    *is_list = datatype.IsList();
+                    std::string datatype_name;
+                    if (*is_list) {
+                      const auto &list_datatype = datatype.AsList();
+                      *is_ref = list_datatype.IsListOfReference();
+                      if (*is_ref) {
+                        datatype_name = list_datatype.GetReferenceDataType().GetName();
+                      } else {
+                        datatype_name =
+                          ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType);
+                      }
+                    } else {
+                      *is_ref = datatype.IsReference();
+                      if (*is_ref) {
+                        datatype_name = datatype.AsReference().GetName();
+                      } else {
+                        datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType);
+                      }
+                    }
+                    char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
+                    strcpy(tmp, datatype_name.c_str());
+                    delete[] * name;
+                    *name = tmp;
+                    return 0;
+                  })
 ERROR_RETURN_CODE(GENERIC_ERROR,
                   int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, long *out), {
                     auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
@@ -773,9 +801,39 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     *out = tmp;
                     return 0;
                   })
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(datatype,
-//                    strcpy(out, wrapped_property->GetDatatype().c_str());)
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_datatype(caosdb_entity_property *property,
+                                                          char **name, bool *is_ref, bool *is_list),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    const auto &datatype = wrapped_property->GetDataType();
+                    *is_list = datatype.IsList();
+                    std::string datatype_name;
+                    if (*is_list) {
+                      const auto &list_datatype = datatype.AsList();
+                      *is_ref = list_datatype.IsListOfReference();
+                      if (*is_ref) {
+                        datatype_name = list_datatype.GetReferenceDataType().GetName();
+                      } else {
+                        datatype_name =
+                          ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType);
+                      }
+                    } else {
+                      *is_ref = datatype.IsReference();
+                      if (*is_ref) {
+                        datatype_name = datatype.AsReference().GetName();
+                      } else {
+                        datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType);
+                      }
+                    }
+                    char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
+                    strcpy(tmp, datatype_name.c_str());
+                    delete[] * name;
+                    *name = tmp;
+                    return 0;
+                  })
+
 CAOSDB_PROPERTY_GET(unit, GetUnit())
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
@@ -893,9 +951,29 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
 CAOSDB_ENTITY_SET(name, name, wrapped_entity->SetName(std::string(name));)
 CAOSDB_ENTITY_SET(description, description,
                   wrapped_entity->SetDescription(std::string(description));)
-// TODO(fspreck)
-// CAOSDB_ENTITY_SET(datatype, datatype,
-//                  wrapped_entity->SetDataType(std::string(datatype));)
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity,
+                                                        const char *datatype, const bool is_ref,
+                                                        const bool is_list),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    if (is_ref) {
+                      // Refernce datatype with name of reference
+                      wrapped_entity->SetDataType(std::string(datatype), is_list);
+                      return 0;
+                    } else {
+                      // Atomic datatype so get from enum
+                      try {
+                        auto enum_value =
+                          ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType);
+                        wrapped_entity->SetDataType(enum_value, is_list);
+                        return 0;
+                      } catch (const std::out_of_range &exc) {
+                        caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                        return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                      }
+                    }
+                  })
 CAOSDB_ENTITY_SET(unit, unit, wrapped_entity->SetUnit(std::string(unit));)
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
@@ -1042,9 +1120,31 @@ CAOSDB_PARENT_SET(name, name, wrapped_parent->SetName(std::string(name));)
 
 CAOSDB_PROPERTY_SET(name, name, wrapped_property->SetName(std::string(name));)
 CAOSDB_PROPERTY_SET(id, id, wrapped_property->SetId(std::string(id));)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_SET(datatype, datatype,
-//                    wrapped_property->SetDataType(std::string(datatype));)
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_datatype(caosdb_entity_property *property,
+                                                          const char *datatype, const bool is_ref,
+                                                          const bool is_list),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    if (is_ref) {
+                      // Refernce datatype with name of reference
+                      wrapped_property->SetDataType(std::string(datatype), is_list);
+                      return 0;
+                    } else {
+                      // Atomic datatype so get from enum
+                      try {
+                        auto enum_value =
+                          ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType);
+                        wrapped_property->SetDataType(enum_value, is_list);
+                        return 0;
+                      } catch (const std::out_of_range &exc) {
+                        caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                        return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                      }
+                    }
+                  })
+
 ERROR_RETURN_CODE(GENERIC_ERROR,
                   int caosdb_entity_property_set_importance(caosdb_entity_property *property,
                                                             const char *importance),
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index 64ac275402aec06e1ef5b80f9c3e1b93bac8e485..bffb63903cfc023b30186e13981d22f5e26c3703 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -168,10 +168,13 @@ TEST_F(test_ccaosdb, test_entity) {
   caosdb_entity_entity_get_description(&entity, &out);
   EXPECT_EQ(strcmp(out, "The length of an object"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_entity_set_datatype(&entity, "DOUBLE");
-  // caosdb_entity_entity_get_datatype(&entity, out);
-  // EXPECT_EQ(strcmp(out, "DOUBLE"), 0);
+  caosdb_entity_entity_set_datatype(&entity, "DOUBLE", false, false);
+  bool is_list[] = {false}; // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  caosdb_entity_entity_get_datatype(&entity, &out, is_ref, is_list);
+  EXPECT_EQ(strcmp(out, "DOUBLE"), 0);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
 
   caosdb_entity_entity_set_unit(&entity, "m");
   caosdb_entity_entity_get_unit(&entity, &out);
@@ -218,8 +221,8 @@ TEST_F(test_ccaosdb, test_property) {
 
   caosdb_entity_property_set_id(&property, "some_id");
   caosdb_entity_property_set_name(&property, "some_name");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_datatype(&property, "TEXT");
+
+  caosdb_entity_property_set_datatype(&property, "TEXT", false, false);
   caosdb_entity_property_set_importance(&property, "FIX");
   caosdb_entity_property_set_unit(&property, "some_unit");
   caosdb_entity_property_set_string_value(&property, "some_value");
@@ -231,9 +234,12 @@ TEST_F(test_ccaosdb, test_property) {
   caosdb_entity_property_get_name(&property, &out);
   EXPECT_EQ(strcmp(out, "some_name"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_datatype(&property, out);
-  // EXPECT_EQ(strcmp(out, "TEXT"), 0);
+  bool is_ref[] = {false};  // NOLINT
+  bool is_list[] = {false}; // NOLINT
+  caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list);
+  EXPECT_EQ(strcmp(out, "TEXT"), 0);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_FALSE(*is_list);
 
   caosdb_entity_property_get_importance(&property, &out);
   EXPECT_EQ(strcmp(out, "FIX"), 0);
@@ -254,26 +260,27 @@ TEST_F(test_ccaosdb, test_list_property) {
   int return_code(caosdb_entity_create_property(&property));
   EXPECT_EQ(return_code, 0);
 
-  // TODO(fspreck)
-  // return_code = caosdb_entity_property_set_datatype(&property, "LIST<TEXT>");
-  // EXPECT_EQ(return_code, 0);
+  return_code = caosdb_entity_property_set_datatype(&property, "TEXT", false, true);
+  EXPECT_EQ(return_code, 0);
 
   const char *value_list[] = {"val0", "val1", "val2"}; // NOLINT
   return_code = caosdb_entity_property_set_string_list_value(&property, value_list, 3);
   EXPECT_EQ(return_code, 0);
 
-  // TODO(fspreck)
-  // char out_type[255] = {"abc"}; // NOLINT
-  // return_code = caosdb_entity_property_get_datatype(&property, out_type);
-  // EXPECT_EQ(return_code, 0);
-  // EXPECT_EQ(strcmp(out_type, "LIST<TEXT>"));
+  char *out = nullptr;      // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  bool is_list[] = {false}; // NOLINT
+  return_code = caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_EQ(strcmp(out, "TEXT"), 0);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_TRUE(*is_list);
 
   int length[] = {0}; // NOLINT
   return_code = caosdb_entity_property_get_value_list_length(&property, length);
   EXPECT_EQ(return_code, 0);
   EXPECT_EQ(*length, 3);
 
-  char *out = nullptr; // NOLINT
   for (int i = 0; i < *length; i++) {
     return_code = caosdb_entity_property_get_string_list_value_at(&property, &out, i);
     EXPECT_EQ(return_code, 0);
@@ -299,8 +306,8 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) {
 
   caosdb_entity_property_set_id(&input_property, "property_id");
   caosdb_entity_property_set_name(&input_property, "property_name");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_datatype(&input_property, "TEXT");
+
+  caosdb_entity_property_set_datatype(&input_property, "TEXT", false, false);
   caosdb_entity_property_set_string_value(&input_property, "property_value");
 
   caosdb_entity_entity entity;
@@ -340,10 +347,15 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) {
   caosdb_entity_property_get_name(&output_property, &out);
   EXPECT_EQ(strcmp(in, out), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_datatype(&input_property, in);
-  // caosdb_entity_property_get_datatype(&output_property, out);
-  // EXPECT_EQ(strcmp(in, out), 0);
+  bool is_list[] = {false}; // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  caosdb_entity_property_get_datatype(&input_property, &in, is_ref, is_list);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
+  caosdb_entity_property_get_datatype(&output_property, &out, is_ref, is_list);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_EQ(strcmp(in, out), 0);
 
   caosdb_entity_property_get_string_value(&input_property, &in);
   caosdb_entity_property_get_string_value(&output_property, &out);