ServicesInbox

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 KunCSRQzLPryQwbHxSfp

The 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_producers list 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, HTTP technical_notes.summary) or it fails with 400 technical_notes_required. Notes are structured handoff context: summary, risk level, open questions, successor hint.
  • Actions gate - attaching actions on a channel without actions_allowed fails with 400 actions_not_allowed.
  • Scheduled delivery gate - a future deliver_at on a channel without scheduled_delivery_allowed fails with 400 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:01Z

Promotion 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.

On this page