DocsReference

OpenSearch compatibility

Search implements a documented subset of the OpenSearch REST API. GET / reports opensearch 3.5.0 so that official clients connect. That describes the wire protocol, not full feature parity.

Explicit, not silentAn unsupported query, aggregation, parameter or API returns a clear error. Search never accepts a request and quietly ignores the parts that would change your results.

How this is tested: the official opensearch-py client runs end to end in CI, and a differential suite compares responses with a real OpenSearch 2.19.1 instance.

APIs

Supported API endpoints
AreaEndpointsNotes
IndicesPUT GET HEAD DELETE /{index}, GET /{index}/_mapping, /{index}/_refreshMappings can only be set at creation.
DocumentsPUT /{index}/_doc/{id} (incl. op_type=create), POST /{index}/_doc, GET HEAD DELETE /{index}/_doc/{id}Real-time GET sees acknowledged writes before refresh.
UpdatePOST /{index}/_update/{id}Partial merge, upsert, doc_as_upsert. No scripts.
BulkPOST /_bulk, /{index}/_bulkindex, create, update, delete.
Search/{index}/_search, /{index}/_count, /_msearch, /{index}/_msearchmsearch runs its items one after another, 64 by default.
Point in timePOST /{index}/_search/point_in_time, pit in the body, DELETE /_search/point_in_time[/_all]Use with search_after for deep pagination.
AliasesPOST /_aliases, GET /_alias/{alias}, GET /{index}/_alias, PUT DELETE /{index}/_alias/{alias}
TasksPOST /_reindex, /{index}/_update_by_query, /{index}/_delete_by_query, GET /_tasks/{id}, POST /_tasks/{id}/_cancelDurable and resumable.
Templates and streams/_index_template/{name}, /_data_stream/{name}, POST /{alias}/_rolloverThin template API. Rollover takes no conditions. Lifecycle is an engine-specific lifecycle block.
Security/_plugins/_security/api/{internalusers,roles,rolesmapping}, /_plugins/_security/api/accountOther _plugins/_security paths return 400.
HealthGET /, GET /_cluster/healthA healthy single-region install reports yellow, as a single-node OpenSearch does.

Queries

Query support
SupportedRefused with an error
match_all, match, term, terms, range, exists, bool, match_phrase, match_phrase_prefix, prefix, wildcard, regexp, fuzzy, multi_match (best_fields, most_fields, phrase, phrase_prefix). boost is accepted on all of them. query_string, simple_query_string, knn, neural, nested, ids, constant_score, dis_max, function_score, script, script_score, geo_*, span_*, more_like_this, percolate, and others.

Search body options: from / size, sort (including _seq_no), _source includes and excludes, track_total_hits, search_after and pit. Use ?search_type=dfs_query_then_fetch for globally consistent scoring.

Aggregations

Aggregation support
SupportedRefused with an error
min, max, sum, avg, value_count, terms. No sub-aggregations. date_histogram, histogram, cardinality, filter, filters, range, percentiles, stats, top_hits, composite, nested, pipeline aggregations, and others.

Mappings and field types

Types: text, keyword, integer, long, float, double, boolean, date, dense_vector.

  • Strict mappings. Every field must be declared. An unknown field or an incompatible type is rejected, and there is no dynamic mapping.
  • type is the only mapping parameter. analyzer, index, store and the rest are refused.
  • Arrays (other than dense_vector) and nested or dotted field paths are refused.
  • The analyzer is a simple lowercase tokenizer chain, not OpenSearch's standard analyzer, so relevance scores and some matches can differ.

Not supported

  • Multi-index requests: wildcards, comma-separated lists and _all. Each request targets exactly one index.
  • _search/scroll: use point-in-time with search_after instead.
  • _cat, _mget, _settings and per-index settings.
  • /_snapshot: snapshots are managed in the console. They are metadata-only and live in the same bucket, so they are not independent backups.
  • Highlighting, URI search (?q=), and gzip request or response bodies. Official clients default to uncompressed.
  • Security features: document- and field-level security, OIDC/SAML and multi-tenancy.
  • Scripting of any kind.

Engine-specific extensions

These endpoints have no OpenSearch equivalent and are documented as extensions.

Engine-specific endpoints
EndpointPurpose
POST /{index}/_documentsImport plain text or Markdown with automatic chunking. Source IDs are immutable, so an identical retry resumes.
POST /{index}/_semantic_searchExact cosine retrieval with optional hybrid reciprocal-rank fusion. It scans 10,000 filtered documents by default (100,000 maximum), handles up to 4,096 dimensions and returns up to 1,000 hits. Over-budget requests fail explicitly.
/{index}/_estimateReturns a query's cost estimate without running it.
/_security/apikey, /_security/sigv4Create and revoke API keys and SigV4 credentials. A secret is shown once.
/_migration/…Analyze, copy, cut over and roll back an index from OpenSearch. The source must be quiesced; there is no change-data capture.
GET /_licenseLicense state (see Licensing).

Behaviour worth knowing

  • Durability and visibility are separate. A write is acknowledged once it is in the write-ahead log in S3. Search sees it after a refresh, or after ?refresh=wait_for.
  • Queries over the cost budget are rejected with 429 rather than running up unbounded S3 reads.