Document APIs

Document APIs

Document APIs create, read, update, and delete individual documents in your indexes. Use them for custom ingestion scripts, one-off fixes, or bulk loads alongside Logstash.

Connection details: Connect to Your Cluster.

Full specification: OpenSearch Document APIs (opens in a new tab).

Common endpoints

MethodPathPurpose
POST/{index}/_docIndex a document (auto-generate _id)
PUT/{index}/_doc/{id}Index a document with a specific _id
GET/{index}/_doc/{id}Get a document by _id
POST/{index}/_update/{id}Partial update
DELETE/{index}/_doc/{id}Delete a document
POST/_bulkBulk index/update/delete
POST/{index}/_delete_by_queryDelete documents matching a query
POST/{index}/_update_by_queryUpdate documents matching a query
⚠️

/_delete_by_query and /_update_by_query are irreversible on live data. Test with a narrow query and _count first.

Index a single document

curl -X POST "@opensearch.endpointAddress:443/my-logs/_doc" \
  -u "@opensearch.username:@opensearch.password" \
  -H "Content-Type: application/json" \
  -d '{
    "@timestamp": "2026-06-11T12:00:00Z",
    "level": "INFO",
    "message": "Example log line from curl"
  }'

Get a document by ID

curl -X GET "@opensearch.endpointAddress:443/my-logs/_doc/YOUR_DOCUMENT_ID" \
  -u "@opensearch.username:@opensearch.password"

Bulk index

Bulk requests use newline-delimited JSON (NDJSON): action line, then optional source line, repeated.

curl -X POST "@opensearch.endpointAddress:443/_bulk" \
  -u "@opensearch.username:@opensearch.password" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @- <<'EOF'
{"index":{"_index":"my-logs"}}
{"@timestamp":"2026-06-11T12:00:01Z","message":"First line"}
{"index":{"_index":"my-logs"}}
{"@timestamp":"2026-06-11T12:00:02Z","message":"Second line"}
EOF

Send bulk payloads in batches (for example 1,000–5,000 lines) to avoid timeouts. For production ingestion, Logstash is usually more resilient.

Delete by query

Count first:

curl -X POST "@opensearch.endpointAddress:443/my-logs/_count" \
  -u "@opensearch.username:@opensearch.password" \
  -H "Content-Type: application/json" \
  -d '{"query": {"term": {"level": "DEBUG"}}}'

Then delete:

curl -X POST "@opensearch.endpointAddress:443/my-logs/_delete_by_query" \
  -u "@opensearch.username:@opensearch.password" \
  -H "Content-Type: application/json" \
  -d '{"query": {"term": {"level": "DEBUG"}}}'

Python bulk example

bulk_index.py
import json
import requests
 
endpoint = "@opensearch.endpointAddress:443"
auth = ("@opensearch.username", "@opensearch.password")
 
lines = []
for i in range(3):
    lines.append(json.dumps({"index": {"_index": "my-logs"}}))
    lines.append(json.dumps({
        "@timestamp": "2026-06-11T12:00:00Z",
        "message": f"Log line {i}",
    }))
 
body = "\n".join(lines) + "\n"
response = requests.post(
    f"{endpoint}/_bulk",
    auth=auth,
    headers={"Content-Type": "application/x-ndjson"},
    data=body,
)
response.raise_for_status()
print(response.json())

Further reading