diff --git a/plugins/channeltx/filesource/filesource.cpp b/plugins/channeltx/filesource/filesource.cpp
index ef0d55c91..693e724a2 100644
--- a/plugins/channeltx/filesource/filesource.cpp
+++ b/plugins/channeltx/filesource/filesource.cpp
@@ -379,6 +379,7 @@ int FileSource::webapiReportGet(
 }
 
 int FileSource::webapiActionsPost(
+        const QStringList& channelActionsKeys,
         SWGSDRangel::SWGChannelActions& query,
         QString& errorMessage)
 {
@@ -386,14 +387,24 @@ int FileSource::webapiActionsPost(
 
     if (swgFileSourceActions)
     {
-        bool play = swgFileSourceActions->getPlay() != 0;
-        FileSourceBaseband::MsgConfigureFileSourceWork *msg = FileSourceBaseband::MsgConfigureFileSourceWork::create(play);
-        m_basebandSource->getInputMessageQueue()->push(msg);
+        if (channelActionsKeys.contains("play"))
+        {
+            bool play = swgFileSourceActions->getPlay() != 0;
+            FileSourceBaseband::MsgConfigureFileSourceWork *msg = FileSourceBaseband::MsgConfigureFileSourceWork::create(play);
+            m_basebandSource->getInputMessageQueue()->push(msg);
+
+            if (getMessageQueueToGUI())
+            {
+                MsgConfigureFileSourceWork *msgToGUI = MsgConfigureFileSourceWork::create(play);
+                getMessageQueueToGUI()->push(msgToGUI);
+            }
+        }
+
         return 202;
     }
     else
     {
-        errorMessage = "Missing FileSourceActions key in JSON body";
+        errorMessage = "Missing FileSourceActions in query";
         return 400;
     }
 }
diff --git a/plugins/channeltx/filesource/filesource.h b/plugins/channeltx/filesource/filesource.h
index b91eb7f55..09804499f 100644
--- a/plugins/channeltx/filesource/filesource.h
+++ b/plugins/channeltx/filesource/filesource.h
@@ -206,6 +206,7 @@ public:
             QString& errorMessage);
 
     virtual int webapiActionsPost(
+            const QStringList& channelActionsKeys,
             SWGSDRangel::SWGChannelActions& query,
             QString& errorMessage);
 
diff --git a/plugins/channeltx/filesource/filesourcegui.cpp b/plugins/channeltx/filesource/filesourcegui.cpp
index 073c82803..8f866d0fc 100644
--- a/plugins/channeltx/filesource/filesourcegui.cpp
+++ b/plugins/channeltx/filesource/filesourcegui.cpp
@@ -96,7 +96,7 @@ bool FileSourceGUI::handleMessage(const Message& message)
         displayRateAndShift();
         return true;
     }
-    else if (FileSource::MsgConfigureFileSource::match(message))
+    else if (FileSource::MsgConfigureFileSource::match(message)) // API settings feedback
     {
         const FileSource::MsgConfigureFileSource& cfg = (FileSource::MsgConfigureFileSource&) message;
         m_settings = cfg.getSettings();
@@ -149,6 +149,20 @@ bool FileSourceGUI::handleMessage(const Message& message)
 
 		return true;
 	}
+    else if (FileSource::MsgConfigureFileSourceWork::match(message)) // API action "play" feedback
+    {
+        const FileSource::MsgConfigureFileSourceWork& notif = (const FileSource::MsgConfigureFileSourceWork&) message;
+        bool play = notif.isWorking();
+        ui->play->blockSignals(true);
+        ui->navTime->blockSignals(true);
+        ui->play->setChecked(play);
+        ui->navTime->setEnabled(!play);
+        m_enableNavTime = !play;
+        ui->play->blockSignals(false);
+        ui->navTime->blockSignals(false);
+
+        return true;
+    }
     else
     {
         return false;
diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
index 1d8cc286f..842f061cf 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
+++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
@@ -165,6 +165,23 @@ bool RTLSDRGui::handleMessage(const Message& message)
 
         return true;
     }
