# Connect tools and notification delivery

> Connect external tools, create delivery channels, and verify alerts can reach responders.

Canonical page: https://anectico.com/docs/manage/connections-and-notifications/


Connections authorize Anectico to interact with another product. Notification channels define a concrete
delivery destination used by alert rules. A connection alone does not route any alert.

## Connect an external tool

Open **Connections** and choose a provider:

- Slack, GitHub, Jira, and Linear use an authorization flow;
- PagerDuty accepts an Events API v2 routing key.

For PagerDuty, create or choose a service in **Services → Service Directory**, add
an **Events API V2** integration, and paste its **Integration Key** into Anectico.
Use the service's routing key, not a PagerDuty REST API access key. The current
sender supports PagerDuty's **US region** only. Each customer supplies the key
for their own service; no shared Anectico PagerDuty account is required.

PagerDuty delivery currently creates trigger events only. Acknowledging or
resolving an alert in Anectico does not acknowledge or resolve its PagerDuty
incident, and changes in PagerDuty do not sync back. Manage the PagerDuty incident
there. Testing a channel creates a real incident; resolve it after verification.

Complete the provider flow, return to Anectico, and confirm the provider shows **Connected**. A
**Needs reauth** state means the saved authorization can no longer be used. Choose **Reauthorize**
to replace its OAuth grant in place; linked tickets remain pinned to that connection. Disconnect a
provider only after checking alert routes and linked ticket workflows that depend on it.

If Anectico detects more than one non-revoked connection for a provider, the page shows
**Connection conflict** with every exact connection ID and status; it does not hide a broken
connection behind an active duplicate. Disconnect the unintended duplicate before choosing
**Reauthorize** on the connection that existing tickets use.

Jira setup asks for the target project key, issue type, optional priority, and any required
`customfield_N` values before redirecting to Jira. Linear setup asks for the team plus the open and
done workflow-state IDs. These values are non-secret connection metadata and survive the OAuth
callback; access and refresh tokens remain write-only. Reauthorization pre-fills the current setup
so you can rotate authorization without silently changing the ticket destination.

For Jira status changes to sync back, a Jira administrator must also create a signed webhook in
**Jira settings → System → Webhooks**. Select issue-created and issue-updated events, filter to
the connected project, and use the URL shown in **Connections → Jira → Configure status sync**.
Generate a random signing secret of at least 20 characters and save the same value in both places.
Anectico encrypts it and never displays it again. Delete the Jira webhook when disconnecting.
This additional setup is required for Jira; authorizing OAuth alone enables outbound ticket actions.
Jira status-sync events retain only the issue key and status category in the event stream.
Profile names, emails, comments, and other original webhook fields are removed before storage.
A restricted account-reference inventory supports Atlassian personal-data reporting and erasure;
disconnecting Jira removes that connection's retained references.
Linear's app webhook is installed with workspace authorization and needs no customer signing secret.

Credential rotations are validated before Anectico replaces the current credential. If another admin
rotated it first, refresh and retry against the new version; an invalid or stale update leaves the
last working credential untouched. Disconnect is an idempotent revocation. Existing durable delivery
attempts remain pinned to the credential they started with, while new sends no longer select it. A
new delivery with no active connection fails once as a configuration error; it is not repeatedly sent
to the retry queue. Restore or replace the connection before retrying that notification route.

## Create a notification channel

Open **Settings → Notifications → Notification channels**. Create a channel for webhook, Slack,
email, or PagerDuty delivery. Select the connected provider or enter the required destination, save,
then choose **Test** on the saved channel.

Provider rate-limit responses can postpone retries according to `Retry-After`, bounded to 24 hours
and never shorter than the normal backoff. Slack message previews are shortened to fit its section
limit. Slack and PagerDuty delivery do not follow redirects; configure the final destination.
Custom notification templates are validated by rendering sample data and have a 1 MiB rendered
output limit. Invalid field references and incompatible template operations are rejected at save.

Only attach a channel to an alert rule after the test succeeds. When deleting a channel, update every
rule that routes to it; those rules will otherwise stop delivering to that destination.

A failed test reports one of a fixed set of plain-language reasons — an invalid or incomplete
configuration, a malformed or non-routable webhook URL, a missing connected integration, an
unreachable destination, or a destination that answered and refused, in which case its own HTTP
status is included. As with the sanitized provider errors in delivery history, these reasons never
carry raw provider error text or any part of the stored channel configuration. See
[Alerts or integrations are not delivering](/docs/help/alerts-and-connections) for the full list and
what each one points at.

### What reaches a channel without a rule

Most deliveries come from an alert rule you attached the channel to. Two things reach **every**
enabled channel in the organization without one:

