diff --git a/gui/src/components/editQuantity/ActionEditQuantity.js b/gui/src/components/editQuantity/ActionEditQuantity.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb51d6a3828898daa6eeb2d54492a4894398f753
--- /dev/null
+++ b/gui/src/components/editQuantity/ActionEditQuantity.js
@@ -0,0 +1,58 @@
+/*
+ * Copyright The NOMAD Authors.
+ *
+ * This file is part of NOMAD. See https://nomad-lab.eu for further info.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, {useCallback} from 'react'
+import {
+  Button,
+  Tooltip
+} from '@material-ui/core'
+import PropTypes from 'prop-types'
+import {getFieldProps} from './StringEditQuantity'
+import {getDisplayLabel} from "../../utils"
+import {useErrors } from '../errors'
+import {useEntryStore } from '../entry/EntryContext'
+import {useRecoilValue} from "recoil"
+import {configState} from "../archive/ArchiveBrowser"
+
+export const ActionEditQuantity = React.memo(function ButtonEditQuantity(props) {
+  const {quantityDef, value, onChange, ...otherProps} = props
+  const fieldProps = getFieldProps(quantityDef)
+  const {saveArchive} = useEntryStore()
+  const {raiseError} = useErrors()
+  const config = useRecoilValue(configState)
+  const label = getDisplayLabel(quantityDef, true, config?.showMeta)
+
+  const handleClick = useCallback(() => {
+    onChange?.(true)
+    saveArchive().catch(raiseError)
+  }, [onChange, saveArchive, raiseError])
+
+  return <Tooltip title={fieldProps.helpDescription}>
+    <Button
+      variant="outlined"
+      disabled={value}
+      onClick={handleClick}
+      color="primary"
+      {...otherProps}
+    >{label}</Button>
+  </Tooltip>
+})
+ActionEditQuantity.propTypes = {
+  quantityDef: PropTypes.object.isRequired,
+  value: PropTypes.bool,
+  onChange: PropTypes.func
+}
diff --git a/gui/src/components/editQuantity/EditQuantity.js b/gui/src/components/editQuantity/EditQuantity.js
index b0522110d39f9ccd28394d73f0de3914aca28f1d..53f4c8b56b08f1b6c1bd8a1136df39568eedcf15 100644
--- a/gui/src/components/editQuantity/EditQuantity.js
+++ b/gui/src/components/editQuantity/EditQuantity.js
@@ -22,6 +22,7 @@ import {NumberEditQuantity} from './NumberEditQuantity'
 import {EnumEditQuantity} from './EnumEditQuantity'
 import {AutocompleteEditQuantity} from './AutocompleteEditQuantity'
 import {BoolEditQuantity} from './BoolEditQuantity'
+import {ActionEditQuantity} from './ActionEditQuantity'
 import FileEditQuantity from './FileEditQuantity'
 import RichTextEditQuantity from './RichTextEditQuantity'
 import ReferenceEditQuantity from './ReferenceEditQuantity'
@@ -38,6 +39,7 @@ export const editQuantityComponents = {
   RadioEnumEditQuantity: RadioEnumEditQuantity,
   AutocompleteEditQuantity: AutocompleteEditQuantity,
   BoolEditQuantity: BoolEditQuantity,
+  ActionEditQuantity: ActionEditQuantity,
   FileEditQuantity: FileEditQuantity,
   DateTimeEditQuantity: DateTimeEditQuantity,
   DateEditQuantity: DateEditQuantity,
diff --git a/nomad/datamodel/metainfo/action.py b/nomad/datamodel/metainfo/action.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4c73d3de524f16e174415d663477c1bbde37261
--- /dev/null
+++ b/nomad/datamodel/metainfo/action.py
@@ -0,0 +1,69 @@
+#
+# Copyright The NOMAD Authors.
+#
+# This file is part of NOMAD. See https://nomad-lab.eu for further info.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from nomad.datamodel.data import ArchiveSection
+from nomad.metainfo import Quantity, Package
+
+m_package = Package()
+
+
+class ActionSection(ArchiveSection):
+    """
+    Use this section to define actions that can be triggered from the ELN
+    interface.
+
+    Usage:
+    - In any of your schemas, use a a section that inherits from this one.
+    - Provide a `description` and an eln annotation for the `action_trigger`
+      quantity. To show a button that sets the trigger and performs a save
+      operation, use the `ActionEditQuantity` component in the eln annotation .
+    - Define a `perform_action` function that contains the code to trigger.
+
+    Example Usage:
+    ```python
+    class MyAction(ActionSection):
+        action_trigger = Quantity(
+            description='Description for this action. Will be shown as a tooltip.',
+            a_eln=dict(component='ActionEditQuantity', label='Button label'),
+        )
+
+        def perform_action(self, archive, logger):
+            # First check that was this action requested. Note that you do not
+            # have to modify this quantity: it will be set and reset
+            # automatically.
+            if self.action_trigger:
+                # Perform your action here
+                pass
+    ```
+    """
+
+    action_trigger = Quantity(type=bool)
+
+    def normalize(self, archive, logger):
+        try:
+            if self.action_trigger:
+                self.perform_action(archive, logger)
+        finally:
+            self.action_trigger = False
+
+    def perform_action(self, archive, logger):
+        raise NotImplementedError(
+            'No implementation provided for the perform_action function of an ActionSection.'
+        )
+
+
+m_package.__init_metainfo__()
diff --git a/nomad/datamodel/metainfo/annotations.py b/nomad/datamodel/metainfo/annotations.py
index 8f353097c43d4eb30510c60cdb34465612919d49..c5ae113ece24cda391eaf0c36172922f65efb882 100644
--- a/nomad/datamodel/metainfo/annotations.py
+++ b/nomad/datamodel/metainfo/annotations.py
@@ -48,6 +48,7 @@ class ELNComponentEnum(str, Enum):
     UserEditQuantity = 'UserEditQuantity'
     AuthorEditQuantity = 'AuthorEditQuantity'
     QueryEditQuantity = 'QueryEditQuantity'
+    ActionEditQuantity = 'ActionEditQuantity'
 
 
 valid_eln_types = {
@@ -79,7 +80,7 @@ valid_eln_components = {
         ELNComponentEnum.RichTextEditQuantity,
         ELNComponentEnum.EnumEditQuantity,
     ],
-    'bool': [ELNComponentEnum.BoolEditQuantity],
+    'bool': [ELNComponentEnum.BoolEditQuantity, ELNComponentEnum.ActionEditQuantity],
     'number': [
         ELNComponentEnum.NumberEditQuantity,
         ELNComponentEnum.SliderEditQuantity,