Skip to main content
Algolia doesn’t directly search your data sources. Instead, you upload the parts of your data that are relevant for search to Algolia. Algolia stores this data in an : a data structure optimized for fast search.

Required credentials

To send data to Algolia, you need an Application ID and a valid API key (with addObjects permission). You can find them in the API Keys section of Algolia’s dashboard.
  • Application ID. Your Application ID is what Algolia uses to identify your app, where all your indices live.
  • API key. API keys control access to Algolia’s API and determine what you’re allowed to do, such as searching an index, or adding new . For better security, create specific API keys with minimal permissions for indexing tasks, which you should only use in server-side code. Keep your indexing API keys secret.
Only use the Admin API key to create other API keys. Don’t use the Admin API key in your apps.

Fetch your data

Before sending anything to Algolia, you need to retrieve your data. You can do this in several ways, depending on the nature of your app.

From a database

IEnumerable FetchDataFromDataBase() {
  // Fetch data from your database
}

var actors = FetchDataFromDataBase();
func fetchDataFromDatabase() []Actor {
	// Fetch data from your database
}

func main() {
	records := fetchDataFromDatabase()
}
public List fetchDataFromDatabase() {
  // Fetch data from your database
}

List actors = fetchDataFromDataBase();
const fetchDataFromDatabase = () => {
	// Fetch data from your database.
};

const records = fetchDataFromDatabase();
fun fetchFromDatabase(): List {
  // Fetch data from your database
}

val actors: List = fetchFromDatabase()
function fetchDataFromDatabase() {
  // Fetch data from your database
}

$records = fetchDataFromDatabase();
def fetch_data_from_database():
  data = {}
  # Fetch data from your database
  return data

records = fetch_data_from_database()
def fetch_data_from_database
  # Fetch data from your database
end

records = fetch_data_from_database
def fetchDataFromDatabase(): Iterable[Actor] = {
  // Fetch data from your database
}

val actors = fetchDataFromDatabase()
func fetchDataFromDataBase() -> [[String: Any]] {
  // Fetch data from your database
}

let records = fetchDataFromDataBase()

From a file

You can use this actors dataset to test this out.
using System.Collections.Generic;
using System.IO;
using Algolia.Search.Clients;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class Actor
{
    public string Name { get; set; }
    public string ObjectID { get; set; }
    public int Rating { get; set; }
    public string ImagePath { get; set; }
    public string AlternativePath { get; set; }
}

public class AlgoliaActorsIndexer
{
    private SearchClient client;
    private SearchIndex index;

    public AlgoliaActorsIndexer(string appId, string apiKey, string indexName)
    {
        client = new SearchClient(appId, apiKey);
        index = client.InitIndex(indexName);
    }

    public void IndexActorsFromFile(string filePath)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new DefaultContractResolver
            {
                NamingStrategy = new CamelCaseNamingStrategy()
            }
        };

        IEnumerable actors = JsonConvert.DeserializeObject>(File.ReadAllText(filePath), settings);
        index.SaveObjects(actors);
    }
}

// Usage
public class Program
{
    public static void Main(string[] args)
    {
        AlgoliaActorsIndexer indexer = new AlgoliaActorsIndexer("undefined", "undefined", "actors");
        indexer.IndexActorsFromFile("actors.json");
    }
}
package main

import (
	"encoding/json"
	"io/ioutil"
)

type Actor struct {
	Name            string `json:"name"`
	Rating          int    `json:"rating"`
	ImagePath       string `json:"image_path"`
	AlternativeName string `json:"alternative_name"`
	ObjectID        string `json:"objectID"`
}

func main() {
	var actors []Actor
	data, _ := ioutil.ReadFile("actors.json")
	_ = json.Unmarshal(data, &actors)
}
import java.io.FileInputStream;
import java.io.InputStream;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Actor {
    // Getters/Setters ommitted
    private String name;
    private String objectID;
    private int rating;
    private String imagePath;
    private String alternativePath;
}

ObjectMapper objectMapper = Defaults.getObjectMapper();

InputStream input = new FileInputStream("actors.json");
Actor[] actors = objectMapper.readValue(input, Actor[].class);
const records = require("./actors.json");
@Serializable
data class Actor(
    val name: String,
    val rating: Int,
    val imagePath: String,
    val alternativePath: String,
    override val objectID: ObjectID
) : Indexable

val string = File("actors.json").readText()
val actors: List = Json.plain.parse(Actor.serializer().list, string)
$records = json_decode(file_get_contents('actors.json'), true);
import json

with open('actors.json') as f:
    records = json.load(f)
require 'json'

file    = File.read('actors.json')
records = JSON.parse(file)
import org.json4s._
import org.json4s.native.JsonMethods._

