diff --git a/common/cpp/include/asapo/common/common_c.h b/common/cpp/include/asapo/common/common_c.h
index d9920cbf602b41cfbf9ddb90967ef01a43fcc8f6..08cff2ad6c14c333959fc469e512871086e47a9e 100644
--- a/common/cpp/include/asapo/common/common_c.h
+++ b/common/cpp/include/asapo/common/common_c.h
@@ -41,7 +41,7 @@ void* asapo_new_handle();
 void asapo_error_explain(const AsapoErrorHandle error, char* buf, size_t max_size);
 AsapoBool asapo_is_error(AsapoErrorHandle err);
 
-AsapoStringHandle asapo_string_create(const char* str);
+AsapoStringHandle asapo_string_from_c_str(const char* str);
 const char* asapo_string_c_str(const AsapoStringHandle str);
 size_t asapo_string_size(const AsapoStringHandle str);
 
@@ -58,6 +58,11 @@ void asapo_stream_info_get_timestamp_created(const AsapoStreamInfoHandle info,
 void asapo_stream_info_get_timestamp_last_entry(const AsapoStreamInfoHandle info,
                                                 struct timespec* stamp);
 
+AsapoSourceCredentialsHandle asapo_create_source_credentials(enum AsapoSourceType type,
+        const char* beamtime,
+        const char* beamline,
+        const char* data_source,
+        const char* token);
 
 
 const char* asapo_message_data_get_as_chars(const AsapoMessageDataHandle data);
diff --git a/common/cpp/src/common/common_c_glue.cpp b/common/cpp/src/common/common_c_glue.cpp
index 4d942d70746a2c95b0f8e0fdaa58ebc3747b740e..d0d89d599d6605358d79ed28036b3c2cec9a895f 100644
--- a/common/cpp/src/common/common_c_glue.cpp
+++ b/common/cpp/src/common/common_c_glue.cpp
@@ -48,7 +48,7 @@ extern "C" {
                   "AsapoHandleSize is not correct");
 
 
-    AsapoStringHandle asapo_string_create(const char* str) {
+    AsapoStringHandle asapo_string_from_c_str(const char* str) {
         return AsapoStringHandle(new std::string(str));
     }
 
@@ -182,4 +182,8 @@ extern "C" {
     }
 
 
+    AsapoBool asapo_is_error(AsapoErrorHandle err) {
+        return err != nullptr && err->handle != nullptr;
+    }
+
 }
diff --git a/consumer/api/c/include/asapo/consumer_c.h b/consumer/api/c/include/asapo/consumer_c.h
index cf88fefe659384008b3e18fd23fa083572b61a3f..bc73c17e2ec3c7f8e9207e068c0549ca315dc5b2 100644
--- a/consumer/api/c/include/asapo/consumer_c.h
+++ b/consumer/api/c/include/asapo/consumer_c.h
@@ -164,12 +164,6 @@ void asapo_consumer_set_resend_nacs(AsapoConsumerHandle consumer,
                                     uint64_t resend_attempts);
 
 const char* asapo_message_data_get_as_chars(const AsapoMessageDataHandle data);
-AsapoSourceCredentialsHandle asapo_create_source_credentials(enum AsapoSourceType type,
-        const char* beamtime,
-        const char* beamline,
-        const char* data_source,
-        const char* token);
-
 const char* asapo_message_meta_get_name(const AsapoMessageMetaHandle md);
 void asapo_message_meta_get_timestamp(const AsapoMessageMetaHandle md,
                                       struct timespec* stamp);
diff --git a/consumer/api/cpp/src/consumer_c_glue.cpp b/consumer/api/cpp/src/consumer_c_glue.cpp
index 977d90baf1249d1faa0321ed1e81bffc32d3a012..969804d432dfcfc09a82ab6ddc0913a606ea3546 100644
--- a/consumer/api/cpp/src/consumer_c_glue.cpp
+++ b/consumer/api/cpp/src/consumer_c_glue.cpp
@@ -90,11 +90,6 @@ extern "C" {
                   kFabric == asapo::NetworkConnectionType::kFabric,
                   "incompatible bit reps between c++ and c for asapo::NetworkConnectionType");
 
-    AsapoBool asapo_is_error(AsapoErrorHandle err) {
-        return err != nullptr && err->handle != nullptr;
-    }
-
-
     enum AsapoConsumerErrorType asapo_error_get_type(const AsapoErrorHandle error) {
         auto consumer_err =
             dynamic_cast<const asapo::ServiceError<asapo::ConsumerErrorType,
diff --git a/examples/consumer/CMakeLists.txt b/examples/consumer/CMakeLists.txt
index 0cf72e439d5fd58b000b3fd78c1a9fe0d98c760d..3d5359f708d9f0ed2a0a64f8edd5c207be82b261 100644
--- a/examples/consumer/CMakeLists.txt
+++ b/examples/consumer/CMakeLists.txt
@@ -1,7 +1,6 @@
 find_package(Threads)
 
 add_subdirectory(getnext)
-add_subdirectory(simple-consumer-c)
 
 if(BUILD_EXAMPLES AND BUILD_PYTHON)
         add_subdirectory(getnext_python)
diff --git a/examples/consumer/simple-consumer-c/CMakeLists.txt b/examples/consumer/simple-consumer-c/CMakeLists.txt
deleted file mode 100644
index cdecb5b90dbe60461e808e940007a6ffea48ee26..0000000000000000000000000000000000000000
--- a/examples/consumer/simple-consumer-c/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-set(TARGET_NAME "asapo-consume-c")
-
-set(SOURCE_FILES consume.c)
-
-add_executable(${TARGET_NAME} ${SOURCE_FILES})
-target_link_libraries(${TARGET_NAME} asapo-consumer ${CMAKE_THREAD_LIBS_INIT})
diff --git a/examples/consumer/simple-consumer-c/consume.c b/examples/consumer/simple-consumer-c/consume.c
deleted file mode 100644
index f9d36a40aee80d56e1d99673d702129a6f548cde..0000000000000000000000000000000000000000
--- a/examples/consumer/simple-consumer-c/consume.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "asapo/consumer_c.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-void exit_if_error(const char *error_string, const AsapoErrorHandle err) {
-    if (err) {
-        char buf[1024];
-        asapo_error_explain(err, buf, sizeof(buf));
-        printf("%s %s\n", error_string, buf);
-        exit(EXIT_FAILURE);
-    }
-}
-
-int main() {
-    AsapoErrorHandle err = asapo_new_handle();
-    AsapoMessageMetaHandle mm = asapo_new_handle();
-    AsapoMessageDataHandle data = asapo_new_handle();
-
-    const char *endpoint = "localhost:8400";
-    const char *beamtime = "asapo_test";
-    const char *token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMWY2OG0ydWlkZDE3dWxmaDN1ZyIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJyZWFkIl19fQ.zo7ZDfY2sf4o9RYuXpxNR9kHLG594xr-SE5yLoyDC2Q";
-
-    const char * path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"; //set it according to your configuration.
-
-    AsapoSourceCredentialsHandle cred = asapo_create_source_credentials(kProcessed,
-                                                                        beamtime,
-                                                                        "", "", token);
-    AsapoConsumerHandle consumer = asapo_create_consumer(endpoint,
-                                                         path_to_files, 1,
-                                                         cred,
-                                                         &err);
-    asapo_free_handle(&cred);
-
-    exit_if_error("Cannot create consumer", err);
-    asapo_consumer_set_timeout(consumer, 1000ull);
-
-    AsapoStringHandle group_id = asapo_consumer_generate_new_group_id(consumer, &err);
-    exit_if_error("Cannot create group id", err);
-
-    asapo_consumer_get_next(consumer, group_id, &mm, &data, "default",&err);
-    exit_if_error("Cannot get next record", err);
-
-
-    printf("id: %lu\n", asapo_message_meta_get_id(mm));
-    printf("file name: %s\n", asapo_message_meta_get_name(mm));
-    printf("file content: %s\n", asapo_message_data_get_as_chars(data));
-
-    asapo_free_handle(&mm);
-    asapo_free_handle(&data);
-    asapo_free_handle(&consumer);
-    asapo_free_handle(&group_id);
-
-    return EXIT_SUCCESS;
-}
diff --git a/producer/api/c/include/asapo/producer_c.h b/producer/api/c/include/asapo/producer_c.h
index f29bc92b564f5a5960e5d3d36ad1829b813b4613..d96f278aa3de7e3796d1f530e38ab2aff0aab5af 100644
--- a/producer/api/c/include/asapo/producer_c.h
+++ b/producer/api/c/include/asapo/producer_c.h
@@ -15,9 +15,9 @@ typedef struct {
 #endif
 
 typedef void(*AsapoRequestCallback)(AsapoRequestCallbackPayloadHandle, AsapoErrorHandle);
-const size_t kMaxMessageSize = 1024;
-const size_t kMaxVersionSize = 10;
-const size_t kNCustomParams = 3;
+#define kMaxMessageSize 1024
+#define kMaxVersionSize 10
+#define kNCustomParams 3
 
 //! c version opf asapo::Opcode
 enum AsapoOpcode {
@@ -37,7 +37,7 @@ enum AsapoOpcode {
 
 //! c version of asapo::GenericRequestHeader
 struct AsapoGenericRequestHeader {
-    AsapoOpcode op_code;
+    enum AsapoOpcode op_code;
     uint64_t    data_id;
     uint64_t    data_size;
     uint64_t    meta_size;
@@ -73,7 +73,7 @@ enum AsapoLogLevel {
 
 AsapoProducerHandle asapo_create_producer(const char* endpoint,
                                           uint8_t n_processing_threads,
-                                          AsapoRequestHandlerType type,
+                                          enum AsapoRequestHandlerType type,
                                           AsapoSourceCredentialsHandle source_cred,
                                           uint64_t timeout_ms,
                                           AsapoErrorHandle* error);
@@ -125,13 +125,13 @@ int asapo_producer_send_stream_finished_flag(AsapoProducerHandle producer,
                                              AsapoErrorHandle* error);
 int asapo_producer_send_beamtime_metadata(AsapoProducerHandle producer,
                                           const char* metadata,
-                                          AsapoMetaIngestOp mode,
+                                          enum AsapoMetaIngestOp mode,
                                           AsapoBool upsert,
                                           AsapoRequestCallback callback,
                                           AsapoErrorHandle* error);
 int asapo_producer_send_stream_metadata(AsapoProducerHandle producer,
                                         const char* metadata,
-                                        AsapoMetaIngestOp mode,
+                                        enum AsapoMetaIngestOp mode,
                                         AsapoBool upsert,
                                         const char* stream,
                                         AsapoRequestCallback callback,
@@ -139,10 +139,10 @@ int asapo_producer_send_stream_metadata(AsapoProducerHandle producer,
 
 AsapoMessageDataHandle asapo_request_callback_payload_get_data(AsapoRequestCallbackPayloadHandle handle);
 AsapoStringHandle asapo_request_callback_payload_get_response(AsapoRequestCallbackPayloadHandle handle);
-const AsapoGenericRequestHeader* asapo_request_callback_payload_get_original_header(
+const struct AsapoGenericRequestHeader* asapo_request_callback_payload_get_original_header(
     AsapoRequestCallbackPayloadHandle handle);
 
-void asapo_producer_set_log_level(AsapoProducerHandle producer, AsapoLogLevel level);
+void asapo_producer_set_log_level(AsapoProducerHandle producer, enum AsapoLogLevel level);
 void asapo_producer_enable_local_log(AsapoProducerHandle producer, AsapoBool enable);
 void asapo_producer_enable_remote_log(AsapoProducerHandle producer, AsapoBool enable);
 int asapo_producer_set_credentials(AsapoProducerHandle producer, AsapoSourceCredentialsHandle source_cred,
diff --git a/producer/api/cpp/CMakeLists.txt b/producer/api/cpp/CMakeLists.txt
index 75c8f7d162ba8dfda1a4e1a55a76fc961ea457fd..7701657c2785e9a31bc8ec7b07512027adaf2ac5 100644
--- a/producer/api/cpp/CMakeLists.txt
+++ b/producer/api/cpp/CMakeLists.txt
@@ -25,6 +25,7 @@ if (BUILD_STATIC_CLIENT_LIBS)
     add_library(${TARGET_NAME} STATIC $<TARGET_OBJECTS:producer_lib_objects> $<TARGET_OBJECTS:system_io> $<TARGET_OBJECTS:logger> $<TARGET_OBJECTS:json_parser>
             $<TARGET_OBJECTS:curl_http_client> $<TARGET_OBJECTS:request_pool> $<TARGET_OBJECTS:data_structs> $<TARGET_OBJECTS:version> $<TARGET_OBJECTS:common>)
     target_include_directories(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+    target_include_directories(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../c/include>)
     target_include_directories(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${ASAPO_CXX_COMMON_INCLUDE_DIR}>)
     target_include_directories(${TARGET_NAME} INTERFACE $<INSTALL_INTERFACE:include>)
     target_link_libraries(${TARGET_NAME} CURL::libcurl ${CMAKE_THREAD_LIBS_INIT})
diff --git a/tests/automatic/common/cpp/include/testing_c.h b/tests/automatic/common/cpp/include/testing_c.h
new file mode 100644
index 0000000000000000000000000000000000000000..0075cd45cfa79b78287a89773c49f615cdb1175e
--- /dev/null
+++ b/tests/automatic/common/cpp/include/testing_c.h
@@ -0,0 +1,50 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifndef ASAPO_TESTS_AUTOMATIC_COMMON_CPP_INCLUDE_TESTING_C_H_
+#define ASAPO_TESTS_AUTOMATIC_COMMON_CPP_INCLUDE_TESTING_C_H_
+
+#define EXIT_IF_ERROR(...) exit_if_error_(__VA_ARGS__,__LINE__)
+#define ASSERT_EQ_INT(...) assert_eq_int_(__VA_ARGS__,__LINE__)
+#define ASSERT_EQ_STRING(...) assert_eq_string_(__VA_ARGS__,__LINE__)
+#define ASSERT_TRUE(...) assert_true_(__VA_ARGS__,__LINE__)
+
+void assert_eq_int_(uint64_t expected, uint64_t got, const char* message, int line) {
+    printf("asserting %s at %d\n", message, line);
+    if (expected != got) {
+        printf("%s: expected %llu got %llu at %d\n", message, (unsigned long long)expected, (unsigned long long)got, line);
+        exit(EXIT_FAILURE);
+    }
+}
+
+void assert_eq_string_(const char* expected, const char* got, const char* message, int line) {
+    printf("asserting %s at %d\n", message, line);
+    if (strcmp(expected, got) != 0) {
+        printf("%s: expected %s got %s at %d\n", message, expected, got, line);
+        exit(EXIT_FAILURE);
+    }
+}
+
+void assert_true_(int value, const char* message, int line) {
+    printf("asserting %s at %d\n", message, line);
+    if (value != 1) {
+        printf("%s failed at %d\n", message, line);
+        exit(EXIT_FAILURE);
+    }
+}
+
+void exit_if_error_(const char* error_string, const AsapoErrorHandle err, int line) {
+    printf("asserting no error for %s at %d\n", error_string, line);
+    if (asapo_is_error(err)) {
+        char buf[1024];
+        asapo_error_explain(err, buf, sizeof(buf));
+        printf("%s %s\n", error_string, buf);
+        exit(EXIT_FAILURE);
+    }
+}
+
+
+
+#endif //ASAPO_TESTS_AUTOMATIC_COMMON_CPP_INCLUDE_TESTING_C_H_
diff --git a/tests/automatic/consumer/consumer_api/consumer_api.c b/tests/automatic/consumer/consumer_api/consumer_api.c
index ed81afab911933054f4c398fd3ddf156540e3ab3..24ac19d554f3cce0894bf2658a3ff70f8b72896c 100644
--- a/tests/automatic/consumer/consumer_api/consumer_api.c
+++ b/tests/automatic/consumer/consumer_api/consumer_api.c
@@ -1,49 +1,10 @@
 #include "asapo/consumer_c.h"
+#include "testing_c.h"
 
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 
-#define EXIT_IF_ERROR(...) exit_if_error_(__VA_ARGS__,__LINE__)
-#define ASSERT_EQ_INT(...) assert_eq_int_(__VA_ARGS__,__LINE__)
-#define ASSERT_EQ_STRING(...) assert_eq_string_(__VA_ARGS__,__LINE__)
-#define ASSERT_TRUE(...) assert_true_(__VA_ARGS__,__LINE__)
-
-void assert_eq_int_(uint64_t expected, uint64_t got, const char *message, int line) {
-    printf("asserting %s at %d\n",message,line);
-    if (expected!=got) {
-        printf("%s: expected %llu got %llu at %d\n",message, (unsigned long long)expected, (unsigned long long)got,line);
-        exit(EXIT_FAILURE);
-    }
-}
-
-void assert_eq_string_(const char * expected, const char *got, const char *message, int line) {
-    printf("asserting %s at %d\n",message,line);
-    if (strcmp(expected,got)!=0) {
-        printf("%s: expected %s got %s at %d\n",message, expected, got,line);
-        exit(EXIT_FAILURE);
-    }
-}
-
-void assert_true_(int value, const char *message, int line) {
-    printf("asserting %s at %d\n",message,line);
-    if (value!=1) {
-        printf("%s failed at %d\n",message, line);
-        exit(EXIT_FAILURE);
-    }
-}
-
-void exit_if_error_(const char *error_string, const AsapoErrorHandle err, int line) {
-    printf("asserting no error for %s at %d\n",error_string,line);
-    if (asapo_is_error(err)) {
-        char buf[1024];
-        asapo_error_explain(err, buf, sizeof(buf));
-        printf("%s %s\n", error_string, buf);
-        exit(EXIT_FAILURE);
-    }
-}
-
-
 void test_datasets(AsapoConsumerHandle consumer, AsapoStringHandle group_id) {
     AsapoErrorHandle err = asapo_new_handle();
 
@@ -51,8 +12,8 @@ void test_datasets(AsapoConsumerHandle consumer, AsapoStringHandle group_id) {
     AsapoDataSetHandle dataset = asapo_consumer_get_next_dataset(consumer,group_id, 0, "default", &err);
     EXIT_IF_ERROR("asapo_consumer_get_next_dataset", err);
     ASSERT_EQ_INT(3,asapo_dataset_get_size(dataset),"asapo_dataset_get_size");
-    AsapoMessageDataHandle md0 = asapo_dataset_get_item(dataset,0);
-    AsapoMessageDataHandle md2 = asapo_dataset_get_item(dataset,2);
+    AsapoMessageMetaHandle md0 = asapo_dataset_get_item(dataset,0);
+    AsapoMessageMetaHandle md2 = asapo_dataset_get_item(dataset,2);
     ASSERT_EQ_STRING("1_1",asapo_message_meta_get_name(md0),"dataset 0 filename");
     ASSERT_EQ_STRING("1_3",asapo_message_meta_get_name(md2),"dataset 2 filename");
     ASSERT_EQ_STRING("{\"test\":10}",asapo_message_meta_get_metadata(md0),"dataset 0 meta");
@@ -63,7 +24,7 @@ void test_datasets(AsapoConsumerHandle consumer, AsapoStringHandle group_id) {
 // get last
     dataset = asapo_consumer_get_last_dataset(consumer, 0, "default", &err);
     EXIT_IF_ERROR("asapo_consumer_get_last_dataset", err);
-    AsapoMessageDataHandle md = asapo_dataset_get_item(dataset,0);
+    AsapoMessageMetaHandle md = asapo_dataset_get_item(dataset,0);
     ASSERT_EQ_STRING("10_1",asapo_message_meta_get_name(md),"dataset 10 filename");
     asapo_free_handle(&md);
     asapo_free_handle(&dataset);
diff --git a/tests/automatic/producer/CMakeLists.txt b/tests/automatic/producer/CMakeLists.txt
index 38bd45932b4a517d8ef088d9662a4452d3dc1cd1..a2e60a0e8d3f3fb7892ad5ad17972fa8ccffa170 100644
--- a/tests/automatic/producer/CMakeLists.txt
+++ b/tests/automatic/producer/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(file_monitor_producer)
 add_subdirectory(beamtime_metadata)
 
 add_subdirectory(cpp_api)
+add_subdirectory(c_api)
 
 if (BUILD_PYTHON)
     add_subdirectory(python_api)
diff --git a/tests/automatic/producer/c_api/CMakeLists.txt b/tests/automatic/producer/c_api/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d112715d80b40c21257927e01d3088cbd051c5f0
--- /dev/null
+++ b/tests/automatic/producer/c_api/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(TARGET_NAME producer_api_c)
+set(SOURCE_FILES producer_api.c)
+
+
+################################
+# Executable and link
+################################
+add_executable(${TARGET_NAME} ${SOURCE_FILES})
+target_link_libraries(${TARGET_NAME} test_common asapo-producer)
+
+################################
+# Testing
+################################
+add_script_test("${TARGET_NAME}" "$<TARGET_FILE:${TARGET_NAME}>")
+
diff --git a/tests/automatic/producer/c_api/check_linux.sh b/tests/automatic/producer/c_api/check_linux.sh
new file mode 100644
index 0000000000000000000000000000000000000000..895a669225ee55fe02773d800a6d76fe6821d21f
--- /dev/null
+++ b/tests/automatic/producer/c_api/check_linux.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -e
+
+trap Cleanup EXIT
+
+beamtime_id=asapo_test
+data_source=c
+beamline=test
+receiver_root_folder=/tmp/asapo/receiver/files
+facility=test_facility
+year=2019
+receiver_folder=${receiver_root_folder}/${facility}/gpfs/${beamline}/${year}/data/${beamtime_id}
+
+
+Cleanup() {
+	echo cleanup
+	rm -rf ${receiver_root_folder}
+  echo "db.dropDatabase()" | mongo ${beamtime_id}_${data_source}
+}
+
+mkdir -p ${receiver_folder}
+
+echo test > file1
+
+$@ "127.0.0.1:8400" $data_source $beamtime_id
diff --git a/tests/automatic/producer/c_api/check_windows.bat b/tests/automatic/producer/c_api/check_windows.bat
new file mode 100644
index 0000000000000000000000000000000000000000..0fdbabcbed5fdd6d82a1e429fbb7174ec9cc2228
--- /dev/null
+++ b/tests/automatic/producer/c_api/check_windows.bat
@@ -0,0 +1,28 @@
+SET mongo_exe="c:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"
+SET beamtime_id=asapo_test
+SET beamline=test
+SET data_source=c
+SET receiver_root_folder=c:\tmp\asapo\receiver\files
+SET receiver_folder="%receiver_root_folder%\test_facility\gpfs\%beamline%\2019\data\%beamtime_id%"
+SET dbname=%beamtime_id%_%data_source%
+
+mkdir %receiver_folder%
+
+echo test > file1
+
+ping 192.0.2.1 -n 1 -w 1000 > nul
+
+"%1" "127.0.0.1:8400" %data_source% %beamtime_id%   > out
+type out
+
+goto :clean
+
+:error
+call :clean
+exit /b 1
+
+:clean
+rmdir /S /Q %receiver_root_folder%
+echo db.dropDatabase() | %mongo_exe% %dbname%
+
+
diff --git a/tests/automatic/producer/c_api/producer_api.c b/tests/automatic/producer/c_api/producer_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c60a637ccc635dab948a4d07a25adf1f06001b3
--- /dev/null
+++ b/tests/automatic/producer/c_api/producer_api.c
@@ -0,0 +1,94 @@
+#include "asapo/producer_c.h"
+#include "testing_c.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+void TestMeta(const std::unique_ptr<asapo::Producer>& producer) {
+    asapo::Error err;
+    std::string meta = R"({"data":"test","embedded":{"edata":2}})";
+    producer->SendBeamtimeMetadata(meta, asapo::MetaIngestMode{asapo::MetaIngestOp::kInsert, true}, nullptr);
+    producer->WaitRequestsFinished(5000);
+    auto meta_received = producer->GetBeamtimeMeta(5000, &err);
+    M_AssertTrue(meta_received == meta);
+    std::string meta_update = R"({"embedded":{"edata":3}})";
+    std::string meta_updated = R"({"data":"test","embedded":{"edata":3}})";
+    producer->SendBeamtimeMetadata(meta_update, asapo::MetaIngestMode{asapo::MetaIngestOp::kUpdate, false}, nullptr);
+    producer->WaitRequestsFinished(5000);
+    meta_received = producer->GetBeamtimeMeta(5000, &err);
+    M_AssertTrue(meta_received == meta_updated);
+}
+
+
+void Test(const std::unique_ptr<asapo::Producer>& producer) {
+    asapo::MessageMeta fi;
+    asapo::Error err;
+
+    std::string client, server;
+    bool supported;
+    err = producer->GetVersionInfo(&client, &server, &supported);
+    M_AssertTrue(err == nullptr, "Version OK");
+    M_AssertTrue(supported, "client supported by server");
+    M_AssertTrue(!client.empty(), "client version");
+    M_AssertTrue(!server.empty(), "server version");
+
+
+    TestMeta(producer);
+
+    producer->GetStreamInfo("default", 5000, &err);
+    if (err) {
+        printf("%s\n", err->Explain().c_str());
+    }
+    M_AssertTrue(err == nullptr, "stream info");
+
+}
+
+
+std::unique_ptr<asapo::Producer> CreateProducer(const Args& args) {
+    asapo::Error err;
+    auto producer = asapo::Producer::Create(args.server, 2,
+                                            asapo::RequestHandlerType::kTcp,
+                                            asapo::SourceCredentials{asapo::SourceType::kProcessed, args.beamtime,
+                                                    "", args.source, ""}, 60000, &err);
+    if (err) {
+        std::cerr << "Cannot start producer. ProducerError: " << err << std::endl;
+        exit(EXIT_FAILURE);
+    }
+
+    producer->EnableLocalLog(true);
+    producer->SetLogLevel(asapo::LogLevel::Debug);
+    return producer;
+}
+
+ */
+
+int main(int argc, char* argv[]) {
+    if (argc <4) {
+        abort();
+    }
+    const char *endpoint = argv[1];
+    const char *source = argv[2];
+    const char *beamtime = argv[3];
+
+
+    AsapoErrorHandle err = asapo_new_handle();
+    AsapoSourceCredentialsHandle cred = asapo_create_source_credentials(kProcessed,
+                                                                        beamtime,
+                                                                        "", source, "");
+
+    AsapoProducerHandle producer = asapo_create_producer(endpoint,2,kTcp, cred,60000,&err);
+
+    asapo_producer_enable_local_log(producer, 1);
+    asapo_producer_set_log_level(producer, Debug);
+
+
+    EXIT_IF_ERROR("create producer", err);
+
+    asapo_free_handle(&err);
+    asapo_free_handle(&cred);
+    asapo_free_handle(&producer);
+    return 0;
+}