Reference¶
CLI Tree¶
The complete CLI tree is rendered by ChatStyle. See CLI Tree. chatevent --tree is the full view with parameter signatures, while chatevent --tree-brief is the compact view without signatures; both are shared by docs and tests.
HTTP API¶
| Method | Path | Purpose |
|---|---|---|
GET |
/api/health |
Health check and current SQLite DB path. |
POST |
/api/login |
Username/password Web login; sets browser cookie. |
POST |
/api/logout |
Clear browser cookie. |
GET |
/api/session |
Return current API token or cookie identity. |
GET |
/login |
Default ChatLogin login page. |
GET |
/login/assets/{name} |
Public ChatLogin login JS/CSS assets. |
GET |
/api/users |
Admin-only user list. |
POST |
/api/users |
Admin creates a username/password user. |
POST |
/api/me/token |
Current account issues a one-time arch_xxx API token. |
POST |
/api/users/{id}/token |
Admin issues a one-time API token for a user. |
DELETE |
/api/users/{id} |
Admin deletes a user. |
GET |
/api/schema/event |
Return the ChatEvent JSON Schema. |
GET |
/api/schema/subscription |
Return the Subscription JSON Schema. |
GET |
/api/platforms |
Return the platform action catalog. |
POST |
/api/subscriptions |
Create or update a subscription. |
GET |
/api/subscriptions |
List subscriptions. |
DELETE |
/api/subscriptions/{id} |
Delete a subscription without deleting captured events. |
POST |
/api/events |
Record one normalized ChatEvent. |
GET |
/api/events |
Query events with source, kind, subscription, keyword, since checkpoint, recent-day, and captured-at range filters. |
GET |
/api/events/{dedupe_key} |
Read one stored event. |
GET |
/api/stats |
Return event/source/duplicate statistics. |
POST |
/webhooks/zulip |
Receive Zulip event-queue/message payloads. |
POST |
/webhooks/discourse |
Receive Discourse webhook payloads. |
POST |
/webhooks/gitea |
Receive Gitea webhook payloads. |
POST |
/webhooks/github |
Receive GitHub webhook payloads. |
CLI and REST API mapping¶
chatevent api ... is the command-line client for the REST API. It reads CHATEVENT_API_URL by default and falls back to http://127.0.0.1:8765.
| CLI | REST API |
|---|---|
chatevent api health |
GET /api/health |
chatevent api stats |
GET /api/stats |
chatevent api platforms |
GET /api/platforms |
chatevent api schema event |
GET /api/schema/event |
chatevent api subscriptions |
GET /api/subscriptions |
chatevent api subscription <id> |
GET /api/subscriptions/{id} |
chatevent api events --source discourse --days 7 |
GET /api/events?... |
chatevent api event <dedupe_key> |
GET /api/events/{dedupe_key} |
chatevent api record-json event.json |
POST /api/events |
chatevent api save-subscription subscription.json |
POST /api/subscriptions |
chatevent api delete-subscription <id> |
DELETE /api/subscriptions/{id} |
Action and carrier target fields¶
Both ChatEvent and Subscription support structured action targets while keeping old fields compatible:
Subscription.target: canonical string for display and hand-written config.Subscription.scope: structured carrier target withtype,key,display,url,parent, andmetadata;typeis open-ended.Subscription.actions: structured action selectors; if onlyevent_kindsis provided, the service derives them automatically.ChatEvent.action: concrete action withkind,object_type,verb, andmetadata.ChatEvent.actor/actor_role: initiator and platform-specific role; role stays an open string, e.g. maintainer, member, bot, or moderator.ChatEvent.target: concrete object acted on;parentlinks repo/PR/comment or stream/topic/message carrier chains.
Old clients that only send kind, subject_id, and subject_type remain valid. New adapters write full action and target whenever possible.
Query events¶
curl -k 'https://event.public.wzhecnu.cn/api/events?source=discourse&kind=reply.created&days=7&limit=20'
Downstream systems consume by checkpoint:
curl -k 'https://event.public.wzhecnu.cn/api/events?source=discourse&subscription_id=discourse-practice&since=2026-08-18T12:47:37Z&limit=50'
Common parameters:
| Parameter | Meaning |
|---|---|
source |
Platform source such as discourse. |
kind |
Event kind such as reply.created. |
subscription_id |
Subscription id. |
since |
Consumer checkpoint: return only events with captured_at > since; timezone is required, e.g. 2026-08-18T12:47:37Z. |
days |
Shortcut date filter: return events captured in the last N days, e.g. days=7. |
from |
Captured-at range start: return events with captured_at >= from; timezone is required. |
to |
Captured-at range end: return events with captured_at <= to; timezone is required. |
q |
Keyword search across payload, actor, and conversation fields. |
limit |
Number of events to return, from 1 to 500. |
Responses include items, count, latest_captured_at, and next_since. Consumers should save next_since after successful processing and send it as since on the next poll. The Observatory uses days for the last 24 hours / 3 days / 7 days / 30 days presets, and from/to for custom ranges.
Deduplication¶
The default dedupe key is:
Repeated delivery of the same event does not create a new row; it increments seen_count and contributes to /api/stats duplicate_count.
Storage and online editing¶
Subscription configuration and the event ledger are stored in SQLite. The default database is inside ChatEnv/ChatArch home:
Path precedence is --db, CHATEVENT_DB, ChatEnv get_paths().home_dir/chatevent/events.db, $CHATARCH_HOME/chatevent/events.db, then ~/.chatarch/chatevent/events.db. On first default-path use, if legacy ~/.chatevent/events.db exists and the new database does not, ChatEvent copies it into the ChatArch-internal path and keeps the legacy file.
subscriptions.body stores the full Subscription JSON, including last_cursor and last_event_at updates after events arrive; events.body stores the full ChatEvent JSON.
The Web Observatory Subscriptions tab can create, edit, enable/disable, and delete subscriptions. Production or public deployments should configure user login and may keep a bootstrap API token: CHATEVENT_ADMIN_TOKEN first, then CHATEVENT_ADMIN_TOKEN_FILE, then the default file $CHATARCH_HOME/chatevent/secrets/admin-token or ~/.chatarch/chatevent/secrets/admin-token. The bootstrap token is for API/CLI initialization or recovery only; it is not a Web login credential.
Temporary Zulip Topic Watches¶
Temporary topic watches are ordinary Subscription records with a documented contract:
{
"source": "zulip",
"target": "stream:voice note/topic:assignment-123",
"event_kinds": ["message.created"],
"capture_modes": ["api_cursor", "poll"],
"filters": {"stream": "voice note", "topic": "assignment-123"},
"metadata": {
"temporary": true,
"assignment_id": "assign-123",
"interval_seconds": 5,
"expires_at": "2026-08-26T12:30:00+00:00",
"hot_until": "2026-08-26T12:15:00+00:00",
"reason": "active assignment clarification",
"content_policy": "topic-scoped-message-content",
"policy_boundary": "platform-scope-only; consumer filters sender/assignment policy"
}
}
chatevent capture subscription-once currently supports Zulip topic subscriptions through the /messages API and stores the newest message id in last_cursor. Normalized Zulip events include payload.sender_id, payload.sender_email, payload.sender_full_name, payload.sender_is_bot, actor.id, actor.display, and actor.metadata.email. ChatEvent does not filter for Rex, assignment tags, confirmation words, or bot/self policy; consumers such as ChatAssign apply those predicates when they query Event.
Login, User Management, And Isolation¶
ChatEvent uses a minimal username/password + API token model. EventStore remains authoritative for accounts, roles, enabled state, and tokens:
GET /: when users or bootstrap credentials are configured, unauthenticated callers receive the default ChatLogin page; authenticated callers receive the Observatory.GET /login: returns ChatLoginLoginUI;nextaccepts only safe local absolute paths, and mounted/root_path deployments get prefixed form and asset URLs.POST /api/login: validateusername/passwordand set a browser cookie. The response keeps the oldSessionStatusfields and additionally returns canonicalcsrf_tokenand a safenext.POST /api/logout: clear the browser cookie. Cookie-session calls must includeX-CSRF-Token.GET /api/session: validate the currentX-ChatEvent-Admin-Tokenor cookie and returnadmin_required,authenticated,user, whether the caller is the bootstrap admin, and the cookie session CSRF token. Anonymous callers still receive 200.GET /api/users: list users as an administrator.POST /api/users: create a username/password user; the server stores only the password hash. Cookie sessions must include CSRF; successfully validated API tokens and the legacy admin token are CSRF-exempt.POST /api/me/token: issue a one-timearch_xxxAPI token for the current logged-in account. Cookie sessions must include CSRF.POST /api/users/{id}/token: issue a one-time API token for a target user as an administrator. Cookie sessions must include CSRF.DELETE /api/users/{id}: delete a user as an administrator. Cookie sessions must include CSRF.
After an admin token or users exist, read APIs such as /api/stats, /api/events, /api/events/{dedupe_key}, schema, platforms, and subscriptions require login. Cookie-authenticated subscription writes and deletes also require CSRF. Only truly validated arch_xxx API tokens or the legacy admin token are CSRF-exempt; a forged token header does not bypass cookie CSRF. Event-write and webhook endpoints remain reachable so platform events can still arrive.
CHATEVENT_BOOTSTRAP_USERNAME and CHATEVENT_BOOTSTRAP_PASSWORD_FILE can initialize the first administrator account. Password storage keeps the pbkdf2_sha256$iterations$salt_hex$digest_hex string format. ChatEvent delegates new password hashing and existing password verification to ChatLogin PBKDF2 helpers, but it does not rewrite existing users merely for migration. Browser sessions use ChatLogin SessionManager with a bounded in-memory store; every protected request re-reads the current EventStore user enabled state and role instead of authorizing from the session snapshot. CHATEVENT_SESSION_TTL_SECONDS and CHATEVENT_MAX_SESSIONS tune TTL and capacity.
CHATEVENT_ADMIN_TOKEN / secrets/admin-token is the bootstrap administrator API credential for CLI/model/API user creation or recovery. Subscription.owner_user_id is the current isolation boundary: subscriptions created by member accounts are automatically owned by that user; members can only read, update, and delete their own subscriptions; admins can manage all subscriptions. The event stream remains an Observatory debugging view for now and can be tightened by tenant/user owner later.