Skip to content

/openobserve-api

This skill should be used when user asks to "query OpenObserve", "create OpenObserve dashboard", "edit OpenObserve panel", "fetch OpenObserve logs", "run OpenObserve search", "list OpenObserve streams", "ingest into OpenObserve", or works with OpenObserve Cloud / self-hosted via

shell
$ npx -y skills add fcakyon/claude-codex-settings --skill openobserve-api --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/openobserve-api
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

This skill should be used when user asks to "query OpenObserve", "create OpenObserve dashboard", "edit OpenObserve panel", "fetch OpenObserve logs", "run OpenObserve search", "list OpenObserve streams", "ingest into OpenObserve", or works with OpenObserve Cloud / self-hosted via

SKILL.md

openobserve-api.SKILL.md
name: openobserve-api
description: This skill should be used when user asks to "query OpenObserve", "create OpenObserve dashboard", "edit OpenObserve panel", "fetch OpenObserve logs", "run OpenObserve search", "list OpenObserve streams", "ingest into OpenObserve", or works with OpenObserve Cloud / self-hosted via REST API. Covers auth, search/SQL, streams, dashboards (CRUD + per-panel ops), the v8 panel JSON schema, and known pitfalls (re-aggregation, hash concurrency, microsecond timestamps).
license: Apache-2.0

OpenObserve REST API Skill

Programmatic OpenObserve usage for AI agents. Talk to any OpenObserve instance (Cloud or self-hosted) using `curl` and the documented REST API. No CLI required — there is no first-party OpenObserve CLI.

Retrieval First

Your knowledge of OpenObserve API shapes may be outdated. **Prefer retrieval over pre-training**:

| Source | How to retrieve | Use for | | ------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | Docs repo | `gh api repos/openobserve/openobserve-docs/contents/docs/reference/api/{path}.md -q .content \| base64 -d` | Authoritative request/response samples | | Server source | `gh api repos/openobserve/openobserve/contents/src/handler/http/request/dashboards/mod.rs -q .content \| base64 -d` | Endpoint paths, query params, status codes | | Panel schema | `gh api repos/openobserve/openobserve/contents/src/config/src/meta/dashboards/v8/mod.rs -q .content \| base64 -d` | Exact panel JSON structure (Rust structs) |

When docs and server source disagree, **trust the server source** — handlers ship faster than docs.

1. Auth

HTTPS basic auth with email + password. There is no token endpoint.

# Method 1: curl -u shorthand
curl -u "you@example.com:PASSWORD" "https://eu1.openobserve.ai/api/<org>/streams"

# Method 2: explicit header
TOKEN=$(printf '%s' "you@example.com:PASSWORD" | base64)
curl -H "Authorization: Basic $TOKEN" "https://eu1.openobserve.ai/api/<org>/streams"

Endpoints below assume `BASE=https://<host>/api/<org>` and `AUTH="-u you@example.com:PASSWORD"`.

2. Search / Query — `POST $BASE/_search`

Optional query string `?type=logs|metrics|traces` (default `logs`).

curl $AUTH -H 'Content-Type: application/json' \
  "$BASE/_search?type=logs" \
  -d '{
    "query": {
      "sql": "SELECT host_name, COUNT(*) AS n FROM \"my_stream\" GROUP BY host_name ORDER BY n DESC",
      "start_time": 1777000000000000,
      "end_time":   1777999999000000,
      "from": 0,
      "size": 100
    },
    "search_type": "ui"
  }'
  • **Timestamps are microseconds** (Unix epoch × 1_000_000). Always set `start_time`/`end_time` — missing them scans everything.
  • `search_type` ∈ `ui | dashboards | reports | alerts` — affects rate limits and audit logs.
  • Pagination: `from` (offset) + `size` (limit, max ~10000 per request).
  • Response: `{ took, hits[], total, from, size, scan_size }`.
  • SQL flavor: DataFusion / Arrow SQL. Identifiers in double quotes (`"stream_name"`), strings in single quotes (`'value'`).
  • Time-bucketed group by: `SELECT histogram(_timestamp, '5 minute') AS ts, COUNT(*) FROM "stream" GROUP BY ts ORDER BY ts`.
  • Term aggregation: `SELECT k8s_namespace, COUNT(*) FROM "stream" GROUP BY k8s_namespace`.
  • Full-text: `match_all('text')`, `str_match(field, 'text')`. Default full-text fields: `log, message, msg, content, data, json`.
  • PromQL on metrics: `POST $BASE/prometheus/api/v1/query_range`.
  • Trace context window: `GET $BASE/{stream}/_around?key=<ts_us>&size=N`.

3. Streams — `GET $BASE/streams`

# List
curl $AUTH "$BASE/streams?fetchSchema=false&type=logs"

# Schema
curl $AUTH "$BASE/streams/<stream>/schema?type=logs"

# Update settings
curl $AUTH -X PUT -H 'Content-Type: application/json' "$BASE/streams/<stream>/settings" -d '{"partition_keys":["host_name"]}'

# Delete
curl $AUTH -X DELETE "$BASE/streams/<stream>?type=logs"

Field types: `Utf8 | Int64 | Float64 | Timestamp | Boolean`. Timestamp field is always `_timestamp` (microseconds).

4. Dashboards — `GET|POST|PUT|DELETE $BASE/dashboards`

All take `?folder=<folder_id>` (default `default`).

# List
curl $AUTH "$BASE/dashboards?folder=default"

# Get one (returns versioned wrapper {v1..v8, version, hash, updatedAt})
curl $AUTH "$BASE/dashboards/<dashboard_id>?folder=default"

# Create — body is the UNWRAPPED inner v8 object
curl $AUTH -X POST -H 'Content-Type: application/json' \
  "$BASE/dashboards?folder=default" \
  -d @dashboard-v8.json

# Update — REQUIRES the current hash for optimistic concurrency
HASH=$(curl -s $AUTH "$BASE/dashboards/<id>?folder=default" | jq -r .hash)
curl $AUTH -X PUT -H 'Content-Type: application/json' \
  "$BASE/dashboards/<id>?folder=default&hash=$HASH" \
  -d @updated-dashboard.json

# Delete
curl $AUTH -X DELETE "$BASE/dashboards/<id>?folder=default"

# Move between folders
curl $AUTH -X PUT -H 'Content-Type: application/json' \
  "$BASE/folders/dashboards/<id>" \
  -d '{"from":"default","to":"<target_folder_id>"}'

**Critical: PUT/POST body must be the unwrapped inner v8 object**, not the full `{v1..v8, version, hash}` wrapper. The server returns the wrapper but expects you to send only the inner object back.

# Read, mutate, write — the correct pattern
RAW=$(curl -s $AUTH "$BASE/dashboards/<id>?folder=default")
HASH=$(echo "$RAW" | jq -r .hash)
echo "$RAW" | jq '.v8 | .title = "New Title"' \
  | curl -s $AUTH -X PUT -H 'Content-Type: application/json' \
    "$BASE/dashboards/<id>?folder=default&hash=$HASH" -d @-

A `409 Conflict` response means the hash is stale — refetch and retry.

Per-panel operations (v8 only — return new hash)

# Add panel
curl $AUTH -X POST -H 'Conten
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withclaude-codex-settings

Battle-tested Claude Code, OpenAI Codex, Cursor configs, plugins, hooks and agents with Kimi, MiniMax and GLM API support.

Get the whole plugin, auto-invoked
Stats
955
Stars
0
Views
83
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
7h ago
Last commit
1y ago
Created

Repo: fcakyon/claude-codex-settings

Other skills on claude-codex-settings.