diff --git a/README.rst b/README.rst
index 91f2785..f2fb6d5 100644
--- a/README.rst
+++ b/README.rst
@@ -125,6 +125,22 @@ Collection searches support these methods (in addition to the shared methods abo
     >>> api.keyword("M*D09")
 
 
+As an alternative to chaining methods together to set the parameters of your query, a
+method exists to allow you to pass your parameters as keyword arguments:
+
+::
+
+    # search for AST_L1T version 003 granules at latitude 42, longitude -100
+    >>> api.parameters(
+        short_name="AST_L1T",
+        version="003",
+        point=(-100, 42)
+    )
+
+Note: the kwarg key should match the name of a method from the above examples, and the value
+should be a tuple if it's a parameter that requires multiple values.
+
+
 To inspect and retreive results from the API, the following methods are available:
 
 ::
diff --git a/cmr/queries.py b/cmr/queries.py
index bfc187c..7f56c22 100644
--- a/cmr/queries.py
+++ b/cmr/queries.py
@@ -8,6 +8,7 @@ except ImportError:
     from urllib import pathname2url as quote
 
 from datetime import datetime
+from inspect import getmembers, ismethod
 from re import search
 from requests import get, exceptions
 
@@ -99,6 +100,35 @@ class Query(object):
 
         return self.get(self.hits())
 
+    def parameters(self, **kwargs):
+        """
+        Provide query parameters as keyword arguments. The keyword needs to match the name
+        of the method, and the value should either be the value or a tuple of values.
+
+        Example: parameters(short_name="AST_L1T", point=(42.5, -101.25))
+
+        :returns: Query instance
+        """
+
+        # build a dictionary of method names and their reference
+        methods = {}
+        for name, func in getmembers(self, predicate=ismethod):
+            methods[name] = func
+
+        for key, val in kwargs.items():
+
+            # verify the key matches one of our methods
+            if key not in methods:
+                raise ValueError("Unknown key {}".format(key))
+
+            # call the method
+            if isinstance(val, tuple):
+                methods[key](*val)
+            else:
+                methods[key](val)
+
+        return self
+
     def format(self, output_format="json"):
         """
         Sets the format for the returned results.

Param() method that accepts keyword args
This might be kind of a neat alternative to using the different methods directly. For example:
```python
# current way
api.short_name("AST_L1T").version("006").point(-100, 42).query()

# param() way
api.params(
    short_name="AST_L1T",
    version="006",
    point=(-100, 42)
).query()
```

And then in params() the class could inspect itself for those methods and delegate the parameters to the appropriate methods that we've already made. I'm thinking about this as an alternative to how we do it, not a replacement.
diff --git a/tests/test_granule.py b/tests/test_granule.py
index 11b481b..338ca10 100644
--- a/tests/test_granule.py
+++ b/tests/test_granule.py
@@ -350,6 +350,22 @@ class TestGranuleClass(unittest.TestCase):
         with self.assertRaises(ValueError):
             query = GranuleQuery(None)
     
+    def test_valid_parameters(self):
+        query = GranuleQuery()
+
+        query.parameters(short_name="AST_L1T", version="003", point=(-100, 42))
+
+        self.assertEqual(query.params["short_name"], "AST_L1T")
+        self.assertEqual(query.params["version"], "003")
+        self.assertEqual(query.params["point"], "-100.0,42.0")
+    
+    def test_invalid_parameters(self):
+        query = GranuleQuery()
+
+        with self.assertRaises(ValueError):
+            query.parameters(fake=123)
+            query.parameters(point=(-100, "badvalue"))
+
     def test_valid_formats(self):
         query = GranuleQuery()
         formats = ["json", "xml", "echo10", "iso", "iso19115", "csv", "atom", "kml", "native"]

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
appdirs==1.4.0
astroid==1.4.9
attrs==22.2.0
certifi==2021.5.30
coverage==6.2
importlib-metadata==4.8.3
iniconfig==1.1.1
isort==4.2.5
lazy-object-proxy==1.2.2
mccabe==0.5.3
packaging==16.8
pluggy==1.0.0
py==1.11.0
pylint==1.6.4
pyparsing==2.1.10
pytest==7.0.1
pytest-cov==4.0.0
-e git+https://github.com/jddeal/python-cmr.git@77d9eeb9310a34992cd7d0742f7b1903151737b2#egg=python_cmr
requests==2.12.4
six==1.10.0
tomli==1.2.3
typing_extensions==4.1.1
wrapt==1.10.8
zipp==3.6.0

name: python-cmr
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - appdirs==1.4.0
      - astroid==1.4.9
      - attrs==22.2.0
      - coverage==6.2
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - isort==4.2.5
      - lazy-object-proxy==1.2.2
      - mccabe==0.5.3
      - packaging==16.8
      - pluggy==1.0.0
      - py==1.11.0
      - pylint==1.6.4
      - pyparsing==2.1.10
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - requests==2.12.4
      - six==1.10.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - wrapt==1.10.8
      - zipp==3.6.0
prefix: /opt/conda/envs/python-cmr

tests/test_granule.py::TestGranuleClass::test_invalid_parameters tests/test_granule.py::TestGranuleClass::test_valid_parameters
tests/test_granule.py::TestGranuleClass::test_bounding_box_invalid_set tests/test_granule.py::TestGranuleClass::test_bounding_box_set tests/test_granule.py::TestGranuleClass::test_cloud_cover_all tests/test_granule.py::TestGranuleClass::test_cloud_cover_max_only tests/test_granule.py::TestGranuleClass::test_cloud_cover_min_only tests/test_granule.py::TestGranuleClass::test_cloud_cover_none tests/test_granule.py::TestGranuleClass::test_day_night_flag_day_set tests/test_granule.py::TestGranuleClass::test_day_night_flag_invalid_set tests/test_granule.py::TestGranuleClass::test_day_night_flag_invalid_type_set tests/test_granule.py::TestGranuleClass::test_day_night_flag_night_set tests/test_granule.py::TestGranuleClass::test_day_night_flag_unspecified_set tests/test_granule.py::TestGranuleClass::test_downloadable_invalid tests/test_granule.py::TestGranuleClass::test_downloadable_set tests/test_granule.py::TestGranuleClass::test_empty_granule_ur tests/test_granule.py::TestGranuleClass::test_empty_instrument tests/test_granule.py::TestGranuleClass::test_empty_platform tests/test_granule.py::TestGranuleClass::test_entry_title_set tests/test_granule.py::TestGranuleClass::test_granule_ur tests/test_granule.py::TestGranuleClass::test_instrument tests/test_granule.py::TestGranuleClass::test_invalid_format tests/test_granule.py::TestGranuleClass::test_invalid_mode tests/test_granule.py::TestGranuleClass::test_invalid_mode_constructor tests/test_granule.py::TestGranuleClass::test_invalid_spatial_state tests/test_granule.py::TestGranuleClass::test_line_invalid_set tests/test_granule.py::TestGranuleClass::test_line_set tests/test_granule.py::TestGranuleClass::test_online_only_invalid tests/test_granule.py::TestGranuleClass::test_online_only_set tests/test_granule.py::TestGranuleClass::test_orbit_number_encode tests/test_granule.py::TestGranuleClass::test_orbit_number_set tests/test_granule.py::TestGranuleClass::test_platform tests/test_granule.py::TestGranuleClass::test_point_invalid_set tests/test_granule.py::TestGranuleClass::test_point_set tests/test_granule.py::TestGranuleClass::test_polygon_invalid_set tests/test_granule.py::TestGranuleClass::test_polygon_set tests/test_granule.py::TestGranuleClass::test_short_name tests/test_granule.py::TestGranuleClass::test_temporal_invalid_date_order tests/test_granule.py::TestGranuleClass::test_temporal_invalid_strings tests/test_granule.py::TestGranuleClass::test_temporal_invalid_types tests/test_granule.py::TestGranuleClass::test_temporal_option_set tests/test_granule.py::TestGranuleClass::test_temporal_set tests/test_granule.py::TestGranuleClass::test_valid_formats tests/test_granule.py::TestGranuleClass::test_valid_spatial_state tests/test_granule.py::TestGranuleClass::test_version
README.rst cmr/queries.py
README.rst cmr/queries.py