+    else if (RTLSDRInput::MsgFileRecord::match(message)) // API action "record" feedback
+    {
+        const RTLSDRInput::MsgFileRecord& notif = (const RTLSDRInput::MsgFileRecord&) message;
+        bool record = notif.getStartStop();
+
+        ui->record->blockSignals(true);
+        ui->record->setChecked(record);
+
+        if (record) {
+            ui->record->setStyleSheet("QToolButton { background-color : red; }");
+        } else {
+            ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
+        }
+
+        ui->record->blockSignals(false);
+        return true;
+    }
 	else
 	{
 		return false;
diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
index 7a1f485ba..71552fc94 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
+++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
@@ -757,6 +757,7 @@ int RTLSDRInput::webapiReportGet(
 }
 
 int RTLSDRInput::webapiActionsPost(
+        const QStringList& deviceActionsKeys,
         SWGSDRangel::SWGDeviceActions& query,
         QString& errorMessage)
 {
@@ -764,14 +765,24 @@ int RTLSDRInput::webapiActionsPost(
 
     if (swgRtlSdrActions)
     {
-        bool record = swgRtlSdrActions->getRecord() != 0;
-        MsgFileRecord *msg = MsgFileRecord::create(record);
-        getInputMessageQueue()->push(msg);
+        if (deviceActionsKeys.contains("record"))
+        {
+            bool record = swgRtlSdrActions->getRecord() != 0;
+            MsgFileRecord *msg = MsgFileRecord::create(record);
+            getInputMessageQueue()->push(msg);
+
+            if (getMessageQueueToGUI())
+            {
+                MsgFileRecord *msgToGUI = MsgFileRecord::create(record);
+                getMessageQueueToGUI()->push(msgToGUI);
+            }
+        }
+
         return 202;
     }
     else
     {
-        errorMessage = "Missing RtlSdrActions key in JSON body";
+        errorMessage = "Missing RtlSdrActions in query";
         return 400;
     }
 }
diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.h b/plugins/samplesource/rtlsdr/rtlsdrinput.h
index c3135c9cc..7beb9da88 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrinput.h
+++ b/plugins/samplesource/rtlsdr/rtlsdrinput.h
@@ -132,6 +132,7 @@ public:
             QString& errorMessage);
 
     virtual int webapiActionsPost(
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& actions,
             QString& errorMessage);
 
diff --git a/sdrbase/channel/channelapi.h b/sdrbase/channel/channelapi.h
index e2e995a38..c47b98228 100644
--- a/sdrbase/channel/channelapi.h
+++ b/sdrbase/channel/channelapi.h
@@ -98,10 +98,12 @@ public:
      * API adapter for the channel actions POST requests
      */
     virtual int webapiActionsPost(
+            const QStringList& channelActionsKeys,
             SWGSDRangel::SWGChannelActions& query,
             QString& errorMessage)
     {
         (void) query;
+        (void) channelActionsKeys;
         errorMessage = "Not implemented"; return 501;
     }
 
diff --git a/sdrbase/dsp/devicesamplemimo.h b/sdrbase/dsp/devicesamplemimo.h
index 087494e89..260d93f63 100644
--- a/sdrbase/dsp/devicesamplemimo.h
+++ b/sdrbase/dsp/devicesamplemimo.h
@@ -137,9 +137,11 @@ public:
     }
 
     virtual int webapiActionsPost(
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& actions,
             QString& errorMessage)
     {
+        (void) deviceActionsKeys;
         (void) actions;
         errorMessage = "Not implemented";
         return 501;
diff --git a/sdrbase/dsp/devicesamplesink.h b/sdrbase/dsp/devicesamplesink.h
index 7b09a51d6..3af929ff1 100644
--- a/sdrbase/dsp/devicesamplesink.h
+++ b/sdrbase/dsp/devicesamplesink.h
@@ -113,9 +113,11 @@ public:
     }
 
     virtual int webapiActionsPost(
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& actions,
             QString& errorMessage)
     {
+        (void) deviceActionsKeys;
         (void) actions;
         errorMessage = "Not implemented";
         return 501;
diff --git a/sdrbase/dsp/devicesamplesource.h b/sdrbase/dsp/devicesamplesource.h
index dfcc00bf0..1ec089687 100644
--- a/sdrbase/dsp/devicesamplesource.h
+++ b/sdrbase/dsp/devicesamplesource.h
@@ -119,9 +119,11 @@ public:
     }
 
     virtual int webapiActionsPost(
+            const QStringList& deviceSettingsKeys,
             SWGSDRangel::SWGDeviceActions& actions,
             QString& errorMessage)
     {
+        (void) deviceSettingsKeys;
         (void) actions;
         errorMessage = "Not implemented";
         return 501;
diff --git a/sdrbase/resources/webapi.qrc b/sdrbase/resources/webapi.qrc
index 399ff0a6d..ea0058c8e 100644
--- a/sdrbase/resources/webapi.qrc
+++ b/sdrbase/resources/webapi.qrc
@@ -18,6 +18,7 @@
         webapi/doc/swagger/include/CWKeyer.yaml
         webapi/doc/swagger/include/DATVDemod.yaml
         webapi/doc/swagger/include/DSDDemod.yaml
+        webapi/doc/swagger/include/DeviceActions.yaml
         webapi/doc/swagger/include/DeviceSettings.yaml
         webapi/doc/swagger/include/FCDPro.yaml
         webapi/doc/swagger/include/FCDProPlus.yaml
diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h
index eacb89fce..c5f409e84 100644
--- a/sdrbase/webapi/webapiadapterinterface.h
+++ b/sdrbase/webapi/webapiadapterinterface.h
@@ -884,12 +884,14 @@ public:
      */
     virtual int devicesetDeviceActionsPost(
             int deviceSetIndex,
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error
     )
     {
         (void) deviceSetIndex;
+        (void) deviceActionsKeys;
         (void) query;
         (void) response;
         error.init();
@@ -1000,12 +1002,14 @@ public:
     virtual int devicesetChannelActionsPost(
             int deviceSetIndex,
             int channelIndex,
+            const QStringList& channelActionsKeys,
             SWGSDRangel::SWGChannelActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error)
     {
         (void) deviceSetIndex;
         (void) channelIndex;
+        (void) channelActionsKeys;
         (void) query;
         (void) response;
         error.init();
diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp
index ff7a0b973..28c16d2ae 100644
--- a/sdrbase/webapi/webapirequestmapper.cpp
+++ b/sdrbase/webapi/webapirequestmapper.cpp
@@ -153,6 +153,10 @@ const QMap WebAPIRequestMapper::m_channelTypeToSettingsKey = {
     {"WFMMod", "WFMModSettings"}
 };
 
+const QMap WebAPIRequestMapper::m_channelTypeToActionsKey = {
+    {"FileSource", "FileSourceActions"}
+};
+
 const QMap WebAPIRequestMapper::m_sourceDeviceHwIdToSettingsKey = {
     {"Airspy", "airspySettings"},
     {"AirspyHF", "airspyHFSettings"},
@@ -175,6 +179,10 @@ const QMap WebAPIRequestMapper::m_sourceDeviceHwIdToSettingsKe
     {"XTRX", "XtrxInputSettings"}
 };
 
+const QMap WebAPIRequestMapper::m_sourceDeviceHwIdToActionsKey = {
+    {"RTLSDR", "rtlSdrActions"}
+};
+
 const QMap WebAPIRequestMapper::m_sinkDeviceHwIdToSettingsKey = {
     {"BladeRF1", "bladeRF1OutputSettings"},
     {"BladeRF2", "bladeRF2OutputSettings"},
@@ -184,7 +192,23 @@ const QMap WebAPIRequestMapper::m_sinkDeviceHwIdToSettingsKey
     {"PlutoSDR", "plutoSdrOutputSettings"},
     {"RemoteOutput", "remoteOutputSettings"},
     {"SoapySDR", "soapySDROutputSettings"},
+<<<<<<< ours
     {"XTRX", "XtrxOutputSettings"}
+=======
+    {"XTRX", "xtrxOutputSettings"}
+};
+
+const QMap WebAPIRequestMapper::m_sinkDeviceHwIdToActionsKey = {
+};
+
+const QMap WebAPIRequestMapper::m_mimoDeviceHwIdToSettingsKey= {
+    {"BladeRF2", "bladeRF2MIMOSettings"},
+    {"TestMI", "testMISettings"},
+    {"TestMOSync", "testMOSyncSettings"}
+>>>>>>> theirs
+};
+
+const QMap WebAPIRequestMapper::m_mimoDeviceHwIdToActionsKey= {
 };
 
 WebAPIRequestMapper::WebAPIRequestMapper(QObject* parent) :
@@ -311,6 +335,8 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http
                 devicesetChannelSettingsService(std::string(desc_match[1]), std::string(desc_match[2]), request, response);
             } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelReportURLRe)) {
                 devicesetChannelReportService(std::string(desc_match[1]), std::string(desc_match[2]), request, response);
+            } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelActionsURLRe)) {
+                devicesetChannelActionsService(std::string(desc_match[1]), std::string(desc_match[2]), request, response);
             }
             else // serve static documentation pages
             {
@@ -1922,9 +1948,11 @@ void WebAPIRequestMapper::devicesetDeviceActionsService(const std::string& index
     response.setHeader("Content-Type", "application/json");
     response.setHeader("Access-Control-Allow-Origin", "*");
 
-    if (request.getMethod() == "POST")
+    try
     {
-        try
+        int deviceSetIndex = boost::lexical_cast(indexStr);
+
+        if (request.getMethod() == "POST")
         {
             QString jsonStr = request.getBody();
             QJsonObject jsonObject;
@@ -1933,19 +1961,17 @@ void WebAPIRequestMapper::devicesetDeviceActionsService(const std::string& index
             {
                 SWGSDRangel::SWGDeviceActions query;
                 SWGSDRangel::SWGSuccessResponse normalResponse;
-                int deviceSetIndex = boost::lexical_cast(indexStr);
                 resetDeviceActions(query);
+                QStringList deviceActionsKeys;
 
-                if (jsonObject.contains("direction")) {
-                    query.setDirection(jsonObject["direction"].toInt());
-                } else {
-                    query.setDirection(0); // assume Rx
-                }
-
-                if (jsonObject.contains("deviceHwType") && jsonObject["deviceHwType"].isString())
+                if (validateDeviceActions(query, jsonObject, deviceActionsKeys))
                 {
-                    query.setDeviceHwType(new QString(jsonObject["deviceHwType"].toString()));
-                    int status = m_adapter->devicesetDeviceActionsPost(deviceSetIndex, query, normalResponse, errorResponse);
+                    int status = m_adapter->devicesetDeviceActionsPost(
+                        deviceSetIndex,
+                        deviceActionsKeys,
+                        query,
+                        normalResponse,
+                        errorResponse);
                     response.setStatus(status);
 
                     if (status/100 == 2) {
@@ -1970,19 +1996,19 @@ void WebAPIRequestMapper::devicesetDeviceActionsService(const std::string& index
                 response.write(errorResponse.asJson().toUtf8());
             }
         }
-        catch (const boost::bad_lexical_cast &e)
+        else
         {
+            response.setStatus(405,"Invalid HTTP method");
             errorResponse.init();
-            *errorResponse.getMessage() = "Wrong integer conversion on device set index";
-            response.setStatus(400,"Invalid data");
+            *errorResponse.getMessage() = "Invalid HTTP method";
             response.write(errorResponse.asJson().toUtf8());
         }
     }
-    else
+    catch(const boost::bad_lexical_cast &e)
     {
-        response.setStatus(405,"Invalid HTTP method");
         errorResponse.init();
-        *errorResponse.getMessage() = "Invalid HTTP method";
+        *errorResponse.getMessage() = "Wrong integer conversion on device set index";
+        response.setStatus(400,"Invalid data");
         response.write(errorResponse.asJson().toUtf8());
     }
 }
@@ -2281,7 +2307,7 @@ void WebAPIRequestMapper::devicesetChannelReportService(
     }
 }
 
-void WebAPIRequestMapper::devicesetChannelActtionsService(
+void WebAPIRequestMapper::devicesetChannelActionsService(
         const std::string& deviceSetIndexStr,
         const std::string& channelIndexStr,
         qtwebapp::HttpRequest& request,
@@ -2306,17 +2332,17 @@ void WebAPIRequestMapper::devicesetChannelActtionsService(
                 SWGSDRangel::SWGChannelActions query;
                 SWGSDRangel::SWGSuccessResponse normalResponse;
                 resetChannelActions(query);
+                QStringList channelActionsKeys;
 
-                if (jsonObject.contains("direction")) {
-                    query.setDirection(jsonObject["direction"].toInt());
-                } else {
-                    query.setDirection(0); // assume Rx
-                }
-
-                if (jsonObject.contains("channelType") && jsonObject["channelType"].isString())
+                if (validateChannelActions(query, jsonObject, channelActionsKeys))
                 {
-                    query.setChannelType(new QString(jsonObject["channelType"].toString()));
-                    int status = m_adapter->devicesetChannelActionsPost(deviceSetIndex, channelIndex, query, normalResponse, errorResponse);
+                    int status = m_adapter->devicesetChannelActionsPost(
+                        deviceSetIndex,
+                        channelIndex,
+                        channelActionsKeys,
+                        query,
+                        normalResponse,
+                        errorResponse);
                     response.setStatus(status);
 
                     if (status/100 == 2) {
@@ -2523,7 +2549,59 @@ bool WebAPIRequestMapper::validateDeviceSettings(
         return false;
     }
 
-    return getDevice(deviceSettingsKey, &deviceSettings, jsonObject, deviceSettingsKeys);
+    return getDeviceSettings(deviceSettingsKey, &deviceSettings, jsonObject, deviceSettingsKeys);
+}
+
+bool WebAPIRequestMapper::validateDeviceActions(
+        SWGSDRangel::SWGDeviceActions& deviceActions,
+        QJsonObject& jsonObject,
+        QStringList& deviceActionsKeys)
+{
+    if (jsonObject.contains("direction")) {
+        deviceActions.setDirection(jsonObject["direction"].toInt());
+    } else {
+        deviceActions.setDirection(0); // assume single Rx
+    }
+
+    if (jsonObject.contains("deviceHwType") && jsonObject["deviceHwType"].isString()) {
+        deviceActions.setDeviceHwType(new QString(jsonObject["deviceHwType"].toString()));
+    } else {
+        return false;
+    }
+
+    QString *deviceHwType = deviceActions.getDeviceHwType();
+    QString deviceActionsKey;
+
+    if (deviceActions.getDirection() == 0) // source
+    {
+        if (m_sourceDeviceHwIdToSettingsKey.contains(*deviceHwType)) {
+            deviceActionsKey = m_sourceDeviceHwIdToActionsKey[*deviceHwType];
+        } else {
+            return false;
+        }
+    }
+    else if (deviceActions.getDirection() == 1) // sink
+    {
+        if (m_sinkDeviceHwIdToSettingsKey.contains(*deviceHwType)) {
+            deviceActionsKey = m_sinkDeviceHwIdToActionsKey[*deviceHwType];
+        } else {
+            return false;
+        }
+    }
+    else if (deviceActions.getDirection() == 2) // MIMO
+    {
+        if (m_mimoDeviceHwIdToSettingsKey.contains(*deviceHwType)) {
+            deviceActionsKey = m_mimoDeviceHwIdToActionsKey[*deviceHwType];
+        } else {
+            return false;
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return getDeviceActions(deviceActionsKey, &deviceActions, jsonObject, deviceActionsKeys);
 }
 
 bool WebAPIRequestMapper::validateChannelSettings(
@@ -2546,7 +2624,33 @@ bool WebAPIRequestMapper::validateChannelSettings(
     QString *channelType = channelSettings.getChannelType();
 
     if (m_channelTypeToSettingsKey.contains(*channelType)) {
-        return getChannel(m_channelTypeToSettingsKey[*channelType], &channelSettings, jsonObject, channelSettingsKeys);
+        return getChannelSettings(m_channelTypeToSettingsKey[*channelType], &channelSettings, jsonObject, channelSettingsKeys);
+    } else {
+        return false;
+    }
+}
+
+bool WebAPIRequestMapper::validateChannelActions(
+    SWGSDRangel::SWGChannelActions& channelActions,
+    QJsonObject& jsonObject,
+    QStringList& channelActionsKeys)
+{
+    if (jsonObject.contains("direction")) {
+        channelActions.setDirection(jsonObject["direction"].toInt());
+    } else {
+        channelActions.setDirection(0); // assume single Rx
+    }
+
+    if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) {
+        channelActions.setChannelType(new QString(jsonObject["channelType"].toString()));
+    } else {
+        return false;
+    }
+
+    QString *channelType = channelActions.getChannelType();
+
+    if (m_channelTypeToActionsKey.contains(*channelType)) {
+        return getChannelActions(m_channelTypeToActionsKey[*channelType], &channelActions, jsonObject, channelActionsKeys);
     } else {
         return false;
     }
@@ -2936,7 +3040,7 @@ bool WebAPIRequestMapper::appendPresetChannelKeys(
         {
             SWGSDRangel::SWGChannelSettings *channelSettings = new SWGSDRangel::SWGChannelSettings();
             channel->setConfig(channelSettings);
-            return getChannel(m_channelURIToSettingsKey[*channelURI], channelSettings, channelSettingsJson["config"].toObject(), channelKeys.m_channelKeys);
+            return getChannelSettings(m_channelURIToSettingsKey[*channelURI], channelSettings, channelSettingsJson["config"].toObject(), channelKeys.m_channelKeys);
         }
         else
         {
@@ -2949,7 +3053,7 @@ bool WebAPIRequestMapper::appendPresetChannelKeys(
     }
 }
 
-bool WebAPIRequestMapper::getChannel(
+bool WebAPIRequestMapper::getChannelSettings(
     const QString& channelSettingsKey,
     SWGSDRangel::SWGChannelSettings *channelSettings,
     const QJsonObject& channelSettingsJson,
@@ -3102,6 +3206,38 @@ bool WebAPIRequestMapper::getChannel(
     }
 }
 
+bool WebAPIRequestMapper::getChannelActions(
+    const QString& channelActionsKey,
+    SWGSDRangel::SWGChannelActions *channelActions,
+    const QJsonObject& channelActionsJson,
+    QStringList& channelActionsKeys
+)
+{
+    QStringList channelKeys = channelActionsJson.keys();
+
+    if (channelKeys.contains(channelActionsKey) && channelActionsJson[channelActionsKey].isObject())
+    {
+        QJsonObject actionsJsonObject = channelActionsJson[channelActionsKey].toObject();
+        channelActionsKeys = actionsJsonObject.keys();
+
+        if (channelActionsKey == "FileSourceActions")
+        {
+            channelActions->setFileSourceActions(new SWGSDRangel::SWGFileSourceActions());
+            channelActions->getFileSourceActions()->fromJsonObject(actionsJsonObject);
+        }
+        else
+        {
+            return false;
+        }
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
 bool WebAPIRequestMapper::appendPresetDeviceKeys(
         SWGSDRangel::SWGDeviceConfig *device,
         const QJsonObject& deviceSettngsJson,
@@ -3130,7 +3266,7 @@ bool WebAPIRequestMapper::appendPresetDeviceKeys(
         {
             SWGSDRangel::SWGDeviceSettings *deviceSettings = new SWGSDRangel::SWGDeviceSettings();
             device->setConfig(deviceSettings);
-            return getDevice(m_deviceIdToSettingsKey[*deviceId], deviceSettings, deviceSettngsJson["config"].toObject(), devicelKeys.m_deviceKeys);
+            return getDeviceSettings(m_deviceIdToSettingsKey[*deviceId], deviceSettings, deviceSettngsJson["config"].toObject(), devicelKeys.m_deviceKeys);
         }
         else
         {
@@ -3143,7 +3279,7 @@ bool WebAPIRequestMapper::appendPresetDeviceKeys(
     }
 }
 
-bool WebAPIRequestMapper::getDevice(
+bool WebAPIRequestMapper::getDeviceSettings(
         const QString& deviceSettingsKey,
         SWGSDRangel::SWGDeviceSettings *deviceSettings,
         const QJsonObject& deviceSettingsJson,
@@ -3315,6 +3451,39 @@ bool WebAPIRequestMapper::getDevice(
 
 }
 
+bool WebAPIRequestMapper::getDeviceActions(
+        const QString& deviceActionsKey,
+        SWGSDRangel::SWGDeviceActions *deviceActions,
+        const QJsonObject& deviceActionsJson,
+        QStringList& deviceActionsKeys
+)
+{
+    QStringList deviceKeys = deviceActionsJson.keys();
+
+    if (deviceKeys.contains(deviceActionsKey) && deviceActionsJson[deviceActionsKey].isObject())
+    {
+        QJsonObject actionsJsonObject = deviceActionsJson[deviceActionsKey].toObject();
+        deviceActionsKeys = actionsJsonObject.keys();
+
+        if (deviceActionsKey == "rtlSdrActions")
+        {
+            deviceActions->setRtlSdrActions(new SWGSDRangel::SWGRtlSdrActions());
+            deviceActions->getRtlSdrActions()->fromJsonObject(actionsJsonObject);
+        }
+        else
+        {
+            return false;
+        }
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+
+}
+
 void WebAPIRequestMapper::appendSettingsSubKeys(
         const QJsonObject& parentSettingsJsonObject,
         QJsonObject& childSettingsJsonObject,
diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h
index c61bfe2ba..e2375ed7d 100644
--- a/sdrbase/webapi/webapirequestmapper.h
+++ b/sdrbase/webapi/webapirequestmapper.h
@@ -88,14 +88,16 @@ private:
     void devicesetChannelIndexService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
     void devicesetChannelSettingsService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
     void devicesetChannelReportService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
-    void devicesetChannelActtionsService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
+    void devicesetChannelActionsService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
 
     bool validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer);
     bool validatePresetIdentifer(SWGSDRangel::SWGPresetIdentifier& presetIdentifier);
     bool validatePresetExport(SWGSDRangel::SWGPresetExport& presetExport);
     bool validateDeviceListItem(SWGSDRangel::SWGDeviceListItem& deviceListItem, QJsonObject& jsonObject);
     bool validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings, QJsonObject& jsonObject, QStringList& deviceSettingsKeys);
-    bool validateChannelSettings(SWGSDRangel::SWGChannelSettings& deviceSettings, QJsonObject& jsonObject, QStringList& channelSettingsKeys);
+    bool validateDeviceActions(SWGSDRangel::SWGDeviceActions& deviceActions, QJsonObject& jsonObject, QStringList& deviceActionsKeys);
+    bool validateChannelSettings(SWGSDRangel::SWGChannelSettings& channelSettings, QJsonObject& jsonObject, QStringList& channelSettingsKeys);
+    bool validateChannelActions(SWGSDRangel::SWGChannelActions& channelActions, QJsonObject& jsonObject, QStringList& channelActionsKeys);
     bool validateAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice, QJsonObject& jsonObject, QStringList& audioInputDeviceKeys);
     bool validateAudioOutputDevice(SWGSDRangel::SWGAudioOutputDevice& audioOutputDevice, QJsonObject& jsonObject, QStringList& audioOutputDeviceKeys);
     bool validateAMBEDevices(SWGSDRangel::SWGAMBEDevices& ambeDevices, QJsonObject& jsonObject);
@@ -113,24 +115,38 @@ private:
             WebAPIAdapterInterface::ChannelKeys& channelKeys
     );
 
-    bool getChannel(
+    bool getChannelSettings(
         const QString& channelSettingsKey,
         SWGSDRangel::SWGChannelSettings *channelSettings,
         const QJsonObject& channelSettingsJson,
         QStringList& channelSettingsKeys
     );
 
+    bool getChannelActions(
+        const QString& channelActionsKey,
+        SWGSDRangel::SWGChannelActions *channelActions,
+        const QJsonObject& channelActionsJson,
+        QStringList& channelSettingsKeys
+    );
+
     bool appendPresetDeviceKeys(
             SWGSDRangel::SWGDeviceConfig *device,
             const QJsonObject& deviceSettngsJson,
             WebAPIAdapterInterface::DeviceKeys& devicelKeys
     );
 
-    bool getDevice(
+    bool getDeviceSettings(
         const QString& deviceSettingsKey,
         SWGSDRangel::SWGDeviceSettings *deviceSettings,
         const QJsonObject& deviceSettingsJson,
-        QStringList& deviceSettingsKeys
+        QStringList& deviceActionsKeys
+    );
+
+    bool getDeviceActions(
+        const QString& deviceActionsKey,
+        SWGSDRangel::SWGDeviceActions *deviceActions,
+        const QJsonObject& deviceActionsJson,
+        QStringList& deviceActionsKeys
     );
 
     void appendSettingsSubKeys(
@@ -173,6 +189,14 @@ private:
     static const QMap m_channelTypeToSettingsKey;
     static const QMap m_sourceDeviceHwIdToSettingsKey;
     static const QMap m_sinkDeviceHwIdToSettingsKey;
+<<<<<<< ours
+=======
+    static const QMap m_mimoDeviceHwIdToSettingsKey;
+    static const QMap m_channelTypeToActionsKey;
+    static const QMap m_sourceDeviceHwIdToActionsKey;
+    static const QMap m_sinkDeviceHwIdToActionsKey;
+    static const QMap m_mimoDeviceHwIdToActionsKey;
+>>>>>>> theirs
 };
 
 #endif /* SDRBASE_WEBAPI_WEBAPIREQUESTMAPPER_H_ */
diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp
index 2b3b337f8..67adb1a19 100644
--- a/sdrgui/webapi/webapiadaptergui.cpp
+++ b/sdrgui/webapi/webapiadaptergui.cpp
@@ -1569,6 +1569,7 @@ int WebAPIAdapterGUI::devicesetDeviceSettingsGet(
 
 int WebAPIAdapterGUI::devicesetDeviceActionsPost(
         int deviceSetIndex,
+        const QStringList& deviceActionsKeys,
         SWGSDRangel::SWGDeviceActions& query,
         SWGSDRangel::SWGSuccessResponse& response,
         SWGSDRangel::SWGErrorResponse& error)
@@ -1594,7 +1595,7 @@ int WebAPIAdapterGUI::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource();
-                int res = source->webapiActionsPost(query, *error.getMessage());
+                int res = source->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -1620,7 +1621,7 @@ int WebAPIAdapterGUI::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink();
-                int res = sink->webapiActionsPost(query, *error.getMessage());
+                int res = sink->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -1646,7 +1647,7 @@ int WebAPIAdapterGUI::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO();
-                int res = mimo->webapiActionsPost(query, *error.getMessage());
+                int res = mimo->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -2389,6 +2390,7 @@ int WebAPIAdapterGUI::devicesetChannelReportGet(
 int WebAPIAdapterGUI::devicesetChannelActionsPost(
         int deviceSetIndex,
         int channelIndex,
+        const QStringList& channelActionsKeys,
         SWGSDRangel::SWGChannelActions& query,
         SWGSDRangel::SWGSuccessResponse& response,
         SWGSDRangel::SWGErrorResponse& error)
@@ -2415,7 +2417,7 @@ int WebAPIAdapterGUI::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
 
                     if (res/100 == 2)
                     {
@@ -2451,7 +2453,7 @@ int WebAPIAdapterGUI::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
 
                     if (res/100 == 2)
                     {
@@ -2503,7 +2505,7 @@ int WebAPIAdapterGUI::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
                     if (res/100 == 2)
                     {
                         response.init();
diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h
index de9f4fbc8..52568f68d 100644
--- a/sdrgui/webapi/webapiadaptergui.h
+++ b/sdrgui/webapi/webapiadaptergui.h
@@ -225,6 +225,7 @@ public:
 
     virtual int devicesetDeviceActionsPost(
             int deviceSetIndex,
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error);
@@ -300,6 +301,7 @@ public:
     virtual int devicesetChannelActionsPost(
             int deviceSetIndex,
             int channelIndex,
+            const QStringList& channelActionsKeys,
             SWGSDRangel::SWGChannelActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error);
diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp
index 1953c4f58..b64e0d271 100644
--- a/sdrsrv/webapi/webapiadaptersrv.cpp
+++ b/sdrsrv/webapi/webapiadaptersrv.cpp
@@ -1666,6 +1666,7 @@ int WebAPIAdapterSrv::devicesetDeviceSettingsGet(
 
 int WebAPIAdapterSrv::devicesetDeviceActionsPost(
         int deviceSetIndex,
+        const QStringList& deviceActionsKeys,
         SWGSDRangel::SWGDeviceActions& query,
         SWGSDRangel::SWGSuccessResponse& response,
         SWGSDRangel::SWGErrorResponse& error)
@@ -1691,7 +1692,7 @@ int WebAPIAdapterSrv::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource();
-                int res = source->webapiActionsPost(query, *error.getMessage());
+                int res = source->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -1717,7 +1718,7 @@ int WebAPIAdapterSrv::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink();
-                int res = sink->webapiActionsPost(query, *error.getMessage());
+                int res = sink->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -1743,7 +1744,7 @@ int WebAPIAdapterSrv::devicesetDeviceActionsPost(
             else
             {
                 DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO();
-                int res = mimo->webapiActionsPost(query, *error.getMessage());
+                int res = mimo->webapiActionsPost(deviceActionsKeys, query, *error.getMessage());
 
                 if (res/100 == 2)
                 {
@@ -2485,6 +2486,7 @@ int WebAPIAdapterSrv::devicesetChannelReportGet(
 int WebAPIAdapterSrv::devicesetChannelActionsPost(
         int deviceSetIndex,
         int channelIndex,
+        const QStringList& channelActionsKeys,
         SWGSDRangel::SWGChannelActions& query,
         SWGSDRangel::SWGSuccessResponse& response,
         SWGSDRangel::SWGErrorResponse& error)
@@ -2511,7 +2513,7 @@ int WebAPIAdapterSrv::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
 
                     if (res/100 == 2)
                     {
@@ -2547,7 +2549,7 @@ int WebAPIAdapterSrv::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
 
                     if (res/100 == 2)
                     {
@@ -2599,7 +2601,7 @@ int WebAPIAdapterSrv::devicesetChannelActionsPost(
 
                 if (channelType == *query.getChannelType())
                 {
-                    int res = channelAPI->webapiActionsPost(query, *error.getMessage());
+                    int res = channelAPI->webapiActionsPost(channelActionsKeys, query, *error.getMessage());
                     if (res/100 == 2)
                     {
                         response.init();
diff --git a/sdrsrv/webapi/webapiadaptersrv.h b/sdrsrv/webapi/webapiadaptersrv.h
index cf2d743db..a70f4bf27 100644
--- a/sdrsrv/webapi/webapiadaptersrv.h
+++ b/sdrsrv/webapi/webapiadaptersrv.h
@@ -235,6 +235,7 @@ public:
 
     virtual int devicesetDeviceActionsPost(
             int deviceSetIndex,
+            const QStringList& deviceActionsKeys,
             SWGSDRangel::SWGDeviceActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error);
@@ -310,6 +311,7 @@ public:
     virtual int devicesetChannelActionsPost(
             int deviceSetIndex,
             int channelIndex,
+            const QStringList& channelActionsKeys,
             SWGSDRangel::SWGChannelActions& query,
             SWGSDRangel::SWGSuccessResponse& response,
             SWGSDRangel::SWGErrorResponse& error);