Files
coder/docs/admin/monitoring/notifications/index.md
T
Nick Vigilante d40e24cf7d docs: nest the CLI reference by subcommand (#29956)
## Summary

Nests the CLI reference by subcommand so the Command Line sidebar
collapses from 156 flat entries to 49 top-level verbs.
Each page's URL follows the invocation, its page title is the full
command as inline code, and its sidebar label is only its own verb as
inline code.

| | Before | After |
| --- | --- | --- |
| File | `docs/reference/cli/oauth2-provider_dcr_disable.md` |
`docs/reference/cli/oauth2-provider/dcr/disable.md` |
| URL | `/reference/cli/oauth2-provider_dcr_disable` |
`/reference/cli/oauth2-provider/dcr/disable` |
| Page title (front matter) | `oauth2-provider dcr disable` | `` `coder
oauth2-provider dcr disable` `` |
| Sidebar label (manifest) | `oauth2-provider dcr disable` | ``
`disable` `` |

Resolves DOCS-140 (coder/coder half). Also fixes the Makefile part of
DOCS-1073 / DOCS-912, which this change depends on.

## Changes

- `scripts/clidocgen`: pages nest by command path. A command with
visible subcommands becomes its directory's `index.md`, so
`oauth2-provider/index.md` and `oauth2-provider/dcr/index.md` sit above
`oauth2-provider/dcr/disable.md`. Subcommand table links are relative to
the parent page.
- `scripts/clidocgen`: the manifest "Command Line" section is built from
the command tree (nested, sorted by name, hidden commands skipped)
instead of a flat list. The redundant `coder` child that pointed back at
`reference/cli/index.md` is gone.
- `Makefile`: the CLI rule now replaces `docs/reference/cli/` wholesale,
so stale pages get removed. The manifest rule now runs `clidocgen
-manifest-only` on top of the API staging manifest, so the CLI nav is
generated instead of edited by hand. As a result, the nine pages that
had no nav entry (`ai-gateway*`, `secret enable/disable`, `server
fix-oidc-links`) now have one.
- `scripts/configdocgen` and 48 prose pages: links point at the new
paths (for example `reference/cli/server.md` is now
`reference/cli/server/index.md`).

## How to review/QA this PR

- `docs/reference/cli/**/*` (approximately 190 pages): Each of these
pages are generated automatically. Some pages appear deleted, and some
pages appear new. Every deleted page corresponds to a new page somewhere
else, so no information is being deleted. The docs in this section
should adhere to the following, so a test in the build preview for each
of these items should be satisfactory:
- [ ] Each subcommand of a command gets nested as a child instead of
being displayed as a flat list.
  - [ ] Each parent command is stored in an `index.md` file.
- [ ] The title of each page inside the page should now feature the full
`coder XYZ` command.
- [ ] The title of each page inside the page should now be formatted as
inline code.
- [ ] The title of each page in the sidebar should be the most granular
subcommand of the whole command string (if the page's title is `coder
ai-gateway keys create`, the sidebar label is `create`).
- [ ] The title of each page in the sidebar should now be formatted as
inline code.
  - [ ] The page slug for each page is now the most granular subcommand.
  - [ ] All links now point to the correct page.
- `docs/manifest.json`: The changes here reflect the updated structure
of the `docs/reference/cli` section.
- `docs/**/*.md` outside of `docs/reference/cli/**/*` (approximately 50
pages): The extent of the changes in these pages are just updating the
paths to point to the new page locations.
- [ ] The links on the page all point to the correct new path in
`docs/reference/cli`.
- `scripts/clidocgen` (4 files): This is the Go code responsible for
generating everything inside of `docs/reference/cli/**/*`. A typical
code review here should be satisfactory.
- `scripts/configdocgen` (2 files): these two files just have updates to
the raw `.md` path used by `docs/admin/setup/configuration-reference.md`
and updates the tests to reflect that.
- `Makefile`: This updates the `make` targets for generating the CLI
docs to fit the new structure.

## Merge ordering

Without the renderer PRs deployed, both docs sites show literal
backticks in titles and sidebar labels. Without the redirects, the old
flat URLs return 404.

1. Deploy before merging this PR: coder/docs-engine#176 (beta-docs
renders these titles as inline code) and coder/coder.com#1111 (classic
docs renders them as inline code). Both are safe to ship first, because
titles without backticks render as before.
2. Merge this PR.
3. Merge coder/coder.com#1112 (redirects from the old flat URLs) only
once this content reaches the mainline release branch that serves
unversioned `/docs`.

## Testing

- `go test ./scripts/clidocgen/ ./scripts/configdocgen/
./scripts/docshtmlcheck/`: pass. New tests cover page paths, subcommand
links, the nested manifest, and front matter quoting.
- `make docs/reference/cli/index.md docs/manifest.json
docs/admin/setup/configuration-reference.md`, then a forced rerun: the
second run produced no diff.
- Checked the manifest: all 164 CLI entries resolve to a file, no page
is missing a nav entry, and everything outside "Command Line" is
byte-identical.
- Relative `.md` links across `docs/`: 0 broken, same as `main`.
- `make pre-commit` and `make pre-push`: pass. On earlier pre-push
attempts, different unrelated vitest files timed out under host load.
Those files pass when run alone, and the final push passed with
`PARALLEL_JOBS=1`.

<details>
<summary>Implementation plan and decision log</summary>

**Goal (from DOCS-140 and the requester):** URLs follow the command
hierarchy. Pages are titled with the full command, and sidebar entries
with the last verb only. Both are formatted as inline code.

**Contract with the renderers:** a title wrapped entirely in one pair of
backticks (``^`[^`]+`$``) renders as inline code. Plain-text consumers
(`<title>`, meta, search, llms corpus) strip the backticks. Page title
comes from front matter `title`, and the sidebar label from the manifest
node `title`.

**Decisions**

- A parent command is `dir/index.md` rather than a sibling `dir.md`. The
root CLI page is already `index.md`, and both docs-engine and the legacy
coder.com renderer map `x/index.md` to `/x`.
- The manifest is built from the command tree, not from the written
files, so ordering is deterministic and the nesting matches the pages
exactly.
- The manifest discard bug (DOCS-1073 item 1) is fixed here, because
without that fix the generated nested manifest would never reach the
tree. DOCS-1073 items 2 through 4 (a prose fix and a hidden-command
policy) are out of scope.
- `-manifest-only` keeps the existing parallel `make gen` layout: the
API rule still owns `_gen/manifest-staging.json`, and CLI regeneration
doesn't retrigger swag.
- The renderer and redirect work lives in the companion PRs in
coder/docs-engine and coder/coder.com. It is linked above and not
duplicated here.

</details>

---

> [!NOTE]
> Generated by Coder Agents on behalf of @nickvigilante.
2026-09-28 15:44:10 -04:00

17 KiB
Raw Blame History

title
title
Notifications

Notifications are sent by Coder in response to specific internal events, such as a workspace being deleted or a user being created.

Available events may differ between versions. For a list of all events, visit your Coder deployment's https://coder.example.com/deployment/notifications.

Event Types

Notifications are sent in response to internal events, to alert the affected user(s) of the event.

Coder supports the following list of events:

Template Events

These notifications are sent to users with template admin roles:

  • Report: Workspace builds failed for template
    • This notification is delivered as part of a weekly cron job and summarizes the failed builds for a given template.
  • Template deleted
  • Template deprecated

User Events

These notifications are sent to users with owner and user admin roles:

  • User account activated
  • User account created
  • User account deleted
  • User account suspended

These account notifications cover both user and service accounts.

These notifications are sent to users themselves:

  • User account suspended
  • User account activated
  • User password reset (One-time passcode)

Workspace Events

These notifications are sent to the workspace owner:

  • Workspace automatic build failure
  • Workspace autostop reminder
  • Workspace created
  • Workspace deleted
  • Workspace manual build failure
  • Workspace manually updated
  • Workspace marked as dormant
  • Workspace marked for deletion
  • Out of memory (OOM) / Out of disk (OOD)
  • Workspace automatically updated

Delivery Methods

Notifications can be delivered through the Coder dashboard Inbox and by SMTP or webhook. OOM/OOD notifications can be delivered to users in VS Code.

You can configure:

Premium customers can configure which method to use for each of the supported Events. See the Preferences section for more details.

Configuration

You can modify the notification delivery behavior in your Coder deployment's https://coder.example.com/settings/notifications, or with the following server flags:

Required CLI Env Type Description Default
✔️ --notifications-dispatch-timeout CODER_NOTIFICATIONS_DISPATCH_TIMEOUT duration How long to wait while a notification is being sent before giving up. 1m
✔️ --notifications-method CODER_NOTIFICATIONS_METHOD string Which delivery method to use (available options: 'smtp', 'webhook'). See Delivery Methods below. smtp
-️ --notifications-max-send-attempts CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS int The upper limit of attempts to send a notification. 5
-️ --notifications-inbox-enabled CODER_NOTIFICATIONS_INBOX_ENABLED bool Enable or disable inbox notifications in the Coder dashboard. true

Configure OOM/OOD notifications

You can monitor out of memory (OOM) and out of disk (OOD) errors and alert users when they overutilize memory and disk.

This can help prevent agent disconnects due to OOM/OOD issues.

To enable OOM/OOD notifications on a template, follow the steps in the resource monitoring guide.

SMTP (Email)

Use the smtp method to deliver notifications by email to your users. Coder does not ship with an SMTP server, so you will need to configure Coder to use an existing one.

Server Settings:

Required CLI Env Type Description Default
✔️ --email-from CODER_EMAIL_FROM string The sender's address to use (e.g. "Coder <coder@example.com>").
✔️ --email-smarthost CODER_EMAIL_SMARTHOST string The SMTP relay to send messages (format: hostname:port)
✔️ --email-hello CODER_EMAIL_HELLO string The hostname identifying the SMTP server. localhost

Authentication Settings:

Required CLI Env Type Description
- --email-auth-username CODER_EMAIL_AUTH_USERNAME string Username to use with PLAIN/LOGIN authentication.
- --email-auth-password CODER_EMAIL_AUTH_PASSWORD string Password to use with PLAIN/LOGIN authentication.
- --email-auth-password-file CODER_EMAIL_AUTH_PASSWORD_FILE string File from which to load password for use with PLAIN/LOGIN authentication.
- --email-auth-identity CODER_EMAIL_AUTH_IDENTITY string Identity to use with PLAIN authentication.

TLS Settings:

Required CLI Env Type Description Default
- --email-force-tls CODER_EMAIL_FORCE_TLS bool Force a TLS connection to the configured SMTP smarthost. If port 465 is used, TLS will be forced. See https://datatracker.ietf.org/doc/html/rfc8314#section-3.3. false
- --email-tls-starttls CODER_EMAIL_TLS_STARTTLS bool Enable STARTTLS to upgrade insecure SMTP connections using TLS. Ignored if CODER_EMAIL_FORCE_TLS is set. false
- --email-tls-skip-verify CODER_EMAIL_TLS_SKIPVERIFY bool Skip verification of the target server's certificate (insecure). false
- --email-tls-server-name CODER_EMAIL_TLS_SERVERNAME string Server name to verify against the target certificate.
- --email-tls-cert-file CODER_EMAIL_TLS_CERTFILE string Certificate file to use.
- --email-tls-cert-key-file CODER_EMAIL_TLS_CERTKEYFILE string Certificate key file to use.

NOTE: you MUST use CODER_EMAIL_FORCE_TLS if your smarthost supports TLS on a port other than 465.

Send emails using G-Suite

After setting the required fields above:

  1. Create an App Password using the account you wish to send from.

  2. Set the following configuration options:

    CODER_EMAIL_SMARTHOST=smtp.gmail.com:465
    CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
    CODER_EMAIL_AUTH_PASSWORD="<app password created above (no spaces)>"
    

    Note: The CODER_EMAIL_AUTH_PASSWORD must be entered without spaces.

See this help article from Google for more options.

Send emails using Outlook.com

After setting the required fields above:

  1. Set up an account on Microsoft 365 or outlook.com

  2. Set the following configuration options:

    CODER_EMAIL_SMARTHOST=smtp-mail.outlook.com:587
    CODER_EMAIL_TLS_STARTTLS=true
    CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
    CODER_EMAIL_AUTH_PASSWORD="<account password>"
    

See this help article from Microsoft for more options.

Webhook

The webhook delivery method sends an HTTP POST request to the defined endpoint. The purpose of webhook notifications is to enable integrations with other systems.

Settings:

Required CLI Env Type Description
✔️ --notifications-webhook-endpoint CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT url The endpoint to which to send webhooks.

Here is an example payload for Coder's webhook notification:

{
    "_version": "1.0",
    "msg_id": "88750cad-77d4-4663-8bc0-f46855f5019b",
    "payload": {
        "_version": "1.0",
        "notification_name": "Workspace Deleted",
        "user_id": "4ac34fcb-8155-44d5-8301-e3cd46e88b35",
        "user_email": "danny@coder.com",
        "user_name": "danny",
        "user_username": "danny",
        "actions": [
            {
                "label": "View workspaces",
                "url": "https://et23ntkhpueak.pit-1.try.coder.app/workspaces"
            },
            {
                "label": "View templates",
                "url": "https://et23ntkhpueak.pit-1.try.coder.app/templates"
            }
        ],
        "labels": {
            "initiator": "danny",
            "name": "my-workspace",
            "reason": "initiated by user"
        }
    },
    "title": "Workspace \"my-workspace\" deleted",
    "body": "Hi danny\n\nYour workspace my-workspace was deleted.\nThe specified reason was \"initiated by user (danny)\"."
}

The top-level object has these keys:

  • _version: describes the version of this schema; follows semantic versioning
  • msg_id: the UUID of the notification (matches the ID in the notification_messages table)
  • payload: contains the specific details of the notification; described below
  • title: the title of the notification message (equivalent to a subject in SMTP delivery)
  • body: the body of the notification message (equivalent to the message body in SMTP delivery)

The payload object has these keys:

  • _version: describes the version of this inner schema; follows semantic versioning
  • notification_name: name of the event which triggered the notification
  • user_id: Coder internal user identifier of the target user (UUID)
  • user_email: email address of the target user
  • user_name: name of the target user
  • user_username: username of the target user
  • actions: a list of CTAs (Call-To-Action); these are mainly relevant for SMTP delivery in which they're shown as buttons
  • labels: dynamic map of zero or more string key-value pairs; these vary from event to event

User Preferences

All users have the option to opt-out of any notifications. Go to Account -> Notifications to turn notifications on or off. The delivery method for each notification is indicated on the right hand side of this table.

User Notification Preferences

Delivery Preferences

Note

Delivery preferences is a Premium feature. Learn more.

Administrators can configure which delivery methods are used for each different event type.

preferences

You can find this page under https://$CODER_ACCESS_URL/deployment/notifications?tab=events.

Custom notifications

Custom notifications let you send an ad‑hoc notification to yourself using the Coder CLI. These are useful for surfacing the result of long-running tasks or important state changes. At this time, custom notifications can only be sent to the user making the request.

To send a custom notification, execute coder notifications custom <title> <message>.

Note: The recipient is always the requesting user as targeting other users or groups isn’t supported yet.

Examples

  • Send yourself a quick update:
coder templates push -y && coder notifications custom "Template push complete" "Template version uploaded."
  • Use in a script after a long-running task:
#!/usr/bin/env bash
set -o pipefail

if make test 2>&1 | tee test_output.log; then
  coder notifications custom "Tests Succeeded" $'Test results:\n  • ✅ success'
else
  failures=$(grep -Po '\d+(?=\s+failures)' test_output.log | tail -n1 || echo 0)
  coder notifications custom "Tests Failed" $'Test results:\n  • ❌ failed ('"$failures"' tests failed)'
  exit 1
fi

Stop sending notifications

Administrators may wish to stop all notifications across the deployment. We support a killswitch in the CLI for these cases.

To pause sending notifications, execute coder notifications pause.

To resume sending notifications, execute coder notifications resume.

Troubleshooting

If notifications are not being delivered, use the following methods to troubleshoot:

  1. Ensure notifications are being added to the notification_messages table.

  2. Review any available error messages in the status_reason column

  3. Review the logs. Search for the term notifications for diagnostic information.

    • If you do not see any relevant logs, set CODER_LOG_FILTER=".*notifications.*" to filter for notification-related logs.
  4. If you are on version 2.15.x, notifications must be enabled using the notifications experiment.

    Notifications are enabled by default in Coder v2.16.0 and later.

Internals

The notification system is built to operate concurrently in a single- or multi-replica Coder deployment, and has a built-in retry mechanism. It uses the configured Postgres database to store notifications in a queue and facilitate concurrency.

All messages are stored in the notification_messages table.

Messages older than seven days are deleted.

Message States

states

A notifier here refers to a Coder replica which is responsible for dispatching the notification. All running replicas act as notifiers to process pending messages.

  • a message begins in pending state
  • transitions to leased when a Coder replica acquires new messages from the database
    • new messages are checked for every CODER_NOTIFICATIONS_FETCH_INTERVAL (default: 15s)
  • if a message is delivered successfully, it transitions to sent state
  • if a message encounters a non-retryable error (e.g. misconfiguration), it transitions to permanent_failure
  • if a message encounters a retryable error (e.g. temporary server outage), it transitions to temporary_failure
    • this message will be retried up to CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS (default: 5)
    • this message will transition back to pending state after CODER_NOTIFICATIONS_RETRY_INTERVAL (default: 5m) and be retried
    • after CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS is exceeded, it transitions to permanent_failure

See Troubleshooting above for more details.