Skip to main content
To change the settings for all requests, you can initialize the API client with a custom configuration. To configure individual requests, see Request options.
Not all API clients support all customization options.

Custom configuration

Customize the API client by creating a configuration object or by passing additional options when instantiating the client.
using Algolia.Search.Clients;

// Create custom configuration
var config = new SearchConfig(
    appId: "ALGOLIA_APPLICATION_ID",
    apiKey: "ALGOLIA_API_KEY"
);

// Customize the configuration ...

// Instantiate SearchClient with custom configuration
var client = new SearchClient(config);
import 'package:algoliasearch/algoliasearch.dart';

Future<void> main() async {
  final options = ClientOptions(
    // Customize the configuration ...
  );

  final client = SearchClient(
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_API_KEY',
    options: options,
  );
}
package main

import (
 "github.com/algolia/algoliasearch-client-go/v4/algolia/search"
 "github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
)

func main() {
 // Create custom configuration
 config := search.SearchConfiguration{
  Configuration: transport.Configuration{
   AppID:  "ALGOLIA_APPLICATION_ID",
   ApiKey: "ALGOLIA_API_KEY",
   // Customize the configuration ...
  },
 }

 // Instantiate SearchClient with custom configuration
 client, err := search.NewClientWithConfig(config)
}
package org.example;

import com.algolia.api.SearchClient;
import com.algolia.config.ClientOptions;

public class Main {
    public static void main(String[] args) {
        // Add options through method calls as shown in the other examples on this page
        var options = ClientOptions.builder().build();

        var client = new SearchClient(
            "ALGOLIA_APPLICATION_ID",
            "ALGOLIA_API_KEY",
            options
        );
    }
}
import { searchClient } from "@algolia/client-search";

const options = {
  // Customize the configuration
};

const client = searchClient(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_API_KEY",
  options,
);
package org.example

import com.algolia.client.api.SearchClient
import com.algolia.client.configuration.ClientOptions

fun main() {
    val options = ClientOptions(
        // Customize the configuration ...
    )

    val client = SearchClient(
        appId = "ALGOLIA_APPLICATION_ID",
        apiKey = "ALGOLIA_API_KEY",
        options = options
    )
}
<?php

require_once realpath(__DIR__.'/vendor/autoload.php');

use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\Configuration\SearchConfig;

// Create custom configuration
$config = SearchConfig::create(
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_API_KEY',
);

// Customize the configuration
// $config-> ...

// Instantiate SearchClient with custom configuration
$client = SearchClient::createWithConfig(config: $config);
from algoliasearch.search.client import SearchClientSync
from algoliasearch.search.config import SearchConfig

# Create custom configuration
config = SearchConfig(
    app_id="ALGOLIA_APPLICATION_ID",
    api_key="ALGOLIA_API_KEY",
)

# Customize the configuration

# Create client with custom configuration
client = SearchClientSync(config=config)
require "algolia"

app_id = "ALGOLIA_APPLICATION_ID"
api_key = "ALGOLIA_API_KEY"

client = Algolia::SearchClient.create(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_API_KEY"
)

# Get the configuration object
config = client.api_client.config

# Customize the configuration
# ...
package org.example

import algoliasearch.config.ClientOptions
import algoliasearch.api.SearchClient

// Add options through method calls as shown in the other examples on this page
val options = ClientOptions.builder().build()

@main
def main(): Unit = {
    val client = SearchClient(
        appId = "ALGOLIA_APPLICATION_ID",
        apiKey = "ALGOLIA_API_KEY",
        clientOptions = options
    )
}
@preconcurrency import Search

// Create custom configuration
let config = try SearchClientConfiguration(
    appID: "ALGOLIA_APPLICATION_ID",
    apiKey: "ALGOLIA_API_KEY",
    // Customize the configuration ...
)


// Instantiate SearchClient with custom configuration
let client = try SearchClient(configuration: config)

Adjust timeouts

