Queries OpenSearch Dashboards APIs via curl to discover workspaces, index patterns, datasets, saved objects, and configurations. Useful for observability setup and data source management.
npx claudepluginhub opensearch-project/observability-stack --plugin observabilityThis skill is limited to using the following tools:
| Variable | Default | Description |
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
| Variable | Default | Description |
|---|---|---|
OSD_ENDPOINT | http://localhost:5601 | OpenSearch Dashboards base URL |
OPENSEARCH_USER | admin | Username (same as OpenSearch) |
OPENSEARCH_PASSWORD | My_password_123!@# | Password (same as OpenSearch) |
Note: All OSD API calls require the osd-xsrf: true header.
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/workspaces/_list" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/workspaces/<WORKSPACE_ID>" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OSD_ENDPOINT/api/workspaces/_associate" \
-H 'osd-xsrf: true' \
-H 'Content-Type: application/json' \
-d '{"workspaceId": "<WORKSPACE_ID>", "savedObjects": [{"type": "data-source", "id": "<DATASOURCE_ID>"}]}'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/opensearch-dashboards/settings" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=index-pattern&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/w/<WORKSPACE_ID>/api/saved_objects/_find?type=index-pattern&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/index-pattern/<INDEX_PATTERN_ID>" \
-H 'osd-xsrf: true'
Datasets are an evolution of index patterns that classify indices by signal type (logs, traces, metrics). Users define which indices are logs vs traces through the Dashboards UI. See Dataset Discovery documentation for details.
To discover datasets programmatically, query the saved objects API for index patterns with their signalType, displayName, and description fields:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?fields=title&fields=type&fields=displayName&fields=signalType&fields=description&per_page=10000&type=index-pattern" \
-H 'osd-xsrf: true'
Index patterns created by the observability stack init script include schema mappings that identify their signal type (e.g., otelLogs for log indices, trace-specific time fields for trace indices). These mappings are visible in the index pattern's attributes.fields property.
The APM plugin stores correlations saved objects that define how traces, logs, and metrics are linked. Two correlation types are created by the init script:
trace-to-logs-* — Links a trace index pattern to a log index pattern for cross-signal navigationAPM-Config-* — Ties together the traces index, service map index, and Prometheus datasource for the APM UIcurl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/w/<WORKSPACE_ID>/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
The _find API requires a type parameter. To get a count without loading objects, use per_page=0:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=index-pattern&per_page=0" \
-H 'osd-xsrf: true'
Common saved object types: index-pattern, query, dashboard, visualization, config, correlations, data-source, data-connection, explore.
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-source&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-connection&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=explore&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=query&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=dashboard&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=visualization&per_page=100" \
-H 'osd-xsrf: true'
To discover existing Prometheus data connections, use the saved objects API (the data-connection type):
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-connection&per_page=100" \
-H 'osd-xsrf: true'
The init script creates Prometheus data connections via the direct query API:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OSD_ENDPOINT/api/directquery/dataconnections" \
-H 'osd-xsrf: true' \
-H 'Content-Type: application/json' \
-d '{"name": "MyPrometheus", "connector": "prometheus", "allowedRoles": ["all_access"], "properties": {"prometheus.uri": "http://prometheus:9090", "prometheus.auth.type": "basicauth", "prometheus.auth.username": "", "prometheus.auth.password": ""}}'
When OSD is not available, query OpenSearch directly to discover indices and field mappings:
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/_cat/indices?format=json&v" | python3 -c "
import sys, json
for idx in json.load(sys.stdin):
name = idx['index']
if any(p in name for p in ['otel-', 'logs-otel-', 'apm-']):
print(f\"{name} docs={idx['docs.count']} size={idx['store.size']}\")"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/otel-v1-apm-span-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/logs-otel-v1-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/otel-v2-apm-service-map-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OPENSEARCH_ENDPOINT/_plugins/_ppl" \
-H 'Content-Type: application/json' \
-d '{"query": "describe otel-v1-apm-span-000001"}'
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OPENSEARCH_ENDPOINT/_plugins/_ppl" \
-H 'Content-Type: application/json' \
-d '{"query": "describe logs-otel-v1-000001"}'
When dynamic discovery is not possible, these are the default index patterns used by the observability stack:
| Signal | Index Pattern | Description |
|---|---|---|
| Traces | otel-v1-apm-span-* | Trace span data with serviceName, traceId, spanId |
| Logs | logs-otel-v1-* | Log entries with resource.attributes.service.name |
| Service Maps | otel-v2-apm-service-map-* | Service topology with sourceNode, targetNode |