- an incident opening or resolving;
- an agent **review signal** opening or clearing — an undeclared agent, a deployment whose
  configuration no longer matches the bill of materials that attests it, or a deployment with no
  registered configuration at all.

A review signal that is still standing is not re-announced while it stands; you get one message when
it opens and one when it clears, and the two are paired so the second closes out the first. If you do
not want these on a destination, disable that channel — they are not rule-routed, so removing a rule
will not stop them.

## Configure personal contact methods

In **Settings → Notifications → My contact methods**, add an email address or Slack DM destination.
Those are the personal methods that deliver today; SMS and phone are shown as coming soon and cannot
be selected. Slack DM requires an active Slack connection. Contact methods belong to the signed-in
member, while notification channels belong to the organization.

After adding a contact method, confirm it is available when building the relevant on-call and
escalation workflow.

A contact method also carries a **verification state**, shown alongside it and set by Anectico
itself. It records whether the address was confirmed to belong to you, so it is not something you,
the CLI, the API or an agent can set: a value supplied on a create or an update is ignored, and an
edit that changes the destination clears it. Read it; do not send it. If a responder has no personal
method, on-call delivery can use that member's confirmed account email as a fallback without adding
an editable contact-method row.

Slack alert and escalation messages include **Acknowledge**. Anectico accepts the click only after Slack
signature/freshness verification and an explicit mapping from that Slack user to a current Anectico
organization member. The first ACK wins across Slack, dashboard, CLI, and MCP; repeated clicks cannot
change its actor, time, or note, and the canonical ACK stops the escalation.

## Troubleshoot delivery

1. Test the saved notification channel directly.
2. Confirm its connection is active and the destination still exists.
3. Confirm the alert rule is enabled and routes to that exact channel.
4. Check whether the alert actually entered the firing state.
5. For on-call paging, confirm the active schedule, escalation step, and responder contact method.
6. In delivery history, select the same project as the alert. Delivery records are project-scoped and
   show attempts, sanitized provider errors, and provider correlation IDs without exposing secrets.

For durable alert and incident deliveries, each send attempt is recorded before contacting the
provider. An attempt can therefore have an unknown outcome after a crash, and a retry can produce
a duplicate. The persisted attempt budget still applies across worker restarts; once exhausted,
the delivery moves to `dlq` instead of sending again. Attempts are not a count of confirmed receipts.
Silence and analytics-source holds do not consume send attempts.

Delivery history requires `channels:read` and a selected project. REST and CLI pages default to
50 records and reject limits above 50. REST, MCP and CLI delivery reads return operational metadata;
rendered notification payloads are never returned through these customer receipts.

For metric-watch deliveries, `payload_withheld: true` additionally tells you that the original
metric content could not be authorized with your current credential and retained evidence. The
check requires `alerts:rules:read`, `analytics:read`, `persons:read`, `insights:read`, and the original
saved insight's source permissions (for example, `agents:content:read`). Missing permissions, erased
or expired evidence, removed correlation, or an unavailable source check can cause this flag.
Status and attempts remain visible, and the flag does not mean delivery failed. A false flag does
not make rendered content part of the customer receipt. Pausing a watch does not itself invalidate
readable history. History reads never rerun a query to replace the original measurement.

For ordinary cohort alerts, `payload_withheld` checks the exact cohort generation recorded with
the notification. In addition to `channels:read`, you need `analytics:read` and that generation's
source permissions, such as `persons:profile:read` for property cohorts or `agents:content:read`
for content-dependent behavioral cohorts. Missing permissions, erased or expired evidence, and
an unavailable source check withhold content while preserving delivery status and attempts.
The current cohort generation never replaces the original generation during a history read.
These receipts still omit rendered notification payloads even when the flag is false.

For ordinary cohort notifications, background cleanup also removes the retained rendered body
when the original generation is permanently pruned or its original content-erasure evidence has
been invalidated. Delivery status and attempt history remain available. A pending notification
then stops retrying. Cleanup runs in bounded passes, so physical removal can follow the earlier
read/send refusal. Temporary permission loss, policy denial or an unavailable source check does
not itself delete history. Once the body is removed, a retry cannot restore it.

For native metric-watch notifications, cleanup follows the original published analytics result.
Its immutable expiry or a completed change to its original content-erasure revisions can remove
the retained rendered body. The original result and snapshot remain the reference even after the
result payload is pruned. Pausing the watch, changing its latest revision, losing permissions, or
an unavailable check does not by itself delete the body. Missing or corrupt original lifecycle
evidence also prevents deletion. Delivery receipts remain available, and unfinished retries stop
after the body is removed. These notifications use the same bounded cleanup scheduling described
above.

Never paste provider tokens or routing keys into support messages.

- [Create alerts](/docs/respond/alerts)
- [Handle incidents and on-call](/docs/respond/incidents-and-on-call)
