Skip to main content
The latest major version of the algoliasearch-scala package is version 2. This page helps you upgrade from version 1 and explains the breaking changes you need to address. Algolia generates the version 2 client from OpenAPI specifications, which provides consistent behavior across all languages and up-to-date API coverage. The main architectural change is the removal of the domain-specific language (DSL). Instead of writing expressions like client.execute { search into "index" query "q" } (version 1), you call methods directly on the SearchClient instance, passing named parameters. For the full list of changes, see the Scala changelog.

Update your dependencies

Update the algoliasearch-scala package to version 2. With sbt, update the version range in your build.sbt file:
build.sbt
// version 1
libraryDependencies += "com.algolia" %% "algoliasearch-scala" % "[1,)"

// version 2
libraryDependencies += "com.algolia" %% "algoliasearch-client-scala" % "[2,)"
With Maven, update the version in your pom.xml file:
pom.xml
<!-- version 1 -->
<dependency>
    <groupId>com.algolia</groupId>
    <artifactId>algoliasearch-scala_2.13</artifactId>
    <version>[1,)</version>
</dependency>

<!-- version 2 -->
<dependency>
    <groupId>com.algolia</groupId>
    <artifactId>algoliasearch-client-scala_2.13</artifactId>
    <version>[2,)</version>
</dependency>
The version 2 client is cross-published for Scala 2.13 and Scala 3. sbt resolves the correct artifact automatically based on your scalaVersion. If you use Maven, replace _2.13 with _3 in the artifactId for Scala 3 projects.

Update imports

The package namespace changed from algolia to algoliasearch. Version 2 also includes dedicated imports for each API.
Scala
// version 1
import algolia.AlgoliaClient
import algolia.AlgoliaDsl._
import algolia.objects.Query

// version 2
import algoliasearch.api.SearchClient
Version 2 includes separate client classes for each API. If you only need a specific API, import the corresponding client:
Scala
// Search API
import algoliasearch.api.SearchClient
// Recommend API
import algoliasearch.api.RecommendClient
// A/B testing API
import algoliasearch.api.AbtestingClient
// Analytics API
import algoliasearch.api.AnalyticsClient
// Ingestion API
import algoliasearch.api.IngestionClient
// Insights API
import algoliasearch.api.InsightsClient
// Monitoring API
import algoliasearch.api.MonitoringClient
// Personalization API
import algoliasearch.api.PersonalizationClient
// Query Suggestions API
import algoliasearch.api.QuerySuggestionsClient
// Usage API
import algoliasearch.api.UsageClient

Update client initialization

The client class was renamed from AlgoliaClient to SearchClient, and you no longer use the new keyword.
Scala
// version 1
val client = new AlgoliaClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")

// version 2
val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")
Unlike other language clients, version 1 of the Scala client didn’t have a separate initIndex step. The DSL handled index references inline, embedding the index name into expressions like search into "index". In version 2, you pass indexName as a named parameter to every method. There’s no index object and no DSL expression.

Remove the domain-specific language

This is the most significant change when upgrading the Scala client. Version 1 provided a domain-specific language (DSL) through algolia.AlgoliaDsl._ that let you write expressive, English-like code inside client.execute { ... } blocks. Version 2 removes the DSL entirely. Every client.execute { ... } call must be replaced with a direct method call on the client. Here are the most common DSL patterns and their replacements:
Scala
// version 1
val future: Future[Search] =
    client.execute {
        search into "ALGOLIA_INDEX_NAME" query Query(query = Some("QUERY"))
    }

// version 2
val response: Future[SearchResponse] =
  client.searchSingleIndex(
    indexName = "ALGOLIA_INDEX_NAME",
    searchParams = Some(
      SearchParamsObject(query = Some("QUERY"))
    )
  )

Index an object

Scala
// version 1
client.execute {
    index into "ALGOLIA_INDEX_NAME" `object` Contact("Jimmie", "Barninger", 93, "California Paint")
}

// version 2
val response: Future[SaveObjectResponse] =
  client.saveObject(
    indexName = "ALGOLIA_INDEX_NAME",
    body = JObject(
      List(
        JField("name", JString("Jimmie")),
        JField("company", JString("California Paint")),
        JField("objectID", JString("1"))
      )
    )
  )

Parse results

Scala
// version 1 (case class deserialization via json4s)
val future: Future[Seq[Contact]] =
    client
        .execute { search into "index" query "a" }
        .map { search => search.as[Contact] }

// version 2
// The response contains raw JSON. Parse with json4s or your preferred library.
val response: Future[SearchResponse] =
  client.searchSingleIndex(
    indexName = "ALGOLIA_INDEX_NAME",
    searchParams = Some(
      SearchParamsObject(query = Some("a"))
    )
  )
Search your codebase for client.execute, AlgoliaDsl, and import algolia. to find every place that needs changing.

Update search calls

Search a single index

