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())
- The Elasticsearch node URL(s).
- Authentication credentials (API key, username/password, or service token).
- 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:
graph TB
subgraph clients [Client Layer]
LC["New - Low-level API"]
TC["NewTyped - Typed API"]
end
subgraph shared [Shared Infrastructure]
OPTS["Options - WithAddresses, WithAPIKey, ..."]
TP["Transport - retry, compression, node selection"]
end
LC --> OPTS
TC --> OPTS
OPTS --> TP
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 client.ToTyped(). 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:
graph LR
TC["TypedClient"]
subgraph common [Common Operations]
Core
Indices
Cluster
Cat
end
subgraph search_ns [Search and Analytics]
Search["Core.Search"]
Esql
Eql
Sql
AsyncSearch
end
subgraph ingest_ns [Data Ingestion]
Bulk["Core.Bulk"]
Ingest
Transform
end
subgraph management [Management]
Security
Ml
Snapshot
Slm
Ilm
end
TC --> common
TC --> search_ns
TC --> ingest_ns
TC --> management
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.
}
- Create a bulk request builder.
- Append an index operation with metadata and document body.
- 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.
- Conventions: naming, structure, enums, and unions in the typed API
- esdsl builders: fluent DSL builders for queries, aggregations, mappings, and sort options
- Using the API: practical examples for common operations
- Low-level API and migration guide: raw-JSON control and migration instructions