diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f7b1b02..ccff6d3 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,10 +4,12 @@ CHANGELOG
 This document describes changes between each past release.
 
 
-10.2.0 (unreleased)
+10.1.1 (unreleased)
 ===================
 
-- Nothing changed yet.
+**Bug fixes**
+
+- Fix JSON support for `in_` and `exclude_`. (#188)
 
 
 10.1.0 (2018-11-05)
diff --git a/kinto_http/session.py b/kinto_http/session.py
index f516a29..aa2ccef 100644
--- a/kinto_http/session.py
+++ b/kinto_http/session.py
@@ -73,7 +73,15 @@ class Session(object):
             kwargs['headers'] = dict()
 
         if kwargs.get('params') is not None:
-            kwargs['params'] = {k: json.dumps(v).strip('"') for k, v in kwargs["params"].items()}
+            params = dict()
+            for key, value in kwargs["params"].items():
+                if key.startswith('in_') or key.startswith('exclude_'):
+                    params[key] = ','.join(value)
+                elif isinstance(value, str):
+                    params[key] = value
+                else:
+                    params[key] = json.dumps(value)
+            kwargs['params'] = params
 
         if not isinstance(kwargs['headers'], dict):
             raise TypeError("headers must be a dict (got {})".format(kwargs['headers']))

json encoding of querystring parameters fails
For instance:

/v1/buckets/bid/collections/cid/records?in_id=["be503c41-3aa6-42e1-9214-0d00ee0ce9ac","51f65e45-b17c-4dc1-970f-1da8f219824f","b4bb1714-cfe3-4cde-9903-66c47b4ce2f2"]&_sort=-published_date&max_published_date="2018-11-12T15:52:00"&language=fr&_limit=100

Doesn't work while:

/v1/buckets/bid/collections/cid/records?in_id=be503c41-3aa6-42e1-9214-0d00ee0ce9ac,51f65e45-b17c-4dc1-970f-1da8f219824f,b4bb1714-cfe3-4cde-9903-66c47b4ce2f2&_sort=-published_date&max_published_date=%222018-11-12T15:52:00%22&language=fr&_limit=100

Does.
diff --git a/kinto_http/tests/test_session.py b/kinto_http/tests/test_session.py
index b3cec55..4492f8d 100644
--- a/kinto_http/tests/test_session.py
+++ b/kinto_http/tests/test_session.py
@@ -241,13 +241,17 @@ class SessionJSONTest(unittest.TestCase):
                                  _sort="-published_date",
                                  is_published=True,
                                  price=12,
-                                 contains_id=["toto", "tata"]))
+                                 contains_id=["toto", "tata"],
+                                 in_id=["toto", "tata"],
+                                 exclude_id=["titi", "tutu"]))
         self.requests_mock.request.assert_called_with(
             'get', 'https://example.org/v1/buckets/buck/collections/coll/records', params={
-                "_sort": "-published_date",
+                "_sort": '-published_date',
                 "is_published": "true",
                 "price": "12",
-                "contains_id": '["toto", "tata"]'
+                "contains_id": '["toto", "tata"]',
+                "in_id": 'toto,tata',
+                "exclude_id": 'titi,tutu'
             }, headers=self.requests_mock.request.headers)
 
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest numpy>=1.16.0 pandas>=1.0.0
apt-get update apt-get install -y gcc libffi-dev libssl-dev
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2018.10.15
chardet==3.0.4
exceptiongroup==1.2.2
idna==2.7
iniconfig==2.1.0
-e git+https://github.com/Kinto/kinto-http.py.git@ab2f0502c914d031319875379532fd57d50b8870#egg=kinto_http
numpy==2.0.2
packaging==24.2
pandas==2.2.3
pluggy==1.5.0
pytest==8.3.5
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.20.0
six==1.17.0
tomli==2.2.1
tzdata==2025.2
Unidecode==1.0.22
urllib3==1.24.1

