diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index c1397f41b5bd587ffab37f78fc55b96e8756f46b..4c0f81b0178a4f9b08943617dd03d77118b28945 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -418,11 +418,11 @@ int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **ou
 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_datatype_get_datatype_name(caosdb_entity_datatype *datatype, char **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);
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index 1e2b62fb233c2beeae7e19c4b903e35206032e54..c89e0a3922d868bf0c793adaeb2e646f4bc97dc1 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -1064,6 +1064,31 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     }
                     return 0;
                   })
+ERROR_RETURN_CODE(
+  GENERIC_ERROR,
+  int caosdb_entity_datatype_get_datatype_name(caosdb_entity_datatype *datatype, char **out), {
+    auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype);
+    std::string datatype_name;
+    if (wrapped_datatype->IsList()) {
+      const auto &list_datatype = wrapped_datatype->GetAsList();
+      if (list_datatype.IsListOfAtomic()) {
+        datatype_name = ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType);
+      } else {
+        datatype_name = list_datatype.GetReferenceDataType().GetName();
+      }
+    } else {
+      if (wrapped_datatype->IsAtomic()) {
+        datatype_name = ENUM_NAME_FROM_VALUE(wrapped_datatype->GetAsAtomic(), AtomicDataType);
+      } else {
+        datatype_name = wrapped_datatype->GetAsReference().GetName();
+      }
+    }
+    char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
+    strcpy(tmp, datatype_name.c_str());
+    delete[] *out;
+    *out = tmp;
+    return 0;
+  })
 
 VALUE_IS(null, IsNull)
 VALUE_IS(string, IsString)
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index cb84419bfcea7e864b635b868633c7f9529cc1c0..0a48c7b0c7fce20dc85c5666f84b56c922b4d364 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -202,6 +202,23 @@ TEST_F(test_ccaosdb, test_datatype) {
   EXPECT_EQ(return_code, 0);
   EXPECT_TRUE(is_a);
 
+  char *name = nullptr; // NOLINT
+  return_code = caosdb_entity_datatype_get_datatype_name(&atomic, &name);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_STREQ(name, "INTEGER");
+
+  return_code = caosdb_entity_datatype_get_datatype_name(&reference, &name);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_STREQ(name, "MyType");
+
+  return_code = caosdb_entity_datatype_get_datatype_name(&list_of_atomics, &name);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_STREQ(name, "DATETIME");
+
+  return_code = caosdb_entity_datatype_get_datatype_name(&list_of_references, &name);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_STREQ(name, "MyType");
+
   return_code = caosdb_entity_delete_datatype(&atomic);
   EXPECT_EQ(return_code, 0);
   return_code = caosdb_entity_delete_datatype(&reference);