Skip to main content
Index APIs let you create, configure, and operate on indices — the top-level containers for your data. You can also manage mappings (schema), index templates, and aliases through these APIs.

Create an index

PUT /{index}
curl -X PUT http://localhost:9200/products \
  -H "Content-Type: application/json" \
  -d '{
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    },
    "mappings": {
      "properties": {
        "name": {"type": "text"},
        "price": {"type": "double"},
        "in_stock": {"type": "boolean"},
        "created_at": {"type": "date"}
      }
    }
  }'
Response:
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "products"
}
Elasticsearch also creates indices automatically the first time you index a document. For production use, define explicit mappings and settings upfront via index templates to avoid unintended schema inference.

Get index information

Retrieve settings, mappings, and aliases for one or more indices.
# Single index
curl http://localhost:9200/products

# Multiple indices
curl http://localhost:9200/products,orders

# Wildcard
curl "http://localhost:9200/logs-2024-*"

Check if an index exists

Returns 200 OK if the index exists, 404 Not Found if it does not. No body is returned.
curl -I http://localhost:9200/products

Delete an index

Deleting an index permanently removes all documents and cannot be undone. Snapshots are the only way to recover deleted data.
curl -X DELETE http://localhost:9200/products
To delete multiple indices at once:
curl -X DELETE http://localhost:9200/products,archive-2022

Open and close an index

Closing an index frees up shard resources (heap, file descriptors) while preserving the data. A closed index cannot be searched or indexed into.
# Close
curl -X POST http://localhost:9200/products/_close

# Reopen
curl -X POST http://localhost:9200/products/_open

Refresh

Make all changes since the last refresh immediately visible to search. Elasticsearch automatically refreshes every second (controlled by index.refresh_interval).
# Refresh a single index
curl -X POST http://localhost:9200/products/_refresh

# Refresh multiple indices
curl -X POST http://localhost:9200/products,orders/_refresh

# Refresh all indices
curl -X POST http://localhost:9200/_refresh
Avoid calling _refresh after every indexing operation in high-throughput pipelines. It reduces indexing throughput significantly. Use ?refresh=wait_for on individual index requests when you need a specific document to be searchable immediately.

Flush

Persist operations from the transaction log to Lucene and clear the translog. Useful before taking a snapshot.
curl -X POST http://localhost:9200/products/_flush

Force merge

Reduce the number of Lucene segments in an index. Fewer segments improve search performance and reduce memory overhead. On a write-heavy index, avoid force merging until the index is no longer receiving writes.
# Merge to a single segment (best for read-only indices)
curl -X POST "http://localhost:9200/products/_forcemerge?max_num_segments=1"

# Only expunge deleted documents
curl -X POST "http://localhost:9200/products/_forcemerge?only_expunge_deletes=true"
Force merge is resource-intensive and should be run during off-peak hours. Do not run it on active write indices.

Update index settings

Dynamically change settings on an existing index. Some settings (such as number_of_shards) are immutable after index creation.
curl -X PUT http://localhost:9200/products/_settings \
  -H "Content-Type: application/json" \
  -d '{
    "index": {
      "number_of_replicas": 2,
      "refresh_interval": "30s"
    }
  }'
Temporarily disable refresh during a large bulk load, then restore it:
# Disable
curl -X PUT http://localhost:9200/products/_settings \
  -H "Content-Type: application/json" \
  -d '{"index": {"refresh_interval": "-1"}}'

# Re-enable (restore default)
curl -X PUT http://localhost:9200/products/_settings \
  -H "Content-Type: application/json" \
  -d '{"index": {"refresh_interval": null}}'

Mappings

Mappings define the schema for an index — the field names and their data types.

Get mapping

curl http://localhost:9200/products/_mapping

Add or update fields

You can add new fields to an existing mapping, but you cannot change the type of an existing field. To change a field’s type, you must reindex into a new index.
curl -X PUT http://localhost:9200/products/_mapping \
  -H "Content-Type: application/json" \
  -d '{
    "properties": {
      "description": {
        "type": "text",
        "analyzer": "english"
      },
      "sku": {
        "type": "keyword"
      }
    }
  }'
Adding a new field does not reindex existing documents. The new field will only appear in documents indexed after the mapping update.

Index templates

Index templates define settings and mappings that are automatically applied when a new index whose name matches the template pattern is created.

Create a composable index template

curl -X PUT http://localhost:9200/_index_template/logs-template \
  -H "Content-Type: application/json" \
  -d '{
    "index_patterns": ["logs-*"],
    "priority": 100,
    "template": {
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 1,
        "index.lifecycle.name": "logs-policy"
      },
      "mappings": {
        "properties": {
          "@timestamp": {"type": "date"},
          "level": {"type": "keyword"},
          "message": {"type": "text"},
          "host": {"type": "keyword"}
        }
      }
    }
  }'

List templates

curl http://localhost:9200/_index_template
curl http://localhost:9200/_index_template/logs-template

Delete a template

curl -X DELETE http://localhost:9200/_index_template/logs-template

Aliases

Aliases are secondary names that point to one or more indices. They support zero-downtime reindexing, time-based index rolling, and filtered views.

Manage aliases with the aliases API

curl -X POST http://localhost:9200/_aliases \
  -H "Content-Type: application/json" \
  -d '{
    "actions": [
      {
        "add": {
          "index": "products-v2",
          "alias": "products",
          "is_write_index": true
        }
      },
      {
        "remove": {
          "index": "products-v1",
          "alias": "products"
        }
      }
    ]
  }'
Action types:
ActionDescription
addAdd an alias to an index
removeRemove an alias from an index
remove_indexDelete the underlying index

Filtered alias

A filtered alias exposes only a subset of documents, useful for multi-tenant or soft-delete patterns.
curl -X POST http://localhost:9200/_aliases \
  -H "Content-Type: application/json" \
  -d '{
    "actions": [
      {
        "add": {
          "index": "orders",
          "alias": "active-orders",
          "filter": {
            "term": {"status": "active"}
          }
        }
      }
    ]
  }'

Get aliases

# All aliases for an index
curl http://localhost:9200/products/_alias

# Specific alias
curl http://localhost:9200/_alias/active-orders

# Check if an alias exists
curl -I http://localhost:9200/_alias/products

Common index settings reference

SettingDescription
number_of_shardsPrimary shards. Immutable after creation.
number_of_replicasReplica copies per primary. Can be changed dynamically.
refresh_intervalHow often to refresh (1s default). Set to -1 to disable.
index.max_result_windowMax from + size value (default 10000).
index.lifecycle.nameILM policy name to attach to this index.
index.routing.allocation.require.*Force shards to nodes with matching attributes.

Build docs developers (and LLMs) love