Channels and Delivery
Channels are where inbox policy lives: who may send, what a message must
carry, and how delivery behaves. Creating or managing them requires a
platform admin or service principal token - a regular user token gets
403 insufficient_permissions ("channel administration requires admin or
service principal"). Reading and listing channels is open to any
authenticated user.
Creating channels
snug inbox channel create --name docs4.alerts \
--description "Docs guide channel" \
--actions-allowed --scheduled-delivery-allowed
snug inbox channel list
snug inbox channel get --channel-id KunCSRQzLPryQwbHxSfpThe created channel (captured live) - note the server assigns a random
channel_id, which is what every send and filter refers to, not the
name:
{
"channel_id": "KunCSRQzLPryQwbHxSfp",
"name": "docs4.alerts",
"allowed_producers": [],
"default_priority": "normal",
"retention_days": 90,
"actions_allowed": true,
"technical_notes_required": false,
"delivery_policy": {
"pubsub_topic": null,
"scheduled_delivery_allowed": true,
"websocket_fanout": false
},
"created_by": "docs-wave-admin", ...
}There is no delete or update endpoint - channel policy is fixed at
creation. The HTTP list endpoint supports q over name and description
(GET /api/v1/inbox/channels?q=docs4); the CLI channel list takes no
flags.
Policy gates on send
Each gate below applies to a restricted channel created with --producer svc-docs4 --technical-notes-required:
- Producer allowlist - an empty
allowed_producerslist means any authenticated user may send. A non-empty list admits only the listed principal ids (and platform admins). Anyone else:403 producer_not_allowed. - Technical notes - with
technical_notes_required, a send must include technical notes with a non-empty summary (CLI--notes, HTTPtechnical_notes.summary) or it fails with400 technical_notes_required. Notes are structured handoff context: summary, risk level, open questions, successor hint. - Actions gate - attaching actions on a channel without
actions_allowedfails with400 actions_not_allowed. - Scheduled delivery gate - a future
deliver_aton a channel withoutscheduled_delivery_allowedfails with400 scheduled_delivery_not_allowed.
Scheduled delivery
On a channel that allows it, a future deliver_at returns
"status": "scheduled" and the message stays invisible to the recipient
until due:
snug inbox send --to user_123 --channel KunCSRQzLPryQwbHxSfp \
--title "Scheduled ping" --msg "See you soon" \
--deliver-at 2026-08-28T05:04:01ZPromotion is automatic: the server runs delivery workers on a roughly one-second tick. The message was absent from the list immediately after sending and present a few seconds after its due time, with no manual step.
Expiry and self-destruct
Two per-message controls, both HTTP-only fields on send:
expires_at- the message is swept once the timestamp passes.self_destruct_after_read_seconds- a countdown that starts when the message is read. With a 2-second fuse: after reading and waiting, the message was not deleted but redacted - title replaced with[self-destructed], body emptied, and the message auto-archived.
The same background workers that promote scheduled messages run these sweeps continuously.
Manual maintenance
POST /api/v1/inbox/maintenance/run (CLI: snug inbox maintenance)
force-runs one round of the promotion, expiry, and self-destruct sweeps
and reports what it did. It requires a platform admin token - a regular
user gets 403 insufficient_permissions:
{ "promoted": 0, "expired": 0, "self_destructed": 0 }Since the server sweeps on its own, this endpoint is for operations - forcing a sweep in tests or after bulk imports - not something clients need in normal use.