diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/.gitignore b/clients/algoliasearch-client-dart/packages/chopper_requester/.gitignore
new file mode 100644
index 0000000000..3a85790408
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/.gitignore
@@ -0,0 +1,3 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/README.md b/clients/algoliasearch-client-dart/packages/chopper_requester/README.md
new file mode 100644
index 0000000000..573efd3c04
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/README.md
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Algolia API Chopper Requester
+
+
+
+ Use the Chopper Requester to send requests to the Algolia API with the Algolia Search Client for Dart. This package provides a custom Requester for the Algolia Search Client, allowing users to send requests to the Algolia API using the Chopper HTTP client.
+
+
+## 💡 Installation
+
+Add Chopper Requester as a dependency in your project directly from pub.dev:
+
+#### For Dart projects:
+
+```shell
+dart pub add algolia_chopper_requester
+```
+
+#### For Flutter projects:
+
+```shell
+flutter pub add algolia_chopper_requester
+```
+
+### Basic Usage
+
+```dart
+final String appId = 'latency';
+final String apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
+
+final SearchClient _client = SearchClient(
+ appId: appId,
+ apiKey: apiKey,
+ options: ClientOptions(
+ requester: ChopperRequester(
+ appId: appId,
+ apiKey: apiKey,
+ )
+ ),
+);
+
+Future search(String query) => _client.searchIndex(
+ request: SearchForHits(
+ indexName: 'flutter',
+ query: query,
+ hitsPerPage: 5,
+ ),
+ );
+```
+
+You can configure the `ChopperRequester` with the following parameters:
+
+### Configuration
+
+```dart
+final requester = ChopperRequester({
+ /// Your Algolia Application ID
+ required String appId,
+ /// Your Algolia Search-Only API Key
+ required String apiKey,
+ /// Additional headers to send with the request
+ Map? headers,
+ /// The segments to include in the `User-Agent` header
+ Iterable? clientSegments,
+ /// The logger to use for debugging
+ Logger? logger,
+ /// The Chopper Interceptors to use for modifying the request
+ Iterable? interceptors,
+ /// The HTTP client to use for sending requests
+ Client? client,
+ /// A custom JSON converter to use for serializing and deserializing JSON
+ JsonConverter? converter,
+});
+```
+
+### Advanced Usage
+
+To set the connect timeout one has to do that directly on the `Client`, i.e.
+
+```dart
+final requester = ChopperRequester(
+ appId: appId,
+ apiKey: apiKey,
+ client: http.IOClient(
+ HttpClient()..connectionTimeout = const Duration(seconds: 60),
+ ),
+);
+```
+
+#### Custom Interceptors
+
+For interceptors please see the [Chopper documentation](https://hadrien-lejard.gitbook.io/chopper/interceptors).
+
+#### Custom Clients
+
+Via the `client` option users can use platform specific HTTP clients such:
+- [cronet_http](https://pub.dev/packages/cronet_http) on Android
+ ```dart
+ final requester = ChopperRequester(
+ appId: appId,
+ apiKey: apiKey,
+ client: CronetClient.fromCronetEngine(
+ CronetEngine.build(
+ cacheMode: CacheMode.memory,
+ cacheMaxSize: 50 * 1024 * 1024,
+ ),
+ closeEngine: true,
+ ),
+ );
+ ```
+- [cupertino_http](https://pub.dev/packages/cupertino_http) on iOS/macOS
+ ```dart
+ final requester = ChopperRequester(
+ appId: appId,
+ apiKey: apiKey,
+ client: CupertinoClient.fromSessionConfiguration(
+ (URLSessionConfiguration.defaultSessionConfiguration()
+ ..timeoutIntervalForRequest = const Duration(seconds: 30)),
+ ),
+ );
+ ```
+
+#### Parsing JSON in the background using Isolates
+
+Parsing JSON in the background is a good idea if you don't want to block the main thread.
+Please see the [Chopper documentation](https://hadrien-lejard.gitbook.io/chopper/faq#decoding-json-using-isolates) on Decoding JSON using Isolate worker pools.
+
+## License
+
+Chopper Requester for Algolia Search Client is an open-sourced software licensed under the [MIT license](LICENSE).
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/example/example.dart b/clients/algoliasearch-client-dart/packages/chopper_requester/example/example.dart
new file mode 100644
index 0000000000..155f7c2679
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/example/example.dart
@@ -0,0 +1,55 @@
+import 'dart:io' show HttpClient;
+
+import 'package:algolia_chopper_requester/algolia_chopper_requester.dart';
+import 'package:algolia_client_core/algolia_client_core.dart';
+import 'package:http/http.dart' as http show Client;
+import 'package:http/io_client.dart' show IOClient;
+
+void main() async {
+ const String appId = 'latency';
+ const String apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
+
+ // Create a custom http [Client] with a connection timeout of 30 seconds
+ final http.Client client = IOClient(
+ HttpClient()..connectionTimeout = const Duration(seconds: 30),
+ );
+
+ // Creating an instance of the RetryStrategy with necessary parameters.
+ // This will retry the failed requests with a backoff strategy.
+ final RetryStrategy requester = RetryStrategy.create(
+ segment: AgentSegment(value: 'CustomClient'),
+ appId: appId,
+ apiKey: apiKey,
+ defaultHosts: () => [
+ Host(url: 'latency-dsn.algolia.net'),
+ Host(url: 'latency-1.algolianet.com'),
+ ],
+ options: ClientOptions(
+ requester: ChopperRequester(
+ appId: appId,
+ apiKey: apiKey,
+ // Optionally, pass a custom http [Client] to the ChopperRequester.
+ // NOTE: The [Client] must be manually disposed of after use.
+ client: client,
+ ),
+ ),
+ );
+
+ // Executing a GET request on the '/1/indexes/instant_search' endpoint.
+ final Map response = await requester.execute(
+ request: ApiRequest(
+ method: RequestMethod.get,
+ path: '/1/indexes/instant_search',
+ queryParams: {'query': 'a', 'hitsPerPage': '5'},
+ ),
+ );
+
+ // Printing json response.
+ print(response);
+
+ // Dispose of the requester to clean up its resources.
+ requester.dispose();
+
+ // Disposing a custom [Client] has to be done manually.
+ client.close();
+}
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/lib/algolia_chopper_requester.dart b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/algolia_chopper_requester.dart
new file mode 100644
index 0000000000..193b31ba8f
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/algolia_chopper_requester.dart
@@ -0,0 +1,4 @@
+library algolia_chopper_requester;
+
+export 'package:chopper/chopper.dart' show Interceptor;
+export 'src/chopper_requester.dart';
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/agent_interceptor.dart b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/agent_interceptor.dart
new file mode 100644
index 0000000000..e2649535a5
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/agent_interceptor.dart
@@ -0,0 +1,21 @@
+import 'dart:async' show FutureOr;
+
+import 'package:algolia_client_core/algolia_client_core.dart' show AlgoliaAgent;
+import 'package:chopper/chopper.dart';
+import 'package:algolia_chopper_requester/src/platform/platform.dart';
+
+/// Interceptor that attaches the Algolia agent to outgoing requests.
+///
+/// This interceptor modifies the query parameters of each request to include the
+/// formatted representation of the Algolia agent.
+class AgentInterceptor implements Interceptor {
+ /// The Algolia agent to be attached to outgoing requests.
+ final AlgoliaAgent agent;
+
+ /// Constructs an [AgentInterceptor] with the provided Algolia agent.
+ const AgentInterceptor({required this.agent});
+
+ @override
+ FutureOr> intercept(Chain chain) =>
+ chain.proceed(Platform.algoliaAgent(chain, agent.formatted()));
+}
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/auth_interceptor.dart b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/auth_interceptor.dart
new file mode 100644
index 0000000000..fdd2018ad0
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/auth_interceptor.dart
@@ -0,0 +1,33 @@
+import 'dart:async' show FutureOr;
+
+import 'package:chopper/chopper.dart';
+
+/// Interceptor that attaches the application id and API key to outgoing requests.
+///
+/// This interceptor modifies the headers of each request to include the
+/// application id and API key for Algolia authentication.
+class AuthInterceptor implements Interceptor {
+ /// The application id used for Algolia authentication.
+ final String appId;
+
+ /// The API key used for Algolia authentication.
+ final String _apiKey;
+
+ /// Constructs an [AuthInterceptor] with the provided application id and API key.
+ const AuthInterceptor({
+ required this.appId,
+ required String apiKey,
+ }) : _apiKey = apiKey;
+
+ @override
+ FutureOr> intercept(Chain chain) =>
+ chain.proceed(
+ applyHeaders(
+ chain.request,
+ {
+ 'x-algolia-application-id': appId,
+ 'x-algolia-api-key': _apiKey,
+ },
+ ),
+ );
+}
diff --git a/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/chopper_requester.dart b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/chopper_requester.dart
new file mode 100644
index 0000000000..9b1aa704eb
--- /dev/null
+++ b/clients/algoliasearch-client-dart/packages/chopper_requester/lib/src/chopper_requester.dart
@@ -0,0 +1,136 @@
+import 'dart:async' show TimeoutException;
+
+import 'package:algolia_client_core/algolia_client_core.dart';
+import 'package:chopper/chopper.dart';
+import 'package:algolia_chopper_requester/src/agent_interceptor.dart';
+import 'package:algolia_chopper_requester/src/auth_interceptor.dart';
+import 'package:algolia_chopper_requester/src/platform/platform.dart';
+import 'package:algolia_chopper_requester/src/version.dart';
+import 'package:http/http.dart' as http;
+import 'package:logging/logging.dart' show Logger;
+
+/// A [Requester] implementation using the Chopper library.
+///
+/// This class sends HTTP requests using the Chopper library and handles
+/// response conversion and error handling.
+class ChopperRequester implements Requester {
+ /// The underlying Chopper client.
+ AuthInterceptor _authInterceptor;
+ late final ChopperClient _client;
+
+ /// Constructs a [ChopperClient] with the given [appId] and [apiKey].
+ ChopperRequester({
+ required String appId,
+ required String apiKey,
+ Map? headers,
+ Iterable? clientSegments,
+ Logger? logger,
+ Iterable? interceptors,
+ http.Client? client,
+ JsonConverter? converter,
+ }) : _authInterceptor = AuthInterceptor(
+ appId: appId,
+ apiKey: apiKey,
+ ) {
+ _client = ChopperClient(
+ client: client,
+ converter: converter ?? const JsonConverter(),
+ interceptors: [
+ _authInterceptor,
+ AgentInterceptor(
+ agent: AlgoliaAgent(packageVersion)
+ ..addAll([
+ ...?clientSegments,
+ ...Platform.agentSegments(),
+ ]),
+ ),
+ if (logger != null)
+ HttpLoggingInterceptor(
+ level: Level.body,
+ onlyErrors: false,
+ logger: logger,
+ ),
+ ...?interceptors,
+ ],
+ );
+ }
+
+ @override
+ Future perform(HttpRequest request) async {
+ try {
+ final Response