100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Elasticsearch

The Elasticsearch REST API

How to interact with Elasticsearch over HTTP: indexing, retrieving, searching, and managing documents and indices via the REST API.

Elasticsearch FoundationsBeginner9 min readJul 10, 2026
Analogies

The Elasticsearch REST API

Every operation in Elasticsearch — indexing a document, running a search, checking cluster health, creating an index — is exposed as an HTTP endpoint that accepts and returns JSON. There is no proprietary binary protocol required for basic usage; you can drive the entire system with curl, Kibana's Dev Tools console, or any HTTP client library. The URL pattern typically follows /{index}/_{action}/{id} for document-level operations, such as PUT /products/_doc/1 to index a document with a specific ID, or POST /products/_doc to let Elasticsearch auto-generate one.

🏏

Cricket analogy: Interacting with Elasticsearch purely over HTTP is like a scorer submitting every update through a single standardized online scoring app rather than needing separate specialized radios for different stadiums.

CRUD Operations

Basic document operations map cleanly to HTTP verbs: PUT /index/_doc/{id} creates or fully replaces a document at a specific ID; GET /index/_doc/{id} retrieves it; POST /index/_update/{id} with a partial doc performs a partial update without resending the whole document; and DELETE /index/_doc/{id} removes it. Under the hood, Elasticsearch documents are never modified in place — an update actually marks the old Lucene segment entry as deleted and writes a brand-new document, with old, deleted entries reclaimed later during Lucene's background segment merge process.

🏏

Cricket analogy: Updating a scorecard entry isn't really an in-place edit — it's like crossing out an old tally line and writing a fresh corrected one below it, with the old line only fully erased during a later scorebook cleanup.

bash
# Index a document with an explicit ID
curl -X PUT "http://localhost:9200/products/_doc/1" \
  -H 'Content-Type: application/json' -d '{
    "name": "Wireless Mouse",
    "price": 24.99,
    "in_stock": true
  }'

# Retrieve it
curl -X GET "http://localhost:9200/products/_doc/1"

# Partially update just the price
curl -X POST "http://localhost:9200/products/_update/1" \
  -H 'Content-Type: application/json' -d '{
    "doc": { "price": 19.99 }
  }'

# Delete it
curl -X DELETE "http://localhost:9200/products/_doc/1"

Every write in Elasticsearch is versioned internally. The response to an index/update/delete request includes a _seq_no and _primary_term, which can be used with if_seq_no/if_primary_term parameters to implement optimistic concurrency control, preventing lost updates when two clients modify the same document concurrently.

The Search API and the Bulk API

Searching uses GET or POST /index/_search with a JSON request body written in Query DSL, which combines a query clause (what to match, and how to score it, e.g. match, term, bool) with optional aggregations, sorting, and pagination via from/size or the more scalable search_after cursor for deep pagination. For high-throughput writes, the _bulk API lets you batch many index, update, and delete operations into a single HTTP request using a newline-delimited JSON format, dramatically reducing per-request network overhead compared to issuing thousands of individual calls.

🏏

Cricket analogy: Using the bulk API to index thousands of historical match records in one request is like a statistician submitting an entire season's scorecards in one batch upload instead of mailing in each match's card separately.

json
GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "mouse" } }
      ],
      "filter": [
        { "term": { "in_stock": true } }
      ]
    }
  },
  "sort": [{ "price": "asc" }],
  "size": 10
}

Deep pagination with from/size becomes expensive and is capped at 10,000 results by default (index.max_result_window), because Elasticsearch must fetch and sort from+size documents on every shard before merging results. For paging through large result sets, use search_after with a stable sort (typically including _shard_doc or a tiebreaker field) instead.

  • Every Elasticsearch operation is a JSON-over-HTTP REST endpoint, usable via curl, Kibana Dev Tools, or any HTTP client.
  • PUT/_doc creates or replaces a document; POST/_update performs a partial update; DELETE/_doc removes it.
  • Documents are never modified in place internally; updates write new Lucene entries and mark old ones deleted.
  • _seq_no and _primary_term enable optimistic concurrency control to prevent lost updates.
  • The _search endpoint uses Query DSL, combining query clauses, aggregations, sorting, and pagination.
  • The _bulk API batches many operations into one HTTP request for much higher write throughput.
  • Deep pagination with from/size is capped at 10,000 by default; use search_after for large result sets.

Practice what you learned

Was this page helpful?

Topics covered

#Elasticsearch#ElasticsearchStudyNotes#Database#TheElasticsearchRESTAPI#REST#API#CRUD#Operations#APIs#StudyNotes#SkillVeris