Loading

Typed API

The typed API provides a strongly typed Go API for Elasticsearch, designed with Go structs and the runtime in mind. Requests and responses are modeled as Go types, giving you compile-time safety, IDE autocompletion, and no need to manually parse JSON.

The code is generated from the elasticsearch-specification.

Create a typed client using the NewTyped function with option values:

client, err := elasticsearch.NewTyped(
    elasticsearch.WithAddresses("https://localhost:9200"),
    elasticsearch.WithAPIKey("your-api-key"),
)
if err != nil {
    log.Fatal(err)
}
defer client.Close(context.Background())
		
  1. The Elasticsearch node URL(s).
  2. Authentication credentials (API key, username/password, or service token).
  3. Always close the client when done to release resources.

For full configuration options, see the Configuration reference.

The typed client and the low-level client share the same underlying transport, configuration, and connection pool. The typed API is a higher-level abstraction built on top of the same infrastructure:

Mermaid diagram

Because both clients implement the same transport interface, individual typed endpoint packages (typedapi/core/search, typedapi/indices/create, ...) accept either client type. That means you can mix the two styles in a single application, and you can migrate existing low-level code to the typed API one endpoint at a time. If you already hold a *elasticsearch.Client and want the full typed surface without rebuilding the transport, call elasticsearch.NewTypedFrom(client). See the migration guide for details on both approaches.

The typed client organizes Elasticsearch APIs into namespaces that mirror the REST API structure. Each namespace groups related operations:

Mermaid diagram

Access API methods through the namespace fields on the client:

// Indices namespace
client.Indices.Create("my-index").Do(context.Background())

// Cluster namespace
client.Cluster.Health().Do(context.Background())

// Core namespace (also available directly on the client)
client.Search().Index("my-index").Do(context.Background())

// Security namespace
client.Security.GetUser("admin").Do(context.Background())

// ML namespace
client.Ml.GetJobs().Do(context.Background())
		

The full list of namespaces includes: AsyncSearch, Autoscaling, Cat, Ccr, Cluster, Connector, Core, DanglingIndices, Enrich, Eql, Esql, Features, Fleet, Graph, Ilm, Indices, Inference, Ingest, License, Logstash, Migration, Ml, Monitoring, Nodes, Profiling, QueryRules, Rollup, SearchApplication, SearchableSnapshots, Security, Shutdown, Simulate, Slm, Snapshot, Sql, Ssl, Streams, Synonyms, Tasks, TextStructure, Transform, Watcher, and Xpack.

The typed API includes endpoints that use NDJSON bodies such as bulk and msearch.

For example, you can build a bulk request by appending operations and then executing it:

client, err := elasticsearch.NewTyped(
    // Proper configuration for your Elasticsearch cluster.
)
if err != nil {
    // Handle error.
}

index := "my-index"
id := "1"
bulk := client.Bulk()
if err := bulk.IndexOp(types.IndexOperation{Index_: &index, Id_: &id}, map[string]any{"title": "Test"}); err != nil {
    // Handle error.
}

res, err := bulk.Do(context.Background())
if err != nil {
    // Handle error.
}
if res.Errors {
    // One or more operations failed.
}
		
  1. Create a bulk request builder.
  2. Append an index operation with metadata and document body.
  3. Execute the bulk request and check for errors.

If you already have a newline-delimited JSON payload, you can submit it directly with Raw(io.Reader) on the request builder.