diff --git a/lib/apiserver/routers/smstools-config.js b/lib/apiserver/routers/smstools-config.js
index 37168d5..409269d 100644
--- a/lib/apiserver/routers/smstools-config.js
+++ b/lib/apiserver/routers/smstools-config.js
@@ -82,6 +82,42 @@ async function pageModemSet(req, res) {
     });
 }
 
+async function pageModemSetSingleValue(req, res) {
+    if (!req.body) {
+        res.json({
+            status: 'NOT OK',
+            message: 'Empty body',
+        });
+        return;
+    }
+
+    const modemName = (req.params.modemName || '').trim();
+    if (!modemName) {
+        res.json({
+            status: 'NOT OK',
+            message: 'Invalid modem name',
+        });
+        return;
+    }
+
+    const keyword = (req.body.keyword || '').trim();
+    if (!keyword) {
+        res.json({
+            status: 'NOT OK',
+            message: 'Invalid keyword',
+        });
+        return;
+    }
+
+    const { value } = req.body;
+
+    const result = await smstoolsConfigSetter.setModemSingleValue(modemName, keyword, value);
+    res.json({
+        dirty: !!smstoolsConfigData.dirty,
+        result,
+    });
+}
+
 async function pageModemDelete(req, res) {
     const modemName = (req.params.modemName || '').trim();
     if (!modemName) {
@@ -116,5 +152,6 @@ router.get('/modems', pageModemList);
 
 router.get('/set/:keyword', pageSet);
 router.post('/modem/set/:modemName', bodyParser.json({ type: '*/json' }), pageModemSet);
+router.post('/modem/set-single-value/:modemName', bodyParser({ type: '*/json' }), pageModemSetSingleValue);
 router.get('/modem/delete/:modemName', pageModemDelete);
 router.get('/install-config', pageInstallConfig);
diff --git a/lib/smstools-config/setter.js b/lib/smstools-config/setter.js
index ac677fe..5cc9c3e 100644
--- a/lib/smstools-config/setter.js
+++ b/lib/smstools-config/setter.js
@@ -73,6 +73,30 @@ exports.setModem = async (modemName, data) => {
     return smstoolsConfigData;
 };
 
+exports.setModemSingleValue = async (modemName, keyword, value) => {
+    if (!modemName) return smstoolsConfigData;
+
+    if (keyword === 'device') {
+        const modemWithSameDevice = getModemByDevice(value);
+        if (modemWithSameDevice && modemWithSameDevice !== modemName) {
+            return smstoolsConfigData;
+        }
+    }
+
+    if (!smstoolsConfigData.modems) {
+        smstoolsConfigData.modems = {};
+    }
+
+    if (!smstoolsConfigData.modems[modemName]) {
+        smstoolsConfigData.modems[modemName] = {};
+    }
+
+    smstoolsConfigData.modems[modemName][keyword] = value;
+    smstoolsConfigData.dirty = true;
+    await writeConfig();
+    return smstoolsConfigData;
+};
+
 
 exports.delModem = async (modemName) => {
     if (!modemName) return smstoolsConfigData;