name: kinto-http.py
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
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2018.10.15
      - chardet==3.0.4
      - exceptiongroup==1.2.2
      - idna==2.7
      - iniconfig==2.1.0
      - numpy==2.0.2
      - packaging==24.2
      - pandas==2.2.3
      - pluggy==1.5.0
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.20.0
      - six==1.17.0
      - tomli==2.2.1
      - tzdata==2025.2
      - unidecode==1.0.22
      - urllib3==1.24.1
prefix: /opt/conda/envs/kinto-http.py

kinto_http/tests/test_session.py::SessionJSONTest::test_request_converts_params
kinto_http/tests/test_session.py::SessionTest::test_bad_http_status_raises_exception kinto_http/tests/test_session.py::SessionTest::test_bad_http_status_raises_exception_even_in_case_of_invalid_json_response kinto_http/tests/test_session.py::SessionTest::test_body_is_none_on_304 kinto_http/tests/test_session.py::SessionTest::test_creates_a_session_if_needed kinto_http/tests/test_session.py::SessionTest::test_creation_fails_if_session_and_server_url kinto_http/tests/test_session.py::SessionTest::test_initialization_fails_on_missing_args kinto_http/tests/test_session.py::SessionTest::test_no_auth_is_used_by_default kinto_http/tests/test_session.py::SessionTest::test_no_payload_is_sent_on_get_requests kinto_http/tests/test_session.py::SessionTest::test_passed_data_is_encoded_to_json kinto_http/tests/test_session.py::SessionTest::test_passed_data_is_passed_as_is_when_files_are_posted kinto_http/tests/test_session.py::SessionTest::test_passed_permissions_is_added_in_the_payload kinto_http/tests/test_session.py::SessionTest::test_payload_is_sent_on_put_requests kinto_http/tests/test_session.py::SessionTest::test_raises_exception_if_headers_not_dict kinto_http/tests/test_session.py::SessionTest::test_requests_arguments_are_forwarded kinto_http/tests/test_session.py::SessionTest::test_session_injects_auth_on_requests kinto_http/tests/test_session.py::SessionTest::test_url_is_used_if_schema_is_present kinto_http/tests/test_session.py::SessionTest::test_use_given_session_if_provided kinto_http/tests/test_session.py::SessionTest::test_user_agent_contains_kinto_http_as_well_as_requests_and_python_versions kinto_http/tests/test_session.py::SessionTest::test_user_agent_is_sent_on_requests kinto_http/tests/test_session.py::SessionTest::test_uses_specified_server_url kinto_http/tests/test_session.py::SessionJSONTest::test_passed_date_data_is_encoded_to_json kinto_http/tests/test_session.py::SessionJSONTest::test_passed_datetime_data_is_encoded_to_json kinto_http/tests/test_session.py::SessionJSONTest::test_passed_random_python_data_fails_to_be_encoded_to_json kinto_http/tests/test_session.py::RetryRequestTest::test_can_retry_several_times kinto_http/tests/test_session.py::RetryRequestTest::test_does_not_retry_by_default kinto_http/tests/test_session.py::RetryRequestTest::test_does_not_retry_if_successful kinto_http/tests/test_session.py::RetryRequestTest::test_does_not_retry_on_4XX_errors kinto_http/tests/test_session.py::RetryRequestTest::test_does_not_wait_if_retry_after_header_is_not_present kinto_http/tests/test_session.py::RetryRequestTest::test_fails_if_retry_exhausted kinto_http/tests/test_session.py::RetryRequestTest::test_forced_retry_after_overrides_value_of_header kinto_http/tests/test_session.py::RetryRequestTest::test_next_request_without_the_header_clear_the_backoff kinto_http/tests/test_session.py::RetryRequestTest::test_raises_exception_if_backoff_time_not_spent kinto_http/tests/test_session.py::RetryRequestTest::test_retries_on_409_errors kinto_http/tests/test_session.py::RetryRequestTest::test_succeeds_on_retry kinto_http/tests/test_session.py::RetryRequestTest::test_waits_if_retry_after_header_is_present kinto_http/tests/test_session.py::RetryRequestTest::test_waits_if_retry_after_is_forced
CHANGELOG.rst kinto_http/session.py
CHANGELOG.rst kinto_http/session.py