diff --git a/core/pymod/core/pm3argparse.py b/core/pymod/core/pm3argparse.py
index 51f55bca7287eea8c45fd27508eae0ac8b724b44..59cc9485139069166841e3f68650b0ad30064a40 100644
--- a/core/pymod/core/pm3argparse.py
+++ b/core/pymod/core/pm3argparse.py
@@ -121,6 +121,14 @@ def _AssembleTrgTplAln(target, template):
     new_aln.SetSequenceOffset(1, start)
     return new_aln
 
+class PM3StoreOnceAction(argparse.Action):
+    """Action for argument parsing to prevent multiple calls to an option.
+    """
+    def __call__(self, parser, namespace, values, option_string=None):
+        if getattr(namespace, self.dest, None) is not None:
+            raise argparse.ArgumentError(self, 'may only be used once.')
+        setattr(namespace, self.dest, values)
+
 class PM3ArgumentParser(argparse.ArgumentParser):
     """
     This class is a child of :class:`argparse.ArgumentParser`. It provides a
@@ -224,12 +232,18 @@ class PM3ArgumentParser(argparse.ArgumentParser):
 
         Options/ arguments added:
 
-        * ``--fasta trg:<NAME> <FILE>`` - describing a target-template alignment
-          with ``trg:`` marking the target sequence inside :file:`<FILE>`
+        * ``-f/ --fasta trg:<NAME> <FILE>`` - describing a target-template
+          alignment with ``trg:`` marking the target sequence inside
+          :file:`<FILE>`. The order of arguments is arbitrary which means file
+          names starting with :file:`trg:` will not work.
+
+        * ``-j/ --json <OBJECT>|<FILE>`` - target-template alignments in JSON
+          format. Either an object string or a file name. The string variant is
+          limited to how many characters your command line can gobble.
 
         Exit codes related to alignment input:
 
-        * 11 - no prefix ``trg:`` found for an argument to '--fasta'
+        * 11 - no prefix ``trg:`` found for an argument to ``--fasta``
 
         * 12 - a given alignment file does not exist
 
@@ -248,9 +262,12 @@ class PM3ArgumentParser(argparse.ArgumentParser):
         Attributes added to the namespace returned by
         :meth:`Parse`:
 
-        * :attr:`fasta` - filled with the input of the '--fasta' argument, a
+        * :attr:`fasta` - filled with the input of the ``--fasta`` option, a
                           :class:`list` with multiple :class:`list` objects
 
+        * :attr:`json` - argument of the ``--json`` option, :class:`str`. May
+                         be a filename of a JSON object string.
+
         * :attr:`alignments` - :class:`ost.AlignmentList`, same order as
                                :attr:`fasta`
 
@@ -264,17 +281,26 @@ class PM3ArgumentParser(argparse.ArgumentParser):
         """
         Actually add alignment arguments/ options
         """
+        aln_grp = self.add_mutually_exclusive_group()
         # FastA input: - always pairwise alignments
         #              - callable multiple times
         #              - goes by 'trg:<SEQNAME> <FILE>'
         #              - excludes JSON file/ object
-        #              - leading whitespaces will be deleted
-        self.add_argument('-f', '--fasta', nargs=2, action='append',
-                          metavar=('trg:<NAME>', '<FILE>'),
-                          help='Pairwise alignment in FastA format, needs to '+
-                          'declare what is the target sequence.')
-        # input: FastA/ JSON
-        # determined by extension: if we are wrong, the whole loading fails
+        #              - leading whitespaces of FastA headers will be deleted
+        aln_grp.add_argument('-f', '--fasta', nargs=2, action='append',
+                             metavar=('trg:<NAME>', '<FILE>'),
+                             help='Pairwise alignment in FastA format, needs '+
+                             'to declare what is the target sequence.')
+        # JSON input: - right as string or file
+        #             - object starts with {, so not allowed for files
+        #             - callable only ONCE: should include everything needed
+        #             - fields/ objects used: ...
+        #             - goes by '--json <OBJECT>|<FILE>'
+        #             - excludes '--fasta'
+        #             - leading whitespaces of sequence names will be deleted
+        aln_grp.add_argument('-j', '--json', metavar='<OBJECT>|<FILE>',
+                             help='Alignments provided as JSON file/ object.',
+                             action=PM3StoreOnceAction)
         # possibility to add JSON: mention limitation!
 
 class PM3OptionsNamespace(object):
diff --git a/core/tests/test_pm3argparse.py b/core/tests/test_pm3argparse.py
index 8bd20a84b36636fc702c63119a7d5d0e7537e686..271dfc26e683ae1a8591791f8d2cab681b41df6c 100644
--- a/core/tests/test_pm3argparse.py
+++ b/core/tests/test_pm3argparse.py
@@ -87,8 +87,9 @@ class PM3ArgParseTests(unittest.TestCase):
         self.assertEqual(ecd.exception.code, 2)
         self.assertEqual(self.log.messages['ERROR'],
                          ['usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
-                          '<FILE>]', 'test_pm3argparse.py: error: argument '+
-                          '-f/--fasta: expected 2 argument(s)'])
+                          '<FILE> | -j <OBJECT>|<FILE>]',
+                          'test_pm3argparse.py: error: argument -f/--fasta: '+
+                          'expected 2 argument(s)'])
 
     def testAddAlignmentNoFileArg(self):
         # check failure on missing file argument
@@ -100,8 +101,9 @@ class PM3ArgParseTests(unittest.TestCase):
         self.assertEqual(ecd.exception.code, 2)
         self.assertEqual(self.log.messages['ERROR'],
                          ['usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
-                          '<FILE>]', 'test_pm3argparse.py: error: argument '+
-                          '-f/--fasta: expected 2 argument(s)'])
+                          '<FILE> | -j <OBJECT>|<FILE>]',
+                          'test_pm3argparse.py: error: argument -f/--fasta: '+
+                          'expected 2 argument(s)'])
 
     def testAddAlignemntNoTrgPfx(self):
         # checking that we fail on missing 'trg:' prefix for arguments of
@@ -272,6 +274,38 @@ class PM3ArgParseTests(unittest.TestCase):
         self.assertEqual(opts.alignments[0].GetSequence(1).name, '1AKE.B')
         self.assertEqual(opts.aln_sources[0], 'data/fasta/1ake.fas')
 
+    def testAddAlignmentFastaAndJson(self):
+        # testing that --fasta and --json DO NOT work together
+        parser = pm3argparse.PM3ArgumentParser(__doc__, action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            opts = parser.Parse(['--fasta', 'trg:target',
+                                 'data/fasta/1ake.fas', '--json', 'foo'])
+        self.assertEqual(ecd.exception.code, 2)
+        self.assertEqual(self.log.messages['ERROR'][0],
+                         'usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
+                         '<FILE> | -j <OBJECT>|<FILE>]',
+                         'test_pm3argparse.py: error: argument -j/--json: '+
+                         'not allowed with argument -f/--fasta')
+
+    def testAddAlignmentJsonMulti(self):
+        # passing --json multiple times is not allowed
+        # also serves as a unit test for PM3StoreOnceAction
+        parser = pm3argparse.PM3ArgumentParser(__doc__, action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            opts = parser.Parse(['--json', 'foo', '--json', 'bar'])
+        self.assertEqual(ecd.exception.code, 2)
+        self.assertEqual(self.log.messages['ERROR'][0],
+                         'usage: test_pm3argparse.py [-h] [-f trg:<NAME> '+
+                         '<FILE> | -j <OBJECT>|<FILE>]',
+                         'test_pm3argparse.py: error: argument -j/--json: '+
+                         'may only be used once.')
+
+# test no multiple --json
+
 if __name__ == "__main__":
     from ost import testutils
     testutils.RunTests()