Daemon & Automation
hrida-oikb daemon is the production mode. It reads .hrida-oikb.yaml, syncs every entry on its schedule, and runs a small HTTP server for webhooks, status, manual triggers and metrics.
hrida-oikb daemon # port 8080
hrida-oikb daemon --port 9000
hrida-oikb daemon --config /etc/hrida-oikb/config.yaml
hrida-oikb daemon --no-server # scheduler only, no HTTP server
hrida-oikb daemon --log-format jsonScheduling
Set interval per entry, or once under defaults. Simple intervals and cron expressions can be mixed; OIKB tells them apart automatically.
interval: 30m # every 30 minutes
interval: 6h # every 6 hours
interval: "0 6 * * 1-5" # weekdays at 06:00
interval: "0 0 * * 0" # Sundays at midnightSync locking: two syncs never run against the same Knowledge Base at once. If a webhook fires while a scheduled sync is running, the duplicate is skipped and logged.
Status dashboard
Open the daemon's root URL (http://localhost:8080/) for a live status page: every source with its status, last sync time, duration, file counts and next run. It refreshes every 10 seconds.
HTTP API
| Endpoint | Auth | Description |
|---|---|---|
GET / | Public | Status dashboard |
GET /health | Public | JSON status for every source (last sync, duration, counts, errors). Use as a readiness probe |
GET /health/ready | Public | Lightweight liveness probe, {"ready": true} |
GET /metrics | Public | Prometheus metrics |
GET /history | API key | Sync history. Query: limit, kb_id, errors_only=true |
POST /sync/{name-or-kb-id} | API key | Start a sync now. Add ?dry_run=true to preview |
POST /webhooks/github · /gitlab · /slack · /confluence | Signature | Change notifications from the source system |
API key
Set HRIDA_OIKB_API_KEY (or HRIDA_OIKB_API_KEY_FILE for a Docker secret) to protect /history and /sync:
curl -X POST http://localhost:8080/sync/wiki \
-H "Authorization: Bearer $HRIDA_OIKB_API_KEY"
curl -X POST "http://localhost:8080/sync/wiki?dry_run=true" \
-H "Authorization: Bearer $HRIDA_OIKB_API_KEY"
# {"dry_run": true, "name": "wiki", "kb_id": "...", "result": {"added": 3, "modified": 1, "deleted": 0}}Without HRIDA_OIKB_API_KEY, anyone who can reach the daemon can trigger syncs and read history. Always set it when the port is reachable from other machines.
Let the AI manage syncs
The daemon is also an OpenAPI tool server. In Hrida.ai, add http://hrida-oikb:8080 as a Tool Server (Settings → Connections) with the daemon API key. The AI can then check sync status (get_sync_status), read history (get_sync_history) and start syncs (trigger_sync) from chat. For example: "Is the handbook up to date? If not, sync it."
Webhooks
Sync the moment content changes instead of waiting for the next interval.
-
Mark the entry with
webhook: true, and optionally set a signing secret:yamlsources: - name: docs source: github:owner/repo kb-id: abc123 webhook: true github_secret: ${GITHUB_WEBHOOK_SECRET} -
In the source system, point a webhook at the daemon:
Provider URL Verification GitHub https://oikb.example.com/webhooks/githubgithub_secret(HMAC SHA-256)GitLab /webhooks/gitlabgitlab_secret(token header)Slack /webhooks/slackslack_signing_secretConfluence /webhooks/confluenceNone. Keep this route behind your proxy's access rules
Good to know:
- An entry is triggered only when both its
sourcematches the event and it haswebhook: true. - A push that matches no entry still returns HTTP 200 with
{"status": "ignored"}. If a push doesn't trigger a sync, check the daemon logs rather than the provider's delivery status. - A missing or wrong signature (when a secret is set) returns HTTP 403.
- Signing secrets are shared across the daemon: one
github_secretapplies to every GitHub webhook entry. - Webhooks must be reachable from the internet. Put a TLS reverse proxy in front (see Deployment).
Failure notifications
Post to Slack (or any webhook) when a sync fails:
notify:
url: https://hooks.slack.com/services/T.../B.../xxx
on: error # error (default) | alwaysThe JSON payload has a Slack-ready text field plus source, status, error and duration_ms.
Monitoring
Prometheus metrics
GET /metrics exports, labelled by source:
| Metric | Type | Description |
|---|---|---|
hrida_oikb_sync_total | Counter | Syncs by source and status |
hrida_oikb_sync_duration_seconds | Histogram | Sync duration |
hrida_oikb_files_uploaded_total | Counter | Files added and modified |
hrida_oikb_files_deleted_total | Counter | Files deleted |
hrida_oikb_sync_errors_total | Counter | Failed syncs |
hrida_oikb_info | Info | Build version |
scrape_configs:
- job_name: hrida-oikb
static_configs:
- targets: ["hrida-oikb:8080"]JSON logs
--log-format json or LOG_FORMAT=json writes one JSON object per line, ready for Datadog, Splunk, ELK, CloudWatch or Loki:
{"ts":"2026-05-21T06:00:01Z","level":"INFO","logger":"hrida-oikb.daemon","msg":"Synced github:owner/repo → abc123: 3 added (1823ms)"}History
Every sync is recorded in a local SQLite database:
hrida-oikb history # table
hrida-oikb history --errors # failures only
hrida-oikb history --json --limit 50
hrida-oikb history --clear --days 30 # prune old entriesUploads that hit a temporary server error (5xx) are retried up to 3 times with exponential backoff.