Skip to content

Daemon HTTP API

Health, config, and reload

  • GET /v1/health
  • GET /v1/config
  • POST /v1/reload

GET /v1/config returns the active effective runtime configuration, including the resolved configuration path and post-environment-expansion values. Secret-like fields such as passwords, tokens, API keys, authorization values, credentials, and private keys are recursively replaced with <redacted>. The route is an admin /v1/* endpoint and therefore uses the same CALL_BAXTER_API_KEY protection as the other control-plane reads when admin authentication is enabled. Daemon startup logs also state the resolved config path without dumping secret values.

POST /v1/reload rereads the original YAML configuration file. It validates plugins and the complete rule set, reconciles schedules transactionally, disables removed schedules, and only then swaps the live runtime state. Invalid or duplicate rules return an error and leave the current runtime active.

The daemon also watches the configuration file by default. Changes are reloaded through the same validated atomic path. Set CALL_BAXTER_CONFIG_RELOAD_ENABLED=false to disable the watcher or CALL_BAXTER_CONFIG_RELOAD_SECONDS to change its interval.

For a daemon bound only to a Unix socket, run:

call-baxter \
  --config-file /etc/call-baxter/config.yml \
  --daemon-url http+unix:///run/call-baxter/cb.sock \
  health

When daemon admin authentication is enabled, set CALL_BAXTER_API_KEY for both the daemon and the health-check process, or pass --daemon-api-key. The HTTP client raises on 4xx/5xx responses and health exits non-zero unless the response contains "ok": true, so Docker does not mistake an authentication error for a healthy service.

Registry and rule inspection

  • GET /v1/plugins
  • GET /v1/rules
  • GET /v1/context/events
  • GET /v1/context/actions

Events and actions

  • GET /v1/events
  • POST /v1/events/publish
  • GET /v1/actions
  • POST /v1/actions/execute

Ingress and pollers

  • GET /v1/ingress
  • GET /v1/ingress/runs — list durable ingress ledger entries
  • POST /v1/ingress/runs/{ingress_ref}/reingest — rerun a stored payload through its original ingress
  • POST /v1/ingress/{name} — synchronous by default; add ?async=true for a receipt
  • POST /v1/webhooks/{name} — asynchronous by default; add ?async=false for the result
  • GET /v1/ingress/results/{receipt_ref} — inspect an in-process async receipt
  • GET /v1/pollers
  • POST /v1/pollers/{name}/run

Async ingress validates authentication and the ingress name before returning HTTP 200. Processing then runs outside the ASGI event loop. Start logs include the ingress and a safe payload-kind classification. Completion logs include emitted event references with their source/kind, matched-rule identifiers, action statuses, and failures. A receipt progresses through accepted, processing, and either complete or failed.

Receipt storage is process-local and capped for diagnostics. Only terminal complete or failed receipts are eligible for trimming; accepted and processing receipts remain available until their work reaches a terminal state.

Ingress runs are also recorded durably in SQLite before handler execution. The ledger preserves the ingress name, original payload, terminal status, result, and error text. Use call-baxter ingress runs to find a run and call-baxter ingress reingest ing:123 to reintroduce that payload under the currently loaded config and rules.

The synchronous /v1/events/publish contract is unchanged.

telegram.updates schedules should configure an explicit offset or one of projection_database_url, database_url, or tg_database_url. The daemon logs a startup warning when an enabled Telegram polling schedule lacks all offset persistence.

YAML environment expansion

All YAML string values support ${VAR} and ${VAR:-default}. The latter uses its default when the environment variable is unset or empty. Expansion happens before Pydantic validation and before every manual or automatic reload.

Schedules

  • GET /v1/schedules
  • POST /v1/schedules/sync
  • POST /v1/schedules/run-due

Schedule execution is protected by SQLite leases, so a manual run-due request cannot race the daemon background loop or another replica into executing the same due schedule twice.