case class Actor(name: String,
                 rating: Int,
                 image_path: String,
                 alternative_path: Option[String],
                 objectID: String)

object Main {

  def main(args: Array[String]): Unit = {

    val json = parse(new FileInputStream("actors.json")).extract[Seq[Actor]]

  }

}
let filePath = Bundle.main.path(forResource: "actors", ofType: "json")!
let contentData = FileManager.default.contents(atPath: filePath)!
let records = try! JSONSerialization.jsonObject(with: contentData, options: []) as! [[String: Any]]

From the source code directly

Only use this method for exploration purposes or if you have a small amount of data.
using System.Collections.Generic;

public class Actor
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        IEnumerable records = new List
        {
            new Actor { Name = "Tom Cruise" },
            new Actor { Name = "Scarlett Johansson" }
        };
    }
}
actors := []Actor{
	{Name: "Tom Cruise"},
	{Name: "Scarlett Johansson"},
}
public class Person {

   private String name;

   public Person() {}

   public String getName() {
     return name;
   }

   public Person setName(String name) {
     this.name = name;
     return this;
   }
 }

 ArrayList persons = new ArrayList() {{
    add(new Person().setName("Tom Cruise"));
    add(new Person().setName("Scarlett Johansson"));
 }};
const records = [{ name: "Tom Cruise" }, { name: "Scarlett Johansson" }];
val records = listOf(json { "name" to "Tom Cruise" }, json { "name" to "Scarlett Johansson" })
$records = [
  ['name' => 'Tom Cruise'],
  ['name' => 'Scarlett Johansson']
];
records = [
    {'name': 'Tom Cruise'},
    {'name': 'Scarlett Johansson'}
]
records = [
  { name: 'Tom Cruise' },
  { name: 'Scarlett Johansson' }
]
case class Person(name: String)

val records = Seq(
  Person("Tom Cruise"),
  Person("Scarlett Johansson"),
)
let records: [[String: Any]] = [
  ["name": "Tom Cruise"],
  ["name": "Scarlett Johansson"],
]

Send the data to Algolia

Once the records are ready, you can push them to Algolia using the saveObjects method.
var response = await client.SaveObjectsAsync(
  "INDEX_NAME",
  new List<Object>
  {
    new Dictionary<string, string> { { "objectID", "1" }, { "name", "Adam" } },
    new Dictionary<string, string> { { "objectID", "2" }, { "name", "Benoit" } },
  }
);
response, err := client.SaveObjects(
  "INDEX_NAME",
  []map[string]any{{"objectID": "1", "name": "Adam"}, {"objectID": "2", "name": "Benoit"}})
if err != nil {
  // handle the eventual error
  panic(err)
}
List response = client.saveObjects(
  "INDEX_NAME",
  Arrays.asList(
    new HashMap() {
      {
        put("objectID", "1");
        put("name", "Adam");
      }
    },
    new HashMap() {
      {
        put("objectID", "2");
        put("name", "Benoit");
      }
    }
  )
);
const response = await client.saveObjects({
  indexName: 'cts_e2e_saveObjects_javascript',
  objects: [
    { objectID: '1', name: 'Adam' },
    { objectID: '2', name: 'Benoit' },
  ],
});
var response =
  client.saveObjects(
    indexName = "INDEX_NAME",
    objects =
      listOf(
        buildJsonObject {
          put("objectID", JsonPrimitive("1"))
          put("name", JsonPrimitive("Adam"))
        },
        buildJsonObject {
          put("objectID", JsonPrimitive("2"))
          put("name", JsonPrimitive("Benoit"))
        },
      ),
  )
$response = $client->saveObjects(
    'INDEX_NAME',
    [
        ['objectID' => '1',
            'name' => 'Adam',
        ],

        ['objectID' => '2',
            'name' => 'Benoit',
        ],
    ],
);
response = client.save_objects(
    index_name="INDEX_NAME",
    objects=[
        {
            "objectID": "1",
            "name": "Adam",
        },
        {
            "objectID": "2",
            "name": "Benoit",
        },
    ],
)
response = client.save_objects(
  "INDEX_NAME",
  [{objectID: "1", name: "Adam"}, {objectID: "2", name: "Benoit"}]
)
val response = Await.result(
  client.saveObjects(
    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"))))
    )
  ),
  Duration(100, "sec")
)
let response = try await client.saveObjects(
    indexName: "INDEX_NAME",
    objects: [["objectID": "1", "name": "Adam"], ["objectID": "2", "name": "Benoit"]]
)

Send your data in batches

For better performance, you should send several records at once instead of one by one. If you have many records to index, you should send them in batches.

Next steps

After indexing your data, you can configure relevance settings.
Last modified on May 19, 2026