The DSL search into expression is now client.searchSingleIndex(). Pass the index name and search parameters as named arguments:
Scala
// version 1
val results = client.execute {
    search into "ALGOLIA_INDEX_NAME" query Query(
      query = Some("QUERY"),
      facetFilters = Some(Seq("category:Book"))
    )
}

// version 2
val results: Future[SearchResponse] =
  client.searchSingleIndex(
    indexName = "ALGOLIA_INDEX_NAME",
    searchParams = Some(
      SearchParamsObject(
        query = Some("QUERY"),
        facetFilters = Some(Seq(MixedSearchFilters(Seq("category:Book"))))
      )
    )
  )

Search multiple indices

The multiQueries DSL is now client.search(). Each request in the list requires an indexName:
Scala
// version 1
val results = client.execute {
    multiQueries(
      Seq(search into "INDEX_1" query "QUERY", search into "INDEX_2" query "QUERY")
    )
}

// version 2
val results: Future[SearchResponses] =
  client.search(
    searchMethodParams = SearchMethodParams(
      requests = Seq(
        SearchForHits(indexName = "INDEX_1", query = Some("QUERY")),
        SearchForHits(indexName = "INDEX_2", query = Some("QUERY"))
      )
    )
  )

Search for facet values

The search facet DSL is now on the client and requires indexName and facetName parameters:
Scala
// version 1
client.execute { search facet "category" into "ALGOLIA_INDEX_NAME" query "book" }

// version 2
val results: Future[SearchForFacetValuesResponse] =
  client.searchForFacetValues(
    indexName = "ALGOLIA_INDEX_NAME",
    facetName = "category",
    searchForFacetValuesRequest = Some(
      SearchForFacetValuesRequest(facetQuery = Some("book"))
    )
  )

Update indexing operations

In version 2, indexing methods are direct client method calls with indexName as a parameter.

Add or replace records

Scala
// version 1
client.execute {
    index into "ALGOLIA_INDEX_NAME" `object` Record("Record", "1")
}
client.execute {
    index into "ALGOLIA_INDEX_NAME" objects Seq(Record("Record", "1"))
}

// version 2 (single record)
val result: Future[SaveObjectResponse] =
  client.saveObject(
    indexName = "ALGOLIA_INDEX_NAME",
    body = JObject(List(JField("objectID", JString("1")), JField("name", JString("Record"))))
  )
// version 2 (batch)
val result: Future[Seq[BatchResponse]] =
  client.saveObjects(
    indexName = "ALGOLIA_INDEX_NAME",
    objects = Seq(
      JObject(List(JField("objectID", JString("1")), JField("name", JString("Record"))))
    )
  )

Partially update records

Scala
// version 1
client.execute { partialUpdate from "ALGOLIA_INDEX_NAME" `object` ("1", JObject()) }

// version 2
val result: Future[UpdatedAtWithObjectIDResponse] =
  client.partialUpdateObject(
    indexName = "ALGOLIA_INDEX_NAME",
    objectID = "1",
    attributesToUpdate = JObject(List(JField("name", JString("Updated"))))
  )

Delete records

Scala
// version 1
client.execute { delete from "ALGOLIA_INDEX_NAME" objectId "1" }

// version 2
val result: Future[DeletedAtResponse] =
  client.deleteObject(
    indexName = "ALGOLIA_INDEX_NAME",
    objectID = "1"
  )

Update settings, synonyms, and rules

Get and set settings

Scala
// version 1
client.execute { settings of "ALGOLIA_INDEX_NAME" }
client.execute {
    setSettings of "ALGOLIA_INDEX_NAME" `with` Settings(searchableAttributes = Some(Seq("title", "author")))
}

// version 2
val settings: Future[IndexSettings] =
  client.getSettings(
    indexName = "ALGOLIA_INDEX_NAME"
  )
val updated: Future[UpdatedAtResponse] =
  client.setSettings(
    indexName = "ALGOLIA_INDEX_NAME",
    indexSettings = IndexSettings(
      searchableAttributes = Some(Seq("title", "author"))
    )
  )

Save synonyms and rules

Many synonym and rule operations weren’t available in version 1 of the Scala client. Version 2 includes full coverage of the API, including saveSynonyms, saveRules, and replaceAllObjects.
Scala
// version 2 -- save synonyms
val result: Future[UpdatedAtResponse] =
  client.saveSynonyms(
    indexName = "ALGOLIA_INDEX_NAME",
    synonymHit = Seq(
      SynonymHit(
        objectID = "1",
        `type` = SynonymType.withName("synonym"),
        synonyms = Some(Seq("car", "auto"))
      )
    ),
    replaceExistingSynonyms = Some(true)
  )
Scala
// version 2 -- save rules
val result: Future[UpdatedAtResponse] =
  client.saveRules(
    indexName = "ALGOLIA_INDEX_NAME",
    rules = Seq(
      Rule(
        objectID = "1",
        conditions = Some(Seq(
          Condition(
            pattern = Some("shoes"),
            anchoring = Some(Anchoring.withName("contains"))
          )
        )),
        consequence = Consequence(
          params = Some(ConsequenceParams(query = Some("sneakers")))
        )
      )
    ),
    clearExistingRules = Some(true)
  )