The following example shows how to adjust the default timeouts for all requests.
// ...
config.ReadTimeout = TimeSpan.FromSeconds(100);
config.WriteTimeout = TimeSpan.FromSeconds(100);
config.ConnectTimeout = TimeSpan.FromSeconds(100);
// ...
// ...
final options = ClientOptions(
  readTimeout = Duration(seconds: 100),
  writeTimeout = Duration(seconds: 100),
  connectTimeout = Duration(seconds: 100),
);
// ...
// ...
config := search.SearchConfiguration{
 Configuration: transport.Configuration{
  // ...
  ReadTimeout:    100 * time.Second,
  WriteTimeout:   100 * time.Second,
  ConnectTimeout: 100 * time.Second,
 },
}
// ...
// Additional import
import java.time.Duration`

// ...
var options = ClientOptions
    .builder()
    .setConnectTimeout(Duration.ofSeconds(100))
    .setReadTimeout(Duration.ofSeconds(100))
    .setWriteTimeout(Duration.ofSeconds(100))
    .build();
// ...
// ...
const options = {
  // Adjust timeouts
  timeouts: {
    read: 10000,
    write: 10000,
    connect: 10000,
  },
};
//
// Additional imports
import kotlin.time.DurationUnit
import kotlin.time.toDuration

// ...
val options = ClientOptions(
    connectTimeout = 100.toDuration(DurationUnit.SECONDS),
    readTimeout = 100.toDuration(DurationUnit.SECONDS),
    writeTimeout = 100.toDuration(DurationUnit.SECONDS)
)
// ...
<?php
// ...
$config->setConnectTimeout(100);
$config->setReadTimeout(100);
$config->setWriteTimeout(100);
// ...
# ...
config.connect_timeout = 100_000
config.read_timeout = 100_000
config.write_timeout = 100_000
# ...
# ...
config.read_timeout = 10_000
config.write_timeout = 10_000
config.connect_timeout = 10_000
# ...
// Additional imports
import scala.concurrent.duration.DurationInt

// ...
val options = ClientOptions
    .builder()
    // Adjust timeouts
    .withConnectTimeout(100.seconds)
    .withReadTimeout(100.seconds)
    .withWriteTimeout(100.seconds)
    .build()
// ...
// ...
let config = try SearchClientConfiguration(
    // ...
    writeTimeout: 100,
    readTimeout: 100,
)
// ...
For more information about these timeouts, see Request options.

Enable compression

Enable gzip compression to reduce the size of request bodies sent to Algolia’s servers. When enabled, POST and PUT request bodies that exceed a minimum size are compressed before sending.
namespace Algolia;

using System;
using Algolia.Search.Clients;
using Algolia.Search.Http;
using Algolia.Search.Models.Common;
using Algolia.Search.Models.Search;

class Compression
{
  async Task Main(string[] args)
  {
    // Initialize the client with gzip compression enabled
    // Compression reduces the size of request bodies sent to Algolia
    var client = new SearchClient(
      new SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
      {
        Compression = CompressionType.Gzip,
      }
    );

    // Search with compressed request body
    try
    {
      var result = await client.SearchSingleIndexAsync<Hit>(
        "INDEX_NAME",
        new SearchParams(new SearchParamsObject { Query = "comedy" })
      );
      Console.WriteLine(result);
    }
    catch (Exception e)
    {
      Console.WriteLine(e.Message);
    }
  }
}

import 'package:algolia_client_search/algolia_client_search.dart';

void compression() async {
  // Initialize the client with gzip compression enabled
  // Compression reduces the size of request bodies sent to Algolia
  final client = SearchClient(
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_API_KEY',
    options: ClientOptions(compression: 'gzip'),
  );

  try {
    // Search with compressed request body
    final result = await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchParamsObject(
        query: "comedy",
      ),
    );
    print(result);
  } catch (e) {
    print("Error: ${e.toString()}");
  }
}

package main

import (
	"fmt"

	"github.com/algolia/algoliasearch-client-go/v4/algolia/compression"
	"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
	"github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
)

func enableCompression() {
	// Initialize the client with gzip compression enabled
	// Compression reduces the size of request bodies sent to Algolia
	cfg := search.SearchConfiguration{
		Configuration: transport.Configuration{
			AppID:       "ALGOLIA_APPLICATION_ID",
			ApiKey:      "ALGOLIA_API_KEY", // #nosec G101 -- credentials are placeholders
			Compression: compression.GZIP,
		},
	}

	client, err := search.NewClientWithConfig(cfg)
	if err != nil {
		panic(err)
	}

	// Search with compressed request body
	result, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
		"INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
		search.NewEmptySearchParamsObject().SetQuery("comedy"))))
	if err != nil {
		panic(err)
	}

	_ = result

	fmt.Println("Search with compression completed successfully")
}

package com.algolia;

import com.algolia.api.SearchClient;
import com.algolia.config.*;
import com.algolia.model.search.*;

public class compression {

  public static void main(String[] args) throws Exception {
    // Initialize the client with gzip compression enabled
    // Compression reduces the size of request bodies sent to Algolia
    SearchClient client = new SearchClient(
      "ALGOLIA_APPLICATION_ID",
      "ALGOLIA_API_KEY",
      ClientOptions.builder().setCompressionType(CompressionType.GZIP).build()
    );

    // Search with compressed request body
    var result = client.searchSingleIndex("INDEX_NAME", new SearchParamsObject().setQuery("comedy"), Hit.class);
    System.out.println(result.getHits());
    client.close();
  }
}

import { algoliasearch } from 'algoliasearch';

// Initialize the client with gzip compression enabled
// Compression reduces the size of request bodies sent to Algolia
const client = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY', {
  compression: 'gzip',
});

// Search with compressed request body
const searchCompression = async () => {
  const result = await client.searchSingleIndex({ indexName: 'movies_index', searchParams: { query: 'comedy' } });
  console.log(result.hits);
};

searchCompression()
  .then(() => console.log('Done!'))
  .catch((err) => console.error(err));

package org.example

import com.algolia.client.api.SearchClient
import com.algolia.client.configuration.*
import com.algolia.client.extensions.*
import com.algolia.client.model.search.*
import com.algolia.client.transport.*

suspend fun main() {
  // Initialize the client with gzip compression enabled
  // Compression reduces the size of request bodies sent to Algolia
  val client =
    SearchClient(
      appId = "ALGOLIA_APPLICATION_ID",
      apiKey = "ALGOLIA_API_KEY",
      options = ClientOptions(compressionType = CompressionType.GZIP),
    )

  // Search with compressed request body
  try {
    val result =
      client.searchSingleIndex(
        indexName = "INDEX_NAME",
        searchParams = SearchParamsObject(query = "comedy"),
      )
    println(result.hits)
  } catch (e: Exception) {
    println(e.message)
  }
}

<?php

require __DIR__.'/../vendor/autoload.php';
use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\Configuration\SearchConfig;

// Initialize the client with gzip compression enabled
// Compression reduces the size of request bodies sent to Algolia
$config = SearchConfig::create('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY')
    ->setCompressionType('gzip')
;
$client = SearchClient::createWithConfig($config);

// Search with compressed request body
$result = $client->searchSingleIndex(
    'INDEX_NAME',
    ['query' => 'comedy',
    ],
);
var_dump($result);

from algoliasearch.search.config import SearchConfig
from algoliasearch.search.client import SearchClientSync


# Initialize the client with gzip compression enabled
# Compression reduces the size of request bodies sent to Algolia
_config = SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
_config.compression_type = "gzip"
_client = SearchClientSync.create_with_config(config=_config)

# Search with compressed request body
_client.search_single_index(
    index_name="INDEX_NAME",
    search_params={
        "query": "comedy",
    },
)

require "algolia"

# Initialize the client with gzip compression enabled
# Compression reduces the size of request bodies sent to Algolia
client = Algolia::SearchClient.create(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_API_KEY",
  compression_type: "gzip"
)

# Search with compressed request body
result = client.search_single_index("INDEX_NAME", Algolia::Search::SearchParamsObject.new(query: "comedy"))
puts(result)

import algoliasearch.api.SearchClient
import algoliasearch.config.*
import algoliasearch.extension.SearchClientExtensions

import algoliasearch.search.SearchParamsObject
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContextExecutor}

object Compression {
  def main(args: Array[String]): Unit = {
    implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global

    // Initialize the client with gzip compression enabled
    // Compression reduces the size of request bodies sent to Algolia
    val client = SearchClient(
      appId = "ALGOLIA_APPLICATION_ID",
      apiKey = "ALGOLIA_API_KEY",
      clientOptions = ClientOptions
        .builder()
        .withCompressionType(CompressionType.Gzip)
        .build()
    )

    // Search with compressed request body
    try {
      val result = Await.result(
        client.searchSingleIndex(
          indexName = "INDEX_NAME",
          searchParams = Some(
            SearchParamsObject(
              query = Some("comedy")
            )
          )
        ),
        Duration(100, "sec")
      )
      println(result)
    } catch {
      case e: Exception => println(e)
    }
  }
}

import AlgoliaCore
import AlgoliaSearch
import Foundation

func compression() async throws {
    // Initialize the client with gzip compression enabled
    // Compression reduces the size of request bodies sent to Algolia
    let configuration = try SearchClientConfiguration(
        appID: "ALGOLIA_APPLICATION_ID",
        apiKey: "ALGOLIA_API_KEY",
        compression: .gzip
    )
    let client = SearchClient(configuration: configuration)

    do {
        // Search with compressed request body
        let response: SearchResponse<Hit> = try await client.searchSingleIndex(
            indexName: "INDEX_NAME",
            searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(query: "comedy"))
        )
        print(response)
    } catch {
        print(error.localizedDescription)
    }
}

The JavaScript client only supports compression in Node.js builds. Browser and worker builds don’t support compression.The Kotlin client supports compression on JVM only.

Customize user agent information

The following example shows how to add a custom user agent string to the default.
// ...
config.UserAgent.AddSegment("custom c# client", "optional version");
// ...
// ...
final options = ClientOptions(
  agentSegments: [
    AgentSegment(value: 'custom dart client', version: 'optional version'),
  ],
);
// ...
// ...
config := search.SearchConfiguration{
    Configuration: transport.Configuration{
        // ...
        // Completely replace the user agent string
        UserAgent:  "custom go client (optional version)"
    },
}
// ...

// You can get the user agent string from an instance of an API client
defaultUserAgent := client.GetConfiguration().Configuration.UserAgent
// ...
var options = ClientOptions
                .builder()
                .addAlgoliaAgentSegment("custom java client", "optional version")
                .build();
// ...
// ...
client.addAlgoliaAgent("custom javascript client", "optional version");
// ...
// ...
<?php
// Additional import
use Algolia\AlgoliaSearch\Support\AlgoliaAgent;

// ...
AlgoliaAgent::addAlgoliaAgent(
    clientName: $client->getClientConfig()->getClientName(),
    segment: 'custom php client',
    version: 'optional version'
);
// ...
# ...
client.add_user_agent_segment("custom ruby client", "optional version")
# ...
// Additional import
import algoliasearch.config.AgentSegment

// ...
val options = ClientOptions
    .builder()
    .withAgentSegments(Seq(AgentSegment("custom scala client"), AgentSegment("optional version")))
    .build();
// ...

Add default headers

The following example shows how to add a custom header to all API requests.
// ...
config.DefaultHeaders.Add("extra-header", "greetings");
// ...
// ...
final options = ClientOptions(
    headers: <String, dynamic>{
      'extra-header': 'greetings',
    },
  );
);
// ...
// ...
config := search.SearchConfiguration{
 Configuration: transport.Configuration{
  // ...
  DefaultHeaders: map[string]string{
   "extra-header": "greetings",
  },
 },
}
// ...
// ...
var options = ClientOptions
    .builder()
    .addDefaultHeader("extra-header", "greetings")
    .build();
// ...
// ...
const options = {
  baseHeaders: {
    // Due to CORS restrictions, you can't use arbitrary headers in browsers
    "extra-header": "greetings",
  },
  // Also works with query parameters
  baseQueryParameters: {
    queryParam: "value",
  },
};
// ...
// ...
const options = ClientOptions(
    defaultHeaders = mapOf("extra-header" to "greetings")
)
// ...
<?php
// ...
$config->setDefaultHeaders(['extra-header' => 'greetings']);
// ...
# ...
config.headers["extra-header"] = "greetings"
# ...
# ...
config.header_params[:"extra-header" => "greetings"]
# ...
// ...
var options = ClientOptions
    .builder()
    .withDefaultHeaders(Map("extra-header" -> "greetings"))
    .build();
// ...
// ...
let config = try SearchClientConfiguration(
    // ...
    defaultHeaders: ["extra-header": "greetings"]
)
// ...
If you use the JavaScript API client in a browser — including when you use InstantSearch or Autocomplete, which rely on the API client — you can’t send arbitrary HTTP headers.Browsers enforce cross-origin resource sharing (CORS) rules. During the OPTIONS preflight request, the API explicitly lists which headers it accepts in the access-control-allow-headers response header. Any header not listed there is blocked by the browser.To see which headers are allowed, check the access-control-allow-headers value in the preflight response in your browser’s developer tools.

Logging

You can set a custom logger to enable more or less logging output.
using Algolia.Search.Clients;
// Install with `dotnet add package Microsoft.Extensions.Logging.Console`
using Microsoft.Extensions.Logging;

var loggerFactory = LoggerFactory.Create(builder =>
{
    // Log everything from Algolia in the console, including debug logs
    builder.AddFilter("Algolia", LogLevel.Debug).AddConsole();
});

var client = new SearchClient(
    "ALGOLIA_APPLICATION_ID",
    "ALGOLIA_API_KEY",
    loggerFactory,
);
// ...
final options = ClientOptions(logger: print);
// ...
// Additional import
import com.algolia.config.LogLevel;

// ...
var options = ClientOptions
    .builder()
    // Print everything to stdout
    .setLogger(message -> System.out.println(message))
    // Adjust the log level (print all request headers)
    .setLogLevel(LogLevel.HEADERS)
    .build();
// ...
// Additional imports
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.LogLevel

// ...
val options = ClientOptions(
    // Adjust the log level
    logLevel = LogLevel.ALL,
    // Print everything to stdout
    logger = object : Logger {
        override fun log(message: String) {
            println(message)
        }
    },
)
// ...
<?php

// ...
$config->setDebug(true);
$config->setDebugFile('path/to/logfile');
// ...
// Additional imports
import algoliasearch.config.{ClientOptions, Logging}

// ...
var options = ClientOptions
    .builder()
    .withLogging(Logging.Full)
    .build()
// ...
// ...
let config = try SearchClientConfiguration(
    // ...
    logLevel: .debug
)
// ...

Custom hosts

The following example shows how to add your own servers.
// ...
const options = {
  hosts: [
    {
      // URL of your server without scheme
      url: "YOUR_SERVER_URL",
      // Whether this server can be used for read, write, or both requests
      accept: "readWrite", // read | write | readWrite
      // https or http
      protocol: "https",
      // Optional, if deviating from the default port
      // port: "PORT"
    },
  ],
};
// ...
// Additional imports
import algolia.config.CallType;
import algolia.config.Host;

// ...
val options = ClientOptions(
    hosts = listOf(
        Host(
            url = "YOUR_SERVER_URL",
            callType = CallType.Read
        ),
        // Add the same server again
        // if you want to use it for both read and write requests
        Host(
            url = "YOUR_SERVER_URL",
            callType = CallType.Write
        )
    )
)
// ...
# Additional import
from algoliasearch.http.hosts import Host, HostsCollection

# ...
config.hosts = HostsCollection(
    hosts=[
        Host(
            # URL without scheme
            url="YOUR_SERVER_URL",
            # Whether to use for read, write, or both requests
            accept=CallType.Read | CallType.Write,
            # scheme: "https" # or "http",
            # port: PORT # if deviating from the default
            # priority: NUMBER # sort priority of this host
        ),
    ],
    # Sort hosts by `priority`
    # reorder_hosts=True
)
# ...
require "algolia"

hosts = [
  Algolia::Transport::StatefulHost.new("YOUR_SERVER_URL")
]

config = Algolia::Configuration.new(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_API_KEY",
  hosts
)

client = Algolia::SearchClient.create_with_config(config)
// Additional imports
import algoliasearch.config.{CallType, ClientOptions, Host}

// ...
val customHosts = Seq(Host("YOUR_SERVER_URL", Set(CallType.Read, CallType.Write)))

var options = ClientOptions
    .builder()
    .withHosts(customHosts)
    .build()
// Additional imports
import Core
import Foundation

// ...
let config = try SearchClientConfiguration(
    // ...
    hosts: [.init(url: URL(string: "YOUR_SERVER_URL"))]
}

// ...

Custom HTTP clients

The following example shows how to use a custom HTTP client to make requests.
using Algolia.Search.Clients;

var config = new SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");

// CustomRequester must implement `IHTTPRequester`
var client = new SearchClient(config, new CustomRequester());
// ...
final Options = ClientOptions(requester: CustomRequester());
// ...
// ...
type CustomRequester struct {
  client *http.Client
}

func NewCustomRequester() *CustomRequester {
  return &CustomRequester{
    client: http.DefaultClient,
  }
}

func (r *CustomRequester) Request(req *http.Request, _ time.Duration, _ time.Duration) (*http.Response, error) {
  // This gets printed to stdout before the request
  fmt.Printf("CustomRequester > Request: %s\n", req.URL.String())

  return r.client.Do(req)
}

config := search.SearchConfiguration{
    transport.Configuration{
        // ...
        Requester: NewCustomRequester(),
    },
}
// ...
var options = ClientOptions
    .builder()
    // CustomRequester must implement `com.algolia.utils.Requester`
    .setRequester(new CustomRequester())
    .build()
import { echoRequester } from "@algolia/requester-node-http";
// ...
const options = {
  // The first parameter is the status to return
  requester: echoRequester(200),
};
// ...
// ...
val options = ClientOptions(
    requester = CustomRequester()
)
// ...
<?php

require_once realpath(__DIR__.'/vendor/autoload.php');

use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\Configuration\SearchConfig;
use Algolia\AlgoliaSearch\Http\CurlHttpClient;
use Algolia\AlgoliaSearch\RetryStrategy\ApiWrapper;
use Algolia\AlgoliaSearch\RetryStrategy\ClusterHosts;

// Create a custom config
$config = SearchConfig::create(
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_API_KEY',
);

// Get the servers for your Algolia cluster
$clusterHosts = ClusterHosts::createFromAppId(applicationId: $appID);

// Create a new HTTP client (implements `HttpClientInterface`)
$customHttpClient = new CurlHttpClient();

$apiWrapper = new ApiWrapper(
    http: $customHttpClient,
    config: $config,
    clusterHosts: $clusterHosts,
);

// Create a custom Search API client
$client = new SearchClient(apiWrapper: $apiWrapper, config: $config);
$client = new SearchClient(config: $config);

Transformation options and the ingestion transporter

To use the WithTransformation helper methods, set transformationOptions on the search client. This creates a dedicated ingestion transporter that handles requests to the transformation pipeline. The ingestion transporter starts from the Ingestion API defaults: 25-second connect, read, and write timeouts, hosts derived from your region, and no compression. It only overrides those defaults with the options you explicitly set in transformationOptions. The transporter doesn’t inherit the configuration of the parent search client. Custom hosts, timeouts, headers, or compression set on the search client don’t apply to transformation requests. To customize the transformation requests, set the corresponding option on transformationOptions instead.
region is required in transformationOptions. The client throws an error if you call a WithTransformation helper method without it.
You can override the following options on transformationOptions, depending on the language: region (required), custom hosts, connect, read, and write timeouts, default headers, and compression. Any option you don’t set keeps its Ingestion API default. For example, to keep the region-derived hosts but raise the timeouts:
namespace Algolia;

using System;
using Algolia.Search.Clients;
using Algolia.Search.Http;
using Algolia.Search.Models.Search;

class SetUpTransformationOptionsWithOverrides
{
  async Task Main(string[] args)
  {
    // Override the Ingestion API defaults. Any option you don't set keeps its default.
    // Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
    var transformationOptions = new TransformationOptions("us")
    {
      ConnectTimeout = TimeSpan.FromMilliseconds(5000),
      ReadTimeout = TimeSpan.FromMilliseconds(30000),
    };
    var client = SearchClient.WithTransformation(
      "ALGOLIA_APPLICATION_ID",
      "ALGOLIA_API_KEY",
      transformationOptions
    );

    // Save records, transforming them through the Push connector
    try
    {
      var result = await client.SaveObjectsWithTransformationAsync(
        "INDEX_NAME",
        new List<Object>
        {
          new Dictionary<string, string> { { "objectID", "1" }, { "name", "Adam" } },
          new Dictionary<string, string> { { "objectID", "2" }, { "name", "Benoit" } },
        },
        true
      );
    }
    catch (Exception e)
    {
      Console.WriteLine(e.Message);
    }
  }
}

import 'package:algolia_client_search/algolia_client_search.dart';

void main() async {
  // Override the Ingestion API defaults. Any option you don't set keeps its default.
  // Replace 'us' with 'eu' if your Algolia application uses the Europe analytics region.
  final client = SearchClient(
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_API_KEY',
    transformationOptions: TransformationOptions(
      region: 'us',
      ingestionClientOptions: ClientOptions(
        connectTimeout: Duration(seconds: 5),
        readTimeout: Duration(seconds: 30),
      ),
    ),
  );

  try {
    // Save records, transforming them through the Push connector
    await client.saveObjectsWithTransformation(
      indexName: "INDEX_NAME",
      objects: [
        {
          'objectID': "1",
          'name': "Adam",
        },
        {
          'objectID': "2",
          'name': "Benoit",
        },
      ],
      waitForTasks: true,
    );
    print('Done!');
  } catch (e) {
    print('Error: ${e.toString()}');
  }
}

package main

import (
	"fmt"
	"time"

	"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
)

func setUpTransformationOptionsWithOverrides() {
	// Override the Ingestion API defaults. Any option you don't set keeps its default.
	// Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
	client, err := search.NewClient(
		"ALGOLIA_APPLICATION_ID",
		"ALGOLIA_API_KEY",
		search.WithTransformationOptions(search.TransformationOptions{
			Region:         "us",
			ConnectTimeout: 5 * time.Second,
			ReadTimeout:    30 * time.Second,
		}),
	)
	if err != nil {
		// The client can fail to initialize if you pass an invalid parameter.
		panic(err)
	}

	// Save records, transforming them through the Push connector
	result, err := client.SaveObjectsWithTransformation(
		"INDEX_NAME",
		[]map[string]any{{"objectID": "1", "name": "Adam"}, {"objectID": "2", "name": "Benoit"}}, search.WithWaitForTasks(true))
	if err != nil {
		panic(err)
	}

	fmt.Printf("Done! Uploaded records in %d batches.", len(result))
}

package com.algolia;

import com.algolia.api.SearchClient;
import com.algolia.config.*;
import com.algolia.model.search.*;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;

public class setUpTransformationOptionsWithOverrides {

  public static void main(String[] args) throws Exception {
    // Override the Ingestion API defaults. Any option you don't set keeps its default.
    // Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
    ClientOptions ingestionOptions = ClientOptions.builder()
      .setConnectTimeout(Duration.ofSeconds(5))
      .setReadTimeout(Duration.ofSeconds(30))
      .build();
    SearchClient client = SearchClient.withTransformation(
      "ALGOLIA_APPLICATION_ID",
      "ALGOLIA_API_KEY",
      new TransformationOptions("us", ingestionOptions)
    );

    // Save records, transforming them through the Push connector
    client.saveObjectsWithTransformation(
      "INDEX_NAME",
      Arrays.asList(
        new HashMap() {
          {
            put("objectID", "1");
            put("name", "Adam");
          }
        },
        new HashMap() {
          {
            put("objectID", "2");
            put("name", "Benoit");
          }
        }
      ),
      true
    );
    client.close();
  }
}

import { algoliasearch } from 'algoliasearch';

// Override the Ingestion API defaults. Any option you don't set keeps its default.
// Replace 'us' with 'eu' if your Algolia application uses the Europe analytics region.
const client = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY', {
  transformationOptions: {
    region: 'us',
    timeouts: { connect: 5000, read: 30000, write: 30000 },
  },
});

async function run() {
  // Save records, transforming them through the Push connector
  const response = await client.saveObjectsWithTransformation({
    indexName: 'INDEX_NAME',
    objects: [
      { objectID: '1', name: 'Adam' },
      { objectID: '2', name: 'Benoit' },
    ],
    waitForTasks: true,
  });
  console.log(response);
}

run().catch((err) => console.error(err));

package org.example

import com.algolia.client.api.SearchClient
import com.algolia.client.configuration.*
import com.algolia.client.extensions.*
import com.algolia.client.transport.*
import kotlin.time.Duration.Companion.seconds
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonObject

suspend fun main() {
  // Override the Ingestion API defaults. Any option you don't set keeps its default.
  // Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
  val client =
    SearchClient.withTransformation(
      appId = "ALGOLIA_APPLICATION_ID",
      apiKey = "ALGOLIA_API_KEY",
      transformationOptions =
        TransformationOptions(
          region = "us",
          clientOptions = ClientOptions(connectTimeout = 5.seconds, readTimeout = 30.seconds),
        ),
    )

  try {
    // Save records, transforming them through the Push connector
    client.saveObjectsWithTransformation(
      indexName = "INDEX_NAME",
      objects =
        listOf(
          buildJsonObject {
            put("objectID", JsonPrimitive("1"))
            put("name", JsonPrimitive("Adam"))
          },
          buildJsonObject {
            put("objectID", JsonPrimitive("2"))
            put("name", JsonPrimitive("Benoit"))
          },
        ),
      waitForTasks = true,
    )
  } catch (e: Exception) {
    println(e.message)
  }
}

<?php

require __DIR__.'/../vendor/autoload.php';
use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\Configuration\SearchConfig;
use Algolia\AlgoliaSearch\Configuration\TransformationOptions;

// Override the Ingestion API defaults. Any option you don't set keeps its default.
// Replace 'us' with 'eu' if your Algolia application uses the Europe analytics region.
$config = SearchConfig::create('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');
$config->setTransformationOptions(
    (new TransformationOptions('us'))
        ->setConnectTimeout(5)
        ->setReadTimeout(30)
);
$client = SearchClient::createWithConfig($config);

// Save records, transforming them through the Push connector
$client->saveObjectsWithTransformation(
    'INDEX_NAME',
    [
        ['objectID' => '1',
            'name' => 'Adam',
        ],

        ['objectID' => '2',
            'name' => 'Benoit',
        ],
    ],
    true,
);

echo 'Done!';

from algoliasearch.search.client import SearchClientSync

from algoliasearch.search.config import SearchConfig, TransformationOptions


# Override the Ingestion API defaults. Any option you don't set keeps its default.
# Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
_config = SearchConfig(
    "ALGOLIA_APPLICATION_ID",
    "ALGOLIA_API_KEY",
    transformation_options=TransformationOptions(
        region="us",
        connect_timeout=5000,
        read_timeout=30000,
    ),
)
_client = SearchClientSync.create_with_config(_config)

# Save records, transforming them through the Push connector
_client.save_objects_with_transformation(
    index_name="INDEX_NAME",
    objects=[
        {
            "objectID": "1",
            "name": "Adam",
        },
        {
            "objectID": "2",
            "name": "Benoit",
        },
    ],
    wait_for_tasks=True,
)

require "algolia"

# Override the Ingestion API defaults. Any option you don't set keeps its default.
# Replace 'us' with 'eu' if your Algolia application uses the Europe analytics region.
client = Algolia::SearchClient.with_transformation(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_API_KEY",
  Algolia::TransformationOptions.new("us", connect_timeout: 5000, read_timeout: 30000)
)

# Save records, transforming them through the Push connector
client.save_objects_with_transformation(
  "INDEX_NAME",
  [{objectID: "1", name: "Adam"}, {objectID: "2", name: "Benoit"}],
  true
)

puts("Done!")

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContextExecutor}

import algoliasearch.api.SearchClient
import algoliasearch.config.*
import algoliasearch.extension.SearchClientExtensions
import org.json4s.*

object SetUpTransformationOptionsWithOverrides {
  def main(args: Array[String]): Unit = {
    implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global

    // Override the Ingestion API defaults. Any option you don't set keeps its default.
    // Replace "us" with "eu" if your Algolia application uses the Europe analytics region.
    val ingestionOptions = ClientOptions
      .builder()
      .withConnectTimeout(Duration(5, "sec"))
      .withReadTimeout(Duration(30, "sec"))
      .build()
    val client = SearchClient.withTransformation(
      appId = "ALGOLIA_APPLICATION_ID",
      apiKey = "ALGOLIA_API_KEY",
      transformationOptions = TransformationOptions(region = "us", clientOptions = Some(ingestionOptions))
    )

    // Save records, transforming them through the Push connector
    try {
      Await.result(
        client.saveObjectsWithTransformation(
          indexName = "INDEX_NAME",
          objects = Seq(
            JObject(List(JField("objectID", JString("1")), JField("name", JString("Adam")))),
            JObject(List(JField("objectID", JString("2")), JField("name", JString("Benoit"))))
          ),
          waitForTasks = true
        ),
        Duration(100, "sec")
      )
    } catch {
      case e: Exception => println(e)
    }
  }
}

import Foundation
#if os(Linux) // For linux interop
    import FoundationNetworking
#endif

import AlgoliaCore
import AlgoliaSearch

func setUpTransformationOptionsWithOverrides() async throws {
    // Override the Ingestion API defaults. Any option you don't set keeps its default.
    // Replace `.us` with `.eu` if your Algolia application uses the Europe analytics region.
    let configuration = try SearchClientConfiguration(
        appID: "ALGOLIA_APPLICATION_ID",
        apiKey: "ALGOLIA_API_KEY",
        transformationOptions: TransformationOptions(
            region: .us,
            readTimeout: 30,
            writeTimeout: 30
        )
    )
    let client = SearchClient(configuration: configuration)

    do {
        // Save records, transforming them through the Push connector
        try await client.saveObjectsWithTransformation(
            indexName: "INDEX_NAME",
            objects: [["objectID": "1", "name": "Adam"], ["objectID": "2", "name": "Benoit"]],
            waitForTasks: true
        )
    } catch {
        print(error.localizedDescription)
    }
}

DNS caching (Java)

By default, the JVM caches DNS resolutions infinitely. Since Algolia uses multiple IP addresses for load balancing, you should reduce the time to live (TTL) of the cache. For example, set the TTL of the cache to 60 seconds:
Java
java.security.Security.setProperty("networkaddress.cache.ttl", "60");
Last modified on June 11, 2026