Skip to content

Onboard search data

This tutorial creates a synthetic docs-search-default data stream. Use a separate naming, mapping, lifecycle, and relevance design for production data.

Before you begin

You need:

  • the deployment-derived Elasticsearch URL;
  • working DNS and TLS;
  • an administrator with permission to create index templates and API keys;
  • approval to create and delete tutorial resources.

Set the endpoint without embedding credentials:

export ELASTICSEARCH_URL="https://<deployment-elasticsearch-hostname>"

Create the data-stream template

curl --fail-with-body --user "<search-administrator>" \
  --request PUT "${ELASTICSEARCH_URL}/_index_template/docs-search-template" \
  --header "Content-Type: application/json" \
  --data '{
    "index_patterns": ["docs-search-*"],
    "data_stream": {},
    "template": {
      "mappings": {
        "properties": {
          "@timestamp": {"type": "date"},
          "title": {"type": "text"},
          "body": {"type": "text"},
          "source_id": {"type": "keyword"}
        }
      }
    }
  }'

Confirm the response contains "acknowledged":true.

Create the writer API key

curl --fail-with-body --user "<api-key-administrator>" \
  --request POST "${ELASTICSEARCH_URL}/_security/api_key" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "docs-search-writer",
    "expiration": "7d",
    "role_descriptors": {
      "docs_search_writer": {
        "indices": [
          {
            "names": ["docs-search-*"],
            "privileges": ["auto_configure", "create_doc"]
          }
        ]
      }
    }
  }'

Confirm that the response contains an API-key ID and encoded key. Store both in the approved secret store.

Create the validation API key

Use a separate read-only identity for the tutorial search:

curl --fail-with-body --user "<api-key-administrator>" \
  --request POST "${ELASTICSEARCH_URL}/_security/api_key" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "docs-search-validator",
    "expiration": "7d",
    "role_descriptors": {
      "docs_search_validator": {
        "indices": [
          {
            "names": ["docs-search-*"],
            "privileges": ["read"]
          }
        ]
      }
    }
  }'

Store the validation key and its ID separately from the writer key. A production ingestion identity normally does not need read.

Load the keys without echoing them

Retrieve the encoded values from the approved secret store and enter them at the prompts:

IFS= read -rsp "Writer API key: " ELASTIC_WRITE_API_KEY
printf "\n"
IFS= read -rsp "Validation API key: " ELASTIC_READ_API_KEY
printf "\n"

The secret input is not echoed and is not part of the command stored in Bash history. Do not export either variable, save it in a shell profile, or enter the value directly on a command line.

Index and search a document

curl --fail-with-body \
  --request POST \
  "${ELASTICSEARCH_URL}/docs-search-default/_doc?op_type=create&refresh=wait_for" \
  --header "Authorization: ApiKey ${ELASTIC_WRITE_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{
    "@timestamp": "2026-07-29T00:00:00Z",
    "title": "Synthetic onboarding document",
    "body": "This document validates the managed search ingestion path.",
    "source_id": "docs-tutorial-001"
  }'

Confirm the response reports "result":"created", then search:

curl --fail-with-body \
  "${ELASTICSEARCH_URL}/docs-search-default/_search?q=source_id:docs-tutorial-001" \
  --header "Authorization: ApiKey ${ELASTIC_READ_API_KEY}"

The response must contain exactly the synthetic document. Remove the keys from the current shell immediately after validation:

unset ELASTIC_WRITE_API_KEY ELASTIC_READ_API_KEY

Clean up

Delete the tutorial data stream and template with an approved administrator, then invalidate the API key:

curl --fail-with-body --user "<search-administrator>" \
  --request DELETE "${ELASTICSEARCH_URL}/_data_stream/docs-search-default"

curl --fail-with-body --user "<search-administrator>" \
  --request DELETE "${ELASTICSEARCH_URL}/_index_template/docs-search-template"

Use both API-key IDs returned at creation time with the invalidate API. Do not reuse either tutorial key for production.