In version 1, replaceAllRules and replaceAllSynonyms weren’t available in the Scala client. In version 2, use client.saveRules() with clearExistingRules = Some(true) or client.saveSynonyms() with replaceExistingSynonyms = Some(true) to replace all rules or synonyms.

Update index management

The copy index and move index DSL commands are replaced by a single operationIndex method.

Copy an index

Scala
// version 1
client.execute { copy index "SOURCE_INDEX_NAME" to "DESTINATION_INDEX_NAME" }

// version 2
val result: Future[UpdatedAtResponse] =
  client.operationIndex(
    indexName = "SOURCE_INDEX_NAME",
    operationIndexParams = OperationIndexParams(
      operation = OperationType.withName("copy"),
      destination = "DESTINATION_INDEX_NAME"
    )
  )

Move (rename) an index

Scala
// version 1
client.execute { move index "SOURCE_INDEX_NAME" to "DESTINATION_INDEX_NAME" }

// version 2
val result: Future[UpdatedAtResponse] =
  client.operationIndex(
    indexName = "SOURCE_INDEX_NAME",
    operationIndexParams = OperationIndexParams(
      operation = OperationType.withName("move"),
      destination = "DESTINATION_INDEX_NAME"
    )
  )

Copy only rules or settings

In version 2, use the scope parameter to limit the operation to specific data:
Scala
// version 2 -- copy only rules and settings from one index to another
val result: Future[UpdatedAtResponse] =
  client.operationIndex(
    indexName = "SOURCE_INDEX_NAME",
    operationIndexParams = OperationIndexParams(
      operation = OperationType.withName("copy"),
      destination = "DESTINATION_INDEX_NAME",
      scope = Some(Seq(ScopeType.withName("rules"), ScopeType.withName("settings")))
    )
  )

Update task handling

Version 1 relied on calling .wait() on Future results or Await.ready. Version 2 replaces this pattern with dedicated wait helpers. Since all methods return Future[...], you can chain waitForTask with a flatMap:
Scala
// version 1
val indexing = client.execute {
    index into "ALGOLIA_INDEX_NAME" `object` Record("test", "1")
}
Await.ready(indexing, Duration.Inf)

// version 2
val result: Future[SaveObjectResponse] =
  client.saveObject(
    indexName = "ALGOLIA_INDEX_NAME",
    body = JObject(List(JField("objectID", JString("1")), JField("name", JString("test"))))
  )
val waited: Future[GetTaskResponse] =
  result.flatMap { r =>
    client.waitForTask(
      indexName = "ALGOLIA_INDEX_NAME",
      taskID = r.taskID
    )
  }
Version 2 includes three wait helpers:

Method changes reference

The following tables list all method names that changed between version 1 and version 2.

Search API client

Version 1 (legacy)Version 2 (current)
add keyclient.addApiKey
clear dictionaryclient.batchDictionaryEntries
copy indexclient.operationIndex
not availableclient.operationIndex
not availableclient.operationIndex
delete keyclient.deleteApiKey
delete dictionaryclient.batchDictionaryEntries
get keyclient.getApiKey
list keysclient.listApiKeys
list indicesclient.listIndices
move indexclient.operationIndex
multipleBatchclient.multipleBatch
multiQueriesclient.search
replace dictionaryclient.batchDictionaryEntries
restore keyclient.restoreApiKey
save dictionaryclient.batchDictionaryEntries
update keyclient.updateApiKey
index.batchclient.batch
clear indexclient.clearObjects
clear rulesclient.clearRules
clear synonymsclient.clearSynonyms
not availableclient.operationIndex
deleteclient.deleteIndex
delete byclient.deleteBy
deleteObjectclient.deleteObject
delete objectIdsclient.deleteObjects
delete ruleclient.deleteRule
delete synonymclient.deleteSynonym
helper.findObjectclient.searchSingleIndex
getObjectclient.getObject
get objectIdsclient.getObjects
get ruleclient.getRule
settings ofclient.getSettings
get synonymclient.getSynonym
index.getTaskclient.getTask
partialUpdateObjectclient.partialUpdateObject
partialUpdate objectsclient.partialUpdateObjects
not availableclient.replaceAllObjects
not availableclient.saveRules
not availableclient.saveSynonyms
saveObjectclient.saveObject
index objectsclient.saveObjects
save ruleclient.saveRule
saveRulesclient.saveRules
save synonymclient.saveSynonym
save synonymsclient.saveSynonyms
searchclient.searchSingleIndex
search facetclient.searchForFacetValues
search rulesclient.searchRules
search synonymsclient.searchSynonyms
setSettings ofclient.setSettings
{operation}.waitclient.waitForTask

Recommend API client

Version 1 (legacy)Version 2 (current)
get frequentlyBoughtTogetherclient.getRecommendations
get recommendationsclient.getRecommendations
get relatedProductsclient.getRecommendations
Last modified on March 2, 2026