Skip to content

Notifications

A destination is a Slack channel, a webhook or an email address that hears your organization's events. Add one under Settings → Notifications, send it a test, and the delivery log shows what the receiver answered. Nothing is sent until a destination exists.

The bell

Every member sees the organization's notifications in the console: the bell before your avatar shows how many arrived since you last opened it, and the list links each one to the app or cluster it is about. Nothing has to be set up for that. Destinations are for hearing about it somewhere else.

Events

EventWhenOn by default
deploy.succeededA build finished and the new version is servingyes
deploy.failedA build or a rollout failed; the previous version is still servingyes
cluster.disconnectedA cluster's agent has been unreachable for two minutesyes
bandwidth.spikeGateway traffic is far above the organization's usual daily level. Nothing is suspendedyes
app.degradedAn app has been unhealthy for five minutesno
service.degradedA managed service has been unhealthy for five minutesno

A destination that names no events hears the four defaults. The health events are opt-in because they are judgements about a duration rather than facts, and a judgement that fires too early teaches people to mute the channel.

One message, then one more

A rollout makes an app unhealthy on purpose for a few seconds; a restart backoff and a node drain do too. So app.degraded, service.degraded and cluster.disconnected fire only once the condition has held for its delay, and they fire once. Still degraded an hour later sends nothing further. When it recovers you get exactly one closing message, app.recovered, service.recovered or cluster.reconnected, naming how long it lasted, and only if the degradation was announced. A destination subscribed to the alert hears the recovery; there is nothing to subscribe to separately.

A deploy that fails and leaves an app degraded produces deploy.failed at once and app.degraded five minutes later. That is two messages about one thing on purpose: the first says the deploy did not work, the second says the app is still not working.

Destinations

  • Slack takes an incoming-webhook URL and renders a Block Kit message. The URL is the credential; it is encrypted at rest and the list shows only its host.
  • Webhook takes any HTTPS URL and receives the JSON below, signed.
  • Email takes an address and receives the same message as the console's alert mails.

Each destination can be narrowed to particular projects. An event with no project, such as a cluster disconnect, reaches only destinations that are not narrowed.

Sends are capped at 60 per destination per hour; a delivery dropped by the cap is recorded as suppressed in the log rather than silently lost.

Webhook payload

{
  "version": 1,
  "id": "68c4…:deploy.failed",
  "type": "deploy.failed",
  "occurredAt": "2026-09-13T12:04:11Z",
  "organization": "acme",
  "project": "demo",
  "cluster": "prod",
  "resource": { "kind": "app", "name": "checkout-api" },
  "title": "checkout-api failed to deploy",
  "summary": "Build 4f2a1c9 failed: exit status 1.",
  "url": "https://app.anyport.dev/orgs/…/projects/demo/apps/checkout-api",
  "details": { "commit": "4f2a1c9", "author": "ada", "reason": "exit status 1" }
}

Every request carries four headers:

HeaderValue
X-Anyport-EventThe event type
X-Anyport-DeliveryThe delivery id, unique per attempt; the body's id is the event's, shared by retries
X-Anyport-TimestampUnix seconds when the request was signed
X-Anyport-Signature-256sha256= + HMAC-SHA256 over timestamp + "." + body, keyed with the signing secret

The signing secret is shown once when the webhook is added and can be rotated from the same panel. Verify the signature and reject timestamps older than a few minutes, and deduplicate on the body's id: a receiver that was down gets the same event again on retry, with the same id.

Retries follow a fixed schedule of 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, about nine hours in all. A 4xx other than 429 is not retried: the destination is wrong, and the row says so.

The log

Settings → Notifications → Deliveries lists every attempt for 30 days with the receiver's status and, for a refusal, its response. From a terminal:

anyport notify destination ls
anyport notify log --destination team-slack

An empty log means nothing has been sent, never that something was lost: the row is written before the first attempt.

Next steps