Skip to content

Channels

Every channel has a type and a config object shaped by that type. Each type’s config is validated with a .strict() schema: a key that is not listed below is rejected with 400, never silently dropped or stored.

Config: { to }

  • to — a valid email address. This is the recipient; the channel is the target, so there is no separate “who receives this” setting.

Config: { webhookUrl }

  • webhookUrl — must be an https://hooks.slack.com/... incoming-webhook URL. Any other host or scheme is rejected.

Config: { url, secret }

  • url — the endpoint WireWatch delivers to. Any valid http(s) URL.
  • secret — a non-empty string used to sign every delivery. See Webhooks for the signature scheme and a sample that verifies it.

Config: { routingKey }

  • routingKey — a PagerDuty Events API v2 integration key.

Config: { apiKey, region }

  • apiKey — an Opsgenie Alert API integration key.
  • region — us or eu. Opsgenie is two separate instances per region, and this decides which one WireWatch talks to.

Every secret field above is encrypted at rest and decrypted only just-in-time to send — a read never returns it. What a read gives back instead differs by type, and two of them give back nothing:

Type Secret field Returned on read
email none the whole config
slack webhookUrl {}
webhook secret { url }
pagerduty routingKey {}
opsgenie apiKey { region }

A Slack webhook URL and a PagerDuty routing key never reappear once saved: reading the channel back gives an empty config, not a masked or partial value. That is not a bug and it does not mean the save failed — if you need to confirm what you entered, the dashboard cannot show you, and the field has to be re-entered to change it. webhook.secret and opsgenie.apiKey behave the same way; only their non-secret sibling fields (url, region) come back.