# AI data handling
Source: https://docs.incident.io/admin/ai-usage
How incident.io uses AI and handles AI data
incident.io uses AI to help take away some of the overhead of incident response — whether that's digesting huge amounts of information, communicating clearly to stakeholders, or distilling previous incidents into powerful learnings. Think of it like a helpful colleague chipping in or taking tasks off your hands when it can.
Our AI features are powered by OpenAI, Anthropic, and Google Vertex. We send data on-demand to their APIs when required by a feature — this includes (but is not limited to) incident updates, summaries, and custom fields. This data is not stored by them and is not used for any reason other than to provide these services. This means it is explicitly *not* used for training purposes.
Audio is handled by two further providers. [Scribe](/ai/scribe) joins your incident calls through Recall.ai, and ElevenLabs transcribes the call audio. We store the resulting transcript, not the audio.
ElevenLabs also transcribes voicemail left on your [call routes](/on-call/live-call-routing#send-calls-to-voicemail). Voicemail works differently: we store the recording as well as the transcript, so you can listen back to it.
OpenAI, Anthropic, Google Vertex, Recall.ai, and ElevenLabs are all listed as our data sub-processors, so all customers automatically consent during sign up. However, if you'd like for us to stop sending data to OpenAI, Anthropic, or Google Vertex, and therefore disable all AI features, contact us at [help@incident.io](mailto:help@incident.io). You can also opt out of ElevenLabs on its own, which limits transcription to what your meeting provider's captions give us.
If your organization has opted out of any subprocessor, [Settings → AI governance](https://app.incident.io/~/settings/ai-governance) shows which ones and what that means for the AI features you can use.
If your incident channels may contain sensitive data like credit card numbers or Social Security numbers, you can enable automatic redaction to strip this before it reaches AI providers. See [Managing sensitive data](/admin/managing-sensitive-data#ai-data-redaction) for details.
For more on how we store and handle data, see our [Trust Center](https://incident.io/security).
# Announcements
Source: https://docs.incident.io/admin/announcements
Control what your incident announcement posts look like with templates, and where they get posted with rules
Announcements keep everyone informed by sharing incidents in a Slack or Microsoft Teams channel.
You don't need to set anything up to get started. Every account comes with a default template and a default rule, so incidents are announced automatically from day one. This page is about customizing that behaviour, which comes in two parts:
* **Templates** control what your announcement posts look like: the fields, actions, and emojis that appear in the post.
* **Rules** control which incidents get announced, and where.
To customize either, go to [Settings → Announcements](https://app.incident.io/~/settings/announcements).
## Templates
A template controls what an announcement post looks like. Every account starts with a single template, which is marked as your **Default**. This is the template used whenever a rule (or workflow) doesn't specify one.
Click a template to edit it. You can add or remove fields and actions, reorder them, and configure which emojis appear next to each field, with a live preview of the post as you go.
To add a field or action, click **Add** and pick from the list.
### Using more than one template
You're not limited to a single template. Click **Add template** to create additional templates. This is useful when you want variations for specific purposes, such as a stripped-back post for a particular audience, or a template paired with a specific [announcement rule](#rules) so different incidents are announced differently.
You can also choose a template in the **Post an incident announcement** step of a [workflow](/workflows). Leaving it
blank falls back to your default template.
## Rules
Rules control which incidents get announced, and where. By default, we announce every new incident and its updates in a single channel. In Slack, that's your `#incidents` channel.
Click a rule to edit it. You can change which channel it posts to, add conditions so it only fires for specific incidents (for example, announcing critical incidents in `#customer-support` too), and pick which template it uses.
Click **Add rule** to create a new rule, for instance to call out specific incident types or severities in a separate channel.
Don't delete whichever channel you're using for default announcements. On Slack, if you already had an `#incidents`
channel when you installed our app, we'll have created a channel called `#incident-io-incidents` instead, which you
can rename to whatever you'd like.
For more on redirecting announcements to a different channel, see [Announcement channels](/incidents/change-announcements).
## Team ownership
You can give one or more teams ownership of a template or a rule:
* **Templates**: set the **Template owner** field when you create or edit a template. Your default template can't be team-owned, and choosing which template is the organization default stays an account-level action.
* **Rules**: set the **Announcement rule owner** field in the rule's create or edit drawer.
Ownership assigns the template or rule to a team. If your organization uses [team roles](/admin/team-roles), that ownership also controls who can manage it: only members of an owning team with the **Manage announcements** permission, or anyone who holds it account-wide, can make changes, and reassigning ownership always needs that permission granted account-wide. See [Team resources](/catalog/team-resources) for what ownership means more generally.
Each team can see the templates and rules they own on their own **Settings → Announcements** page.
## FAQs
Not much. Templates and rules are configured in the same place and work the same way on both platforms.
The main difference is the default announcement channel: on Slack it's your `#incidents` channel, whereas on Microsoft Teams it's the General channel of your Incidents team. See [Announcement channels](/incidents/change-announcements) for more.
The announcement builder does not currently support free-form text or @mentioning Slack user groups directly in the announcement post.
If you need to notify a specific team when an incident is announced, consider these alternatives:
* **Announce to the team's Slack channel**: Use a [rule](#rules) to post directly to the relevant team's channel.
* **Invite the user group via a workflow**: Set up a [workflow](/workflows) to automatically invite the Slack user group to the incident channel.
* **Auto-subscribe to certain incidents**: Encourage folks to [auto-subscribe](/incidents/subscribing) to incidents belonging to their team.
# API keys
Source: https://docs.incident.io/admin/api-keys
Control API access with account-level and team-scoped permissions.
Create and manage API keys from [**Settings → API keys**](https://app.incident.io/~/settings/api-keys).
## Creating an API key
We'll only show the API key token once at creation time, so store it somewhere safe.
API keys can have account-level permissions, team-scoped permissions, or a combination of both. This means teams can manage their own config via the API without risking changes to other teams' resources.
When you create a new API key, you choose which permissions it has. You can only grant permissions that you yourself have. If you only have team-level permissions, you'll only be able to create keys with team-scoped permissions.
### Account-level permissions
Account-level permissions apply across your entire organization. These are the same permissions available when creating [custom roles](/admin/user-permissions#custom-roles), such as creating incidents, managing workflows, or reading catalog data.
### Team-scoped permissions
Team-scoped permissions restrict what a key can do to resources owned by specific teams.
## Permissions reference
Each permission bundles a set of underlying API scopes, so you grant capabilities without assembling scopes by hand. In the create dialog, hover the scopes badge on a permission to see exactly what it includes.
These are the same permissions used to build [custom roles](/admin/user-permissions#custom-roles), so a key can never do more than a user with the equivalent role. You can only grant permissions you already hold; any you don't have appear locked.
A **Team** value of *Yes* means the permission can also be scoped to specific teams, restricting it to resources those teams own.
### Incidents and investigations
| Permission | What it allows | Team |
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ---- |
| **View data** `viewer` | Read-only access to public incidents and most organization settings. | |
| **View all incident data** `global_access` | Adds read access to private incidents, alerts, and escalations. | |
| **Create incidents** `incident_creator` | Open incidents and set fields, role assignments, timestamps, and attachments at creation. | |
| **Edit incidents** `incident_editor` | Update, decline, merge, or cancel incidents, and manage calls and linked alerts. | |
| **Manage incident memberships** `incident_memberships_editor` | View all incident data, including private incidents, and grant or revoke incident access. | |
| **Opt out of post-incident flow** `post_incident_flow_opt_out` | Close an incident by opting it out of the post-incident flow. | |
| **Manage postmortems** `postmortems_manage` | Manage postmortems, including updating their status and running imports. | |
| **Download investigation artifacts** `investigation_download` | Download AI investigation artifacts attached to incidents. | |
| **View call transcripts** `call_transcripts_viewer` | View call sessions and the transcripts Scribe captured for them. | |
| **View participant workload** `incident_workload_viewer` | View participant-workload analytics (who's been involved in how many incidents). | |
| **View private participant workload** `incident_workload_private_viewer` | View participant-workload analytics, including for private incidents. | |
### Catalog and teams
| Permission | What it allows | Team |
| ----------------------------------------------------- | --------------------------------------------------- | ---- |
| **View catalog** `catalog_viewer` | Read-only access to catalog types and entries. | |
| **Manage catalog** `catalog_editor` | Create, edit, and delete catalog types and entries. | Yes |
| **Manage team memberships** `team_memberships_manage` | Update team memberships and edit catalog entries. | |
### On-call, escalations, and notifications
| Permission | What it allows | Team |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---- |
| **Manage on-call resources** `on_call_editor` | Full on-call surface: alerts, sources, routes, schema, schedules, escalations, and maintenance windows. | Yes |
| **View on-call resources** `on_call_viewer` | Read-only view of on-call resources like alerts, escalations, and schedules. | |
| **Create escalations** `escalation_creator` | Create, respond to, and cancel escalations. | Yes |
| **Manage notification methods** `notification_methods_manage` | Configure the on-call paging provider, and users' notification methods and rules. | |
| **View unredacted notification methods** `notification_methods_unredacted_viewer` | View users' notification methods, including unredacted phone numbers. Grant sparingly. | |
### Schedules
| Permission | What it allows | Team |
| --------------------------------------------------------- | ------------------------------------------------------------- | ---- |
| **Create and update schedules** `schedules_editor` | Create, update, delete, and view schedules. | Yes |
| **Read schedules** `schedules_reader` | Read-only access to schedules. | Yes |
| **Create schedule overrides** `schedule_overrides_editor` | Create schedule overrides only, not the schedules themselves. | Yes |
### Workflows
| Permission | What it allows | Team |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---- |
| **Manage workflows** `workflows_editor` | Create, update, delete, and view workflows. | Yes |
| **Manage workflows that run on private incidents** `private_workflows_editor` | Everything in workflows, plus workflows that run on private incidents. | Yes |
| **Workflows on private escalations** `private_escalation_workflows_editor` | Manage workflows that run on private escalations. | |
### Status pages
| Permission | What it allows | Team |
| ------------------------------------------------ | -------------------------------------------------------------------------- | ---- |
| **Publish status pages** `status_page_publisher` | Create status page incidents and maintenance windows, and publish updates. | |
### Secrets
| Permission | What it allows | Team |
| ----------------------------------- | ------------------------------------------------------------ | ---- |
| **Manage secrets** `secrets_manage` | View, create, update, rotate, delete, and reference secrets. | Yes |
| **Use secrets** `secrets_use` | View secret metadata and reference secrets. | Yes |
### Organization and security
| Permission | What it allows | Team |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------- | ---- |
| **Manage organization settings** `manage_settings` | Change organization-level configuration such as custom fields, and manage the catalog. | |
| **Update security settings** `security_settings_editor` | Update the organization's security settings. Grant sparingly. | |
### API keys and attribution
| Permission | What it allows | Team |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| **Manage API keys** `api_keys_manage` | View, create, edit, delete, or rotate API keys. A key with this permission can create more keys, but only within its own access. Can't be granted through the public API. | Yes |
| **Act on behalf of users** `act_on_behalf_of_users` | Attach the on-behalf-of header to attribute API actions to a specific user. Grants no actions on its own, so pair it with another permission. Availability depends on your plan. | |
## Best practices
* **Least privilege**: grant only the permissions a key actually needs.
* **One key per integration**: makes it easy to rotate or revoke one without affecting others, and keeps audit trails clear.
* **Rotate regularly**: and immediately if a key may have been exposed.
* **Review periodically**: remove keys that are no longer in use.
## Editing an API key
Existing API keys can be edited after creation. You can update the key's name, add or remove account-level permissions, and add or remove team-scoped permissions.
To edit a key, you need the same permissions required to manage it — see [Permissions required](#permissions-required) below.
## Permissions required
To manage API keys, you need one of:
* The account-level **Manage API keys** permission (via a [base or custom role](/admin/user-permissions))
* The team-scoped **Manage API keys** permission (via a [team role](/admin/team-roles))
Users with only team-scoped permissions can create, edit, and delete keys within their team, but cannot manage keys belonging to other teams.
## FAQs
A scope is a single, granular capability in the API. A permission bundles several scopes together into something
meaningful, like the **Edit incidents** permission. You choose permissions when creating a key, not individual
scopes. To see the scopes behind a permission, hover its scopes badge in the create dialog.
Yes. A key can be associated with multiple teams, but it will have the same set of team-scoped permissions across
all of them.
Yes. A single key can have account-level permissions (e.g., read catalog data) alongside team-scoped permissions
(e.g., manage schedules for a specific team).
# Audit logs
Source: https://docs.incident.io/admin/audit-logs
Track configuration changes and permission updates across your account
Audit logs track changes made within your incident.io account, giving you a complete record of who changed what and when. Available on the [Enterprise plan](https://incident.io/pricing), powered by [WorkOS](https://workos.com/), with entries retained for one year.
You must be an Owner or Admin to access audit logs. Entries are available from April 18, 2023 onwards.
## What’s tracked
Audit logs capture configuration changes across incident.io, including:
* Alert sources, routes, and escalation paths
* Schedule and on-call configuration changes
* User role assignments and permission updates
* Access grants to private incidents
* Workflow and automation changes
* Integration configurations
Each entry records the actor (person or system making the change), the target (what was modified), and contextual details like location and user agent. Entries conform to a versioned schema — see the [Audit logs API reference](https://docs.incident.io/api-reference/audit-logs) for full details.
## Viewing audit logs
Access audit logs at [Settings → Security](https://app.incident.io/~/settings/security). From there you can:
* View entries in a web interface, filterable by target, event type, actor, and date
* Export entries for a given time period to CSV
* Set up a log stream to a SIEM provider (e.g. Datadog, Splunk, or an Amazon S3 bucket)
## API access
Access audit log entries programmatically via the [Audit logs API](https://docs.incident.io/api-reference/audit-logs).
# Billing methods and mechanics
Source: https://docs.incident.io/admin/billing
How billing works for monthly and annual plans
Our [pricing](https://incident.io/pricing) is based on the number of Responder and On-call seats you use. Choose monthly or annual billing depending on your plan. Manage your billing information in [Settings → Billing](https://app.incident.io/~/settings/billing).
Both monthly and annual billing are available on Team plans. Pro and Enterprise plans are billed annually only.
## Monthly billing
Available on Team plans only.
We charge at the start of each month based on your seats in-use. On subsequent months, we adjust for any changes:
* If you added seats during the month, we charge for the overage (prorated daily)
* If you removed seats, we credit your account (prorated daily)
Your billing date stays the same each month.
## Annual billing
### Team plan
Pay upfront for 12 months based on the seats you’re using when you sign up. Any overages or downgrades throughout the year are settled on your billing date each month, prorated daily.
### Pro and Enterprise plans
Work with our sales team to estimate the seats you’ll need for the year. We invoice on your service start date.
If you need more seats during the year, you have two options:
* **Co-term contract** — add seats at a reduced rate for the remainder of your current subscription
* **Annual true-up** — we bill at the end of the year for additional seats, prorated daily
For details on how to add or remove seats, see [Managing seats](/admin/managing-seats). For what each seat type includes, see [Seat types & viewers](/admin/seat-types).
## FAQs
We’re a UK-based company so we use a W8-BEN form instead of a W-9. You can download our [W8-BEN
form](https://incident.io/docs/files/W-8BEN-E.pdf).
Responder and On-call seats are billed independently. A user with both seats counts against both pools. Viewers are
free and unlimited on all plans. See [Seat types & viewers](/admin/seat-types) for the full breakdown.
# Changing plans
Source: https://docs.incident.io/admin/change-plan
How to upgrade or downgrade your incident.io subscription
## Moving to Pro or Enterprise plan
Upgrades to Pro or Enterprise plans always go through sales:
1. Contact us at [help@incident.io](mailto:help@incident.io) to discuss your requirements
2. We'll help set up a trial if needed
3. Work with sales to finalize contract details
## Moving to Team plan
The Team plan is a self-serve upgrade from the Basic plan. Upgrade through your [billing settings](https://app.incident.io/~/settings/billing).
If you're currently on a Pro or Enterprise trial, contact support to move to Basic first.
## Downgrading to Basic plan
To downgrade to the Basic (free) plan:
1. Contact support to request the downgrade
2. If you've recently paid for a subscription, you may be eligible for a prorated refund
3. Downgrading removes access to premium features — see the [pricing page](https://incident.io/pricing) for what's included in each plan
The Basic plan has a limit of 5 responder/on-call seats. If you're downgrading to Basic, ensure you have no more than 5 active responders by changing excess users to "Viewer only" access.
# Channel bookmarks
Source: https://docs.incident.io/admin/channel-bookmarks
Add custom bookmarks to incident channels for quick access to key information and links
You can create custom bookmarks within your incident channels, to give snapshot information and easy-to-find links.
1. To create a custom bookmark, first navigate to [Settings](https://app.incident.io/~/settings/slack-channel) → [Slack Channel](https://app.incident.io/~/settings/slack-channel).
2. Click the "+ Add New button", and create. You will have three options for the kind of bookmark you'd like to add:
"Pre-defined property" is a field that contains useful information about the incident (i.e. the status of the severity), and will update as it is changed.
"Pre-defined link" lets you choose from our pre-defined bookmarks which link you to a page related to the incident (i.e. a Jira issue ticket).
"Custom link" gives you the ability to bookmark to a link. This can be useful if you have documentation that is commonly accessed during an incident.
3. You can also choose under what condition a bookmark appears (i.e. a link to a critical incident doc only appears on critical incidents).
4. Next click "Create", and your bookmarks will appear at the top of the incident channel when the conditions you selected are met.
Bookmarks are a great way to give at-a-glance information to team members when they join an incident.
The [Slack API](https://api.slack.com/methods/bookmarks.add) limits what we're able to do with the bookmarks in your incident channel. Currently, we're only able to append bookmarks to the end of the list. This might mean that sometimes, you see bookmarks end up in a different order than the one you've set up.
The alternative is to individually remove and re-add all of the bookmarks we've created. This turned out to be visually much more jarring, and it also resulted in the reordering of any bookmarks that had been manually added to the channel. Although having bookmarks out of order isn't ideal, we feel like this is the best option for now.
Some actions, such as creating a call for your incident, happen in the background after we've created your incident channel. In these cases, you're likely to see the "Join the call" button show up at the end of your list of bookmarks. We've got much more control over announcement messages: you'll see that the order here will always be what you expect.
We always keep an eye out for improvements to the Slack API, and we hope to be able to improve this in the future.
# Default timezone
Source: https://docs.incident.io/admin/default-timezone
Set a default timezone for consistent timestamps across your organization
Set a default timezone for your organization so timestamps are consistent across your incident management process — useful for distributed teams who want to standardize on a single timezone like UTC.
To set your default timezone, go to **Settings → Organization** and select a timezone from the dropdown.
## What's affected
The default timezone applies to most areas of incident.io, including incident timelines and timestamps in the dashboard. When enabled, users input timestamps in the organization's default timezone rather than their local time.
The following areas are **not** affected by this setting:
* **On-call schedules** — use their own timezone configuration
* **Insights** — display in the user's local timezone
* **Status page emails** — remain in UTC
If you don't see the timezone setting in your organization settings, contact your Customer Success Manager to have the
feature enabled.
# Deleting your organization
Source: https://docs.incident.io/admin/delete-account
How to delete your incident.io organization
Since account deletion requires administrative verification, contact us at [help@incident.io](mailto:help@incident.io) to delete your organization. You'll need to:
* Be the organization owner or have appropriate permissions
* Contact us from your registered account email address or Slack
* Provide your organization URL (e.g. `https://app.incident.io/your-org-name`)
We'll handle the deletion and cancel your plan. Once complete, all users lose access and automated emails stop. If you want to use incident.io again in the future, you'll need to create a new account.
Looking to delete an individual user account instead? See [Deleting users](/admin/delete-users).
# Deleting users
Source: https://docs.incident.io/admin/delete-users
How user accounts are managed and removed in incident.io
User accounts in incident.io are synced to your Slack workspace, so they're managed through Slack rather than deleted directly. An org Owner/Admin can remove your permissions and set you back to just a `Viewer` role, or you can fully remove the account by deactivating the Slack profile.
If you're an Enterprise customer using SCIM, you can de-provision users via SCIM.
Looking to delete your entire organization? See [Deleting your organization](/admin/delete-account).
# Duplicate user errors
Source: https://docs.incident.io/admin/duplicate-users
Resolve duplicate SAML account errors when logging in
When a user logs in, they might see an error:
> We found multiple SAML accounts for your email address
This happens when we've entered a 'bad state' between incident.io's user management, and your identity provider (e.g. Okta).
This often happens when someone is changing their name, or you're changing the domains of your canonical emails as part of a migration.
To resolve this:
1. Ensure that someone's canonical email address in your IdP (identity provider) exactly matches their email in Slack or Microsoft Teams. If these are not the same, we won't be able to authenticate them correctly
2. Go to [Settings → Users](https://app.incident.io/~/settings/users/users) and search for the user's name. You should see multiple items in the list
3. One of those users should be a 'SAML only' user, meaning they won't have a `Slack` connection badge. This user will also have a 'Deactivate User' button in the bottom left → click this!
Once you have just a single active user, and the email addresses match, the user should now be able to log in successfully.
# Incident forms
Source: https://docs.incident.io/admin/incident-forms
Control which fields appear on declare, accept, update, resolve, and escalate forms
As a responder progresses through an incident, they will encounter several forms designed to collect information about the incident.
These forms exist to make sure that responders share the right information at the right time, so that:
* Automations can run correctly (e.g. workflows that invite the right people depending on what service is affected, or rule-based suggestions tailored to certain situations)
* The wider team is aligned on the core facts of the incident (what product is impacted, how widespread is it, who's leading), and is kept up to date (e.g. via subscriptions)
* You can analyze patterns in incidents via insights
There's always a balance to find here: ask for too much information too soon and responders will be wasting time filling in forms when they should be fixing the issue. Ask for too little, and you can't build targeted automations or keep your teams up-to-date.
We allow you to configure your incident forms to help get this right, giving you the ability to only ask for the information that you need.
You can access these settings via [Settings → Forms](https://app.incident.io/~/settings/forms).
Here, you can configure:
* The **Declare** form, shown when declaring a new incident
* The **Accept** form, shown when accepting a triage incident
* The **Update** form, shown when sharing an update for an incident
* The **Resolve** form, shown when you resolve an incident
* The **Escalate** form, shown when you manually escalate from an incident
## Choosing which fields to include
You can now control exactly which fields will show on each form, and see the impact of those changes in real time. For example, you can hide the summary field when declaring an incident unless it’s at least a **Major** severity.
These work ‘in real time’ too, so when you change the severity from Minor to Major, the summary field will appear in your form.
## Choosing when to make a field required
Required fields are a blessing and a curse: it’s useful to ensure that a responder fills in a field and doesn’t forget, but having lots of required fields can be very frustrating when you’re trying to fix a problem.
You can now choose when you want a field to be required: for example, you might have a role as **Comms Lead** which is required if the severity is Critical, but not for lower severity incidents.
As a bonus, if you have a dropdown custom field, you can choose to include a ‘no value’ item in the dropdown. Use this to ensure that a user makes an active choice to input 'no value' instead of just forgetting to fill out the field.
## Configuring forms by incident type
You can configure a bespoke form that’ll only apply to incidents of that particular type. For the Declare form, as soon as the user chooses that particular type, the rest of the form will change to match that specific type's form configuration.
If an incident type is [owned by a team](/incidents/incident-types#team-ownership-and-permissions), overriding or editing its forms is restricted to that team (or anyone with the **Manage incident types** permission granted globally). Org-wide forms that aren't tied to a specific type still require the permission granted globally.
## Default values
To make it even easier to fill out these forms, you can configure default values against each element in the form. That means that you can now:
* Choose a different default severity (instead of the lowest severity)
* Set a default value for a custom field
* Make incidents triage by default, instead of live
This also allows you to create templates, so you can make it easier for responders to populate summaries and updates consistently.
## Your form, your way
You can now help your responders by including customized descriptions and placeholder text, as well as dividers and help text blocks.
Only require what you absolutely must, and prefer requiring at incident close than at incident start. If you require 5 fields when opening an incident, responders will be forced to provide 5 values before they begin responding.
# Incident timestamps
Source: https://docs.incident.io/admin/incident-timestamps
Validate timestamp ordering to prevent incorrect durations and confusing timelines
Timestamps are a great way to keep track of key moments within your incidents. Within incident.io we provide several default timestamps for you and allow you to create additional timestamps - both automatic and manually filled.
In the heat of the moment, it can be hard to keep track of exactly when everything happened though, perhaps you made a mistake reading a log or pasted the wrong thing when manually entering them. Suddenly your statistics make no sense, you have a negative duration for your resolution time, or your post-mortem timeline just makes no sense.
Validation can help save you from confusing timelines and incorrect metrics.
## Enable validation on a duration metric
Duration metrics define a relationship between 2 timestamps by having a start and an end. You can use a duration metric to enforce that relationship in your timestamps by turning on validation.
[Navigate to your settings page and the timestamps tab](https://app.incident.io/~/settings/lifecycle?tab=timestamps), create a new metric or select an existing one to edit. Select the timestamps you wish to validate and that they are in the order you want to enforce.
Make sure to tick **Enable validation** and then click save.
## Validation when editing timestamps
Now that validation is enabled for that duration metric when you go to edit a timestamp in the dashboard and select the wrong date - you will be given a clear warning preventing you from submitting it.
## Warning when resolving incidents
You may have also configured your timestamps to be required when marking an incident as resolved. The values you enter here may also result in invalid durations however as we do not want to increase unnecessary friction we warn users - and notify them within the incident channel (see below) to prompt someone to fix it.
## Invalid durations notifications
Some timestamps are automatically updated when an incident changes statuses, i.e. we will set the timestamp "Closed at" when an incident is closed. Depending on how you have configured your timestamps this automatic update may happen more than once (for example reopening and closing again an incident).
This means that over time some of the timestamps you might have manually set might now be invalid and no longer make sense.
We will highlight invalid timestamps in the details of the incident:
In addition to this and to help alert you when automatic changes have made a timestamp invalid we will post a message within the incident channel providing a helpful link to edit the duration directly.
Clicking this link takes you directly to an edit duration timestamps modal. From here you can quickly alter the dates and save.
# Instance name, URL, and icon
Source: https://docs.incident.io/admin/instance-customization
Change your incident.io instance name, URL, or icon
incident.io allows you to customize various aspects of your instance to align with your organization's branding. This article explains how to modify your instance name, URL, and icon.
## Changing your incident.io instance name
Your incident.io instance name is tied to your Slack workspace name. To change it:
1. Contact incident.io support
2. Request the instance name change, specifying your desired new instance name
3. The support team will process your request and update the incident.io instance name
## Modifying your incident.io instance URL
To change your incident.io instance URL (e.g., from app.incident.io/oldname to app.incident.io/newname):
1. Contact incident.io support
2. Request a URL change, specifying your desired new URL
3. The support team will process your request and update the URL
## Updating your incident.io instance icon
By default, your instance icon is synced from your Slack workspace. You can also upload a custom icon directly in [**Settings → Organization**](https://app.incident.io/~/settings/organization) — this is available to all customers on both Slack and Microsoft Teams.
To update via Slack:
1. Change your Slack workspace icon following the [official Slack instructions](https://slack.com/intl/en-gb/help/articles/204379773-Upload-a-Slack-icon#free,-pro-and-business+-subscriptions-1)
2. Wait for the next sync between Slack and incident.io
3. The new icon will automatically appear in your incident.io instance
The daily sync between Slack and incident.io may take some time. If you don't see the icon update within 48 hours, contact incident.io support.
# IP allowlists
Source: https://docs.incident.io/admin/ip-allowlists
Restrict access to your incident.io workspace by IP address
Once enabled, all authenticated requests to your [incident.io](http://incident.io/) workspace must originate from an allowed IP.
This includes:
* Dashboard usage
* Public API access
* Mobile app traffic
This *excludes*:
* Public alert ingestion endpoints
* Public webhook endpoints used by third parties
Requests from IPs outside the configured allowlist will receive a 403 response.
```json theme={null}
{
"type": "resource_forbidden",
"status": 403,
"request_id": "g329NK8-",
"errors": [
{
"code": "forbidden",
"message": "Unauthorized"
}
]
}
```
## Permissions
In order for a user to manage the IP allowlist, they must have the "Manage security settings" scope. This is configured in [Settings > Users > Roles](https://app.incident.io/~/settings/users/roles).
Similarly, in order for an API key to manage the IP allowlist, it must have the "Manage security settings" permission.
## Configuring your allowlist
Navigate to [Settings > Security](https://app.incident.io/~/settings/security) and scroll down to "IP allowlists".
Click "Manage" to open the drawer, and enter your selection of IPv4 addresses and/or CIDR IP prefixes.
Your current IP will be pre-filled in the list. Any request to modify an enabled allowlist will be rejected if it does not contain the requestor's IP, to prevent lockout.
Once enabled, the allowlist will immediately become active. Ensure that your allowlist is complete before enabling it.
To enable the allowlist, enable the toggle and click "Save"
## Disabling the allowlist
Use the same toggle as before to disable your allowlist, and click "Save".
This will allow requests from all IPs to access your [incident.io](http://incident.io/) workspace.
Your list of IPs and CIDRs will remain available for future use.
# Managing seats
Source: https://docs.incident.io/admin/managing-seats
How to add, remove, and change seats on your incident.io account
Your incident.io plan includes Responder and On-call paid seats, and unlimited Viewer seats. See [Seat types & viewers](/admin/seat-types) for details of each.
## Changing a user's seat type
You can manage seat assignments from [Settings > Users](https://app.incident.io/~/settings/users).
For Responder seats, users who take any of the Responder actions listed at [seat types & viewers](/admin/seat-types) will automatically be upgraded to a Responder seat.
For On-call, we'll ask you to confirm seat assignment for a user when you:
* Add them to a schedule
* Add them to an escalation path
Users are only removed from a paid Responder or On-call seat if:
* You manually downgrade them in [Settings > Users](https://app.incident.io/~/settings/users)
* Their account is deactivated (via Slack, Microsoft Teams, or SCIM) — see [Deleting users](/admin/delete-users)
## Adding seats
How you add seats depends on your plan.
### Team plan
On the **Team** plan, just assign seats as you need them. We'll bill you prorated on your next invoice (see [Billing methods](/admin/billing#monthly-billing)).
### Pro and Enterprise plans
On the **Pro** and **Enterprise** plans you can always purchase additional On-call and Responder seats by contacting your account manager.
You can also purchase On-call seats self-serve from [Settings > Billing](https://app.incident.io/~/settings/billing). Additional seats will be purchased, provisioned immediately and invoiced on your next invoice.
* Only users with Admin or Billing permissions can purchase seats.
* Seats will be charged pro rata to the end of your subscription term ([co-term](/admin/billing#annual-billing)).
* We will send an invoice for the purchased seats to your billing contact within a few days.
## Removing seats
### Team plan
On the Team plan, you can remove seats at any time.
### Pro and Enterprise plans
On Pro and Enterprise plans, seat counts are set by your contract. To reduce them, speak to your account manager — changes take effect at your next renewal.
# Managing sensitive data
Source: https://docs.incident.io/admin/managing-sensitive-data
Remove or redact sensitive information from alerts, escalations, incidents, and AI features.
When responding to incidents, sensitive information can end up in places you didn't expect — alert payloads, Slack messages, escalation details, or call transcripts. incident.io gives you tools to prevent sensitive data from entering the platform, erase it when it does, and redact it before it reaches AI models.
## Prevention
The best approach is to stop sensitive data from reaching incident.io in the first place.
* **Use IDs, not raw values.** If your monitoring detects an issue with a customer, send a customer ID (e.g., `customer_12345`) rather than their name, email, or account details. Responders can look up details in your internal systems.
* **Keep PII out of your logs.** If alerts are triggered from log queries, sensitive data in your logs will end up in your alerts.
* **Be mindful in Slack and Teams.** It's common for data to be pasted into an incident channel without checking for sensitive fields.
You can build a [workflow](/workflows/getting-started) that posts a reminder in new incident channels, prompting responders to avoid sharing sensitive data.
## Erasing data
If sensitive information has already made its way into incident.io, you can permanently erase it from several places.
Erasing data is permanent and cannot be undone. The original content is replaced with a placeholder value.
By default, only account owners can erase data. You can grant this to other roles by enabling the **Permanently erase data** permission in your [custom RBAC configuration](/admin/user-permissions).
### Alerts
Alerts are the most common way sensitive data enters incident.io, because they're often generated automatically from monitoring tools.
To erase an alert, navigate to the alert in the dashboard and select **Erase data** from the overflow menu. This permanently replaces the alert's title, description, and attributes. Any linked escalation will also have its title and description erased.
If sensitive data keeps arriving from a particular alert source, update the source configuration to strip it out before it reaches incident.io.
### Escalations
To erase an escalation, navigate to it in the dashboard and select **Erase data** from the overflow menu. The title and description are replaced with a placeholder value.
### Incident details
Most incident fields are directly editable, so you can clean up sensitive data without erasing:
* Edit the **name**, **summary**, and any **custom field** values from the incident page
* Edit any **incident updates** that reference sensitive information
### Messages in Slack and Microsoft Teams
When a message in an incident channel is edited or deleted in Slack or Microsoft Teams, any copy stored by incident.io is updated to reflect the change. So if sensitive data is posted in the channel, editing or deleting it at the source removes it from incident.io too.
### Activity log and timeline
Changes to an incident are recorded in the activity log and timeline. To erase sensitive data from timeline entries:
1. Open the incident and go to the **Post-incident** tab
2. Click the pencil icon to enter edit mode under **Timeline**
3. Use **Erase data** in the overflow menu of the relevant entry
## AI data redaction
incident.io has Zero Data Retention agreements with all AI providers (OpenAI, Anthropic, and Google Vertex), meaning they don't store any inputs or outputs and don't use them for training.
On top of this, you can enable automatic redaction that strips sensitive patterns from incident channel messages, attachments read by AI, and new spoken Scribe transcript entries. When enabled, matches are replaced with `[REDACTED]` before the content reaches an AI model.
Scribe applies redaction as each transcript entry is processed. The redacted value appears in the transcript and is used by Scribe summaries, key moments, and current topic. Turning on a strategy does not rewrite existing transcript entries.
Available redaction strategies:
| Strategy | What it matches |
| ------------------------------ | ------------------------------------------------------------------------------------ |
| **Credit card numbers** | Common credit card formats (Visa, Mastercard, Amex, etc.) — 13 to 19 digit sequences |
| **US Social Security numbers** | Numbers in XXX-XX-XXXX format |
| **Phone numbers** | Phone numbers in various formats, including international numbers |
You can enable any combination of these strategies.
Redaction can occasionally remove data that isn't actually sensitive (e.g., a long number that resembles a credit card). This may reduce AI accuracy in some cases.
Redaction is off by default. To turn it on for your account, contact your account team or email [help@incident.io](mailto:help@incident.io). Once it's available, you choose which strategies to apply in [Settings → AI governance](https://app.incident.io/~/settings/ai-governance#ai-data-redaction).
For more on how incident.io uses AI, see [AI usage](/admin/ai-usage).
## Audit trail
All data erasure actions are recorded in the [audit log](/admin/audit-logs), including who performed the erasure and when. The erased content itself is not included in audit log entries.
## Need help?
If you need to remove data that isn't covered above, contact us at [help@incident.io](mailto:help@incident.io) and we'll help you clean it up.
Yes. Erasing replaces the original content with a placeholder value and cannot be undone. All erasure events are
recorded in the [audit log](/admin/audit-logs).
By default, only account owners. You can grant this to other roles using the **Permanently erase data** permission
in [custom RBAC](/admin/user-permissions).
If you decide to stop using incident.io, we're happy to delete application data upon request. Contact us at
[help@incident.io](mailto:help@incident.io).
Yes. When enabled, sensitive patterns are stripped from supported content before it is sent to AI providers.
# Mobile access restrictions
Source: https://docs.incident.io/admin/mobile-access-restrictions
Restrict what can be seen on the mobile app from unmanaged devices.
Mobile access restrictions redact sensitive information in the incident.io mobile app when users sign in from personal devices. Responders can still acknowledge pages and manage escalations, but won't see full incident details until they're on a managed device.
This feature is available for our enterpise customers, reach out to your account team to get it enabled.
## How it works
Mobile access restrictions use a secondary SAML provider dedicated to mobile app authentication. This lets you enforce different access policies for managed and unmanaged devices:
* **Primary SAML provider**: locked down to managed devices only via your IdP's conditional access policies, giving full access to the incident.io dashboard
* **Secondary SAML provider**: used by the mobile app, allowing authentication from personal devices with redacted data
When a user signs into the mobile app through the secondary provider, sensitive information is automatically redacted. Core context like alert titles, incident names, and team names remain visible so responders can identify and act on pages, but detailed information like incident summaries, custom fields, timeline activity, and follow-ups is hidden.
## Setting up mobile access restrictions
To enable mobile access restrictions:
1. Make sure [SAML SSO](/admin/saml-sso) is configured and working for your organization
2. Contact incident.io to enable the feature — we'll work with you to set up the secondary SAML provider
3. Configure your IdP's conditional access policies so the primary SAML provider only permits managed devices
4. Navigate to [Settings → Security](https://app.incident.io/~/settings/security) to review the mobile access configuration
# Okta SCIM group setup
Source: https://docs.incident.io/admin/okta-scim
Step-by-step guide to connecting Okta SCIM with incident.io
For organizations that use a SCIM-based IdP (identity provider) solution, incident.io allows you to manage users and permissions from your IdP. Additionally your users and user groups will be synced to the incident.io catalog, making them available for use in workflows and in [our on-call product](https://incident.io/on-call).
To integrate with SCIM, navigate to **Settings > Integrations** and search for **Okta**. Click the **Connect** button in the automatic user provisioning section.
This will launch the SCIM directory sync flow, powered by WorkOS. You can select a provider from the list, or manually enter the details of your own provider if required. In this guide, we'll use **Okta** but WorkOS provides comprehensive instructions on the next step for all of their supported providers.
Follow the steps to create an app in Okta and take care to ensure your push groups are correctly configured. It's easy to create an app, assign groups to the app and then fail to push groups to the app.
If you require more detailed steps on this setup process, you can consult the WorkOS guides here
* For [Okta](https://workos.com/docs/integrations/okta-scim/5-assign-users-and-groups-to-your-application), this article
* For [Google](https://workos.com/docs/integrations/google-directory-sync/4-select-which-groups-to-sync-to-your-application), this article
* For others, search for the relevant provider [here](https://workos.com/docs/integrations)
*Note: Common issues with Okta push group setup are covered in* [this guide](https://support.okta.com/help/s/article/Group-Push-Common-Issues?language=en_US) *.*
Once you've completed the flow and successfully verified your credentials, your SCIM directory will begin to sync with incident.io. This can take some time.
Once your directory is synced, you'll see the success message:
Clicking **Done** will return you to the incident.io Settings page and allow you to map your SCIM groups to roles in incident.io. Click **Add assignment** to map one of your SCIM groups to an incident.io role.
Once you've assigned your SCIM groups to roles, you're ready to click **Continue** and confirm your selection.
At this point, your incident.io users and groups will be managed via SCIM and you will no longer be able to assign roles manually in the incident.io UI.
In addition, your SCIM groups and assigned users will be visible in the catalog, making them available for use in workflows across the product.
# Policies
Source: https://docs.incident.io/admin/policies
Define rules and reminders for on-call setup, debriefs, follow-ups, and post-mortems
You can leverage policies to define rules about how your organization's on-call and incident management program should be setup and run. This includes policies around:
* [Debriefs](/post-incident/debriefs) being scheduled and/or completed
* [Follow-ups](/post-incident/follow-ups) being assigned and/or completed
* [Post-mortems](/post-incident/postmortems-overview) being exported and/or completed
* On-call users having a specific [notification setup](/on-call/notification-policies)
* [On-call schedules being covered](/on-call/coverage-policies) around the clock (24/7), with no gaps
If any of the policy rules are not met, we'll send users [reminders](#notifying-users-about-tasks) to ensure they are addressed within a specified timeframe. In addition, you can set up [policy reports](#policy-reports) to see which tasks are still outstanding across your organization.
Policies are available on Pro and Enterprise plans.
## Creating a policy
To create a policy, go to [Settings → Policies](https://app.incident.io/~/settings/policies). From there, it's recommended to leverage one of our default policy templates.
If you require a more complex setup, you can set up your own policy via `Create new policy` button.
## Viewing outstanding policy tasks
Once your policy is configured, you'll want to see which tasks aren't yet completed — for example, follow-ups still outstanding 30 days after resolve. A few places help you track this:
* **The team page**: each team's **Tasks** tab lists every open task for the team, including policy violations and post-incident tasks, with filters and the associated policy shown for each one. The **Overview** tab also has an at-a-glance **Open tasks** panel.
* **Per-policy**: within each policy's configuration, the right side panel shows outstanding or dismissed tasks for that specific policy.
* **In context**: within an individual incident, or within the Post-incident section of the dashboard.
* **Policy reports**: scheduled summaries delivered to Slack or email (see [Policy reports](#policy-reports)).
***
## Policies and private incidents
By default, policies don't run on [private incidents](/incidents/private-incidents). This is intentional: private incidents are invitation-only, so evaluating them everywhere could surface violations to people who can't access the incident.
If you want a policy to cover private incidents too, you can opt in per policy using the **Also include private incidents** toggle when [creating or editing a policy](#creating-a-policy). Enabling it requires the **Manage policies** permission.
The toggle only appears for incident-based policy types — follow-ups, post-mortems, and debriefs. It doesn't apply to
on-call notification policies, which aren't scoped to a specific incident.
### What happens when it's enabled
When a policy includes private incidents:
* **Violations are only ever shown to people who can access the incident** — in notifications, dashboards, task lists, and counts alike.
* **We only assign violations to users with access to the incident.** We treat an assignee who can't access it as unset and fall through to the next contact in the assignee fallback chain. If nobody in the chain can access the incident, the violation is still tracked, but nobody is notified.
Set a reliable fallback assignee — like the incident lead — who's near-guaranteed to have access, so violations on
private incidents don't go unnotified.
Before enabling, you can **preview the impact**. The preview is filtered to incidents you can personally access.
Access to a private incident's violations follows the incident itself: you need to be a member of the incident, on a team that's been granted access, or hold the **Manage private incidents** permission.
***
## Notifying users about tasks
Within each policy's configuration, you will be able to set who is the assignee (ie. who will be reminded to complete this particular task). For example this could mean:
* For On-call notifications, it would be the on-call user
* For follow-up completion, this could be the follow-up owner
* For post-mortem completion, this could be the incident lead
You can configure when the assignees should be notified about tasks as well. For example, notified follow-up owners:
* 2 days before it's due
* Notifications *before* a due date don't apply to on-call **notification** policies (the ones about a responder's notification setup). This is because you are either in violation of that policy or not — there isn't a way to know you will be in violation beforehand (we aren't mind readers yet!). They *do* apply to [schedule coverage policies](/on-call/coverage-policies), where a gap has a known future start.
* the day it's due
* 1 day after it's due
* etc.
We will then notify these users of their outstanding tasks via Slack, email and the home page (in the right side bar) per the policy's notification configuration.
***
## Policy reports
Policy reports are scheduled summaries of outstanding policy violations, so the right people don't have to check dashboards by hand. Reports are organization-wide — there's no per-user targeting — and you configure them from [**Settings → Policies**](https://app.incident.io/~/settings/policies).
### Cadence
Choose how often a report runs:
* **Daily**
* **Weekly** — pick the day of the week
* **Monthly** — pick the day of the month
For every cadence, you also set the hour and timezone the report is sent.
### Delivery channels
Where a report can be delivered depends on whether your organization uses Slack or Microsoft Teams:
* **Slack organizations**: one or more Slack channels, one or more email addresses, or both.
* **Microsoft Teams organizations**: email only.
### What's in a report
Each report has a header followed by one section per policy, marked as compliant (✅) or as having violations (❗).
* **On-call readiness reports** group by the violating **user**.
* **All other reports** group by the violating **incident**.
Each section shows up to the 5 most recent violating incidents, with deep links so people can jump straight to what needs attention.
### Suppressing empty reports
Turn on **suppress if there are no violations** and no report is sent when there are zero outstanding violations — so a clean week doesn't create noise. This is on by default for new reports.
### Reports and private incidents
By default, policy reports **don't include private incidents** — even for policies that are set to run on private incidents. To include them, an authorized user can enable the **Include private incidents** option, which is shown when a report includes at least one policy that runs on private incidents.
If a report that includes private incidents is delivered to a **public** Slack channel, its reference and name become
visible to everyone in that channel.
# Announcements
Source: https://docs.incident.io/admin/restrict-announcement-management
Let teams manage their own announcement rules and post templates
Give a team the **Manage announcements** permission on a team role, so it only applies to the [announcement rules and post templates](/admin/announcements) that team owns.
Set the owning team using the **Announcement rule owner** field (or **Template owner** for a template) when you create or edit it at [**Settings → Announcements**](https://app.incident.io/~/settings/announcements). Once owned, only members of an owning team with the permission, or anyone who holds it account-wide, can manage it. **Manage announcements** is in the **Standard** role by default, so you'll need to remove it there first.
Changing who owns a rule or template is an account-level action. It needs **Manage announcements** account-wide (typically an admin), so a team-role holder can manage what their team already owns but can't reassign it to another team.
Your **default** template can't be owned by a team, and choosing which template is the organization default is always
an account-level action.
### Announcement rules that run on private incidents
Setting an announcement rule to announce private incidents requires a different permission: the **Manage announcement rules that run on private incidents** permission. This is a broader version of the **Manage announcements** permission. It also covers creating, editing, and deleting announcement rules, so someone who holds it doesn't need **Manage announcements** as well. It can be granted through a team role, so a team can manage rules that announce *their own* [private incidents](/incidents/private-incidents). A team-role holder needs it for every one of the rule's owning teams.
Announcing **all** private incidents (not just an owning team's) always requires the **Manage announcement rules that
run on private incidents** permission account-wide, since it reaches incidents no team has been given access to.
See [Team roles](/admin/team-roles) for the full setup, and [Announcing private incidents](/incidents/announcing-private-incidents) for the per-rule options.
## FAQs
They can be managed by anyone who holds **Manage announcements** account-wide. Until you remove it from your base
roles (typically **Standard**), that's everyone.
Yes. You can assign multiple owning teams, and a member of any one of them (with the permission granted to that
team) can manage it.
Anyone who holds **Manage announcements** account-wide can manage any rule or template that doesn't run on private
incidents, regardless of which team owns it. Rules whose scope includes private incidents also need the **Manage
announcement rules that run on private incidents** permission. See
[above](#announcement-rules-that-run-on-private-incidents).
Yes, if they hold the **Manage announcement rules that run on private incidents** permission for the rule's owning
team(s). They can then set the rule to **Private incidents for owning teams**, the private incidents those teams can
access. Announcing **all** private incidents requires the permission account-wide.
You need the **Manage announcement rules that run on private incidents** permission for *every* owning team (or
account-wide). On a rule owned by teams A and B, holding it for only A isn't enough. This is stricter than **Manage
announcements** itself, where holding it for any one owning team is sufficient, because the rule can announce the
private incidents of *any* owning team, so whoever sets the scope needs authority over all of them.
# Catalog types and entries
Source: https://docs.incident.io/admin/restrict-catalog-management
Let teams manage their own catalog types and entries
As you lean on the catalog as a source of truth, you often don't want everyone able to edit everything in it. Team ownership lets you hand each team control of the catalog types it's responsible for, without giving it the keys to the rest of the catalog.
For example, you might want only the platform team to edit the **Services** type. You do this by giving a catalog type an owning team, then granting the relevant catalog permission to that team's role.
## The permissions
Six catalog permissions can be granted on a team role, so they only apply to the types that team owns:
* **Create catalog types**, **Edit catalog types**, and **Delete catalog types** cover the types themselves
* **Create catalog entries**, **Edit catalog entries**, and **Delete catalog entries** cover the entries of any type the team owns
These permissions are **not** in the **Standard** role, so a catalog type with no owning team is managed only by people who hold the permission account-wide, exactly as today.
## Setting an owning team
Set a catalog type's owner in the **Catalog type owner** field when you create or edit a type in [**Catalog**](https://app.incident.io/~/catalog). You can assign more than one owning team.
Once a type has an owning team, only members of that team with the relevant permission, or anyone who holds it account-wide, can change the type or edit its entries.
System-managed catalog types can't be owned by a team. Their structure is fixed by incident.io, so changes to them
always need the account-wide permission.
## Example: letting a team manage its own services
Say you want the platform team to own the **Services** type: they should be able to create, edit, and delete service entries, but no one outside the team should be able to change them.
1. In [**Catalog**](https://app.incident.io/~/catalog), open the **Services** type and set the **Catalog type owner** to the platform team.
2. At [**Settings → Permissions → Team-level**](https://app.incident.io/~/settings/permissions/team), create (or edit) a team role that includes the **Edit catalog entries** permission (add the **Create catalog entries** and **Delete catalog entries** permissions if they should manage the full set).
3. On the platform team's **Members** tab, assign that role to the people who should manage services.
Now the platform team manages the Services type and its entries, while everyone else sees those controls disabled with a tooltip explaining they don't have permission. See [Team roles](/admin/team-roles) for the general setup and how to remove any account-level default that would otherwise let everyone edit.
## FAQs
Reassigning ownership always requires the **Edit catalog types** permission granted account-wide. A team can manage
a type they own and its entries, but they can't hand the type to another team or remove their own team from it.
Nothing changes for them. They can only be managed by people who hold the relevant catalog permission account-wide,
the same as how every catalog type behaves today.
Yes. You can assign multiple owning teams, and a member of any one of them (with the permission granted to that
team) can manage the type and its entries.
Both GitHub and Terraform can define the owning teams for a catalog type as part of their config, so
externally-managed types can be team-owned just like ones you create in the dashboard, and their entries are gated by
that ownership.
You can also restrict which types a given integration can modify by giving its API key only team-scoped catalog
permissions. A key with team-scoped permissions can create, edit, and delete types (and their entries) for the teams
it's scoped to, but nothing else. See [API keys](/admin/api-keys) for how team-scoped permissions work.
Yes. Anyone who holds the permission account-wide can manage any catalog type or entry, regardless of which team
owns it.
# Alerts and escalations
Source: https://docs.incident.io/admin/restrict-escalation-response
Keep responding to a team's alerts and escalations within that team
By default, anyone in your organization can resolve any alert and acknowledge, snooze, or cancel any escalation. For most teams that's the right thing: anyone can jump in and help out.
As you grow, you might want tighter control to avoid someone accidentally taking actions on alerts or escalations outside their remit. In incident.io, you can restrict acting on alerts and escalations to only the team responsible for them, so that someone in an unrelated team can't accidentally resolve a page or silence an escalation they don't understand. This guide walks through setting that up.
There's one important exception: anyone who's actually paged by an escalation can always acknowledge or snooze it, so you can never be paged by something you're not allowed to silence.
The permission is **Take actions on alerts and escalations**, which covers resolving alerts and acknowledging, snoozing, or cancelling escalations. Ownership comes from the **Team attribute** on an alert, the same attribute used for [routing](/alerts/team-routing); manual escalations fall back to the escalation path they were sent to.
See [Team roles](/admin/team-roles) for how team-based permissions work in general.
## Grant the permission to a team role
At [**Settings → Permissions → Team-level**](https://app.incident.io/~/settings/permissions/team), create or edit a team role and select **Take actions on alerts and escalations**. Assign it to the people on each team who should act on that team's alerts and escalations.
## Remove it from the Standard role
This permission is in the **Standard** role by default, so until you remove it there everyone still holds it account-wide and the restriction has no effect. At [**Settings → Permissions → Account-level**](https://app.incident.io/~/settings/permissions), edit **Standard** and uncheck **Take actions on alerts and escalations**.
## Check it's working
Someone who isn't on the owning team will see the resolve and acknowledge buttons disabled, with a tooltip explaining why. Members of the owning team, and anyone paged by the escalation, can act as normal.
## FAQs
They have no owning team, so once you've restricted the permission, only people who hold it account-wide (such as an
admin) can act on them. If you want a team to handle these alerts, make sure the alert source extracts a Team
attribute. See [Alerts and teams](/alerts/team-routing).
Yes. Anyone notified by an escalation can always acknowledge or snooze it, regardless of team membership. This makes
sure a misrouted page can never reach someone who then can't silence it.
Ownership falls back to the escalation path the escalation was sent to. It can be responded to by anyone who was
paged, anyone who holds the permission account-wide, and members of the team that owns that escalation path.
No. Alerts are still auto-resolved as normal, regardless of who triggers it. These permissions only govern people
resolving alerts directly.
Yes. Anyone who holds the permission account-wide can act on any alert or escalation. This is useful for keeping a
small set of administrators who can step in across teams.
# Incident types and lifecycles
Source: https://docs.incident.io/admin/restrict-incident-type-management
Let teams manage their own incident types and lifecycles
Give a team the **Manage incident types** permission (and **Manage incident lifecycles** for lifecycles) on a team role, so it only applies to the incident types and lifecycles that team owns.
Set an incident type's owner in the **Incident type owner** field at [**Settings → Incident Types**](https://app.incident.io/~/settings/incident-types), and a lifecycle's owner in the **Lifecycle owner** field at [**Settings → Respond → Lifecycle**](https://app.incident.io/~/settings/lifecycle). Once owned, only the owning team, or anyone with the permission account-wide, can change it.
These permissions are **not** in the **Standard** role, so a type or lifecycle with no owning team is managed only by people who hold the permission account-wide, exactly as today.
Your **default** lifecycle can't be owned by a team: it applies to every incident, so changes to it always need the
account-wide permission.
See [Team roles](/admin/team-roles) for the full setup.
## FAQs
Reassigning ownership always requires the **Manage incident types** permission granted account-wide. A team can
manage the configuration of a type they own, but they can't hand it to another team or remove their own team from
it.
Nothing changes for them. They can only be managed by people who hold the **Manage incident types** permission
account-wide, the same as how every incident type behaves today.
Yes. You can assign multiple owning teams, and a member of any one of them (with the permission granted to that
team) can manage the type.
Form overrides for a team-owned incident type follow that type's owning teams, so only the owning team can override
or edit them. Organization-wide forms that aren't tied to a specific type still need the **Manage incident types**
permission granted account-wide. See [Incident forms](/admin/incident-forms).
Yes. Anyone who holds the permission account-wide can manage any incident type or lifecycle, regardless of which
team owns it.
# Workflows
Source: https://docs.incident.io/admin/restrict-workflow-management
Let teams manage their own workflows
Give a team the **Manage workflows** permission on a team role, so it only applies to the workflows that team owns.
Set the owner from the **Owned by** control at the top of the workflow editor (it reads **No team** until you set one), or from the **Advanced settings** panel. Once a workflow has an owning team, only members of an owning team with the permission, or anyone who holds it account-wide, can edit, enable, disable, or delete it.
**Manage workflows** is in the **Standard** role by default, so out of the box everyone can manage every workflow. You'll need to remove it from **Standard** before ownership restricts anything.
### Workflows that run on private incidents
Setting a workflow to run on private incidents needs a second permission, **Manage workflows that run on private incidents**, on top of **Manage workflows**. This can be granted through a team role, so a team can manage workflows that run on *their own* [private incidents](/incidents/private-incidents). A team-role holder needs it for every one of the workflow's owning teams.
Running a workflow on **all** private incidents (not just an owning team's) always requires **Manage workflows that
run on private incidents** account-wide, since it reaches incidents no team has been given access to. Running on
**private escalations** is likewise account-level only, and a team role never grants it.
See [Team roles](/admin/team-roles) for the full setup, [Workflows](/workflows/getting-started) for more on ownership, and [Workflows on private incidents](/incidents/private-incident-workflows) for the per-workflow options.
## FAQs
Reassigning ownership always requires the **Manage workflows** permission granted account-wide. A team can manage a
workflow they own, but they can't hand it to another team or remove their own team from it.
They can be managed by anyone who holds **Manage workflows** account-wide. Until you remove it from your base roles
(typically **Standard**), that's everyone.
Yes. You can assign multiple owning teams, and a member of any one of them (with the permission granted to that
team) can manage the workflow.
Yes. Anyone who holds **Manage workflows** account-wide can manage any workflow, regardless of which team owns it.
Yes, if they hold the **Manage workflows that run on private incidents** permission for the workflow's owning
team(s). They can then set the workflow to run on **Private incidents for owning teams**, the private incidents
those teams can access. To set a workflow to run on **all** private incidents requires the permission account-wide.
You need the **Manage workflows that run on private incidents** permission for *every* owning team (or
account-wide). On a workflow owned by teams A and B, holding it for only A isn't enough. This is stricter than
**Manage workflows** itself, where holding it for any one owning team is sufficient, because the workflow can run on
the private incidents of *any* owning team, so whoever sets the scope needs authority over all of them.
# Role restrictions
Source: https://docs.incident.io/admin/role-restrictions
Control who can be assigned to incident roles and what they can do
Role restrictions let you control who's eligible to be assigned specific roles during an incident, and what permissions each role grants. For example, you may want only members of your Security team to be the Incident Lead for Security incidents, and grant that role permission to manage the incident lifecycle.
Restrictions and permissions are configured per [incident type](/incidents/incident-types), so you can tailor each role to match the needs of different incident types. Role-level permissions are available on the [Enterprise plan](https://incident.io/pricing).
## Setting up
To configure a role, head to **[Settings → Types](https://app.incident.io/~/settings/incident-types)** and select the incident type you want to configure. Scroll to the **Roles** section.
Click the three-dot menu on any role and select **Configure role** to open the configuration drawer. The drawer has two sections: **Who can get this role?** and **Grant additional permissions**.
## Who can get this role?
Restrictions are built using the expression builder. Select a user attribute to restrict on, choose an operator, and pick the values to match against.
Common examples include restricting a role to a specific list of users, or to members of a particular team. You can also restrict based on any user attribute or custom catalog type connected to users.
You can combine multiple conditions:
* **Conditions within the same group** use AND logic - all conditions must be met
* **Separate groups** use OR logic - any group can match
Once saved, restrictions are displayed beneath each role in the Roles section so you know which roles have restrictions set.
Users who don't meet a role's restrictions will appear disabled in role assignment dropdowns. If someone attempts to assign a restricted user directly, an error message explains why the assignment can't be made.
Restrictions are enforced wherever incident roles are assigned:
* **Slack** - when assigning roles via `/inc role` or the channel announcement buttons
* **Microsoft Teams** - when assigning roles via channel announcement buttons
* **Dashboard** - when picking roles during incident declaration or while managing an active incident
* **Workflows** - any steps that assign roles to ineligible users will cause the workflow to fail
## Grant additional permissions
The **Grant additional permissions** section lists permissions you can grant to users holding that role during incidents of this type. Check the ones you want to grant.
For example, you might grant the Incident Lead permission to manage the incident lifecycle and update fields, while giving the Communications Lead only permission to update the timeline.
Permissions granted here are layered on top of any that a user already has through their account-level base or custom roles — you can grant additional permissions to an incident role, but not remove ones a user already has. Each permission shows which account-level roles already grant it, so you can see what a user would have access to regardless of their incident role.
If you're moving permissions from account-level roles to incident roles, set up your incident role permissions
**first**, then remove them from the account-level roles. This avoids a gap where users temporarily lose access to
permissions they need.
### All other participants
Below the named roles, there's an **All other participants** entry. Use this to configure permissions for anyone participating in the incident who doesn't hold a specific role.
This is useful for tightening permissions on sensitive incident types — for example, granting permission to update follow-ups or manage post-mortems only to the Incident Lead, while leaving other participants with more limited access.
## Workflows
If you have workflows that assign incident roles, adding restrictions may cause those workflow steps to fail. A workflow step will fail if the user it tries to assign doesn't meet the role's restrictions.
When you have active workflows that assign roles, you'll see a warning banner in the Roles section of your incident type settings reminding you of this.
Review your [workflows](/workflows) after adding role restrictions to make sure the users being assigned still meet the new requirements.
## FAQs
No - role restrictions are configured per incident type. You'll need to set up restrictions individually for each
type where you want them.
The role dropdown will show all users as disabled. Consider broadening your restrictions if this happens.
# SAML SSO
Source: https://docs.incident.io/admin/saml-sso
Manage access to the incident.io dashboard via your identity provider
Organizations on Enterprise and newer Pro plans can enable SSO using SAML to manage access to the incident.io dashboard via an identity provider (IdP) like Okta or Microsoft Entra ID (formerly Azure AD).
All plans have access to SSO via sign-in with Slack. If your Slack workspace is configured with SAML, incident.io uses that automatically.
## Setting up SAML
To set up SAML, you need Admin or Owner permissions in incident.io, plus admin access to your IdP.
If you're setting up incident.io for the first time, sign in using Slack first, then enable SAML. Admins can perform setup if they have the **Manage security settings** permission.
1. Navigate to [Settings → Security](https://app.incident.io/~/settings/security) and click **Connect**
2. Choose your identity provider from the list and follow the setup instructions
3. Test your connection using the button provided
### Configuring domains
Configure which user email domains authenticate through SAML. By default, only the domain of the user performing setup is configured. Click **Configure domains** to add additional domains for your organization.
## Logging in with SAML
Once SAML is enabled, **all users** in your organization must sign in using SAML. Users attempting to sign in with Slack will be redirected to your IdP to confirm their access.
To sign in, click **Login with SAML SSO** and enter your email address. You'll be redirected to your IdP to authenticate before being directed back to incident.io.
### Dashboard-only users
When users sign in via SAML, incident.io attempts to find their associated Slack account in your workspace. If a user doesn't have access to Slack, or their email addresses don't match, they're created as dashboard-only users. These users cannot be assigned roles, referenced in workflows, or receive subscriptions as Slack messages.
## Disabling SAML
Admins and organization owners can disable SAML in [Settings → Security](https://app.incident.io/~/settings/security). To keep access during an identity provider outage, enable [sign in with email](/admin/sign-in-with-email) before you need it. If you've locked yourself out, contact [help@incident.io](mailto:help@incident.io) for assistance.
If you remove the incident.io app in your IdP, also remove it in incident.io to prevent authentication issues.
When you disable SAML, all users in your organization will need to sign back in using Slack.
## Mobile app sign-in
When SAML is enabled, it is enforced for mobile app sign-in too. Users signing in on the mobile app — whether directly or by scanning a QR code from the web dashboard — are redirected through your identity provider.
Admins can control whether QR code sign-in is available in **Settings → Security** under **QR code mobile login**. Disabling this prevents users from using the QR code flow, but does not affect direct sign-in through the mobile app.
## FAQs
We use WorkOS to provide SAML, which maps users by ID and email address. When logging in, we first check the user's ID. If we don't find a match, we look up by email address and associate the new ID for subsequent logins.
This means that if the ID changes during a migration but the email stays the same, no duplicate users are created — the migration is seamless. However, if both the ID and email change (e.g. after a name change), the user will appear as a new account and we cannot merge them.
Yes — SCIM can be set up independently from SAML but can use the same identity provider. See [SCIM provisioning](/admin/scim) for details.
Yes — if your organization uses managed device policies, you can configure a secondary SAML provider to redact sensitive data on the mobile app. See [Mobile access restrictions](/admin/mobile-access-restrictions) for details.
# Sandbox environments
Source: https://docs.incident.io/admin/sandbox-environments
Set up a separate incident.io environment to test configuration.
A sandbox environment is a separate, fully-featured incident.io organization designed for safely testing configuration before rolling it out in production.
## How it works
The sandbox is a completely independent incident.io organization from your production instance, connected to a completely different Slack workspace or Microsoft Teams tenant for testing purposes.
Because it's a separate organization, configuration cannot be directly promoted from sandbox to production. Teams typically experiment in the sandbox, then recreate what works in production. You can use [Terraform](https://registry.terraform.io/providers/incident-io/incident/latest/docs) to manage configuration as code across both environments and automate this.
## How to request a sandbox environment
Sandbox environments are available to customers on the **Enterprise** plan. To set one up:
1. **Have a test Slack or Teams workspace** — set up a new Slack workspace (a free workspace is fine) or designate a separate Microsoft Teams tenant for testing.
2. **Install incident.io** — install the incident.io app in the new workspace via [incident.io/trial](https://incident.io/trial).
3. **Let us know** — share the workspace name or URL with your Customer Success Manager, or contact [support](mailto:help@incident.io), and we'll mark the account as a sandbox.
If you use SAML SSO, avoid enabling it on your sandbox environment. SAML will automatically redirect users to your
production instance based on their email domain. See [SAML SSO](/admin/saml-sso) for more details.
If you just need to test your configuration or run a practice incident without setting up a full sandbox, use [test
incidents](/incidents/test-incidents) instead.
# SCIM (Automatic user provisioning)
Source: https://docs.incident.io/admin/scim
Sync users, roles, and permissions from your identity provider
You can use SCIM (System for Cross-domain Identity Management) in incident.io to automatically provision users and manage their permissions.
## What does enabling SCIM do?
### Without SCIM
By default, without SCIM, incident.io automatically creates users when they join incident Slack channels, or when they sign in to the web dashboard using Slack or SAML. When a user is deactivated in Slack, they'll be automatically deactivated in incident.io.
Without SCIM, you manually grant users additional base roles and custom roles within incident.io. When a new user joins, an owner/admin (or other user with a custom role that can manage permissions) can manually assign that user some additional permissions by going to [app.incident.io/\~/settings/users](https://app.incident.io/~/settings/users). See [user roles and permissions](/admin/user-permissions) for more details.
### With SCIM
When SCIM is installed, users are automatically created in incident.io when they are assigned in the application in your identity provider (IdP). If a user is unassigned the application in your IdP, they'll be deactivated in incident.io.
Additionally, user permissions are automatically managed by your identity provider, and are no longer editable in incident.io. This means you don't have to manually assign roles to new users, and don't have to manually downgrade users in incident.io if their access levels change in your identity provider. See [user roles and permissions](/admin/user-permissions) for more details.
## Installing SCIM
To install SCIM, you'll need to be an owner in incident.io (or have a custom role that can manage security settings), and have admin permissions in your identity provider.
1. Go to your user settings, and [open the SCIM tab](https://app.incident.io/~/settings/users/scim) and click the `Install` button
2. Choose your identity provider from the list and follow the steps to set up your connection.
We're enabling providers as we confirm they send appropriate group membership updates. If you see a message saying your provider is not yet supported, contact us at [help@incident.io](mailto:help@incident.io).
3. Define the relationships between groups in your identity provider and permissions in incident.io. You only need to do this for groups that you'd like to give elevated permissions to, by default, all users are given the 'Standard' role. To illustrate this further, here are some examples:
* I want all people in the `Engineers` group to have access to [incident.io](http://incident.io/) but not have advanced permissions for administrative tasks. I don't need to define any mapping for this case, as this is the default. The default 'Standard' role assigns all new users a 'Viewer' seat. Learn more about [seat types](/admin/seat-types).
* I want myself and other `Incident Managers` to be admins in incident.io, so I add an assignment, choose the `Incident Managers` group from my identity provider (e.g. Okta, Microsoft Entra ID) and then assign them the `Admin` role.
* I want our IT team to be able to manage SCIM and SAML, so I add an assignment, choose the `IT` group from my identity provider and then assign them a custom role with the `Can manage security settings` permission.
You need at least one group assigned the 'owner' permissions. If you're not in that group, or you remove yourself from it, you'll be locked out of your SCIM settings. If this happens, contact us at [help@incident.io](mailto:help@incident.io).
4. Confirm your SCIM setup. Once you've confirmed this step, we'll start creating users from SCIM and re-assigning any permissions that no longer line up with what you've defined in your SCIM group to role mappings.
## FAQs
SCIM is available to customers on our Enterprise plan - for more pricing details, see [pricing](https://incident.io/pricing/).
When you install SCIM, we'll link existing users to SCIM users using their email address. We'll also update their permissions as defined by the group to role mappings you provide in the SCIM settings page. If a user was previously an admin, and they're not a member of the groups that are assigned the admin role, they'll be downgraded to viewers/responders.
If a user exists in incident.io but not in SCIM, they'll retain their existing role and will be marked as 'Unlinked' in the user list. If you don't want these users to have access to the incident.io dashboard at all, we recommend you install SAML too and link that to the same identity provider (e.g. Okta) so that only users who are assigned the incident.io app can access the dashboard.
When you uninstall SCIM, users will be left in their current state. So if you are an Owner, and you uninstall SCIM, you'll retain that owner role. Users will not be deactivated.
No, once SCIM is installed, it becomes the source of truth for a user's permissions. If you want to elevate a user's permissions, you'll need to add them to an appropriate group in your identity provider.
As our application runs both in Slack and on our web dashboard, it's possible that a user can be deactivated in Okta, but still be an active member of your organization's Slack workspace. If this happens, the user will be treated as 'active' until they're deactivated in Slack. If you don't want this, we recommend you manage your Slack users with the same identity provider set up as you manage your incident.io users.
Yes! Once you have set up SCIM, there's a section on the configuration page where you can define your on-call seat assignments. This lets you pick groups which are automatically given on-call seats.
Once you've selected a group for on-call seats, you'll no longer be able to manually control those group members' on-call seats - they will be automatically assigned seats. Adding new members to those groups will automatically grant them seats. If a member leaves a group which has been assigned seats, that user will retain their seat until it's manually revoked.
Yes — if you have both SAML and SCIM set up, users can sign in via your identity provider and be added to schedules and escalation paths without needing a Slack or Microsoft Teams account.
SCIM provisions the user and assigns their on-call seat, while SAML handles their login. The two don't need to point at the same IdP, as long as the user appears in both with the same email address.
Without SAML and SCIM, users need a Slack or Microsoft Teams account to participate in on-call rotations.
## SAML
We also support SAML, which can be set up independently from SCIM, but can use the same underlying identity provider, such as Okta or Microsoft Entra ID (formerly Azure AD). See [SAML SSO](/admin/saml-sso) for details.
# Seat types and Viewers with incident.io
Source: https://docs.incident.io/admin/seat-types
Our [pricing](https://incident.io/pricing) is based on the number of Responder and On-call seats in your company, so it is only fair that you ask what counts with each seat in incident.io!
## Seat types at a glance
Each paid seat maps to a product — Responder for Response, On-call for On-call. Users can hold one or both paid seats, and anyone without a paid seat can still use parts of our product as a Viewer.
As a rule of thumb, Responder and On-call seats are for users who actively engage with incident.io to be On-call, manage incidents, whereas Viewers (free seats) are users who declare and join an incident channel to contribute information, but do not actively participate in incident response.
| Seat type | Cost | What can you do |
| ------------- | ---- | -------------------------------------------------------------------------------------------------------------------- |
| **Viewer** | Free | Declare incidents, contribute in channels, view post-mortems, alerts, and schedules. Unlimited Viewers on all plans. |
| **Responder** | Paid | Manage incidents: change status, post updates, assign roles, and write post-mortems. |
| **On-call** | Paid | Be paged and included in schedules and escalation paths. |
Someone with a paid Responder or On-call seat can have the role permissions of an [Administrator](/admin/user-permissions), [Owner](/admin/user-permissions) or any [custom role](/admin/user-permissions#h_649c9e2937). Viewers can only have the Standard set of permissions.
***
## On-call seat (paid)
Users who have an On-call seat can:
* Be added to a schedule
* Be added to an escalation path
* Have access to the mobile app
* Incidents
* Escalations
* Schedules
* Overrides
* Cover me
* Get paged via all methods (phone, SMS, WhatsApp, Slack, app, email)
* Request cover via mobile app and Slack
* Create overrides via dashboard, mobile app and Slack
* Create pay reports from On-call
## Responder seat (paid)
Someone with a responder seat can have the role permissions of an [Administrator](/admin/user-permissions), [Owner](/admin/user-permissions) or any [custom role](/admin/user-permissions#h_649c9e2937). Viewers can only have the Standard set of permissions.
Users who have done the following will qualify as Responders:
**Managing and running incidents**
* Changed the status, severity, or [custom field](/incidents/custom-fields) values
* Posted an incident [Update](/incidents/status-updates)
* Changed the incident Status, includes accepted and declined an incident.
* Was assigned or assigned someone else an [incident role](/incidents/incident-roles) (Lead or other)
* Handed over the Lead role
* Created, assigned, updated, was assigned to, or completed an [action](/incidents/task-tracking) or a [follow-up](/post-incident/follow-ups)
* Changed the [Call URL](/incidents/video-calls) associated with the incident
* Changed the incident [Type](/incidents/incident-types)
* Updated the incident [Summary](/ai/summaries)
* Pinned a Slack message to the [timeline](/post-incident/timeline)
* Revoked someone’s access to a [Private Incident](/incidents/private-incidents)
* Renamed an incident
* [Merged](/incidents/merging) an incident
**Documenting incidents**
* Created or edited a [Post-mortem](/post-incident/postmortems-overview)
* Set a [Timestamp](/incidents/lifecycle)
* Removed an [Attachment](/incidents/attachments)
## Viewer only (free)
If you don't have a paid Responder seat or an On-call seat, you can still use parts of the product as a viewer. Viewers can create an incident, observe what is happening in the incident, and post messages in the channel.
As a viewer, you can:
* Create incidents (everyone in the company can declare incidents for free)
* [Decline](/incidents/triaging) an incident
* Join incident channels and post in them (everyone can track and contribute important information to incidents for free)
* Go through a [tutorial incident](https://incident.io/changelog/2021-12-20-tutorial) (everyone can - and should! - learn the ropes of incident.io for free)
* View alerts, escalations and schedules
* Add an [Attachment](/incidents/attachments) (e.g. Zendesk, Github, etc.)
* [Escalate](/incidents/escalating) to someone (e.g. via incident.io On-call/Opsgenie/PagerDuty)
* View [internal status pages](/status-pages/overview#internal-status-pages-19)
* [Publish to status pages](/status-pages/publishing-incidents) (both incident.io status pages and [Atlassian Statuspage](/integrations/statuspage))
* View post-mortems
* Use @incident bot. Note: using the bot to make changes to the incident that only responders should do will upgrade you to a responder (see above actions for [responders](/admin/seat-types#responder-seat-paid))
All our plans allow unlimited viewers free of charge
***
## Adding and removing seats
For details on how to add, remove, or change seats, see [Managing seats](/admin/managing-seats).
***
## FAQs
Learning is free at incident.io. Everyone in your company can — and should! — learn the ropes of incident.io without getting penalized by it and billed.
Your teammates won't be considered Responders (paid users) if they go through our tutorial flow.
You can find full details of our billing methods and mechanics [here](/admin/billing).
# Security FAQs
Source: https://docs.incident.io/admin/security-faqs
Frequently asked questions about security and data handling.
Common questions about incident.io's security practices, data handling, and compliance. For more detailed information, visit our [Trust Center](https://trust.incident.io/).
Our primary web application, Slack integration, and other related components are deployed onto the [Google Cloud Platform](https://cloud.google.com/) (GCP).
Any data we store is kept either in our PostgreSQL database (also securely hosted and managed by GCP) or in GCP's BigQuery platform. All data is encrypted at rest in both Postgres and BigQuery.
Two-factor authentication and IAM policies are applied to restrict access to resources within the Google Cloud Platform.
Yes. We are happy to provide access to our SOC2 data room on request ([help@incident.io](mailto:help@incident.io)).
For transactional data processing (interacting with the Slackbot, and viewing the dashboard), the data is hosted in GCPs Belgium region, in [europe-west1](https://cloud.google.com/about/locations#europe). We additionally have a hot standby in the Netherlands region, [europe-west4](https://cloud.google.com/about/locations#europe).
For analytical data processing (for our internal analytical use case), data is stored [within Europe](https://cloud.google.com/bigquery/docs/locations).
We currently don't send any data outside of Europe.
If you decide to stop using incident.io, we're happy to delete application data upon request. Just let us know at [help@incident.io](mailto:help@incident.io).
For removing specific sensitive data from alerts, escalations, incidents, or AI processing, see [Managing sensitive data](/admin/managing-sensitive-data).
By default, users authenticate via Slack — however your organization authenticates with Slack (directly or via a single sign-on provider), that same mechanism is used to access incident.io.
You can also configure [SAML SSO](/admin/saml-sso) to authenticate users through your identity provider instead.
For the web application, temporary sessions are granted when you sign in. These periodically expire and are refreshed by redirecting the user through the OAuth flow. We can also revoke these tokens.
For the mobile app, users can sign in directly or by scanning a QR code from the web dashboard. When SAML is enabled, mobile sign-in always goes through your identity provider. Admins can disable QR code sign-in in **Settings → Security**.
Yes, incident.io has been approved by Slack and can be found in the Slack App Store
[here](https://slack.com/apps/A01DEGPUHHC-incidentio?tab=more_info).
To delete your entire organization, see [Deleting your organization](/admin/delete-account). To remove an individual user account, see [Deleting users](/admin/delete-users).
# Sign in with email
Source: https://docs.incident.io/admin/sign-in-with-email
Let users access incident.io with a one-time code sent to their email address.
Sign in with email lets users access incident.io with a one-time code sent to their email address. Use it alongside Slack, Microsoft Teams, or SAML SSO to give users a direct dashboard sign-in option.
Email sign-in is also useful as an emergency access route when your normal identity provider or communications platform sign-in path is unavailable.
## When to use email sign-in
Email sign-in gives users another way to reach incident.io without going through Slack, Microsoft Teams, or your identity provider. You might enable it when:
* You want to invite users by email before they have connected a Slack or Microsoft Teams account
* You have dashboard-only users who do not regularly work from your communications platform
* You want a fallback sign-in route if your identity provider is down or misconfigured
* You need access to incident.io while investigating an authentication incident
Email sign-in depends on users being able to receive email. If you rely on it for emergency access, make sure your
internal process accounts for any dependency between your email provider and identity provider.
## Enable email sign-in
You need Admin or Owner permissions in incident.io. Admins can manage this setting if they have the **Manage security settings** permission.
1. Navigate to [Settings → Security](https://app.incident.io/~/settings/security)
2. Find **Sign in with email**
3. Enable the setting
Once enabled, users can sign in using a one-time code sent to their email address.
If your organization uses SAML SSO, users without the **Bypass SAML** permission will still be sent through your SAML
provider after entering an email code.
## Sign in using email
To sign in with email:
1. Go to [app.incident.io](https://app.incident.io)
2. Choose the email sign-in option
3. Enter the email address associated with your incident.io user
4. Use the one-time code sent to your email address to finish signing in
## Use email sign-in as a break-glass access pattern
Email sign-in works well as a break-glass access pattern when Slack, Microsoft Teams, or your SAML provider is unavailable. Enable email sign-in all the time, rather than waiting for an outage, so the fallback path is ready when you need it.
To prepare:
* Confirm your Owners and key Admins have email addresses that can receive login codes during an outage
* Keep at least one Owner or Admin able to manage security settings
* If you use SAML, give at least one Owner or Admin the **Bypass SAML** permission before an outage so they can sign in with email if your SAML provider is unavailable
* Test the flow after enabling it, then include it in your internal access runbooks
During a SAML outage, that Owner or Admin can sign in with email and grant **Bypass SAML** to every user, or every user who needs access during the incident. Users can then sign in with email codes without being sent through the unavailable SAML provider.
After the outage, review changes to the setting and permissions in [audit logs](/admin/audit-logs), then remove any temporary **Bypass SAML** access you no longer need.
## Related docs
* [SAML SSO](/admin/saml-sso)
* [User roles and permissions](/admin/user-permissions)
* [Audit logs](/admin/audit-logs)
# Slack permissions
Source: https://docs.incident.io/admin/slack-scopes
Slack permissions and access scopes required by incident.io
As a workspace app, you can interact with incident.io from anywhere within Slack, but we’re careful with the permissions and scopes we require and request the minimum we need to function.
You can find the [up-to-date list of permissions in Slack here](https://incident-io.slack.com/apps/A01DEGPUHHC-incidentio?tab=settings\&next_id=0).
## Required scopes on installation
All of the following scopes are requested on first installation of our Slack bot, and are required for our app to run.
Respond to direct mentions to our bot from Slack users.
See the bookmarks we set within incident channels.
Set bookmarks in incident channels (such as the alert that triggered the incident).
Create canvases in incident channels.
Read content in Slack channels we're added to, including messages users pin in their incident channel.
Create incident channels.
Read incident channel names.
Write messages and updates in channels we have access to.
Send announcements to public channels we haven't been added to (such as the incident announcement channel).
Post messages with a custom username and avatar, so features like Scribe and Investigations can appear with their own
bot identities.
Add slash commands, such as `/inc` so you can interact with our bot.
Read files shared in channels we have access to (such as images in incident channels).
Upload files to channels we have access to so we can share insights reports and other materials.
See private incident channels we are part of.
Post to private incident channels we are part of.
Read messages in private incident channels we're added to.
Read DMs that are sent to the incident bot.
View URLs in messages.
Show previews of URLs in messages from our bot.
Read pinned messages so we can save them to the incident timeline.
Write new pins to a Slack channel, such as the incident welcome message.
See when users have reacted to messages to trigger an action such as creating follow-ups.
Add reactions to messages, such as marking GitHub pull requests as reviewed.
Read your organization's name and icon.
Read your organization's users.
Match user accounts with other services, such as GitHub.
Read user avatars so they can be displayed in our UI.
List all user groups for syncing schedules.
Sync on-call schedules into your Slack user groups.
## Optional additional scopes
We don't request any of these on installation, but you can choose to provide them later.
Rejoin incident or announcement channels if we lose access. If this isn't granted, users will have to manually add our
bot to any channel they want to interact with us in. If you'd like to configure this, contact us at
[help@incident.io](mailto:help@incident.io).
## Privileged access scopes
Depending on your Slack workspace settings, bots and regular users may be restricted from taking certain actions. If your organization's Slack configuration requires admin access for certain operations, you can choose to additionally provide these scopes, otherwise some incident.io features may be degraded.
You can find out more [details about each of those scopes here](/getting-started/slack-privileged-access)
These scopes are **User Scopes**, which means you're granting us permission to use them on behalf of a specific user, rather than as our bot.
To use any of these, you need to [configure a Slack admin for our bot](/getting-started/slack-admin-setup)
These include:
Create and archive public incident channels, if this requires admin access in your Slack workspace.
Create and archive private incident channels, and remove member's access to them if it's revoked within incident.io.
Sync on-call schedules into your Slack user groups, if this requires admin access in your Slack workspace.
Convert channels between public and private, to match the visibility of an incident.
# Team roles
Source: https://docs.incident.io/admin/team-roles
Give teams control over their own workflows, escalation paths, schedules, incident types, announcements, and more
[Team roles](https://app.incident.io/~/settings/permissions/team) let you give teams the ability to manage their own config without letting them change another team's. Each resource can be owned by a different team: one alert route could be managed by Team A while another is managed by Team B.
Team roles rely on having [teams set up](/catalog/teams) in your catalog. If your organization doesn't use teams yet,
start there.
This page covers how team-based permissions work in general. For the specifics of each resource, see:
* [Alerts and escalations](/admin/restrict-escalation-response) — resolving alerts and responding to escalations
* [Announcements](/admin/restrict-announcement-management) — a team's announcement rules and post templates
* [Catalog types and entries](/admin/restrict-catalog-management) — editing a team's catalog types and their entries
* [Incident types and lifecycles](/admin/restrict-incident-type-management)
* [Workflows](/admin/restrict-workflow-management)
Escalation paths, schedules, alert routes, alert sources, and [API keys](/admin/api-keys) work the same way.
Team roles are **in addition to** [account-level roles](/admin/user-permissions). If someone can manage something at
the account level, they can make changes even if they're not on the team that owns it. This lets a small set of admins
step in across teams.
## How team-based permissions work
Giving a team control of its own resources follows the same shape wherever you do it:
1. **Give the resource an owning team.** Where you set this depends on the resource (see the pages linked above). A resource with no owning team behaves as it did before you started. See [Team resources](/catalog/team-resources) for what ownership means.
2. **Create a team role with the permission.** At [**Settings → Permissions → Team-level**](https://app.incident.io/~/settings/permissions/team), create a team role (or edit an existing one) and select the relevant permission.
3. **Remove the account-level default**, if the permission is granted to everyone. Some permissions (like **Manage workflows** or **Manage announcements**) are in the **Standard** base role out of the box, so everyone holds them account-wide. Until you remove that grant at [**Settings → Permissions → Account-level**](https://app.incident.io/~/settings/permissions), team ownership has no effect on who can manage the resource.
4. **Confirm it's working.** Someone outside an owning team sees the relevant controls disabled, with a tooltip explaining they don't have permission for that resource. Members of the owning team, and anyone who holds the permission account-wide, can manage it as normal.
## Assigning team roles
Who has which team role is controlled via the catalog. Each team role corresponds to an attribute on your Team catalog type (you can [configure which catalog type represents your teams here](https://app.incident.io/~/settings/teams)). You can view and change who has which role from the **Members** tab of the team's page.
You can configure multiple team roles (for example Members and Admins) so that some people on a team get additional permissions the rest don't. Users can hold multiple roles on a team, and if they do, they get the union of permissions across all of them.
If your teams are controlled externally (for example via Linear, GitHub, the catalog importer, or Terraform), then
anyone who can update teams in the external system can control which users have team roles within incident.io.
## Example: team-owned schedules
Say you want everyone on a team to create schedule overrides, but only the team's managers to edit the schedule itself.
First, make sure the schedule is owned by the right team:
Then create two team roles, one for members and one for admins, each granting the schedule permissions that group should have:
Assign those roles on the team's **Members** tab, as [above](#assigning-team-roles). Now everyone on the team can create overrides for schedules they're on, but only the admins can change the schedule itself, like working hours and when shift handovers happen.
## FAQs
Reassigning ownership always requires the relevant permission granted **account-wide**. A team can manage a resource
they own, but they can't hand it to another team or remove their own team from it. This stops a team from quietly
giving away (or locking others out of) a shared resource.
They can be managed by anyone who holds the relevant permission account-wide. For permissions that are in the
**Standard** role by default (like **Manage workflows** or **Manage announcements**), that's everyone until you
remove it in step 3.
Yes. You can assign multiple owning teams, and a member of any one of them (with the permission granted to that
team) can manage the resource.
Yes. Anyone who holds a permission account-wide can manage any resource of that kind, regardless of which team owns
it. This lets a small set of administrators step in across teams.
# Manage your account with Terraform
Source: https://docs.incident.io/admin/terraform
Manage incident.io configuration as code with our official Terraform provider
We maintain an [official Terraform provider](https://registry.terraform.io/providers/incident-io/incident/latest) for incident.io. With this provider you can manage account configuration such as:
* Custom fields
* Incident severities
* Incident roles
* Incident statuses
* Schedules
* Escalation paths
* Alert sources
* Alert routes
* Catalog types and entries
* Maintenance windows
This allows you to bring incident.io account configuration into the same code review and approval cycle as you'd use for other key infrastructure and allows syncing information about your infrastructure or organization into incident.io, such as a list of services or teams.
For resources like schedules, escalation paths, workflows, alert sources, and alert routes, you can configure them in the visual editor first and then export the generated Terraform config — so you don't have to write it from scratch.
As an example, this is how you might configure a custom field for affected services:
```hcl theme={null}
provider "incident" {}
resource "incident_custom_field" "impacted_services" {
name = "Impacted Services"
description = "The services that are impacted by this incident."
field_type = "multi_select"
}
resource "incident_custom_field_option" "impacted_services" {
# Load this from your service catalog, config file, or anywhere.
for_each = toset([
"Payments Service",
"API Gateway",
"Transaction Ledger",
])
custom_field_id = incident_custom_field.impacted_services.id
value = each.value
}
```
Whether a field is required and where it appears is no longer configured on the field itself — set that up in
[incident forms](/admin/incident-forms) in the dashboard.
Full documentation on how to use the provider and all its resources can be found in the Terraform registry at [incident-io/incident](https://registry.terraform.io/providers/incident-io/incident/latest). This includes example code and attribute definitions.
If you need a refresher on how to provision your infrastructure with Terraform, check out Hashicorp's [tutorials and documentation](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/infrastructure-as-code).
### Importing existing resources
If you already have configuration set up in the dashboard, you can bring it under Terraform management without recreating it.
For workflows, schedules, escalation paths, alert sources, and alert routes, the easiest path is exporting from the dashboard (see below), which generates the resource block and the matching `terraform import` command for you. For everything else, or if you prefer to write the configuration yourself:
1. Write a resource block matching your existing configuration
2. Find the resource's ID, from the dashboard URL or [the API](/api-reference/introduction)
3. Import it into your Terraform state:
```bash theme={null}
terraform import incident_schedule.primary 01ABC123DEF456GHI789JKL
```
Or, on Terraform 1.5 and later, use an import block:
```hcl theme={null}
import {
to = incident_schedule.primary
id = "01ABC123DEF456GHI789JKL"
}
```
4. Run `terraform plan` and adjust your configuration until the plan shows no changes
Each resource's page in the [registry documentation](https://registry.terraform.io/providers/incident-io/incident/latest) shows its import syntax.
### Editing Terraform-managed resources in the UI
Once a resource is managed by Terraform, it becomes locked in the dashboard — you can't save changes directly. But you can still use the UI to compose changes visually:
1. Open the resource (e.g. a schedule or escalation path) in the dashboard
2. Make your changes in the visual editor
3. Instead of saving, click **Export** to get the updated `.tf` configuration
4. Review and apply via your normal Terraform workflow
This keeps Terraform as the source of truth while letting you use our powerful visual editor to draft changes.
# User management
Source: https://docs.incident.io/admin/user-management
How users are added to incident.io and how to manage them
There are several ways users get added to your organization, depending on your setup.
## Adding users
| Method | How it works |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Slack or Microsoft Teams** | Users are automatically created when they join an incident channel or interact with incident.io in your communications platform. This is the most common way users are added. |
| **SAML SSO** | Users are created on their first sign-in through your identity provider. See [SAML SSO setup](/admin/saml-sso) for details. |
| **SCIM** | Users are automatically provisioned and deprovisioned from your identity provider. SCIM also manages permissions automatically. See [SCIM provisioning](/admin/scim) for details. |
| **Manual invite** | Invite users from **Settings → Users → Users tab**, or directly when creating or editing a schedule or escalation path. You can invite existing Slack/Teams users or invite people by email. See [Inviting users by email](#inviting-users-by-email) below. |
## Inviting users by email
You can invite users to your organization with just their email address. Note that this is only available to you if your organization has sign in with email or SAML login enabled, and is always disabled if your users are provisioned with SCIM.
To invite users:
1. Go to **Settings → Users → Users tab** and click **Invite user**.
2. Type/paste one or more email addresses. You can mix in existing Slack/Teams users in the same picker.
3. Choose the [seat type](/admin/seat-types) the new users should have, then click **Invite**.
### Inviting from a schedule or escalation path
You can also invite new users while creating or editing a [schedule](/on-call/schedules) or [escalation path](/on-call/escalation-paths). Just type an email address into the user picker.
When you save, we'll create the user, give them an On-call seat, add them to the schedule or escalation path, and send them an email letting them know they've been added.
### Requirements
Inviting users by email requires the **Manage users** permission. Owners and Admins have it by default. You can also grant it via a [custom role](/admin/user-permissions#custom-roles).
Email invites aren't available if your organization uses [SCIM](/admin/scim), since user creation comes from your identity provider. If your [SAML config](/admin/saml-sso) has a domain allowlist, invites are limited to email addresses on those domains.
## Permissions
Each user has a base role (Standard, Admin, or Owner) that determines their core permissions, plus optional custom roles for additional permissions. This determines what they can do on the platform. See [user roles and permissions](/admin/user-permissions) for details.
See [seat types](/admin/seat-types) for details on seats and billing.
## Deactivating users
Users are automatically deactivated when they are deactivated in Slack or Microsoft Teams. If you use [SCIM](/admin/scim), users are also deactivated when unassigned from the application in your identity provider.
To manually deactivate a user, go to **Settings → Users → Users tab**, click the three dot menu next to their name, click **Edit details**, and deactivate them. The same edit menu lets you rename email-only users. Both actions require the **Manage users** permission.
## Duplicate users
If a user has multiple accounts (for example, from joining via both Slack or Microsoft Teams and SAML with different email addresses), you can merge them. See [duplicate users](/admin/duplicate-users) for details.
## FAQs
Already-active members are skipped silently, they won't get a duplicate account or a second invite. You'll see a
summary after submitting that tells you how many were invited and how many already existed.
No. If your SAML config has a domain allowlist, invites are limited to those domains. To invite someone from a
different domain, add the domain to your allowlist first.
Yes. The seat type you pick is applied as soon as the invite is sent. If you invite someone with a Responder or
On-call seat, that seat is consumed from your plan right away.
# User roles and permissions
Source: https://docs.incident.io/admin/user-permissions
Control user access with base roles and custom permissions
User permissions in incident.io are controlled through base roles and custom roles. Each user has one base role that determines their core permissions, plus optional custom roles can grant additional permissions.
Configure roles at **Settings → Permissions → Account-level**. Assign roles to individual users at **Settings → Users → Users tab**.
For information on how roles interact with billing, see [seat types](/admin/seat-types).
## Base roles
Every user has a base role that determines their default permissions. There are three base roles:
* **Standard** — default role for all users. Can view and declare incidents. Responders with this role can participate in incident response.
* **Admin** — all Standard permissions, plus the ability to manage organization settings and billing.
* **Owner** — full access to all incident.io features and settings.
Viewers can only have the Standard role. To assign a user the Admin or Owner role, they must have a Responder or On-call seat.
### Default permissions by role
| Permission | Standard | Admin | Owner |
| ------------------------------------------------------------------- | -------- | ----- | ----- |
| Use incident.io via Slack and dashboard (view and create incidents) | ✅ | ✅ | ✅ |
| Create and edit workflows and announcement rules | ✅ | ✅ | ✅ |
| View organization settings (except billing) | ✅ | ✅ | ✅ |
| Edit organization settings | ❌ | ✅ | ✅ |
| View and edit billing settings | ❌ | ✅ | ✅ |
| View all private incidents (including those they are not part of) | ❌ | ❌ | ✅ |
Slack workspace admins already have access to all private Slack channels, so they can access all private incidents
regardless of their incident.io role.
You can customize base role permissions at **Settings → Permissions → Account-level**. Click the edit icon on any base role to modify its permissions. For example, you could restrict billing access so only Owners can manage billing settings.
## Custom roles
Custom roles grant specific permissions to individual users beyond their base role. They only add permissions — they never remove them. A user receives the union of all permissions from their base role plus any assigned custom roles.
**Example custom roles:**
* **Engineer** — manage API keys and webhooks
* **Finance** — manage billing settings and on-call pay reports
* **Security** — view all private incidents
To create a custom role, go to **Settings → Permissions → Account-level** and click **Add role**. Define the role name, description, and specific permissions to grant.
For a full list of the permissions you can grant, see the [permissions reference](/admin/api-keys#permissions-reference).
## Managing user permissions
View and edit user permissions at **Settings → Users → Users tab**. Each row shows the user's current seat type, base role, and custom roles.
To modify a user's permissions, open the **⋯** menu next to their name and choose **Edit details**. You can change their base role or add custom roles. Users can hold multiple custom roles simultaneously.
# Webhook IP addresses
Source: https://docs.incident.io/admin/webhook-ips
IP addresses used by incident.io webhooks
If you need to allowlist IPs for incoming webhooks from incident.io, here are the addresses to add. Our webhooks are powered by [Svix](https://svix.com/), hosted in the EU region.
```plaintext theme={null}
52.215.16.239
54.216.8.72
63.33.109.123
```
# Using @incident
Source: https://docs.incident.io/ai/at-incident
## What is @incident?
You can tag @incident in any incident channel in Slack, chat from the incident tab in Microsoft Teams, or chat via the incident dashboard. It can be used to draft updates, create follow-ups, pause incidents and more. Essentially, any action you currently do via a command, you can do via the agent instead.
@incident can also answer questions about the incident you’re in, connected alerts, and attachments.
The examples below are relevant for Slack only. In Microsoft Teams, chat to the agent in the embedded tab, or in the dashboard or mobile app.
### Examples to get started
**Handle incident admin**
You can ask @incident to handle anything you'd do as a responder during an incident. That means pausing, renaming, declining, or keeping your incident up to date with changes.
* `@incident pause this till monday`
* `@incident rename this to reflect that it was a misconfiguration problem`
* `@incident can you decline this and create a follow up to stop it paging?`
**Draft updates across stakeholders**
Draft rich updates for different scenarios with @incident. You don't have to be prescriptive about what to include - @incident will use the information available in the channel to reflect the current situation.
* `@incident write an update describing the fix that we've implemented`
* `@incident draft a customer facing message explaining the workaround described above`
* `@incident write up a handover summarizing where we're at and next steps - then assign the lead to Rory`
* `@incident draft an update for my status page, make it clear that the issue is resolved`
**Dive into your codebase**
You can ask questions of any of your connected repositories, to summarize code or provide more clarity.
* `@incident can you find where this function is used? I want to understand the potential impact`
* `@incident can you check our timeline code - when a notification errors, do we surface it?`
**Query telemetry**
If you've connected any telemetry sources for Investigations you can ask natural language questions of your logs or metrics
* `@incident show me 5 example log entries of SMS notification failures from the last 24 hours. Include any error codes, organization names, and country codes.`
* `@incident look at the telemetry for web pod CPU usage during this incident to see if the >75% usage was isolated to a single pod`
**Answer general engineering questions:**
Ask @incident general engineering questions whenever you need it.
* `@incident what does 'skip locked' mean in postgres?`
* `@incident can you rewrite this query to group by customer_id`
* `@incident draft me a SQL query to determine how many payments are currently in 'error' state for this organization. Their ID is [ID]`
**Search past incidents**
Search across your incident history to find patterns or similar issues.
* `@incident have we seen incidents like this before?`
* `@incident did we have an incident about high database CPU in February?`
* `@incident what other incidents have affected ACME?`
## Who can use @incident & how to enable it in your account?
* Available to all **Pro and Enterprise** customers on Slack and Microsoft Teams (on the tab for the incident, or in the dashboard). It is not available for Basic, Team plan, on-call–only participants, or workspaces that opted out of AI features/required sub-processors.
* If it isn't working for you, it's probably because your account doesn't have message storage enabled. You'll need to update your message storage settings to 'All' at [Settings → AI governance](https://app.incident.io/~/settings/ai-governance#store-incident-channel-messages).
## Privacy, Permissions & Data Use
### Do you train models based on our data?
No, we never train or fine tune AI models based on your data. Additionally, we have zero data retention agreements in place with the sub-processors we use to provide our AI features, including OpenAI, Anthropic, and Google Vertex. You can read more detail in our AI Privacy Guidance in our [trust centre](https://trust.incident.io/).
More generally, all of the same controls outlined in our Trust Centre and Privacy Policy apply here, such as encryption.
### Do you use data from private incidents?
By default, all AI features are disabled in private incidents. Optionally, you can opt-in to AI features in private incidents in [Settings → AI governance](https://app.incident.io/~/settings/ai-governance#ai-incident-access). This is available to all Pro and Enterprise customers.
# Deleting call notes
Source: https://docs.incident.io/ai/deleting-notes
If you need to delete the call notes / transcripts that [incident.io](http://incident.io/) records from your incident calls, for example to purge sensitive content, you have two options:
## 1. Manually delete call notes
When you open the call notes on an incident page, you can delete them via the "three dots" menu on the upper right:
## 2. Automatic deletion
You can also configure your call notes to be automatically deleted either 14 or 90 days after the call ends. This can be set in the Scribe configuration (on the AI configuration page).
## What happens when my call notes are deleted?
When we delete call notes via either of the above methods, we:
* **Permanently delete** the raw transcripts and the names of the speakers
* **Archive / "soft delete"** the other information generated from the transcripts, namely:
* Summaries
* Current topics
* Key moments
# macOS app
Source: https://docs.incident.io/ai/desktop-app
Download the incident.io desktop app for macOS to respond to incidents from the notch.
The incident.io macOS desktop app brings incident response to your Mac, so you can get paged, investigate, and post updates back to the team without leaving your terminal.
It runs in your notch or menu bar, ships with a local MCP server, and integrates with your coding agent - Claude Code, Codex, Cursor, and more.
The macOS app is available to all paying customers. Download it from [Settings → Desktop
app](https://app.incident.io/~/settings/desktop-app) in your dashboard.
**Not on macOS?** Use the [remote MCP server](/ai/remote-mcp) instead — same incident.io tools, available from any OS,
Claude.ai in a browser, ChatGPT, or automated agent pipelines.
## What you can do
The macOS app is designed to help you from the moment you're paged, until you resolve the incident, without context-switching back and forth between your coding agent and Slack or Microsoft Teams.
* **Get paged and jump straight in.** High-urgency escalations appear in your notch (or notification center if you prefer menu-bar mode). Acknowledge the page, pin the incident, and start debugging in your coding agent.
* **Investigate with your agent of choice.** The app ships with a local MCP server and one-click integrations for Claude Code, Codex, and Cursor. Any other MCP-compatible client (e.g. OpenCode) can be configured manually.
* **Share findings without leaving your terminal.** Post updates, snippets, and findings directly to the incident channel via the MCP without tabbing away to write them up.
* **Stay in the loop.** New incident updates and status page changes arrive as native notifications, so you can stay heads-down in the code while still tracking what the rest of the team is doing.
## Display modes
Both modes have full functionality: escalation prompts, an incident list, event notifications, and the same incident detail view. Pick whichever fits how you like to work, and switch between them from the app menu at any time.
* **Notch mode** surfaces escalations and incident updates ambiently from the notch area, so you can stay aware of what's happening without switching context. Works on external displays too.
* **Menu bar mode** is the minimalist option with a small menu bar icon that opens the same UI on click. Use this if you'd rather keep incident.io out of sight until you need it.
## Coding agent integrations
The onboarding flow walks you through installing the integration for your coding agent. You can also add or change integrations any time from the app menu.
One-click integrations are available for **Claude Code**, **Codex**, and **Cursor**. Any other MCP-compatible client (e.g. OpenCode) can be set up manually using the MCP config shown in the app menu.
The local MCP exposes the same tools as the [remote MCP server](/ai/remote-mcp), plus extra tooling for live
investigation work and posting back to the incident channel. See the [available tools](/ai/remote-mcp#available-tools)
list on the remote MCP page — everything there works in the macOS app too.
## Pinning incidents
Pin an incident to set it as the active one your coding agent works on. While pinned:
* Your agent treats it as the active incident, so you don't need to repeat the ID each time.
* You receive event notifications when there are new updates on that incident.
You can pin from the app, by acknowledging an escalation prompt, or by asking your agent to do it for you. Unpin from the incident detail view or via your agent.
## Investigations
[Investigations](/ai/investigations) are currently in **Private Beta** and aren't available to everyone yet. If your
organization doesn't have access, the rest of the macOS app still works. Your coding agent will use the MCP tools to
query incident data on demand.
If your organization has Investigations enabled, pinning an incident also syncs its investigation data to your machine in the background. Your coding agent reads findings, checks, and evidence as local files alongside your codebase, so you can ask questions like:
* "Investigate why we're seeing elevated error rates on the checkout service."
* "What's the current load on the production database and how does that compare to normal?"
* "Have any of my recent deployments affected error rates in production?"
## Requirements
* macOS 15 (Sequoia) or later
* Apple Silicon (M1+) or Intel
* An incident.io account on a paid plan
## FAQs
If you're on a Mac and do local development, use the macOS app — it has everything the remote MCP has, plus native
notifications, integration installers, and richer support for investigations. Use the [remote MCP
server](/ai/remote-mcp) if you're on Windows or Linux, develop in a remote/cloud environment, or want to plug
incident.io into an automated agent pipeline.
Not in the same coding agent — they expose the same tools, and your agent will get confused if both are connected.
See [Multiple incident.io MCPs authorized](/ai/mcp-conflict) for how to resolve duplicates. Running them in
different places (e.g. macOS app on your Mac, remote MCP on a separate Linux box) works fine.
The macOS app is free. Capabilities of the MCP are tied to your plan and products — for example, tools to manage
escalations require access to On-call, and asking about telemetry requires access to Investigations.
Use **incident.io menu → Reset** to remove credentials, the bundled CLI, and any agent integrations the app
installed. To remove the app itself, drag it from `/Applications` to the Trash.
# AI feature: Suggested follow-ups
Source: https://docs.incident.io/ai/follow-ups
Suggested follow-ups are given when an incident is resolved. We look back through the channel and spot anywhere follow-ups were discussed. We then match these against actions and follow-ups that are already created.
If we spot any that we think are missing we’ll bring them up as suggestions within the channel. You can then easily create follow-ups off the back of these suggestions.
## Demo
## Configuration
Suggested follow-ups are available to Team, Pro and Enterprise customers. It is "on" by default. To check if it's enabled, head to Settings > AI.
## FAQs
Please find more details in [this article](/admin/ai-usage).
# Manually adding and removing Scribe from your incident calls
Source: https://docs.incident.io/ai/managing-scribe
[Scribe](/ai/scribe) is incident.io's AI-powered transcription and summarization feature for incident calls. It allows you to automatically generate transcripts and summaries of your calls, making it easy to keep track of important discussions and action items.
We understand that during incident calls, there may be times when you need to discuss sensitive or private information that you don't want transcribed. That's why we've introduced the ability to add or remove Scribe from your calls on the fly.
## When to use this feature
Some situations where you may want to temporarily remove Scribe from your calls include:
* Discussing sensitive customer data or PII
* Whenever you need to have "off the record" conversations during an incident
Remember, you can always add Scribe again once you're ready to resume capturing the incident discussion in the transcript and summary.
We hope this new feature gives you more control and flexibility in how you leverage AI transcription during incident response. If you have any other questions, feel free to reach out to our support team.
## How to add or remove Scribe during a call
You can now easily add or remove Scribe transcription at any point during an incident call using the web dashboard, Slack, or Microsoft Teams.
Scribe currently supports Zoom, Google Meet & Microsoft Teams integrations.
## Managing Scribe for Zoom and Google Meet calls
### Web dashboard
1. During an incident call, open the call notes drawer from the incident page
2. Click on the toolbar to expand it, and click 'Remove Scribe from the call'
3. To add scribe back, simply click 'Add Scribe to call' in the same toolbar
### Slack
While an incident call is active, we'll show you buttons to add or remove Scribe based on the current status of Scribe in your call.
### Microsoft Teams
As in Slack, when an incident call is active, we'll show you buttons to add or remove Scribe based on the current status of Scribe in your call.
## Managing Scribe for Microsoft Teams online meetings
We don't track live call information for Microsoft Teams online meetings, so Scribe can *only* be manually added.
### Web dashboard
You can add Scribe to a call using the "Add Scribe" button on the incident details page.
### Slack
You can add Scribe to a call from the incident call modal, which can be accessed via `/inc call` or `/inc scribe`
## Deleting incident call notes
In the event that sensitive or private information is accidentally transcribed, call notes can be easily deleted, removing trace of the information from the dashboard, Slack and Microsoft Teams.
### Web dashboard
Navigate to the relevant incident and select the call notes containing sensitive information. The call notes drawer will open.
Click the three dots in the top-right corner to open the actions menu, and click "Delete notes". You will be prompted with a confirmation modal before proceeding.
Once deleted:
* Transcripts and summaries will no longer be visible via the dashboard
* Summaries and key call information posted in incident channels will be deleted or re-rendered without the deleted notes
* Scribe will be removed if currently active in the incident call
## Accessing transcripts via the API
You can export call sessions and their transcripts programmatically, for example to
archive them or analyze them in your own tooling.
First, create an API key in [API keys](https://app.incident.io/settings/api-keys) with
the **View call transcripts** permission (`call_transcripts_viewer`). Keys with this
permission can read transcripts for any incident they can access: that means public
incidents, unless the key is also granted access to private ones.
Exporting is a two step process:
1. List an incident's call sessions using the
[Call Sessions](/api-reference/call-sessions-v2) endpoint
2. For each session, page through its transcript using the
[Call Transcript Entries](/api-reference/call-transcript-entries-v2) endpoint
```bash theme={null}
# List the call sessions for an incident
curl -s -H "Authorization: Bearer $API_KEY" \
"https://api.incident.io/v2/call_sessions?incident_id=$INCIDENT_ID"
# Page through a session's transcript, oldest first
curl -s -H "Authorization: Bearer $API_KEY" \
"https://api.incident.io/v2/call_transcript_entries?call_session_id=$SESSION_ID&page_size=250"
```
Each transcript entry contains the participant's name, when they started speaking, what
was said, and whether it was spoken aloud or sent as an in-call chat message. Entries
are returned oldest first: keep requesting with the `after` value from
`pagination_meta` until the response no longer includes one, at which point you have
the full transcript.
A few things to be aware of:
* If your organization has turned off transcript viewing in
[Scribe settings](https://app.incident.io/settings/scribe), the API returns empty
results, matching the dashboard
* Deleted call notes are gone from the API too, in the same way they're removed from
the dashboard, Slack and Microsoft Teams
* A live call's transcript is available while the call is ongoing, so you can also poll
for new entries rather than waiting for the call to end
# Google Meet: diagnosing common issues
Source: https://docs.incident.io/ai/meet-issues
This page gives extra detail on errors that you might see when using Google Meet for your incident calls, or when using Scribe to transcribe them.
## Call not found
We need to look up data about the call, in order to fetch information about the people who are participating. If you see this error, it is because we weren't able to fetch information about the current call. If the call URL was set manually, please check that the call can be accessed by the Google account that was used to connect the Google Meet integration.
## Scribe could not join breakout room
If you see this error, it is because Scribe tried to join a Google Meet call which was a breakout room. Scribe does not currently support breakout rooms.
# Remote MCP server
Source: https://docs.incident.io/ai/remote-mcp
Connect AI assistants like Claude, ChatGPT, and coding agents directly to incident.io
The incident.io MCP server lets you connect any AI assistant that supports the [Model Context Protocol](https://modelcontextprotocol.io) directly to your incident data. Query incidents, analyse alerts, check who's on call, manage escalations, and run deep operational analysis — all from your existing AI tools.
You can enable the remote MCP server from [Settings → MCP](https://app.incident.io/~/settings/mcp).
**Already using the incident.io macOS app?**
If so, you already have full access to everything on this page (and more). The macOS app ships with a local MCP server that provides all the MCP tools described here, plus rich support for investigations and interaction with the native UI. No additional setup is needed — if you've installed the macOS app, you're good to go!
The remote MCP server described here is for people who want to connect without installing the macOS app — for example, using Claude.ai in a browser, ChatGPT, or plugging incident.io into automated agent pipelines.
Learn more about the [macOS app](/ai/desktop-app), or download it from [Settings → Desktop app](https://app.incident.io/~/settings/desktop-app) in your dashboard.
## What you can do
### Incident analysis and reporting
Ask questions across your entire incident history without manual data gathering:
* "How many P1 incidents did we have this quarter, and which teams were most affected?"
* "What's the trend in overnight responder workload by alert source?"
* "Show me the top 10 highest-workload incidents this month"
The `incident_stats` tool supports 10 grouping dimensions (severity, status, type, mode, alert source, custom fields, roles, time periods) with workload breakdowns showing where responder time is spent — during working hours, late evening, or overnight.
### Alert and noise analysis
Understand where alert noise is coming from and which areas generate the most on-call work:
* "Which alerts result in actual incidents vs noise?"
* "Break down alert volume and workload by team and service"
* "What proportion of our pages happen overnight, and what triggers them?"
You can analyse alerts by source, priority, time period, and whether they resulted in incidents. Combined with incident stats grouped by team, service, or any custom field, you can trace the full path from alert noise through to responder cost — and identify the highest-ROI improvements to make.
### On-call and escalation management
Check schedules, respond to pages, and analyse paging patterns:
* "Who's on call for the platform team right now?"
* "What's our ack rate by escalation path this month?"
* "Acknowledge the page for INC-456"
### Incident management
Create and update incidents, manage follow-ups, and access investigation data:
* "Create a P2 incident for the payments API degradation"
* "Update INC-123 to resolved"
* "What are the outstanding follow-ups from last week's incidents?"
### Structured operational analysis
Run guided analysis using built-in playbooks that provide step-by-step methodology, your organisation's configuration, and a branded HTML report template:
* "Prepare an operational review for the last quarter"
* "Analyse alert noise and recommend tuning improvements"
* "Assess on-call burden across our teams"
The `analysis_start` tool downloads a workspace with everything needed: playbooks (operational review, alert noise, on-call burden, team health, response effectiveness), your org config for reference, and a report template. The AI follows the playbook stages — collecting stats, drilling into specifics, identifying themes, and synthesising recommendations — producing much richer analysis than ad-hoc queries.
### Deep investigation
For any specific incident, access AI investigation findings, post-mortem documents, and full status update history:
* "Show me INC-123 with the investigation findings and post-mortem"
* "What was the root cause of our most recent major incident?"
* "Download the full investigation for INC-456 so I can analyse it"
Use `incident_show` with `include: ["investigation", "postmortem"]` for a summary of findings inline. For the complete investigation — all findings, checks, conversation history, and evidence — use `investigation_sync`, which downloads the full investigation filesystem as an archive.
**For hands-on investigation work on macOS, the [macOS app](/ai/desktop-app) is the best experience.** It renders
investigation data inline, lets you pin incidents, and post findings directly to incident channels. The
`investigation_sync` tool is designed for automated agents and pipelines that need to pull down investigation data
programmatically for LLM analysis — for example, a coding agent that cross-references investigation findings with code
changes, or an automation that summarises investigations across multiple incidents.
### Team visibility
See which teams own what, and scope analysis to specific teams:
* "What escalation paths and alert sources does the platform team own?"
* "List all teams and their on-call schedules"
### Telemetry and observability
Query logs, metrics, traces, and dashboards across all the observability platforms you've connected to [Investigations](/investigations/overview) — including Datadog, Grafana, Splunk, Honeycomb, Elasticsearch, GCP Cloud Logging, and more.
This works for any debugging scenario, not just active incidents. Use it to investigate production issues, check service health, run ad-hoc queries, or pull data for reports:
* "What are the error rates for the payments service over the last hour?"
* "Show me the logs around the time of INC-123"
* "Query the CPU and memory dashboards for the worker pods"
* "Are there any anomalies in the checkout service latency this week?"
* "Pull the Datadog traces for requests over 5 seconds"
The AI agent plans queries across your datasources, handles pagination and time ranges, and synthesises the results. It can search dashboards by name, query metrics with the right labels, and correlate signals across multiple platforms — saving you from switching between tabs and writing queries manually.
## Setup
The remote MCP server is available at `https://mcp.incident.io/mcp`. There are two ways to authenticate, depending on your use case.
### For interactive use (OAuth)
If you're a human connecting via an AI assistant like Claude, ChatGPT, or Cursor, you'll authenticate with your incident.io account via OAuth. The MCP client handles the flow — you just approve access in your browser when prompted. Actions are attributed to your user account, and you see the same data you'd see in the dashboard.
Most clients discover the OAuth configuration automatically from the server URL, so you never see these details. Some
— like Google's Gemini Enterprise custom connector — ask you to enter them by hand. If yours does, see [Connecting a
client that needs OAuth details manually](#connecting-a-client-that-needs-oauth-details-manually) below.
Add the remote MCP server:
```bash theme={null}
claude mcp add incident-io --transport http https://mcp.incident.io/mcp
```
Claude Code will prompt you to authorise via your browser on first use.
Add the server to your Codex MCP configuration at `~/.codex/config.toml`:
```toml theme={null}
[mcp_servers.incident_io]
type = "url"
url = "https://mcp.incident.io/mcp"
```
Codex will prompt you to authorise on first use.
Open Cursor settings and navigate to **MCP Servers**. Click **Add Server** and enter:
* **Name:** incident.io
* **Type:** HTTP
* **URL:** `https://mcp.incident.io/mcp`
Cursor will prompt you to authorise via your browser.
1. Open Claude Desktop.
2. Go to **Connectors** (or **Customize → Connectors**).
3. Click the **+** next to Connectors.
4. Choose **Add custom connector**.
5. Enter the MCP server URL: `https://mcp.incident.io/mcp`
6. Complete the authorisation flow with incident.io.
7. The connector should then appear in Claude's connected tools.
incident.io is currently available as a custom connector only. We're working on getting it listed in the Claude connector marketplace — stay tuned.
1. In ChatGPT, go to **Settings → Integrations**.
2. Search for "incident.io" or add a custom MCP server with URL `https://mcp.incident.io/mcp`.
3. Authorise access when redirected to incident.io.
#### Connecting a client that needs OAuth details manually
Our remote MCP server uses the standard MCP OAuth pattern: clients discover the configuration from the server URL and register themselves automatically. Assistants like Claude, ChatGPT, and Cursor use this, which is why you only ever paste the server URL.
Some clients — such as Google's Gemini Enterprise custom MCP connector — instead ask you to fill in the OAuth details yourself. Because our server is a PKCE **public client**, there's no client secret to enter, so make sure you enable your client's PKCE option. Use these values:
| Field | Value |
| ----------------- | ----------------------------------------------- |
| MCP server URL | `https://mcp.incident.io/mcp` |
| Authorization URL | `https://app.incident.io/auth/plugin/authorize` |
| Token URL | `https://app.incident.io/auth/plugin/token` |
| Client ID | `incident-mcp` |
| PKCE | Enable it (this is required) |
| Client secret | Leave blank |
| Scopes | Leave empty |
**You'll need an admin to allow the client's redirect domain first.** Built-in clients like Claude, ChatGPT, and
Cursor are trusted automatically, but any other client's redirect host must be added under **Settings → MCP server →
Allowed redirect domains** (up to five). For Gemini Enterprise this is `vertexaisearch.cloud.google.com`. If it's
missing, authorisation fails — the exact domain to add is shown in the error, and you can add it from there in one
click.
An OAuth connection acts as the person who approves it — so pick the right account, ideally a dedicated service account, since it'll see and act on only what that user can. The connection lasts 28 days, after which you'll need to re-approve it in the browser.
### For automated systems (API keys)
If you're connecting programmatic agents, custom workflows, or automation pipelines, use an API key. API keys authenticate as a service actor rather than a specific user, and don't expire until deleted.
1. Go to **Settings → API keys** in your incident.io dashboard.
2. Create a new API key with the scopes you need.
3. Pass it as a Bearer token in the `Authorization` header when connecting your MCP client to `https://mcp.incident.io/mcp`.
For example, to test connectivity, send the MCP `initialize` request — every MCP client opens a session with this call, and a successful response confirms that the endpoint is reachable, your API key is valid, and the protocol version is compatible:
```bash theme={null}
curl -X POST https://mcp.incident.io/mcp \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": { "name": "curl", "version": "0.0.1" }
}
}'
```
To list or call tools beyond this connectivity check, use a real MCP client library — calling tools by hand requires completing the rest of the MCP handshake and parsing server-sent events.
This is ideal for integrating incident.io into your own agents, n8n workflows, Dust, or custom automation pipelines.
## Getting the most out of it
### Read the configuration first
Before filtering or grouping, ask the tools for your organisation's configuration — it lists your severity levels, custom fields, roles, and other values you'll need:
* Use the `resource_show` tool with `resource: "organisation"`, or
* Read the `config://organisation` resource directly (if your client supports MCP resources)
### Use includes for deeper analysis
When investigating an incident, always request the investigation and post-mortem data:
```
incident_show(id: "INC-123", include: ["investigation", "postmortem"])
```
Without these, you only get the basic metadata. With them, you get the AI's analysis of what happened, the team's written post-mortem, and all the evidence gathered during investigation.
### Start with stats, then drill in
For analytical questions, follow the **stats → list → show** pattern:
1. `incident_stats` to get the shape (counts, workload, trends)
2. `incident_list` to browse the interesting groups
3. `incident_show` to get full details on specific incidents
This is much more efficient than paginating through individual incidents.
### Use playbooks for structured analysis
For periodic reviews or deep analysis, use `analysis_start` rather than querying tools ad-hoc. It downloads a workspace with playbooks that guide the AI through a multi-stage process — scoping, data collection, deep dives, theme identification, and synthesis — producing structured recommendations and an HTML report. This consistently produces better results than asking open-ended analytical questions.
### Send feedback
If you hit friction or wish a tool worked differently, use the `feedback` tool to let us know. Your AI assistant will prompt you about this after completing tasks — approve the feedback to help us prioritise improvements.
## Available tools
| Tool | Description |
| ---------------------- | ---------------------------------------------------------------------------------- |
| `alert_list` | Search and browse alerts |
| `alert_show` | Full alert details with linked incidents |
| `alert_source_list` | List configured alert sources |
| `alert_stats` | Alert counts with workload from linked incidents |
| `analysis_start` | Start a structured operational analysis with playbooks and report template |
| `ask` | AI agent for on-call queries, schedule management, and general questions |
| `ask_incident` | AI agent for incident investigation and management actions |
| `ask_telemetry` | AI agent for querying logs, metrics, traces, and dashboards |
| `catalog_entry_list` | Browse entries in a catalog type |
| `catalog_entry_show` | Full catalog entry with all attributes |
| `catalog_type_list` | List catalog types (Service, Team, etc.) |
| `escalation_list` | Search escalations (pages) |
| `escalation_path_list` | List escalation paths |
| `escalation_path_show` | Who would be paged at each level |
| `escalation_respond` | Acknowledge or decline a page |
| `escalation_show` | Full escalation details with transition history |
| `escalation_stats` | Paging counts by path, priority, time of day |
| `feedback` | Submit feedback about the tools |
| `follow_up_create` | Create a follow-up on an incident |
| `follow_up_list` | List post-incident follow-ups |
| `incident_create` | Create a new incident |
| `incident_list` | Search and browse incidents with filters, sortable by workload |
| `incident_show` | Full incident details with optional investigation, post-mortem, and update history |
| `incident_stats` | Aggregate counts and workload by 10+ dimensions |
| `incident_update` | Update incident fields (status, severity, roles, custom fields) |
| `incident_update_list` | Full status update history for an incident |
| `investigation_sync` | Download a full investigation as an archive for LLM analysis |
| `resource_show` | Read organisation config, analysis playbooks, or telemetry datasources |
| `schedule_list` | List on-call schedules |
| `schedule_show` | Schedule details with current and upcoming shifts |
| `team_list` | List teams |
| `team_show` | Team details with owned escalation paths, alert sources, and schedules |
# Scribe: AI-powered transcription and summarization for incident calls
Source: https://docs.incident.io/ai/scribe
Ready to enable Scribe? [Jump to this section](/ai/scribe#enabling-scribe).
Video calls bring responders together allowing rapid coordination across teams and countries but it brings a number of issues.
If you join an incident call in progress it can be hard to quickly build up an understanding of what's happening without interrupting. The same applies when it comes after the incident has been resolved: without the context and detail of the call it can be hard to build up a clear picture of how an incident progressed from declaration to resolution.
You may have someone keeping notes or even responders regularly updating the incident channel with information but this all takes time and distracts from the issue at hand. How do you easily ensure you don't miss any context, important information, decisions or next steps?
By using **Scribe** of course!
## What is Scribe
Scribe is our friendly AI powered note taker - with Scribe enabled our bot will join your incident calls automatically and take detailed notes as well as providing summaries, key moments, and the current topic into your incident channel.
### Feature: Integrated transcripts
By joining the call it has access to the video and audio from that call. It uses this data, in conjunction with streamed captions from the meeting, to deduce who has said what. It is this transcription we use to power the other Scribe features such as summaries, key moments and current topic.
The transcript can be accessed in the incident details page, by clicking 'View notes'.
If your team uses [AI data redaction](/admin/managing-sensitive-data#ai-data-redaction), Scribe applies the configured strategies to new spoken transcript entries as they are processed. Matches appear as `[REDACTED]` in the transcript and are not sent to AI models. Existing transcript entries are not changed.
### Feature: Detailed summaries
One of the hardest things when joining an in progress incident is knowing what everyone is talking about, or how best you can help. Scribe is continually building a picture of what is happening on the call.
Scribe is continuously building a detailed summary of the whole call. It pulls out important information and next steps, along with providing a general summary of the incident call from start to finish.
These summaries are created in real-time, and are viewable within the incident channel and the dashboard.
### Feature: Current topic
Along with frequent call summaries, the current topic is shown in both the incident channel and the dashboard to help give other users an "at a glance" idea of what's being discussed and how things are going, potentially highlighting that they might want to join the call.
### Feature: Proactive key moments
Scribe also looks to actively pull key moments from the call transcript into the incident channel. Key moments are a combination of important decisions, agreements, or when key information was discovered on a call.
Some examples of key moments are decisions to update a status page, or when a roll-back was triggered, or potentially new information came to light that might help in solving the issue.
Key moments also help new responders get up to speed, as well as streamlining the post-incident process when it comes to building a timeline of what happened.
## Enabling Scribe
Scribe is available to Pro and Enterprise customers. By default it is disabled but once you have a call provider set-up ([Zoom](/integrations/zoom), [Microsoft Teams calls](/ai/teams-call-issues), [Google Meet](/integrations/google-meet), or [Webex](/integrations/webex)) you can go to [Settings > AI](https://app.incident.io/~/settings/ai) and enable Scribe there.
Once enabled, Scribe will request to join all Google Meet, Zoom, and Webex incident calls. From here, someone on the incident call can choose to allow or deny entry to Scribe. If you disable auto-joining in [Settings → AI](https://app.incident.io/~/settings/ai), Scribe can be added manually from the call in the dashboard.
**Note**: We highly recommend turning on auto-call creation which automatically attaches a new call to each incident.
### Set a transcription language
Scribe detects the language spoken on each call automatically. In some cases, background noise or some words or phrases can be detected as words in the wrong language. It normally only affects a few words, and doesn't change the summaries or key moments Scribe posts to your incident.
To tell Scribe which languages to expect, go to [Settings → AI](https://app.incident.io/~/settings/ai), open Scribe, and set **Transcription languages**. Pick one or more of the 90+ languages on offer. This biases detection towards those languages, so Scribe is much less likely to drift into a language nobody on the call is speaking. Leave it empty to detect the language of each call automatically.
## FAQs
We use Recall.ai for raw transcription data, who are a third-party sub-processor that provide call transcription services. In order to transcribe the call, Recall.ai store a temporary recording which is deleted when the last human leaves the call. Recall.ai do not retain any data after this point.
Transcription is provided by ElevenLabs, a second sub-processor, which receives the call audio through Recall.ai and returns the transcript. We don't ask ElevenLabs to retain that audio, and it isn't used to train models.
We only store the call transcript, which we use to power Scribe features mentioned in this article. We do not store any audio or video from the call.
If you'd rather we didn't send call audio to ElevenLabs, contact us at [help@incident.io](mailto:help@incident.io). Scribe then transcribes from your meeting provider's captions instead. Webex doesn't offer closed captions, so Webex calls fall back to English-only transcription.
For more information on how we use AI, you can read the [AI data handling](/admin/ai-usage) article.
We require new permissions for Zoom and Google Meet to enable call transcription. If you previously had those integrations setup it might be that you are using an older version of our permissions.
Please make sure to update to the latest by re-authenticating the integration to ensure you have the right permissions.
If you're still seeing issues with Zoom, please check your settings in the Zoom app to ensure that recording has been allowed.
If you are using Webex, please ensure that you have the [incident.io Scribe service app installed](/integrations/webex#5-enable-scribe).
If you are still seeing issues - please reach out to support.
We rely on Zoom meeting captions to generate the transcript of your call. If the bot joined your call but you're not seeing a transcript after a few minutes, it could be because you have meeting captions disabled.
To enable meeting captions, navigate to **Host Caption Control Settings** while in a Zoom meeting, then enable the setting called **Allow Closed Captioning for this meeting.**
If you don't see the option to enable meeting captions in your Zoom client, you likely have the setting turned off globally.
To resolve this, simply go to [Zoom settings](https://zoom.us/profile/setting?tab=meeting) and flip the toggle for **Automated captions.**
If **this is the first time you've installed Zoom**, we recommend to ensure you've ticked the option to allow shared access permissions at the bottom referenced [here](/integrations/zoom).
Should you continue to experience issues, please reach out to support.
Yes. Scribe transcribes calls in more than 90 languages, detecting the language spoken on each call automatically. To tell Scribe which languages to expect on your calls, see [Set a transcription language](#set-a-transcription-language).
The transcript is in the language spoken on the call. The summaries, key moments, and current topic that Scribe posts to your incident channel are written in English, whatever language the call was held in.
See article: [Manually adding and removing Scribe from your incident calls](/ai/managing-scribe)
Scribe doesn't capture messages sent in the meeting's built-in chat. For now, the best approach is to encourage responders to share key information in the incident channel itself rather than the bridge call chat, so that everything is captured in the incident timeline. That way, Scribe handles the verbal discussion and the channel captures any written updates.
# Scribe and incident calls
Source: https://docs.incident.io/ai/scribe-overview
## Errors
This page gives extra detail on errors that you might see when using incident.io to manage your incident calls, or when using Scribe to transcribe your incident calls.
## Call not found
No call could be found for the given incident, and so Scribe was unable to find a call to join. To fix this, you can start a new call, or update the call link to the URL of an existing call, and Scribe will join that instead.
## Scribe cannot join multiple calls
This error is shown when there are multiple active calls for an incident. If this happens, please attempt to end one of these calls. If the error persists after trying this, please contact us.
## Scribe was blocked
You'll see this error when Scribe was blocked from joining the meeting. This might be because your Google Meet or Zoom account has restrictions around allowing guests into calls. Please check that this is configured correctly.
## Scribe was removed
You'll see this error when the Scribe bot was removed from the call by the host. You can add Scribe again from the incident dashboard.
## Rate limited
Some providers impose a rate limit on the number of calls that can be created in a given period. As an example, Zoom (in some cases) imposes a limit of 100 calls per day for a given user. In this case, the user is the one used to connect Zoom when setting up the integration.
If you hit this limit, you may want to consider turning off automatic incident call creation.
# Slack assistant
Source: https://docs.incident.io/ai/slack-assistant
Chat with incident.io's AI agent from anywhere in Slack using the assistant sidebar
Slack's assistant sidebar is a first-class surface for chatting with AI agents — and incident.io is one of them. Open the sidebar from anywhere in Slack and you can manage incidents, check who's on call, search your incident history, and more, all without leaving your current channel.
The assistant is context-aware: open it from an incident channel and it knows which incident you're looking at, tailoring its responses and suggested prompts to your role and the incident lifecycle.
## How to open the assistant
1. Click the **agent/assistant icon** in the **top-right corner** of Slack on desktop or in a browser.
2. If multiple agents are installed, click the **dropdown arrow** and choose **incident.io**.
3. Select a suggested prompt or type a message to get started.
4. Use the **clock icon** to access your message history and resume previous conversations.
You can also start a conversation from the incident.io **app home tab** by clicking **New chat** or selecting the **Chat** tab.
## What you can do
The assistant works in two modes depending on where you open it.
### From anywhere in Slack
When you open the assistant from a non-incident channel, you get **general mode** — useful for day-to-day interactions with incident.io without needing to navigate away from what you're doing.
**On-call and schedules**
Check and manage on-call schedules directly from the sidebar:
* `Who's on call for the platform team?`
* `Show me my upcoming shifts this week`
* `Put me on call for the next 2 hours`
* `I need someone to cover my Friday shift`
**Declare incidents**
Start a new incident from the sidebar when something goes wrong:
* `Declare an incident — EU payments are failing`
**Search past incidents**
Find relevant incidents from your organization's history:
* `Have we seen login failures like this before?`
* `Show me recent P1 incidents from the last month`
**Check service status**
Ask about monitored third-party services:
* `Is AWS reporting any issues right now?`
**Query your catalog**
Look up ownership and organizational data:
* `Which team owns the checkout service?`
### From an incident channel
When you open the assistant while viewing an incident channel, it enters **incident mode** with full context about the incident — including the investigation, alerts, and conversation history.
Everything you can do with [`@incident`](/ai/at-incident) in a channel, you can do here in a private sidebar conversation. That means drafting updates, creating follow-ups, changing severity, assigning roles, and more.
Suggested prompts adapt to your situation. An incident lead on a live incident sees options like "Draft a status update" and "Suggest next steps", while a responder sees "Catch me up" and "What do we know?".
## Enabling the Slack assistant
### Plan availability
The Slack assistant is available to **Pro and Enterprise** customers using Slack.
### Slack workspace configuration
Workspace owners and admins control whether the incident.io agent appears for members. This requires a **paid Slack subscription** (Pro, Business+, or Enterprise).
1. Click **Admin** in the Slack sidebar.
2. Select **Apps and workflows** to open the Slack Marketplace.
3. Find **incident.io** in the Installed apps list.
4. Click the **App settings** tab.
5. Next to "AI agent experience", click **Edit**.
6. Select **Enabled** and click **Save**.
For **Enterprise Grid** workspaces, follow the same steps via **Organization settings** → **Integrations** → **Installed apps**.
By default, app agents are displayed at the top of Slack once enabled by an admin. Individual members can control which agents they see via **Preferences** → **Navigation** → **App agents & assistants**.
### incident.io configuration
The Slack assistant requires the `assistant:write` OAuth scope. If your Slack integration was set up before the assistant feature was available, you may need to re-authorize the Slack app to pick up the new scope. New installations include it automatically.
If it isn't working for you, reach out to support and we can help get it enabled.
## FAQs
The assistant sidebar and `@incident` mentions share the same underlying AI agent. The key difference is the surface: the sidebar gives you a private, persistent conversation that's always one click away from anywhere in Slack. You don't need to be in a specific channel, and your questions aren't broadcast to everyone in the room.
Please find more details in [this article](/admin/ai-usage).
By default, all AI features are disabled in private incidents. You can opt in to AI features in private incidents via [Settings → AI governance](https://app.incident.io/~/settings/ai-governance#ai-incident-access).
# Suggestions
Source: https://docs.incident.io/ai/suggestions
While your team are focused on the incident, how do you ensure you communicate progress accurately, and in a timely manner?
Suggestions uses AI to help teams communicate better during incidents by automatically drafting updates, summaries and follow-up actions based on your incident activity.
## Suggested updates
An incident update is a crucial point in time in an incident, where you can communicate the current progress of an incident, and context of a change in state (i.e. changing status or severity).
We will monitor your incident activity, and nudge your incident responders when the time is right, to share an update with your internal stakeholders.
The update we propose will be generated from all recent meaningful incident activity and chat context, to make sure we capture the soul of the moment.
If you believe the time is right *now*, you can still request a suggested update there and then by talking to incident with:
> @incident draft me a new update
## Suggested summaries
Once an update has been shared, we will then proactively suggest a new incident summary, to help keep participants aligned with the current state of an incident.
We take a collection of information drawn from the incident and use AI to help pull out the important information for you such as the problem, the impact, anything that may have caused it, and the next steps that will be taken to help resolve it.
Overall, this means your incident summaries are more up to date and in a standard format - allowing newcomers to quickly understand where the incident is and help out.
If you want to draft a new summary at any time, the option is still available to request from incident with:
> @incident draft me a new incident summary
## Suggested follow-ups
Suggested follow-ups are given when an incident is resolved. We look back through the channel and spot anywhere follow-ups were discussed. We then match these against actions and follow-ups that are already created.
If we spot any that we think are missing we’ll bring them up as suggestions within the channel. You can then easily create follow-ups off the back of these suggestions.
## At declaration time
When creating an incident from a Slack message using the quick action (three dots menu), AI can automatically generate a title and summary based on the message content. This requires AI features to be enabled in your account settings.
## Suggestions in the dashboard
Suggestions also surface in the dashboard chat, appearing as notifications that you can interact with inline. The same three suggestion types are available — updates, summaries, and follow-ups — configured via the same Settings > Suggestions page as for Slack and Teams.
## Configuring suggestions
Suggested summaries and follow-ups are available to Team, Pro and Enterprise customers. They are "on" by default. To check if they are enabled, head to Settings > Suggestions.
Suggested updates are available to Pro and Enterprise customers, and can also be configured from Settings > Suggestions.
## FAQs
Rule-based suggestions (previously "nudges") allow your team to build custom suggestions that prompt incident responders to take action, based on a set of configurable rules.
To learn more about rule-based suggestions and how to configure them, see [Rule-based suggestions](/incidents/rule-based-suggestions).
Please find more details in [this article](/admin/ai-usage).
# AI feature: Suggested summaries
Source: https://docs.incident.io/ai/summaries
In the heat of the moment, responders don't always have time to digest lots of information or communicate externally what's going on. Often it's hard to switch context and spend some precious minutes repeatedly updating summaries or statuses.
This is where **suggested summaries** comes in.
We take a collection of information drawn from the incident and use AI to help pull out the important information for you such as the problem, the impact, anything that may have caused it, and the next steps that will be taken to help resolve it.
This lets you quickly confirm if the summary is accurate and edit it if you want more detail before rapidly getting on with resolving the incident. Overall, this means your incident summaries are more up to date and in a standard format - allowing newcomers to quickly understand where the incident is and help out.
## Demo
## Generate button
You can also generate a summary on demand using the **Generate** button in the dashboard. It's available in the summary editor and in the **Resolve incident** drawer.
## Configuration
Suggested summaries are available to Team, Pro and Enterprise customers. It is "on" by default. To check if it's enabled, head to Settings > AI.
## FAQs
Please find more details in [this article](/admin/ai-usage).
# Microsoft Teams calls: diagnosing common issues
Source: https://docs.incident.io/ai/teams-call-issues
This page gives extra detail on errors that you might see when using Microsoft Teams for your incident calls.
## Microsoft Teams authentication failed
Seeing this error means that we failed to authenticate with Microsoft while creating your call. Please go to Settings → Integrations and check that your connection to Microsoft is set up correctly.
## External participants not allowed
This error can occur when Microsoft Teams calls are set up to forbid external participants. Please read [Microsoft's article on this issue](https://learn.microsoft.com/en-us/troubleshoot/microsoftteams/meetings/external-participants-join-meeting-blocked).
# Zoom: diagnosing common issues
Source: https://docs.incident.io/ai/zoom-issues
This page gives extra detail on errors that you might see when using Zoom for your incident calls, or when using Scribe to transcribe them.
## Meeting not found
We need to look up data about the call, in order to fetch information about the people who are participating. If you see this error, it is because we weren't able to fetch information about the current call. If the call URL was set manually, please check that the call can be accessed by the Zoom account that was used to connect the Zoom integration.
## Host has disallowed web clients
This means that the meeting host has forbidden joining the call from the web, which prevents Scribe from joining. Sometimes, this can be because E2E encryption has been enabled for the call.
## I've enabled Scribe, but it's not joining my calls?
We require new permissions for Zoom and Google Meet to enable call transcription. If you previously had those integrations setup it might be that you are using an older version of our permissions.
Please make sure to update to the latest by re-authenticating the integration to ensure you have the right permissions.
If you're still seeing issues with Zoom, please check your settings in the Zoom app to ensure that recording has been allowed.
## Scribe is joining my Zoom calls, why am I not seeing a transcript?
We rely on Zoom meeting captions to generate the transcript of your call. If the bot joined your call but you're not seeing a transcript after a few minutes, it could be because you have meeting captions disabled.
To enable meeting captions, navigate to **Host Caption Control Settings** while in a Zoom meeting, then enable the setting called **Allow Closed Captioning for this meeting.**
If you don't see the option to enable meeting captions in your Zoom client, you likely have the setting turned off globally.
To resolve this, simply go to [Zoom settings](https://zoom.us/profile/setting?tab=meeting) and flip the toggle for **Automated captions.**
If **this is the first time you've installed Zoom**, we recommend to ensure you've ticked the option to allow shared access permissions at the bottom referenced [here](/integrations/zoom).
Should you continue to experience issues, please reach out to support.
# Alert Insights
Source: https://docs.incident.io/alerts/alert-insights
Understanding when and how your alerting system fires helps you configure it more effectively and cut down on noise. Less noise means fewer night-time pages, and happier responders.
The Alert insights dashboard splits into two halves. **Alerts created** is about volume: how many alerts are firing, where they're coming from, and which ones fire most often. **Alert acceptance** is about quality: how many of those alerts turn into accepted incidents and how many get declined as noise.
## Filters, date range, and comparison
The controls at the top of the dashboard apply to every panel below them.
* **Date range and aggregation**: pick any window and bucket it by day, week, or month. The default is the last 12 weeks bucketed by week.
* **Compare with previous period**: when enabled, every trend tile and chart shows the matching panel for the prior window of the same length, so you can see if things are trending up or down.
* **Filter**: filter by [alert attribute](/alerts/attributes-and-priorities), [priority](/alerts/priorities), alert source, whether alerts have related incidents, or whether they have related escalations.
## Alerts created
The **Alerts created** section answers "how much is my alerting system firing, and where is it coming from?"
### Total alert volume
The trend tile at the top shows the total number of alerts fired in the selected window, with a sentiment indicator comparing it to the previous period. Use it as a quick health check before drilling into the breakdowns below.
### Alerts created by source or attribute
A stacked bar chart plots alert volume across the selected window. Use the **Alerts created by** selector above the chart to group by alert source or any catalog-backed [alert attribute](/alerts/attributes-and-priorities). This is the fastest way to see whether one product area is generating disproportionate noise, or whether one source is responsible for a spike.
Click any bar segment to open the [underlying alerts drawer](#underlying-alerts-drawer) for that slice. The **Underlying data** button next to the chart title opens the same drawer for the whole chart.
### Alert frequency
The **Alert frequency** table groups alerts by their title and ranks them by how often they fired. For each title you'll see:
* **Occurrences**: how many times the alert fired in the window.
* **Escalations**: how many of those occurrences escalated via [incident.io On-call](/on-call/escalation-paths). Escalations through other tools aren't counted here.
* **Total incidents**: how many incidents were created off the back of those alerts.
* **Last occurrence**: when the alert most recently fired.
You can filter the table inline by any of these columns, click a row to open the [underlying alerts drawer](#underlying-alerts-drawer) for that title, or use the **Export** button to download a CSV scoped to the current dashboard filters.
If you see a title with a lot of occurrences and escalations but no incidents created, that's usually a sign the alert is firing but consistently being declined as noise. It's a good candidate for tuning or rerouting.
## Alert acceptance
The **Alert acceptance** section answers "of the alerts that paged someone, how many were actually worth paging?"
### Declined alerts
The trend tile shows the number of alerts in the selected window that turned into incidents which were then declined, with a comparison to the previous period.
### Alert acceptance rate
A stacked bar chart plots the share of accepted versus declined alerts over time. A rising decline rate is an early signal that pager fatigue is creeping in. Click a stack segment to open the [underlying alerts drawer](#underlying-alerts-drawer) filtered by that status.
### Most frequently declined alerts
A companion to the Alert frequency table, but ranked by decline volume. The same columns as Alert frequency, plus:
* **Declined incidents**: how many of the incidents created from this alert were declined.
* **Decline rate**: declined incidents as a share of total incidents for the alert.
Click any row to inspect the underlying alerts, or export the table as a CSV. If a noisy title keeps topping this list, that's where to focus your tuning effort or [priority routing](/alerts/priority-routing) rules.
## Underlying alerts drawer
Click a chart bar segment, a table row, or the **Underlying data** button anywhere on the dashboard to open a side drawer listing the individual alerts that make up the figure you clicked. The drawer respects the dashboard filters and shows:
* The alert title and source.
* When it fired.
* Whether the resulting incident was accepted or declined.
Click a row to open the full alert details. The drawer also has its own CSV export covering the filtered alert list.
## FAQs
The Escalations column only counts escalations that went through [incident.io On-call](/on-call/escalation-paths). If you're paging some teams through another tool, those won't show up here.
An alert is counted as accepted if it created an incident that wasn't declined. Anything you decline (either manually or via [decision flows](/incidents/decision-flows)) lands in the Declined bucket.
Yes. The **Alerts created by** selector above the chart lets you group by alert source or any catalog-backed [alert attribute](/alerts/attributes-and-priorities), so you can break volume down by team, service, environment, or whatever else you track on alerts.
The dashboard reads from the insights warehouse, which syncs from production on a regular cadence. The sync badge at the top of the page shows when the data was last refreshed.
Yes. The date range, aggregation, comparison toggle, and filter selections are all reflected in the URL, so any view you've set up can be shared by copying the address from your browser.
# Alert notes
Source: https://docs.incident.io/alerts/alert-notes
Document investigations, hand over context, and record actions taken on alerts — without needing to create an incident.
Alert notes let you attach written context to an alert. Use them to document what you investigated, record why you resolved an alert, or hand over context to the next person on call — all without creating an incident.
Notes appear in the [alert timeline](/alerts/alert-timeline), so there's a clear, timestamped record of what happened and who did what.
## Adding a note
Open an alert and select **Add note**. Write your note and submit it. Notes support text formatting and image attachments.
Notes you've written can be edited or deleted. You can't edit or delete notes written by other users.
## Alert notes in the mobile app
Alert notes are also shown in the mobile app. To create a note from the mobile app, select **Add note** at the bottom of the alert screen.
## Alert notes in Slack
If your alert source sends [alert pulse messages](/alerts/slack-channels) to Slack, then alert notes will be posted in the alert pulse thread so your team sees it in context.
Also, if @incident is invited to your alert pulse Slack channel, you can react to any reply in the alert pulse thread with a pencil (✏️) or notebook (📓, 📔) emoji to save that message as a note.
## Finding alerts with notes
Alerts with notes are tagged with the number of notes in the list alerts page, but you can also use the **Has notes** filter on the alert list to show only alerts that have at least one note attached.
## API access
Use the [Alert Notes API](/api-reference/alert-notes-v1) to list, retrieve, create, update, and delete alert notes programmatically.
Note content is supplied and returned as Markdown. Image attachments can't be added via the API, but any images attached in the dashboard are returned via presigned URLs with a 10 minute validity.
# What alert sources are supported?
Source: https://docs.incident.io/alerts/alert-sources
Every monitoring, error tracking, and ticketing tool incident.io can turn into alerts.
Every alert source maps a monitoring, error tracking, ticketing, or security tool to the same alerting flow: connect it once, and its alerts flow into your routes, escalations, and incidents from then on. This page lists the tools incident.io integrates with directly.
Can't find your tool? See [Using HTTP or custom HTTP sources](#using-http-or-custom-http-sources) below.
| Alert source | Setup |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| AWS CloudWatch | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=cloudwatch) |
| AWS SNS | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=sns) |
| Azure Monitor | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=azure_monitor) |
| BigPanda | [Setup guide](/alerts/bigpanda) |
| BugSnag | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=bugsnag) |
| Checkly | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=checkly) |
| Chronosphere | [Setup guide](/alerts/chronosphere) |
| Cloudflare | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=cloudflare) |
| Coralogix | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=coralogix) |
| Cronitor | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=cronitor) |
| Dash0 | [Setup guide](/alerts/dash0) |
| Crowdstrike Falcon | [Setup guide](/alerts/crowdstrike-falcon) |
| Datadog | [Setup guide](/integrations/datadog) |
| Dynatrace | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=dynatrace) |
| Elastic | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=elasticsearch) |
| Email | [Setup guide](/alerts/email-sources) |
| Expel | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=expel) |
| GitHub Issues | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=github_issue) |
| Google Cloud Platform | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=google_cloud) |
| Grafana | [Setup guide](/integrations/grafana) |
| Honeycomb | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=honeycomb) |
| Jira/ITSM | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=jira) |
| Monte Carlo | [Setup guide](/alerts/monte-carlo) |
| Nagios Core | [Setup guide](/alerts/nagios) |
| New Relic | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=new_relic) |
| Opsgenie | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=opsgenie) |
| PagerDuty | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=pager_duty) |
| Panther | [Setup guide](/alerts/panther) |
| Pingdom | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=pingdom) |
| Prometheus Alertmanager | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=alertmanager) |
| PRTG | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=prtg) |
| Runscope | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=runscope) |
| Sentry Issues | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=sentry) |
| Sentry Metrics | [Setup guide](/alerts/sentry-metric-alerts) |
| ServiceNow | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=service_now) |
| SolarWinds AppOptics | [Setup guide](/alerts/solarwinds) |
| Splunk | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=splunk) |
| StatusCake | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=status_cake) |
| Sumo Logic | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=sumo_logic) |
| Uptime.com | [Setup guide](/alerts/uptime) |
| Vercel | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=vercel) |
| Zendesk | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=zendesk) |
## Using HTTP or custom HTTP sources
Any tool that can send a webhook can become an alert source, even if it's not in the list above. Wherever your alerts live, you can start sending them to incident.io.
### Default HTTP
Use a default HTTP source when you control the payload, for internal scripts, custom monitors, or anything else that can send JSON shaped to match incident.io's schema:
```json Expected body structure theme={null}
{
"title": "My first alert",
"description": "Some additional context",
"deduplication_key": "first-alert",
"status": "firing",
"metadata": {
"team": "core",
"service": "api"
}
}
```
Use the `metadata` field to set [alert attributes](/on-call/alert-attributes) for routing and filtering.
### Custom HTTP
Use a custom HTTP source when a tool's webhook payload can't be changed to match that schema. Write a JavaScript transform expression that reshapes whatever the tool actually sends into incident.io's expected format:
```json Example payload from external tool theme={null}
{
"title": "High CPU usage on server-01",
"status": "firing",
"description": "CPU usage exceeded 90% threshold",
"url": "https://monitoring.example.com/alerts/12345",
"team": "platform",
"severity": "critical"
}
```
```javascript Your transform expression theme={null}
// $ represents your incoming payload
return {
title: $.title ? $.title : 'Custom HTTP alert',
status: $.status === 'resolved' ? 'resolved' : 'firing',
description: $.description ? $.description : '',
source_url: $.url,
metadata: { team: $.team, severity: $.severity },
};
```
So you can connect literally anything that speaks webhooks to incident.io, on your own terms, today. See [Custom HTTP alert sources](/alerts/custom-http-sources) for the full walkthrough, including how to power alert attributes and priorities from the transform.
| Alert source | Setup |
| ------------ | --------------------------------------------------------------------------------------- |
| Default HTTP | [Set up in dashboard](https://app.incident.io/~/alerts/sources/create?source_type=http) |
| Custom HTTP | [Setup guide](/alerts/custom-http-sources) |
# Alert timeline
Source: https://docs.incident.io/alerts/alert-timeline
The alert timeline shows the full lifecycle of an alert from the alert details page, so you can understand exactly what happened — like why an alert didn't create an incident, or whether it was grouped into other incidents.
The timeline includes details such as:
* When the alert fired
* When the alert resolved
* What incident it created
* What incident(s) it was marked unrelated to
* What incident(s) it was grouped into
* Any [notes](/alerts/alert-notes) that have been attached to the alert
You can also find timelines for escalations and incidents in their respective part of the product if you want to know more or find out more details about them.
# Can I manually attach alerts to an existing incident?
Source: https://docs.incident.io/alerts/attach-alerts
You can manually attach an alert to an incident from the alert page. Click **Attach to an incident** next to **Related incidents** and select an incident.
You can also attach alerts to an incident from the alerts list: select the alerts to attach using the checkboxes, then click **Bulk action** → **Attach to an incident** from the menu.
## Related Articles
* [Alert grouping](/alerts/grouping-alerts)
* [Creating Escalations and Incidents from Alerts](/alerts/escalations-from-alerts)
# Attributes and Priorities
Source: https://docs.incident.io/alerts/attributes-and-priorities
## Attributes
Alert attributes are how you extract a consistent format of data from your different alert sources, to use in your alert routes.
For example, your Grafana alerts might have a `team` label, while BugSnag alerts have `service` and `customer` tags. Attributes allow you to convert these into a consistent format, so your alert routes don't have to think about where an alert has come from.
Attributes also help responders understand alerts more quickly: rather than having to read through the whole payload, they'll see the extracted attributes first, so they can quickly understand what's going wrong and who's affected.
We have a more detailed end-to-end guide on getting started with **Alerts** [here](/incidents/auto-create).
## Required attributes
If you have attributes that you rely on to handle your alerts correctly, you should make them required. A common use case for this is when setting a **Team** - if an alert is missing this value, then it may not be escalated and nobody will get paged.
Marking alert attributes as required is global configuration, so you should only do this for attributes which you expect to be set on every alert.
We'll then be able to warn you if your alert sources don't have this attribute configured correctly. We can also notify you if we detect alerts that are missing a value for this attribute.
You can enable required attributes and opt in to missing attribute notifications in the [Alert Attribute settings](https://app.incident.io/~/alerts/configuration/attributes).
## Priorities
To use priorities in the escalation path branches, you can create them in [Alert](https://app.incident.io/~/alerts/configuration/priorities) [Attribute settings](https://app.incident.io/~/alerts/attributes).
More details on setting up priorities in this [article](/on-call/escalation-paths).
# Adding BigPanda as an alert source
Source: https://docs.incident.io/alerts/bigpanda
Turn BigPanda incidents into incident.io alerts, with two-way resolution
Connect BigPanda as an alert source to create an incident.io alert for each BigPanda incident. Resolution flows both ways: closing the incident in BigPanda resolves the alert here, and resolving the alert here closes the incident back in BigPanda.
incident.io reads BigPanda's native webhook payload directly, so you don't need to configure a custom body template. Alerts are keyed on the BigPanda `incident.id`, which means updates, closes, and re-opens all match back to the same incident.io alert.
This integration works with BigPanda **incidents** — the correlated objects BigPanda produces. The individual alerts
BigPanda ingests from its own sources are not sent to incident.io.
## Before you start
You'll need the required administrative permissions in both incident.io and BigPanda.
## Create a BigPanda API key
incident.io uses a BigPanda API key to close incidents back in BigPanda when you resolve an alert here. We recommend generating that key with a dedicated **service account** rather than a personal login, so the integration keeps working when people leave and its actions are clearly attributable.
1. In BigPanda, create a new service account for incident.io — for example `incident.io` — and give it the **Admin** role. You can find this under `Settings` → `Access Management` → `Service Accounts`.
2. Generate a new API key attached to the service account with no expiration. This is the key you'll give incident.io in the next step. You can find this under `Settings` → `Access Management` → `API Keys`. You can create a service account key by selecting service account in the `Create Key` Modal. Please select an appropriate expiration and make sure to note its expiry if you do set it to expire.
Tying the key to a service account means it survives staff changes, and any incident BigPanda shows as resolved by
`incident.io` is clearly attributed to that account.
## Install the BigPanda integration
The integration stores the API key used to resolve incidents back in BigPanda.
In incident.io, go to **Settings → Integrations** and find **BigPanda**.
Click **Connect** and paste the **API key** you created above.
On save, `incident.io` validates the key against BigPanda before storing it, so an invalid key is rejected up front.
## Create the alert source
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard.
2. Select the **Sources** tab at the top of the page.
3. Press the **New alert source** button.
4. Search for **BigPanda** and click continue to create the alert source.
5. Copy the **Callback URL** and **bearer token** shown on the setup page — you'll paste these into BigPanda next.
## Configure BigPanda
1. In BigPanda, create a **Webhooks** integration (search for "Webhooks" in BigPanda's integrations).
2. Set its **Callback URL** to the URL from the incident.io setup page.
3. Add a custom header so BigPanda authenticates with us:
* **Header name:** `Authorization`
* **Header value:** `Bearer `
4. Set up an **AutoShare** rule (`Settings` → `Data processing` → `AutoShare`) that shares incidents to this webhook. Point the rule at the webhook you just created and use a filter to choose which incidents are shared — leave it unfiltered to send everything, or scope it to a subset (for example by environment or source). In the AutoShare config, we recommend setting the delay to none and adding a delay on the `incident.io` side if needed. This means alerts are present even if they fire too briefly to page someone.
## How it works
BigPanda fires lifecycle events that incident.io maps onto an alert's status:
| BigPanda event | What happens in incident.io |
| ----------------- | --------------------------- |
| `incident#new` | Creates a firing alert |
| `incident#closed` | Resolves the alert |
| `incident#reopen` | Re-fires the alert |
Because every event is keyed on the BigPanda `incident.id`, a close followed by a re-open lands on the same alert rather than creating a new one.
When you resolve the alert in incident.io, we close the corresponding BigPanda incident using the API key you supplied when installing the integration. This keeps the two systems in sync — without it, the BigPanda incident would stay open and could re-fire the alert on the next webhook.
# Adding Chronosphere as an alert source
Source: https://docs.incident.io/alerts/chronosphere
This article provides step by step instructions for setting up Chronosphere as an alert source within incident.io.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the sources tab at the top of the page
3. Press the 'New alert source' button
4. Search for 'Chronosphere' and click continue to create the alert source
5. Head over to the Chronosphere dashboard, and find the Notifiers page under the Alerts section in the menu bar
6. Create a new notifier by clicking the green button which says 'Create notifier'. Choose a name and select 'Webhook' as the type of notifier. Enter in the URL which we provide in the incident.io dashboard after completing step 4.
7. After saving the notifier, go to the 'Notification policies' page which can be found in the Alerts section as in step 5, above 'Notifiers'.
8. Create a new Notification policy by clicking the green button which says 'Create notification policy'. Choose your notification policy name and parent team, and then add incident.io (or whichever notifier you just set up) as a critical alert notifier. You may also wish to add it as a warning alert notifier.
9. Now, whenever you create a new monitor within Chronosphere, you can select your new notification policy, which will send alerts to the alert source that you set up in incident.io.
# Adding ClickStack as an alert source
Source: https://docs.incident.io/alerts/clickstack
Turn ClickStack observability alerts into pages and incidents in incident.io.
ClickStack is ClickHouse's observability platform, built on HyperDX, for alerting across your logs, metrics, and traces. Connect it to incident.io to page the right people and automatically create incidents when a ClickStack alert fires.
ClickStack sends alerts to incident.io through its **incident.io** webhook destination, pointed at an [HTTP alert source](/alerts/custom-http-sources) you create in incident.io. Once connected, ClickStack alerts flow into your alert routes for escalation and incident creation, just like any other source.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard.
2. Select the sources tab at the top of the page.
3. Press the **New alert source** button.
4. Search for **HTTP**, then click continue to create the alert source.
5. Copy the **Webhook URL** that incident.io generates. It includes a token and looks like `https://api.incident.io/v2/alert_events/http/...?token=...`.
6. In ClickStack, open a search or dashboard chart, add an alert, and select **Add New Webhook**.
7. Set the **Service Type** to **incident.io**, give the webhook a name, and paste in the **Webhook URL** from step 5.
8. Select **Test Webhook** to confirm the connection, then save. You can reuse this webhook across other ClickStack alerts.
If your ClickStack version doesn't offer **incident.io** as a service type, use the **Generic** service type instead and point it at a [custom HTTP source](/alerts/custom-http-sources). The generic webhook body supports the `{{title}}`, `{{body}}`, and `{{link}}` template variables, which you can map onto incident.io's alert schema.
Once alerts are arriving, [create an alert route](/alerts/getting-started) to filter, group, and escalate them, or to automatically create incidents.
# Crowdstrike Falcon
Source: https://docs.incident.io/alerts/crowdstrike-falcon
## Automatically page the right people and create incidents for alerts received from Falcon.
Customers can seamlessly connect Falcon with incident.io to import crucial information. When an alert comes through Falcon, it enables incident.io to page the right person based on the customer’s configuration, provide detailed information about the alert, and gather the necessary team members in the incident channel to collaborate on resolving the incident. Additionally, incident.io can automatically create incidents from alert sources and filter and group them according to the customer’s preferences.
This article provides step by step instructions for setting up Crowdstrike Falcon as an alert source within incident.io.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard and select the sources tab at the top of the page
2. Press the 'New alert source' button and search for 'Crowdstrike Falcon' and click continue to create the alert source
3. Then click the [Crowdstrike Falcon marketplace](https://marketplace.crowdstrike.com/listings/webhook) and choose Configure, head to Webhook and then choose Configure in the Webhook and in the modal 'Add configuration'. You will need to have all four options defaulted to Ok
4. Now you can go back to incident.io and copy and paste the Name, Webhook URL, HMAC Secret key and Signature Header Name to the Crowdstrike Falcon modal.
5. After head to 'All Workflows' in Crowdstrike Falcon and click 'Create workflow' and choose the trigger to be an Event, Name the workflow and click Next to get to the workflow builder
6. Click sequential so it says 'Action'. Click 'Notify' from the modal and 'Call webhook' and then choose webhook name you copy pasted earlier from the drop down menu.
7. Choose Data format to be Custom JSON and go back to incident.io and copy the payload from the alert source
8. Finish the configuration, give a name for the workflow and turn it on and save
9. Now you can go and test the workflow by going to the workflow, click 'Edit' and then 'Execute workflow'
10. You should receive the alert now in incident.io and now you can parse things from the payload!
## Detailed instructions in the video below
***
Can't find the alert source you are looking for? Head to our [integrations page](https://incident.io/integrations) or message us to [support@incident.io](mailto:support@incident.io)
# Custom HTTP alert sources
Source: https://docs.incident.io/alerts/custom-http-sources
Utilizing a JavaScript expression, you can create an alert source which is able to parse almost any shape of a JSON payload. This is useful for connecting [incident.io](http://incident.io/) to alert sources which we don't have an official integration for yet.
## Creating a custom HTTP alert source
When creating a HTTP alert source, you will have the option to use either **Default** or **Custom** source types. The default mode will cover most scenarios, but if you find that your alerting tool has a set payload, you will want to use the custom HTTP source.
Below the Authentication information, there will be 2 fields which you can configure to extract the required information from a JSON payload.
### Transform expression
The transform expression is ES5-compatible JavaScript code that returns an object, matching up with our standard alert schema, having extracted the information from the incoming JSON payload `$`.
The root of the expression will be `source_payload`, so to correctly access the data and set the title for example, you'd need to do:
```javascript theme={null}
return {
title: $.data.event.title,
};
```
Instead of;
```javascript theme={null}
return {
title: $.source_payload.data.event.title,
};
```
| Property | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------- |
| `title` | The title, or name, of the alert |
| `status` | Status reflecting the state of the alert - one of `resolved` or `firing` |
| `description` | An optional long-text description of the alert, which is rendered alongside the title |
| `source_url` | An optional link to the origin of the alert, such as an alerting dashboard or other source |
| `metadata` | An unstructured object `{ }` that contains additional information for attributes like teams, services etc. |
Expressions which take longer than 250 milliseconds to execute will result in a default alert being created.
Plain JavaScript expressions are normally executed in under a millisecond.
### Deduplication key path
The deduplication key path is a `.` separated pointing us at the property we should use as the deduplication key for an alert.
For the sake of reliability and simplification of configuration, this is not executed as JavaScript.
## Powering attributes & priorities
To power attributes, and priorities, via an expression, you should pull the required information into the `metadata` property.
```javascript theme={null}
return {
title: $.title,
metadata: {
priority: $.priority,
team: $.team,
},
};
```
This can be accessed via alert attribute expressions to enrich an alert as with any other alert source.
Although visible as a fallback, `source_payload` cannot be accessed by attribute expressions.
Any properties should be pulled up into `metadata` to ensure they're accessible.
## FAQs
If we hit an error running the transform expression, we will create a default alert, with the whole payload accessible on a `source_payload` property when inspecting the alert.
We will generate a random deduplication key for you so your alert can still be processed, but please note it means **we will not** be able to deduplicate any alerts.
# Adding Dash0 as an alert source
Source: https://docs.incident.io/alerts/dash0
Turn Dash0 check rule notifications into pages and incidents in incident.io.
Dash0 is an observability platform for OpenTelemetry-native monitoring. Connect it to incident.io to page the right people when a Dash0 check fails.
When a check rule fails, Dash0 sends the alert to incident.io through its native incident.io notification channel. Check rule labels are included in the alert payload's `metadata` field, so you can use them to power [alert attributes](/alerts/attributes-and-priorities) and routing.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard.
2. Select the **Sources** tab at the top of the page.
3. Press the **New alert source** button.
4. Search for **Dash0** and click **Continue** to create the alert source.
5. In Dash0, go to **Settings → Notification Channels** and add a new **incident.io** notification channel.
6. Give the channel a name, then paste in the webhook URL from the incident.io alert source setup page.
7. Under **HTTP Headers**, add an `Authorization` header set to `Bearer {secret_token}` using the token shown in incident.io.
8. Assign the channel to your check rules, either directly or using label-based routing.
9. Trigger a check or send a test notification. If it's set up correctly, the alert will appear in incident.io.
You can append query parameters to the webhook URL (e.g. `?team=backend`) to route or enrich alerts without changing the check rule. They're available in attribute expressions under `query_params`.
Once alerts are arriving, [create an alert route](/alerts/getting-started) to filter, group, and escalate them, or to automatically create incidents.
# Why are some of my Datadog alerts not appearing in incident.io?
Source: https://docs.incident.io/alerts/datadog-issues
## Context
When using the Datadog integration with incident.io, some alerts from Datadog monitors may not appear to create incidents in incident.io, even though the webhook integration is properly configured. This behavior is often related to the key being used for the deduplication key.
## Answer
By default, we use Datadog's `$AGGREG_KEY` as the deduplication key for alerts. This means that multiple alerts with the same aggregation key will be deduplicated if there is an existing alert in a firing state, which will lead to other alert events being deduplicated into that firing alert.
If you need to create multiple alerts at the same time from the same monitor, you can modify the deduplication key in your Datadog webhook configuration to make it unique. Here's how:
1. In your Datadog webhook configuration, customize the deduplication\_key field
2. Combine the `$AGGREG_KEY` with another unique identifier, such as `$ALERT_CYCLE_KEY`
3. Use this format: `"deduplication_key": "$AGGREG_KEY-$ALERT_CYCLE_KEY"`
This approach ensures that each alert creates a unique key so that alerts are not deduplicated while you still have firing alerts from that monitor.
For more information about available variables in Datadog webhooks, refer to the [Datadog webhook variables documentation](https://docs.datadoghq.com/integrations/webhooks/#variables).
# What is Alert Deduplication?
Source: https://docs.incident.io/alerts/deduplication
Within the alert payloads received from our alert source integrations, a deduplication key is used to uniquely identify alerts and prevent the generation of duplicate alerts. For instance, if alert A is received with a deduplication key "x" and alert B with the same deduplication key is received while alert A is still active (in a firing state and not resolved), no new alert will be created for alert B. This can often be the reason why alerts may appear to be missing or not showing up within incident.io. Additionally, deduplication keys are used to manage the unique resolution of alerts. If an alert with a resolved status is sent using the same deduplication key as an active alert, the system will resolve the active alert accordingly. For HTTP alert sources, you have complete control over the choice of deduplication keys. However, for other alert sources, the configuration of deduplication keys varies depending on the integration.
To learn more about how deduplication works for a specific alert source, please just head over to [this](/alerts/json-array-troubleshooting) collection of articles. If an article doesn't exist for a specific alert source and you still need assistance, please reach out to [help@incident.io](mailto:help@incident.io).
# Dynamically setting an escalation path
Source: https://docs.incident.io/alerts/dynamic-escalation
If you're looking to stop having to hard-code escalation paths in your workflows, you've come to the right article.
We'll dig into exactly how you can start dynamically setting your escalation paths based on another field e.g. select an affected feature for an incident and then escalate to the team that owns that feature.
**Required reading:** You'll need to have a read of [this article](/catalog/what-data)
Now that you've read that article, you should have a good understanding of the Catalog types we'll need to support this use-case.
Essentially, you'll need a catalog type to represent your Teams and Features, with each Feature having an Owner (Team), and each Team having an Escalation Path.
This then lets you create the following expression wherever you need to get from **Feature → Escalation Path**. This could be within the Escalations section of an Alert Route, or within a workflow that escalates to a team when an incident is declared manually:
Note that the **Incident** → **Affected Service** here is a custom field of type **Feature** from my Catalog which is exposed in my incident declaration and update forms for users to then set.
This would then behave very similarly within an Alert Route depending on what you're pulling out of any given alert. For instance, if my alerts pointed to features I could create an Alert attribute of type **Feature** and do a very similar expression to the above in the my escalation section of my route.
If my alert only pointed me to a team, we could just create an Alert attribute of type **Team** and lookup to escalation path from there.
For more information on how to set an attribute that has a catalog type from an Alert, please see [here](/alerts/team-routing)
# Email alert sources
Source: https://docs.incident.io/alerts/email-sources
Turn inbound emails into structured alerts, with optional JavaScript to extract the fields you need.
Use email alert sources when a monitoring tool, script, or workflow can send email but doesn't support webhooks. Emails sent to the source's unique address can be used to create alerts in incident.io.
## Creating an email alert source
When you create an email source, incident.io generates a unique inbound address like the one below:
```text Example email address theme={null}
abc123xyz-f769e4dda22b@inbound.incident.io
```
Configure your monitoring tool, ticketing system, or forwarding rule to send to this address.
Email sources are useful for:
* Synthetic monitors, cron jobs, or legacy scripts that only emit email
* Customer support or internal escalations where critical emails should trigger alerts
## Default behavior
Without advanced email parsing, email sources work in standard mode:
* The subject becomes the alert title and the body becomes the description
* Each email creates a new alert (no deduplication)
* Alerts stay in `Firing` indefinitely and need manually resolving
In the default mode emails can't resolve themselves, so we recommend enabling [auto-resolve](/on-call/alert-sources#auto-resolve-alerts) on email sources, or using advanced email parsing to derive status from the email content.
## Advanced email parsing
Enable **Advanced email parsing** in the alert source's connection manager to write a transform expression — JavaScript that extracts structured data from incoming emails. Use this when you want to:
* Deduplicate alerts so the same issue doesn't create multiple alerts
* Mark alerts as resolved based on subject or body patterns
* Pull team, severity, or service information into [alert attributes](/on-call/alert-attributes)
The transform expression is ES5-compatible JavaScript that returns an object matching incident.io's standard alert schema, having extracted fields from the inbound email `$`.
```json Example payload theme={null}
{
"id": "01KQHX3X8676X6B4WHJKCBM0PV",
"to": "abc123xyz-f769e4dda22b@inbound.incident.io",
"from": "alerts@my.monitoring.provider",
"subject": "[inc-45] Disk space running low on logging server",
"text": "Automated alert triggered by monitoring system. Severity: warning. Status: triggered. Timestamp: 2026-05-01T13:54:40Z",
"html": "[inc-45] Disk space running low
",
"header_message_id": "1777643680-10362@my.monitoring.provider",
"envelope": {
"to": ["abc123xyz-f769e4dda22b@inbound.incident.io"],
"from": "alerts@my.monitoring.provider"
}
}
```
```javascript Your transform expression theme={null}
return {
title: $.subject,
description: $.text,
status: $.subject.indexOf('RESOLVED') > -1 ? 'resolved' : 'firing',
deduplication_key: $.subject.split(']')[0] + ']',
metadata: {
from: $.from,
},
};
```
### Available fields on `$`
| Field | Description |
| ------------------- | ------------------------------------------------------------------------ |
| `to` | The inbound address that received the email |
| `from` | The sender address from the email headers |
| `subject` | The email subject line |
| `text` | Plain text body |
| `html` | HTML body — prefer `text` for transforms unless you need to parse markup |
| `header_message_id` | The `Message-ID` header — useful as a deduplication key |
| `envelope.from` | SMTP envelope sender |
| `envelope.to` | Array of SMTP envelope recipients |
### Return schema
| Property | Description |
| ------------------- | ------------------------------------------------------------------------------ |
| `title` | The title, or name, of the alert |
| `status` | `firing` or `resolved` — derive from email content |
| `description` | An optional long-text description, rendered alongside the title |
| `source_url` | An optional link to the origin of the alert |
| `deduplication_key` | Used to deduplicate alerts. Returned in the object — not configured separately |
| `metadata` | An unstructured object for attributes like team, service, or severity |
Expressions that take longer than 25 milliseconds to execute will result in a default alert being created. Plain
JavaScript expressions normally execute in well under a millisecond.
## FAQs
If we hit an error running the transform expression, we'll create a default alert with the whole payload accessible on a `source_payload` property when inspecting the alert.
Emails don't have a built-in concept of resolution. Either derive status from the subject or body in your transform
expression (e.g. resolve when the subject starts with `[RESOLVED]`), or enable
[auto-resolve](/on-call/alert-sources#auto-resolve-alerts) on the source so alerts time out after a set duration.
We'll use the message ID from the email headers. The `header_message_id` is a stable per-email identifier; for
repeated alerts about the same underlying issue we'd recommend using transform expressions to derive a key from the
subject or a structured field in the body.
Yes — `$.html` is available, but reliably parsing HTML inside a 25ms transform is hard. Most monitoring tools include a plain text alternative in `$.text`. Prefer that when possible.
# Creating escalations and incidents from alerts
Source: https://docs.incident.io/alerts/escalations-from-alerts
After you have connected your alert source, it's time to create alert routes.
Alert routes process incoming alerts, and determine:
1. How to route alerts to the correct escalation path
2. Which (if any) alerts should create incidents, as well as alert grouping behavior
## Creating a new Alert route
After you have connected your alert source, it's time to create one or more alert routes from it. Remember, you can bring data from multiple data sources to one route!
1. Head to Settings > Alerts
2. Create a new Alert Route, and give it a name
3. Choose the alert sources you want to bring to this route
4. Continue
## Filtering alerts
You can filter alerts out if they are irrelevant to your alert route. Any data from the alert's payload can be used to filter out alerts (leveraging [attributes](/alerts/attributes-and-priorities) ), as well as first-order filters like Source or Priority.
Example: Have an attribute on your alert to capture `Staging` versus `Production` environment, so you can filter out `Staging` alerts.
## Grouping alerts
Group related alerts by time window and/or context (via attributes like service or team) to decrease noise from similar alerts and reduce alert fatigue. See [Alert grouping](/alerts/grouping-alerts) for how to set this up and how it behaves.
Catalog is where you can store your organization structure like services, teams, domains, features, integrations etc. This is what makes Alerts powerful for you to create a configuration that is efficient and alerts in the right way and time. You can read more [about Catalog here](/catalog/catalog-setup).
## Creating escalations from an alert route
You can choose whether you want to page people for your incoming alerts.
Alerts can be escalated to [Escalation paths](https://app.incident.io/~/on-call/escalation-paths), users, or a combination thereof.
You can either point directly to a specific Escalation Path or user; or (which we recommend!), leverage [Expressions](https://www.loom.com/share/59694b3eb37c4ba6a787fa279fb363d1?sid=3307d250-3e30-4b8c-97e6-33b2ca2b44c6) to dynamically pick the right Escalation Path depending on the alert's context.
1. Go to the Alert Route > Set Escalate alert to "Yes"
2. Choose the escalation path(s) you'd like to page (we recommend leveraging a query-based expression to pick the right Path based on e.g. the impacted Service or Team on the alert)
3. Optionally, you can stack multiple escalation rules (for example, "Escalate to the Team labeled against the alert, AND escalate to the Infrastructure team if alert priority = P1")
4. Toggle on auto-cancel escalations if you wish to cancel pages when an alert is resolved (this is useful for flappy alert sources)
If an alert isn't part of a [group](/alerts/grouping-alerts) and its priority increases after it's already been escalated (for example, your monitoring tool sends an updated version of the same alert at a higher priority), we'll automatically trigger a new escalation to reflect the increase. Grouped alerts have their own equivalent setting for escalating **on priority increase**, described in [Alert grouping](/alerts/grouping-alerts).
## Creating incidents
You can choose exactly when and how you want to create incidents, and what type of incident, when alerts are received.
Note: We recommend declaring Triage incidents alongside your paging, as this allows your team to have a dedicated spot to collaborate, and if your team decides this is not an incident, you can simply decline it! Otherwise, if this turns into a real incident you already have all your troubleshooting context in the Slack channel.
To skip triage and create incidents that are immediately active, select **Active** as the starting status. This is
useful for high-confidence alerts that don't need manual confirmation.
1. Go to the Incident Details
2. Choose what information you want to get shown about an incident in the Slack channel when it is posted. You can see a preview on the right side of the screen.
(We recommend ticking "Set with AI" so we can rename your incident and set its summary automatically using the alert's context!)
3. Dynamically set the incident's severity, and pass any data from your alert to your incident using the "Add Custom Field" option (this will let you e.g. pass the tagged Service on your alert as the Affected Service on your incident), keeping data consistent and auto-populated
4. Tick the "Decline triage incidents' box if you'd like to automatically reject triage incidents when the alert resolves itself
We also allow you to turn off incidents and just escalate based on alerts, you can read more about [Paging without incidents here](/internal/paging-without-incidents).
# Creating incidents automatically via alerts
Source: https://docs.incident.io/alerts/getting-started
When incidents occur, the on-call person is typically notified through automated alerts or manual incident creation. In this article, we’ll focus on automating the process of escalating and creating incidents.
Head [here](/on-call/manual-incidents) about manually creating incidents.
## Configuring On-call features
Before configuring alerts for automatic escalation and incident creation, ensure that you have:
1. Set up your teams and any necessary types in the Catalog.
2. Created schedules.
3. Established escalation paths and linked them to the appropriate teams
To learn more about the main steps to configure On-call, head [here](/on-call/getting-started)
## Creating incidents from alerts
Alert configuration consists of configuring your
1. Alert sources and attributes
2. Alert routing including filtering, escalations, incident creation and grouping
### Connecting your alert source
1. Go to [Alert Configuration](https://app.incident.io/~/alerts/configuration)
2. Choose your alert source
3. If a direct integration isn’t available for your source, connect it via HTTP.
4. Follow the setup instructions to connect your source and send a test alert.
5. Configure alert attributes and priority with the help of our AI suggestions.
* Choose to use **attributes** or **priority** from the alert payload or set them as a **static field**
* Ensure that your alert includes an attribute specifying who should be paged. Whether you page based on Team, Service, or another criterion, the alert should be able to reference an escalation path defined in the Catalog.
**Attributes** provide extra context to your alerts, like services, affected features, or environments. Learn more about Attributes here and Priorities [here](/on-call/priority-urgency-severity)
## Routing your alerts to start escalating and creating incidents
Now set up your alert routes to escalate and create incidents automatically.
1. Create a new Alert route in [Alert configuration](https://app.incident.io/~/alerts/routes/create)
2. Select the sources you want to include
3. Filter the alerts you want or don't want to trigger incidents
4. Enable Escalations, choosing either
* **Dynamic escalation** paths based on your team or service attribute (recommended), or
* **Static paths** to use the same escalation path for all alerts
5. Enable incident creation
* Automatically create incidents or filter which alerts should trigger them.
* Configure **grouping** so similar alerts are handled together \[[Learn more](/alerts/grouping-alerts)]
* You can also choose Mode=Test to create test incidents
We recommend using only a few alert routes: One for engineering, one for the support team and maybe one for security teams if needed. Using Catalog to dynamically route escalations eases up the configuration and keeps things aligned. Learn more about Alert configuration [here](/alerts/attributes-and-priorities)
## Creating incidents with a third-party paging tool
If you are still using a third-party tool like PagerDuty or OpsGenie the incident creation can still be manual, but you won't be able to dynamically route escalations as those exist in your third-party tool.
Using both our On-call and Response product can create a lot of benefits like unified data flow, continuous feedback on your alerts and so, better noise management all under in a single pane of glass. Learn more about our On-call [here](https://incident.io/on-call)
# Alert grouping
Source: https://docs.incident.io/alerts/grouping-alerts
Group related alerts into an alert group so you can triage, escalate and attach them to incidents as one.
Alert sources can fire many alerts for the same underlying issue. **Alert grouping** groups those related alerts into a single **alert group**, so you can triage, escalate and attach them to an incident once — instead of handling each alert on its own.
We're currently migrating organisations onto our new alert grouping. While your organisation is being migrated, you may not yet be able to configure grouping outside of incidents. Once you're fully migrated, you'll have access to the full experience as described in this help doc. To read more about the migration, see [here](#alert-grouping-migration)
## How it works
When grouping is enabled on an alert route, each incoming alert is matched to a group using the attributes you've chosen to group by, such as service or region. Alerts that share a key join the same group, as long as they arrive within the group's time window. Windows can be configured in two ways:
* **Fixed window** — the group stays open for a set time after it's created.
* **Extending window** — the window resets each time a new alert joins, so the group stays open while related alerts keep arriving.
An alert group is a bucket of alerts and it takes its **title and description from the first alert** to join.
## Setting up grouping
Grouping can be configured per alert route:
1. Open the alert route you want to group alerts on.
2. Enable grouping and choose the **attributes** to group by.
3. Choose a **fixed** or **extending** window.
a. A fixed window means the alert group will close at the set time after the first alert has arrived.
b. An extending window will close the alert group at the set time after the most recent alert has arrived.
You can then choose to create an incident from grouped alerts, and whether alerts should also create escalations. When they do, you control how a group pages as new alerts join:
* **On every new alert** — page each time an alert joins the group.
* **On priority increase** — only page when an alert with a higher priority joins the group.
* **After a grace period** — wait a set number of minutes before paging, giving you time to action the alert first.
## Attaching groups to incidents
If incident creation is enabled on the route, alert groups are attached to incidents automatically. You can also attach a group to a new or existing incident yourself.
## Managing alerts in a group
Sometimes an alert doesn't belong in the group it's landed in. Take one or more alerts out of a group by clicking **Ungroup**, either for a single alert from its own page, or for several at once from the bulk actions bar.
From the dashboard, Slack, or Microsoft Teams, this shows you what the alert route would do with the ungrouped alerts, pre-filled and editable, so you can review and confirm rather than guess:
* **Do you want to create an incident?**: create a new incident (pre-filled with the title, severity, type, and any custom fields the alert route would have set, and fully editable), merge into an existing incident, or don't create one.
* **Do you want to escalate to anyone?**: escalate to the people or escalation path the alert route would have paged (also editable), or don't escalate.
Choosing not to create an incident and not to escalate simply removes the alerts from the group and does nothing else.
## Private alerts
If you've created a [private alert route](/alerts/private-incidents) then you'll be able to group those alerts and create private alert groups. The visibility of private alert groups is inherited from the visibility of the constituent alerts.
## Alert group limit
We have a limit of 1,000 alerts joining an alert group. Once that limit has been reached, we'll create a new alert group for subsequent alerts to group into. If this is an issue for your organisation, then please get in touch.
## Alert grouping migration
Whether you move across all at once or gradually depends on whether your organization has at least one alert route that currently groups alerts into incidents.
If you don't, there's nothing to switch over, so we'll migrate you fully from the start. You'll be able to configure alert grouping straight away from your [alert route configuration](https://app.incident.io/~/settings/alerts).
If you do, we'll start migrating you gradually. We do this to prevent both the old and new flows each creating incidents or escalations. During this period, some alerts will still group into incidents using the old flow while others start forming alert groups using the new one. Here's how the handover works for a given attribute that you're grouping by (e.g. Alert title)
* While alerts keep arriving within the grouping window, we continue grouping them into incidents using the old flow.
* Once the grouping window closes, new alerts for that attribute will start forming an alert group using the new flow. Depending on how your alert route is configured, it'll then create an incident and escalation.
* Because the old flow's window always extends, alerts will only begin to be grouped into alert groups once there's a gap between alerts arriving that is longer than the grouping window duration.
* An alert will only be processed by the old or new flow; never both.
While you're migrating, you'll get the core new experience — alerts group automatically and you can ungroup any that don't belong — but the extra configuration options listed above are unavailable until the migration finishes. The migration finishes when across all of your alert routes with grouping configured, there aren't any open incidents that an alert could group into.
### What's changing
**Old behavior**
* We'd only allow you to group alerts into an incident.
* If you used **Suggested** alert grouping, we didn't group alerts automatically — we'd ask whether you want to relate each alert to the incident.
* If you used **Automatic** grouping, we'd create and then cancel escalations for each alert being grouped.
* The grouping window always extended — i.e. if a new alert arrived, the window would extend again.
**New behavior**
* Once you're fully migrated, you have more control:
* Choose whether the grouping window is extending or fixed.
* Fine-grained control over how alerts joining a group then escalate.
* Group alerts without creating an incident.
* We attach alerts to the relevant alert group for you automatically, and you can ungroup any that don't belong.
* We don't automatically cancel any escalations made from alerts in a group, as we did if you had previously configured **Automatic** grouping in the old flow.
## FAQs
Not yet — a group's title and description come from the first alert to join it, and aren't editable.
No. Groups close automatically when their window expires, or when all attached incidents are resolved. You can
resolve a group's alerts, but there's no manual close.
You can detach other groups attached to an incident, but not the group that originally opened it.
As part of the alert routing configuration, you can choose a Slack or Teams channel to post messages when alerts go
through the route. These messages don't currently contain information about the alert group.
The grouping window is configurable per alert route, up to a maximum of 48 hours — we preselect 30 minutes when you
first enable grouping, but you can choose any duration in that range, as either a fixed or extending window. If a
new alert arrives after the window has expired, it starts a new alert group (and, if the route creates incidents, a
new incident).
# Heartbeat monitoring
Source: https://docs.incident.io/alerts/heartbeat-monitoring
Detect when a service fails silently
## What is heartbeat monitoring?
Heartbeat monitoring flips the usual alerting model: instead of your monitoring tool pushing an alert when something breaks, your service sends regular "I'm alive" pings to incident.io. If pings stop arriving within the expected window, an alert is fired to detect silent failures. This is useful for:
* **Cron jobs and scheduled tasks**: know immediately if a job silently stops running
* **Third-party integrations and service dependencies**: catch failures in external systems before they show up on status pages
* **Monitoring your monitoring stack**: ensure Prometheus, AlertManager, or other tools are actually running and healthy
## Create heartbeat
Go to [Settings -> On-call -> Heartbeats](https://app.incident.io/~/settings/heartbeats) and click **Create new**. Configure the following fields:
* **Name**: identifies the service you're monitoring. Create a separate heartbeat for each service or job you want to monitor independently.
* **Interval**: how often your service will ping. Must be between 1 second and 48 hours.
* **Grace period** or **Missed tolerance**: choose one to control how much leeway to allow before firing an alert:
* **Grace period**: fires an alert if a ping is late by more than the configured number of seconds. The combined interval and grace period cannot exceed 48 hours.
* **Missed tolerance**: fires an alert after the configured number of consecutive pings are missed (minimum 1). The interval multiplied by the threshold cannot exceed 48 hours.
* **Priority**: the priority for alerts fired by this heartbeat.
* **Heartbeat owner** (optional): the team responsible for this heartbeat.
Click **Save**.
## Create heartbeat via Terraform
Use the `incident_alert_source` resource with `source_type = "heartbeat"` to manage heartbeats as code:
```hcl theme={null}
resource "incident_alert_source" "heartbeats" {
name = "My heart will go on"
source_type = "heartbeat"
template = {
title = {}
description = {}
attributes = []
expressions = []
}
heartbeat_options = {
interval_seconds = 60
grace_period_seconds = 1
failure_threshold = 1
}
}
```
The `title` and `description` fields in the template must be left empty — heartbeat alert sources manage these automatically.
## Set up heartbeat pings
Copy the **ping URL** from the **Ping endpoint** section of your heartbeat using. We support query string authentication or header authentication depending on your set up.
Configure your service to send a GET or POST request to the ping URL at your chosen interval:
```bash theme={null}
curl https://api.incident.io/v2/heartbeat//ping \
-H "Authorization: Bearer "
```
You can use curl, wget, or any HTTP client. Most cron job schedulers and monitoring agents support webhook calls out of the box. The heartbeat won't start monitoring until it receives its first successful ping.
Once your service is sending requests, you will see them appear in the graph view on the left of the page.
## Alerting
When pings stop arriving, incident.io creates an alert. Each heartbeat is an [alert source](https://app.incident.io/~/alerts/sources), so you can connect it to an alert route to control how alerts are routed to your on-call schedule. Check the heartbeat is healthy before connecting, otherwise your on-call could get paged before your service is up.
If pings continue to be missed, the alert stays open until the next successful ping arrives. It won't fire a duplicate while one is already active. The alert resolves automatically when a successful ping is received.
# Extracting JSON alert data
Source: https://docs.incident.io/alerts/json-alert-data
When configuring alerts you can choose to extract specific fields you care about from the JSON payload of your alert.
You can manage this by navigating to [Alerts > Sources](https://app.incident.io/~/alerts/sources) and editing the alert source you wish to extract information from.
While editing the alert, click on the icon in the attributes section.
Once you are ready to add a new attribute, you can choose to add attributes through the use of AI, we will parse through the payload and suggest attributes that are commonly seen and can be linked to a catalog type.
Or you can choose to link an existing attribute or start from scratch by parsing the payload directly.
***
## Extracting fields from JSON
You can see the alert payload for all the alerts you've received.
The input for extracting data works with Javascript, but without any ES6 language features.
**ES6 language features are not supported** This means there is no support for arrow functions, template literals, some string functions, and other features [listed here](https://www.w3schools.com/js/js_es6.asp)
## Options to extract values from the payload
## 1. Extract a simple field
If you click on any field displayed in the payload, you'll automatically see this value extracted.
For example, to extract the `service` field from your metadata, use
```javascript theme={null}
$.metadata.service;
```
This will dynamically fetch whichever value is in the `service` field and apply it to your alert.
## 2. Map array fields
To map an array field, we can use standard Javascript.
In our JSON payload, our tags field has the following format:
```javascript theme={null}
tags: ['feature:api', 'feature:payments', 'service:api'];
```
To filter only certain values from our tags, we can use Javascript filtering:
```javascript theme={null}
$.metadata.tags.filter(function(tag) { return tag.startsWith("feature:") })
// This returns the following
feature:api, feature:payments
```
To map your array, you can also use standard Javascript functions:
```javascript theme={null}
$.metadata.tags.map(function (tag) {
return tag.split(':')[1];
});
// This returns the following
(api, payments);
```
To ensure that your output preserves all values from your array, select *Result is an array.*
Otherwise, your result will just select the first value of your array.
## 3. You can write a custom JavaScript snippet
We support Javascript ES5, so you can write custom code that will allow you to get creative on how you extract values from the payload. If you're a bit rusty with Javascript then it can also be well worth asking an AI coding assistant to help write any given expression - a prompt of " *write an expression to do x in Javascript using only ES5* " usually works quite well
# HTTP Alert Sources and Array Payloads
Source: https://docs.incident.io/alerts/json-array-troubleshooting
When using HTTP alert sources, only JSON objects are accepted at the root level. JSON arrays at the top level are not supported and will cause issues with alert processing.
## What happens when you send a JSON array?
If you send a JSON array as the root payload to an HTTP alert source, you may experience the following behavior:
* Your transform function will have no effect
* An empty alert will be created with no data
This is because we don't expect an array here, so the processing fails when trying to map the payload.
## Supported JSON structure
HTTP alert sources expect a single JSON object at the root level, like this:
```json theme={null}
{
"alert_name": "Server Down",
"severity": "critical",
"message": "Web server is not responding"
}
```
Arrays at the root level are **not supported**:
```json theme={null}
[
{
"title": "Database Connection Failed",
"status": "firing",
"description": "Unable to connect to primary database",
"severity": "critical"
},
{
"title": "High Memory Usage",
"status": "firing",
"description": "Memory usage above 90%",
"severity": "warning"
}
]
```
## Workarounds
If your monitoring service sends JSON arrays (like updown.io), you'll need to:
* Check if your monitoring service offers an alternative webhook format that sends single objects
* Use a middleware service to transform the array into individual object requests
This limitation affects services that send arrays "for future use" where multiple alerts might be included in a single request, even if they currently only send one alert at a time.
# Maintenance windows
Source: https://docs.incident.io/alerts/maintenance-windows
During scheduled maintenance periods (such as database updates, system upgrades, or component maintenance), you may expect alerts to trigger due to temporary service disruptions. These alerts are expected and don't require immediate attention, so you may want to prevent notifications during these planned periods.
Maintenance windows override your alert routing for a set time period, letting you suppress or redirect alerts during planned maintenance. You can hold alerts until the window ends, attach them to an incident, or escalate them to specific targets.
Create maintenance windows from **On-call → Maintenance** in the sidebar, or navigate to [Maintenance windows](https://app.incident.io/~/on-call/maintenance) directly.
## Creating a maintenance window
Give the window a name, assign a lead, and set a start and end time. Then define which alerts the window should catch using condition groups - the same conditions engine used in [alert routes](/alerts/team-routing). You can match on any alert attribute, such as source, service, team, or environment.
## During-window actions
Choose what happens to matching alerts while the window is active:
* **Do nothing with alerts until the window ends**: alerts are held and no escalations or incidents are created. This is the most common choice for routine maintenance.
* **Escalate all alerts**: alerts are escalated to specific escalation paths or users you choose. Use this if you're not expecting alerts and want to be paged as soon as something goes wrong, or to redirect alerts to the team running the maintenance instead of the usual responders.
* **Attach alerts to an incident**: alerts attach to a specific incident you choose. Use this when you want to track maintenance-related alerts in one place.
## After-window actions
Choose what happens when the maintenance window ends:
* **Resolve all alerts**: all held alerts are resolved when the window ends.
* **Reprocess firing alerts**: all alerts that are still firing are reprocessed through your existing alert routes.
* **Do nothing**: alerts remain in their current state.
When reprocessing, if three or more alerts match the same route, they're rolled up into a single escalation to avoid notification storms.
## Viewing alerts during a window
While a maintenance window is active, you can see which alerts it has caught. Open the maintenance window to view all held alerts, their status, alert source, and how much time remains.
If an alert isn't related to the maintenance, you can remove it from the maintenance window so it's routed through your normal alert routes.
## Extending and ending early
Active maintenance windows can be adjusted on the fly:
* **Extend**: push the end time further out if maintenance is taking longer than expected
* **End early**: close the window immediately if maintenance finishes ahead of schedule
When you extend a window, the planned end time updates so after-window actions trigger at the new time.
## Internal announcements
Notify your team about upcoming maintenance by announcing to Slack or Microsoft Teams channels. Configure announcements to send:
* **Before the window starts**: give your team a heads-up that maintenance is about to begin
* **Before the window ends**: alert your team that normal routing is about to resume
Set the lead time in minutes (e.g., announce 15 minutes before start) and include a custom message with any relevant context.
## FAQs
It depends on the during-window action you've configured. By default, alerts are held until the window ends without
creating escalations or incidents. You can also attach them to an incident or escalate them as normal.
Yes. You can manually remove individual alerts from a maintenance window if they need to be handled through normal
routing.
The planned end time updates to the new time. After-window actions (resolve, reprocess, or do nothing) trigger at
the new end time instead of the original.
No. Private alerts always route normally and are not caught by maintenance windows.
Yes. Active maintenance windows can appear in the dashboard sidebar, so your team has visibility into what's
currently suppressed.
Alerts caught by maintenance windows are filtered out of the **On-call → Alerts** view by default. To include them,
use the **Include maintenance window alerts** filter toggle.
# Alert attribute merge strategies
Source: https://docs.incident.io/alerts/merge-strategies
Control how your alert data is captured and updated over time using attributes and merge strategies.
Alerts often fire more than once for the same issue. Each time they do, the payload might contain new information, a severity that's gone from warning to critical, an updated error count, or additional affected services. **Merge strategies** give you control over what happens to each attribute when an update arrives: keep the original value, replace it with the latest, accumulate a list. You can now decide, per attribute, exactly how your alert data evolves.
### What are Alert Attributes?
Attributes are the key pieces of information you pull out of your alert payloads, things like `team`, `service`, `error_message`, or `priority`. They can be a single value (like a team name), a list (like multiple affected services), or a reference to something in your [Catalog](/catalog) (like a Team or Service entry). Once set up, attributes are what your alert routes can use to decide where to escalate and how to create incidents.
### Getting started
1. Head to **Settings → Routing** in the dashboard
2. Click on your alert source (e.g. HTTP, Datadog, PagerDuty)
3. Scroll until you find the attributes section and click **Edit**
4. Click the **cog** next to an attribute to change its **merge strategy**
***
## Understanding Merge Strategies
When the same alert fires multiple times, merge strategies determine how attribute values are combined or replaced. Here's how each of them works:
> **Rankable types** are: Alert Priority, Incident Severity, Follow-up Priority, or custom catalog types with ranking.
| **Strategy** | **Scalar** | **Array** | **Rankable Required** |
| ------------ | ---------- | --------- | --------------------- |
| First Wins | Yes | Yes | No |
| Last Wins | Yes | Yes | No |
| Accumulate | No | Yes | No |
| Maximum | Yes | No | Yes |
| Minimum | Yes | No | Yes |
***
### First Wins
Keeps the first value ever set for the attribute. Basically, once the value is set it never changes regardless of subsequent alerts. Available for all attribute types.
**Example:** First alert sets `service = "payments"`, second alert sends `service = "checkout"` → result is `service = "payments"`.
Best for preserving original state, like an initial error message or first reported time.
***
### Last Wins
Always updates to the latest value each time an alert with the same de-duplication key fires. This is available for all attribute types and only applies **before** the alert escalates or creates an incident.
**Example:** First alert sets `error_count = "5"`, second alert sends `error_count = "12"` → result is `error_count = "12"`.
Best for tracking current state, like a live error count or status.
***
### Accumulate
Combines all values into a single deduplicated list. This is available for **array attributes only** and applies **before** the alert escalates or creates an incident.
**Example:** First alert sends `affected_services = ["api", "web"]`, second sends `["api", "database"]` → result is `["api", "web", "database"]`.
Best for building up lists of affected services, regions, or endpoints over time.
***
### Maximum
Keeps the highest ranked value. This is available for scalar attributes with **rankable types** only and applies **before** the alert escalates or creates an incident.
**Example:** First alert sets `priority = "medium"`, second sends `priority = "critical"` → result is `priority = "critical"`.
Best for ensuring the most critical priority always wins.
***
### Minimum
Keeps the lowest ranked value. Works the same as Maximum, so only works with rankable types and applies **before** the alert escalates or creates an incident.
**Example:** First alert sets `priority = "critical"`, second sends `priority = "low"` → result is `priority = "low"`.
Best for de-escalating priority when subsequent alerts signal recovery.
***
## When Attributes Stop Updating
Once an alert has created an incident or triggered an escalation, **attribute values are locked**. Any subsequent alert fires will not update them.
This is by design — it ensures your incident data reflects the state at the moment action was taken, prevents confusing mid-incident changes, and keeps your audit trail clean.
| Strategy | Locks after incident/escalation? |
| ---------- | ------------------------------------- |
| First Wins | N/A (already locked from first value) |
| Last Wins | Yes, stops updating |
| Accumulate | Yes, stops accumulating |
| Maximum | Yes, stops comparing |
| Minimum | Yes, stops comparing |
***
## FAQs
The new strategy applies to future alert fires only. Existing attribute values are not retroactively changed.
Yes! Each attribute can have its own merge strategy, or fall back to the source default.
Types that have a defined ordering. Built-in rankable types are Alert Priority, Incident Severity, and Follow-up
Priority. Custom catalog types can also be marked as rankable.
Attributes lock when an incident or escalation is created — this ensures the incident reflects the state at the time action was taken.
# Customizing alert messages
Source: https://docs.incident.io/alerts/message-customization
Control which information is displayed in alert messages sent to Slack or Teams channels.
Alerts are routed into Slack or Teams in various ways:
* Sent directly to channels
* Escalated to a channel or a user
* Attached to incident channels
You can now use templates to control which information is displayed in these alert messages, so that your responders can infer crucial context and filter out noise at a glance.
## Creating a template
Manage your templates in Settings > Slack / Teams Messages.
By default, all admins have the permission to manage alert message templates: this can be configured in Settings > Permissions.
**Title**
Customize the message title with alert variables such as the title, status and the source type. The alert status (i.e. firing or resolved) will be kept up to date in the title.
**Description**
Configure whether to show the alert's description. Descriptions are set at the alert source level, and can be customized per alert source.
**Attributes**
Configure the visibility and order of [alert attributes](/alerts/attributes-and-priorities) in the message.
You can preview how your changes will be applied using real alert data from your different alert sources.
## Applying templates to alert routes
You can configure which template an alert route should use. If no template is specified, then we will apply the default template. The default template can be changed in Settings > Slack / Teams Messages.
You can select a specific template to use, or use an expression. For example, you can conditionally select templates based on alert attributes, alert source types and more.
# Why is an alert missing an attribute?
Source: https://docs.incident.io/alerts/missing-attributes
If you're receiving alerts successfully, but some of the attributes aren't getting set correctly, there are a few tools you can use to figure out what the problem is.
### Inspect the original payload
To see exactly what data we received, navigate to the alert and click "Inspect" in the overflow menu:
This shows you:
* what the original payload we received was
* what JavaScript was used to extract attributes from that payload (in case someone has changed them since the alert was received!)
* what that Javascript returned, and whether that matched any catalog types
### Common issues
**Unexpected payload**
Your alert source might not be sending the same data for all alerts, meaning that an expression that normally returns a value doesn't return anything sometimes!
This will show up in the inspector as the JavaScript returning no value.
You can fix this by:
* changing the configuration inside your alert source, to make sure (for example) all alerts have a `team` label
* using `||` in your JavaScript to define multiple ways of finding an attribute, for example `$.metadata.team || $.labels.team`
**Missing catalog entry**
For catalog-powered alert attributes, if your JavaScript returns a value that can't be found in Catalog, the attribute won't get set.
This will show up in the inspector as the JavaScript returning a value, but no entry matching.
You can fix this by:
* checking the configuration inside your alert source for typos - for example `team=paymnts` won't find a team called `Payments` !
* using aliases in Catalog to make a single catalog entry match many different input strings - you can learn more about this [here](/on-call/catalog-integration)
# Adding Monte Carlo as an alert source
Source: https://docs.incident.io/alerts/monte-carlo
This article provides step by step instructions for setting up Monte Carlo as an alert source within incident.io. This will allow you to receive alerts, page the right people & open incidents when they are using Monte Carlo to detect data quality issues (eg: we don't have as many customer emails as we did yesterday).
## Instructions to set up
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the Configuration tab at the top of the page
3. Press the 'New alert source' button
4. Search for 'Monte Carlo' and click continue to create the alert source
5. Head over to the [notification settings page](https://getmontecarlo.com/settings/notifications/settings) in Monte Carlo
6. Create an [audience](https://docs.getmontecarlo.com/docs/how-to-add-an-audience) or edit an existing audience.
7. Name the Audience and select **incident.io** as the **Recipient channel.**
8. Enter the destination incident.io URL from incident.io and token if applicable.
9. \[Optional] Name this recipient, as a single audience can have multiple recipients.
10. Create the audience
## Alert events and updates
The following events receive an update to incident.io:
1. Alert is created
2. Alert is acknowledged
3. Alert status is updated
4. Alert owner is changed
5. External ticket is attached to an alert (Jira, ServiceNow, etc.)
6. Alert is marked as incident
7. Alert is unmarked as incident
8. Alert is resolved
Monte Carlo integration will use 'Last wins' in the alert updates, meaning that every new alert we receive with the same "incident\_id", we'll update the fields to the newest value. incident.io uses "incident\_id" as a deduplication key, so if there are other alerts coming with the same id, it will not create new alerts for them.
**The following are the key fields that are changed by alert updates.**
| Webhook event | alert\_feedback | declared\_alert\_severity | owner |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------- | ----------------------- |
| Alert is created | `null` | `null` | not included in payload |
| Alert is acknowledged | `investigating` | -- | -- |
| Alert status is updated | `investigating`, `no_status`, `work_in_progress`, `fixed`, `expected`, `no_action_needed`, `false_positive` | -- | -- |
| Alert owner is changed | -- | -- | email of assigned owner |
| External ticket is attached to an alert | -- | -- | -- |
| Alert is marked as incident | `investigating` (only if current is `null` or `no_status`) | `SEV-1`, `SEV-2`, `SEV-3`, `SEV-4` | -- |
| Alert is unmarked as incident | -- | `null` | -- |
| Alert is resolved | `fixed`, `expected`, `no_action_needed`, `false_positive` | -- | -- |
# Adding Nagios as an Alert Source
Source: https://docs.incident.io/alerts/nagios
This article provides step by step instructions for setting up Nagios Core as an alert source within incident.io.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the sources tab at the top of the page
3. Press the 'New alert source' button
4. Search for Nagios and click continue to create the alert source
5. Install the incident-io [Nagios Plugin](https://github.com/incident-io/nagios-plugin) by following the instructions in the GitHub repo and enter the URL and token as prompted by the alert source page.
# Adding Panther as an Alert Source
Source: https://docs.incident.io/alerts/panther
This article provides step by step instructions for setting up Panther as an alert source within incident.io.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the sources tab at the top of the page
3. Press the 'New alert source' button
4. Search for 'Panther' and click continue to create the alert source
5. Switch over to your Panther dashboard, and select 'Alert Destinations' under the 'Configure' section
6. If you already have another alert destination set up, click the 'Create New' button in the top right hand corner. Otherwise, click 'Add your first Destination'.
7. Choose 'Custom Webhook' from the list of destinations
8. Copy the Webhook URL provided to you after you created a Panther alert source in the incident.io dashboard, and make sure to add a custom HTTP header for 'Authorization'. The value for this header is provided to you in the incident.io dashboard, alongside the Webhook URL.
9. Click 'Add Destination' and then 'Send Test Alert' to test your integration. You should be able to see a test alert in your incident.io dashboard!
# Priorities in Alerts and On-call
Source: https://docs.incident.io/alerts/priorities
Priorities are a great way to tell how important an alert is and it helps your team to understand how fast they should act on the alert or the incident, but also who should be the people involved. Great examples of Priorities are P1, P2, P3 etc - where P1 is the biggest priority.
You can use Priorities in our Escalation paths to choose what should happen in each priority, but also using them to have default priorities per alert source. Below we'll go through how to configure priorities, but also some tips how to use them
## Configuring Priorities
## Creating priorities
We have introduced Priorities as a first-class citizen to incident.io, meaning that you can configure it in the Priorities tab without creating them as a separate custom field.
1. Head to [Priorities](https://app.incident.io/~/alerts/configuration/priorities)
2. Add the priorities you use in your organization
3. Choose a default priority, meaning that this is what we'll suggest in your sources
## Viewing priorities in Catalog
Catalog is the engine that powers automation and expressions in incident.io. It allows you to sync or create your organization structure like teams and services and then connecting them into other incident.io native types like escalation paths, schedules and priorities.
Just head to [Catalog](https://app.incident.io/~/catalog/) > Alert Priority and you'll be able to see all Priorities that you have created earlier in the [Priorities -tab](https://app.incident.io/~/alerts/configuration/priorities) [.](https://app.incident.io/~/alerts/configuration/priorities)
## Setting priorities from your Alert source
For any given alert, you'll want to look at trying to set the alert priority based on the content within the alert itself e.g. if my alert indicates a higher level of priority in the payload, I probably want the same level of priority to be reflected in the Alert Priority set against that alert. To do so:
1. Head to the Alert source
2. Scroll down to Priority towards the end of the alert attributes section
3. Click 'Use a variable'
4. Add new expression
5. Query and choose Payload
6. Then write Javascript expression to extract what you need. In this simple case that is \$.metadata.priority. Now you should see the example of the preview
7. Choose 'Alert priority' as what the result should be parsed into
8. And choose the empty value if needed
9. Continue and Save
If you are not receiving preview both from your payload and your Alert Priority, it means there might be some differences in the priority labels you have set up either in incident.io or in your alert source. You can try using .toLowerCase() etc in the Javascript expression if there are differences.
If you are bringing priorities from multiple alert sources with different aliases, you can simplify your Javascript by creating aliases to each priority in the Catalog e.g. if you are using P1 in incident.io, but in your alerts refer to these as Critical, you could add that as an alias so that a value of `critical` will return the P1 alert priority.
Some companies prefer having severity as a way of looking how important an alert or an incident is. You will be able to bring severity from your alert source and connecting that to our Priorities through the Javascript expression.
## If you have Priorities set up as a Custom field
You might have created Priorities before we brought in our native 'Alert priorities'. This is why you might not be able to use Priorities in Escalation paths. If this is the case, we would recommend you copying your custom field values to the [Alert Priorities](https://app.incident.io/~/alerts/configuration/priorities) configuration and then deleting your custom field.
## Using Priorities in Escalation paths
You can now set up rules around priority in Escalation paths to ensure you page the right people at the right time without causing additional noise.
1. Head to [Escalation paths](https://app.incident.io/~/on-call/escalation-paths)
2. Create a new escalation path or choose a current one
3. Click '+ Add branch' and 'Add condition'
4. Choose Priority and which ones you want to add as a rule, in example Priority is P1 or P2
5. Add more levels if needed
6. Create or Save changes
More information about Smart Escalation paths and using Priorities, head [here!](/on-call/escalation-paths)
# Routing alerts by priority using alert source configs
Source: https://docs.incident.io/alerts/priority-routing
## Overview
When configuring escalation paths, you can branch based on **priority** and **working hours**. If you want to vary how alerts are handled based on other attributes — such as the service, environment, team, or severity label from your monitoring tool — the right place to do that is in your **alert sources**, not in the escalation path itself.
This article explains how to configure your alert sources so that the right priority is assigned to each alert before it reaches your escalation path.
## Why set priority at the alert source level?
Escalation paths are intentionally kept simple: they branch on **priority** and **working hours** only. This is because escalation paths aren't just used for alerts - they're also used if you ever want to manually escalate to that team.
If you want incoming alerts to be routed differently based on attributes like:
* The **service** or **component** that triggered the alert
* The **environment** (production vs staging)
* A **severity** label from your monitoring tool
* Any other payload field
...the way to achieve this is by **mapping those attributes to a priority** in your alert source config. Your escalation path then branches on the resulting priority.
## How to set priority in an alert source
1. Navigate to **Settings > Alerts > Routing**
2. Click on the alert source you want to configure
3. In the alert source configuration page, find the **Priority** section
4. Click **Edit** to open the priority configuration drawer
### Option 1: Set a static priority
If all alerts from this source should have the same priority:
1. Select **A static value**
2. Choose the priority level (e.g. P1, P2, P3)
3. Click **Apply**
This is useful when you know that every alert from a particular source is always the same urgency — for example, a source that only fires for critical production outages.
### Option 2: Set a dynamic priority based on the alert payload
If alerts from this source should have different priorities depending on what's in the payload:
1. Select **A dynamic value**
2. Use an **expression** to derive the priority from the incoming alert payload
For example, you might:
* Map a Datadog monitor's `priority` tag to an incident.io priority
* Use the `severity` field from a Prometheus Alertmanager payload
* Check whether the alert's `environment` label is `production` (P1) or `staging` (P3)
Expressions allow you to inspect any field in the incoming alert payload and map it to one of your configured alert priorities. You can use the **alert preview** on the right-hand side of the configuration page to see real payloads and test your expressions.
## Managing alert priorities
You can manage which priorities are available across your organization from the alert source configuration page:
1. In the priority configuration drawer, click **Manage priorities**
2. Add, rename, re-order, or remove priorities as needed
Priorities are shared across all alert sources and escalation paths, so changes here will be reflected everywhere.
### Putting it all together
Here is a typical setup:
1. **Alert source**: Incoming Datadog alerts have their priority set dynamically based on the monitor's priority tag
2. **Alert route**: Routes alerts to the appropriate escalation path based on the affected service
3. **Escalation path**: Branches on priority — P1 alerts page the on-call engineer immediately, P2 alerts wait 5 minutes, P3 alerts wait until working hours
# Routing private alerts to escalate and create incidents
Source: https://docs.incident.io/alerts/private-incidents
Private alerts and escalations allow you to restrict visibility of sensitive information to specific teams or individuals. When you create private alerts, any escalations and incidents created from them will also be private.
## Setting up private alerts and escalations
Go to [Settings > Alerts](https://app.incident.io/~/settings/alerts) and create a new alert source and follow its setup instructions - note that it isn't yet private, so be considerate with what you send in any test events.
In the "Configure" step, under "Alert privacy", select "Private" and choose which teams can view alerts from this source. The alert source itself remains visible to everyone—only the alerts created from it are restricted.
To configure automatic private escalation and incident creation from these alerts, continue on to creating a private alert route.
Note that if you escalate these alerts, anyone who's escalated to will also be able to see the alert that paged them.
Similarly, if you create private incidents from these alerts, anybody who you invite to that incident will also be able to see its related alerts.
## Create a private alert route
In [Settings > Alerts](https://app.incident.io/~/settings/alerts), create a route that references your private alert source and configure the escalation path as normal. Private alert sources can only have a single alert route. You can group alerts from a private route — see [Private alerts](/alerts/grouping-alerts#private-alerts) for how visibility works for private alert groups.
When an alert is sent to your private source, the alert will be private, and any escalations and incidents created from it will also be private. You cannot mix public and private visibility in this chain.
Note that any users who are paged as a result of these escalations will be given full access to view the alert and the escalation. If your escalation path is configured to notify a Slack channel, notifications to private Slack channels are delivered normally, but public channel notifications will be skipped (and we'll indicate this on the timeline) to avoid leaking private information. Microsoft Teams channel notifications are not currently supported for private alerts.
Previously, you could configure alert routes to create private incidents while the alerts themselves remained public. With the new private alerts feature, the entire chain (alert, escalation, and incident) must have the same visibility.
If you have existing alert routes configured to create private incidents but using public alert sources, you can edit your source to make it private. If you've got many sources connected to a single private route, you'll need to split them out 1-1 with a route to make them fully private.
## Understanding access to private resources
Access to private alerts, escalations, and incidents follows specific rules detailed below.
### Alerts
**You can view a private alert if:**
* You're an organization owner (or you have the "private alerts view" global scope)
* You're a member of one of the teams configured in the alert source's "visible to teams" setting
* You were paged via a private escalation that was triggered by the alert
* You're a member of a private incident that was created by the alert
**You cannot view a private alert if:**
* The alert created an escalation that paged an escalation path, but you weren't personally paged
* You were invited to the incident created from the alert and then removed (and you're not in a configured team or weren't paged)
### Escalations
**You can view a private escalation if:**
* You created the escalation
* You were paged as part of the escalation
* You're a member of a private incident that the escalation is related to
**You cannot view a private escalation if:**
* Your team can see the alert that created it, but you weren't personally paged or invited to the incident
* You were invited to the incident and then removed (and you didn't create the escalation or weren't paged)
### Incidents
**You can view a private incident if:**
* You were invited to it manually
* It was created by an alert, and you were paged by an escalation that was also created from that alert
* A workflow that was opted into running on private incidents automatically invited you to it
**You cannot view a private incident if:**
* It was created by an alert you can see—being able to see the alert doesn't automatically grant access to the incident
### Other notes
* Team membership determines alert access: If you're removed from a team, you'll lose access to alerts only visible to that team (unless you have proxy access through being paged or being in the incident).
* Insights: certain on-call dashboards (currently Alerts and Pager load) can include private alerts and escalations, but only for people who can already see every incident, alert, and escalation across your organization. This requires the "Manage private incidents", "Manage private alerts", and "Manage private escalations" permissions.
# Why are my Prometheus Alertmanager alerts not appearing in incident.io?
Source: https://docs.incident.io/alerts/prometheus-issues
## Context
When using Prometheus Alertmanager to send alerts to incident.io, you might notice that some alerts don't appear as expected in the incident.io interface. This typically happens due to how Alertmanager groups alerts and how incident.io processes these grouped alerts.
## Answer
The behavior you're seeing is related to how Prometheus Alertmanager groups alerts and how incident.io processes these grouped alerts. Here's what you need to know:
## How Alertmanager Grouping Works
Alertmanager groups alerts based on the `group_by` labels specified in your route configuration. When multiple alerts share the same group labels, they're combined into a single notification. For example:
```yaml theme={null}
route:
group_by:
- job
group_interval: 1m
group_wait: 30s
receiver: incident.io
```
## How incident.io Processes Grouped Alerts
When incident.io receives grouped alerts from Alertmanager:
* Multiple alerts within the same group are treated as a single alert in incident.io
* Subsequent alerts with the same group key will be deduplicated while the original alert is still firing
* A new alert will only be created once the previous alert with the same group key has been resolved
## Solutions
To ensure alerts appear as expected in incident.io, you can:
1. Adjust your `group_by` labels in the Alertmanager configuration to create more granular groupings
2. Wait for existing alerts to resolve before expecting new alerts with the same group key to appear
3. If you need individual alerts instead of grouped alerts, you can consider using the Grafana alert source instead of Alertmanager, as it handles grouped alerts differently.
Note: If you need to track individual alerts rather than grouped alerts, the Grafana alert source might be more suitable as it creates independent alerts from grouped alerts.
# Why am I not receiving subsequent Sentry alert notifications?
Source: https://docs.incident.io/alerts/sentry-dedup
## Context
When configuring Sentry as an alert source, you may notice that while the initial test notification is received successfully, subsequent alert notifications appear not to come through, even though they are being sent from Sentry's side.
## Answer
This issue is most commonly seen when first setting up and testing the Sentry alert source.
If you're not receiving subsequent Sentry alerts, this is likely due to an existing alert still in a firing state that is using the same deduplication key. Here's how it works:
* We use the `issue_id` as a deduplication key for Sentry alerts
* If multiple active alerts are triggered for the same `issue_id`, only the first alert will be shown
* The duplicate alerts will be automatically deduplicated to prevent alert fatigue
* A new alert will only be created when:
* A different `issue_id` is received
* The previous alert with the same `issue_id` has been resolved
To verify if you're receiving alerts correctly, test with a new alert that has a different `issue_id` than any currently active alerts.
# How do I map alert severities to incident.io alert priorities?
Source: https://docs.incident.io/alerts/severity-mapping
When integrating external alerting systems (like Alertmanager, Grafana, or other monitoring tools) with incident.io, you may need to map incoming alert severities to incident.io alert priorities. For example, you might want alerts marked as "critical" or "error" to automatically map to your P1 priority in incident.io.
You can map external alert severities to incident.io priorities using priority aliases. This allows you to match incoming severity values without modifying the alert payload or writing complex parsing logic.
To set up priority aliases:
1. Navigate to your Alert Configuration page
2. Click on the gear (settings) icon - this should take you [here](https://app.incident.io/~/alerts/configuration/priorities)
3. Click edit on the priority you want to add aliases for
For example, you could set up the following aliases:
* For P1/Urgent priority: add aliases like "critical", "error", "p1", "urgent"
* For P2 priority: add aliases like "high", "p2", "major"
* For P3 priority: add aliases like "medium", "p3", "warning"
Once aliases are configured, incident.io will automatically match the incoming severity value from your alert payload to the appropriate priority. The severity value should be passed in your alert payload (commonly found in fields like "\$.labels.severity" or similar JSON paths).
Note: Priority matching is case-sensitive. Make sure your aliases match the exact case of your incoming alert severities. For example, if your alerts use "High", you'll need "High" as an alias, not just "high".
# Sending alerts to Slack channels
Source: https://docs.incident.io/alerts/slack-channels
You can now use alert routes to send all, or some, of your alerts coming into incident.io into Slack channels. You might want to do this if:
* You want to increase awareness about what alerts are coming through to incident.io
* You want a space directly in Slack to take actions from your alerts
* You want to declare incidents manually from alerts, rather than automatically
## Enabling sending alerts to Slack
You can choose to enable sending alerts to Slack from an alert route. Once enabled, you'll be able to select private or public channels to send your alerts to.
## Filtering the alerts you send to Slack
If you only want to send a subset of your alerts to Slack, you can add filter conditions when you configure the Slack channels.
## Sending alerts to a different channel according to the alert
Using expressions and the Catalog, you can choose to send alerts to different Slack channels according to alert attributes.
For example, if you have a `Team` alert attribute, and your `Team` has a `Slack Channel` attribute, you'll be able to dynamically pick where to send your alerts:
You can read more about configuring alert attributes [here](/on-call/catalog-integration)
## Taking actions from the alert
From an alert in Slack, you’ll be able to:
* Declare an incident, or join one if it already exists
* Go to the alert’s source - this could be a Grafana dashboard, an external issue, or a custom URL
* Silence an alert, for alert sources that support it
* Resolve an alert
* Go to the alert in the [incident.io](http://incident.io/) dashboard, and view more from there!
If your alert route is set to create private incidents, incidents declared from an alert in Slack will be created as private. The person declaring the incident will be automatically invited.
# Adding SolarWinds AppOptics as an alert source
Source: https://docs.incident.io/alerts/solarwinds
This article provides step by step instructions for setting up SolarWinds AppOptics as an alert source within incident.io.
## Instructions
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the sources tab at the top of the page
3. Press the 'New alert source' button
4. Search for 'AppOptics' and click continue to create the alert source
5. Head over to the AppOptics dashboard, and navigate to *Settings* → *Metric Settings* → *Notification Services*
6. Click on *Webhooks* to add a configuration
7. Enter a name for your webhook, and the URL provided from your incident.io dashboard, and click *Add*.
7. Now, you can configure your alerts to be sent to incident.io, by navigating to the *Notifications* tab on any alert you want to connect, and enabling the notification service you just created.
8. Finally, you can test the connection by clicking *Test Fire* on the right hand side of the page.
# Alerts and teams
Source: https://docs.incident.io/alerts/team-routing
Route alerts to the right team, and control who can act on them
Now that you have [Alerts sources](https://app.incident.io/~/alerts/sources) set up, and have [extracted all your desired data](/alerts/json-alert-data) from the Alert JSON payload, such as Team, Status, etc. We can use this data to:
1. Set catalog-backed custom fields
2. Escalate to a team's escalation path
3. Announce to the team's Slack channel and so much more
In this article, we'll focus on escalating to the responsible team so that only the team responsible for a certain area will be notified, ensuring that the right people are involved from the beginning of an incident.
## Setting the right attribute resource type
Before we can set these attributes, let's take a closer look at the "Team" Attribute. The return type of this attribute should be "Team" [Catalog](/catalog/catalog-setup) type, this is what will allow us to navigate to different attributes such as escalation path, Slack channels, and more.
## Escalating to the right escalation path
In the [Alert route](https://app.incident.io/~/alerts/routes), you can use these attributes to set values of custom fields, for example, by setting the "Responsible Team" custom field.
Furthermore, you can use the value that was set by this attribute to navigate to this team's escalation path, by taking advantage of the Catalog mapping.
Using the "Account" value that was extracted from the alert source, we can set this value in the custom field by using the catalog entry alias.
That's It!! You have now successfully set a custom field and escalated to the right Team's escalations path by extracting a data point from your alerts payload, setting it to the Team's custom field, and navigating to their escalation path
This will only work if your Catalog type has aliases set for each of their entries.
## Owning teams and permissions
By default, anyone in your organization can resolve any alert and acknowledge, snooze, or cancel any escalation. For most teams that's exactly what you want. But if you're a larger organization, you might prefer to keep those actions within the team that's responsible for an alert, so an engineer in one team can't accidentally resolve a page that belongs to another.
You can do this with **team-based permissions**. The permission that controls these actions is **Take actions on alerts and escalations**. It covers resolving alerts, and acknowledging, snoozing, and cancelling escalations. By default it's granted to everyone, but you can instead grant it to specific [team roles](/admin/team-roles), so that it only applies to the alerts and escalations a team owns.
When it's granted at the team level, the team that "owns" an alert is determined by its **Team attribute**, the same attribute you set up above for routing. The work you've already done to tag alerts with a team does double duty: it routes the alert *and* decides who's allowed to act on it.
If an alert has no Team attribute (or the source doesn't extract one), it has no owning team. When this permission is granted at the team level, only people who still have it granted globally will be able to act on those alerts.
### Who can resolve an alert?
When the permission is granted at the team level rather than globally, you can resolve an alert if either of the following is true:
* You have the permission granted globally (for example, an admin)
* You're a member of a team that owns the alert, with the permission granted to that team
Alerts are still auto-resolved as normal, regardless of who triggers it.
### Who can act on an escalation?
By default, anyone who can see an escalation can acknowlege, snooze, or cancel it. If you've configured team-level permissions, then any of the following grant you permission to act on an escalation:
* You have the permission granted globally (for example as an account-level admin)
* You're a member of a team that owns the alert the escalation came from, with the permission granted to that team
* You're a member of the team that owns the escalation path the escalation was sent to, with the permission granted to that team
* **You were paged by the escalation**: anyone notified can always acknowledge or snooze it, even if they're not on the owning team. This protects you from a misrouted alert paging someone who then can't make it stop.
For how to set this up, see [Restrict escalation response to a team](/admin/restrict-escalation-response).
# Adding Uptime.com as an alert source
Source: https://docs.incident.io/alerts/uptime
## Instructions
To open the alert source creation form directly, simply follow [this link](https://app.incident.io/~/alerts/sources/create), and skip to step 4.
1. Head over to the [Alerts](https://app.incident.io/~/alerts/sources) section in your incident.io dashboard
2. Select the Sources tab at the top of the page
3. Press the 'New alert source' button
4. Search for 'Uptime', select it and customize the name if desired. Click continue to create the alert source.
5. Switch to your Uptime.com dashboard and navigate to Notifications: Integrations.
6. Click 'New Profile' in the top right, and select 'Custom Postback URL (Webhook)' as the provider type.
7. Assign the integration to an existing Uptime.com contact or create a new contact for the integration.
8. Grab the webhook URL and Authorization token provided to you on the incident.io alert source and paste them in to 'URL' and 'Custom HTTP Headers' field.
9. Once you've clicked save, Uptime will prompt you to test the integration. Click 'Start Test' and make sure the test alert arrives.
10. Navigate to 'Monitoring' to select the Uptime.com check(s) for which you want to receive alerts in incident.io and assign them to the contact you've assigned the Integration Profile to.
And you're done! Next time an Uptime.com monitoring check fails, you'll receive an alert within incident.io.
## FAQs
When an Uptime.com monitoring check starts firing, you'll receive an alert in incident.io. If you receive additional failing checks from the monitor, these will be deduplicated in incident.io to limit alert noise.
**Uptime.com** ' `test` ' and ' `alert_raised` ' events map to the incident.io ' `firing` ' status. ' `alert_cleared` ' events map to the incident.io ' `resolved` ' status.
# Why aren't my Grafana alerts appearing within incident.io?
Source: https://docs.incident.io/alerts/why-isn-t-my-grafana-test-alert-triggering-multiple-times
## Context
When using Grafana to send alerts to incident.io, you might notice that some alerts don't appear as expected in the incident.io interface. This typically happens due to deduplication logic within incident.io.
## Answer
This behavior is most commonly seen when sending test alerts from Grafana to [incident.io](http://incident.io/) and it happens because Grafana uses the same 'fingerprint' for each test alert, and incident.io uses this fingerprint as the deduplication key for Grafana alerts. To send multiple test alerts successfully, you'll need to resolve the existing alert first within incident.io.
To test multiple Grafana alerts:
1. Navigate to the alert details page in incident.io
2. Click the resolve button in the top right corner of the alert page
3. Send a new test alert from Grafana
Note: In a production environment with real Grafana alerts, this manual resolution isn't necessary. Grafana automatically sends a 'resolve' notification which will clear the alert in incident.io, allowing subsequent alerts with the same fingerprint to trigger normally.
# Created private
Source: https://docs.incident.io/api-reference/action-v1/created-private
/openapi/webhooks.json webhook private_incident.action_created_v1
This webhook is emitted whenever a follow-up for a private incident is created.
# Created public
Source: https://docs.incident.io/api-reference/action-v1/created-public
/openapi/webhooks.json webhook public_incident.action_created_v1
This webhook is emitted whenever a follow-up is created.
# Updated private
Source: https://docs.incident.io/api-reference/action-v1/updated-private
/openapi/webhooks.json webhook private_incident.action_updated_v1
This webhook is emitted whenever a follow-up for a private incident is updated.
# Updated public
Source: https://docs.incident.io/api-reference/action-v1/updated-public
/openapi/webhooks.json webhook public_incident.action_updated_v1
This webhook is emitted whenever a follow-up is updated.
# List
Source: https://docs.incident.io/api-reference/actions-v1/list
/openapi/deprecated-endpoints.json get /v1/actions
List all actions for an organisation.
🔑 Requires the `actions.view` scope.
# Show
Source: https://docs.incident.io/api-reference/actions-v1/show
/openapi/deprecated-endpoints.json get /v1/actions/{id}
Get a single incident action.
🔑 Requires the `actions.view` scope.
# Actions
Source: https://docs.incident.io/api-reference/actions-v2
API endpoints for actions
Manage incident actions.
Incident actions are used during an incident, to track work such as 'restart the database' or 'contact the customer'.
You can manage actions in the incident Slack channel with /incident actions, or on
the incident homepage.
## The action object
# Create
Source: https://docs.incident.io/api-reference/actions-v2/create
/openapi/tags/actions-v2.json post /v2/actions
Create a new incident action.
🔑 Requires the `actions.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/actions-v2/delete
/openapi/tags/actions-v2.json delete /v2/actions/{id}
Delete an incident action.
🔑 Requires the `actions.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/actions-v2/list
/openapi/tags/actions-v2.json get /v2/actions
List all actions for an organisation.
🔑 Requires the `actions.view` scope.
# Show
Source: https://docs.incident.io/api-reference/actions-v2/show
/openapi/tags/actions-v2.json get /v2/actions/{id}
Get a single incident action.
🔑 Requires the `actions.view` scope.
# Update
Source: https://docs.incident.io/api-reference/actions-v2/update
/openapi/tags/actions-v2.json put /v2/actions/{id}
Update an existing incident action.
🔑 Requires the `actions.update` scope.
# Scrubbed v1
Source: https://docs.incident.io/api-reference/activity-log/scrubbed-v1
/openapi/audit-logs.json webhook activity_log.scrubbed.1
This entry is created whenever an activity log entry is permanently erased
# Alert Attributes
Source: https://docs.incident.io/api-reference/alert-attributes-v2
API endpoints for alert attributes
View and manage alert attributes.
Alert attributes are used to parse structured data from alerts coming in via alert sources.
## The alert attribute object
# Create
Source: https://docs.incident.io/api-reference/alert-attributes-v2/create
/openapi/tags/alert-attributes-v2.json post /v2/alert_attributes
Create a new alert attribute.
🔑 Requires the `alert_schema.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/alert-attributes-v2/delete
/openapi/tags/alert-attributes-v2.json delete /v2/alert_attributes/{id}
Destroy an alert attribute.
🔑 Requires the `alert_schema.update` scope.
# List
Source: https://docs.incident.io/api-reference/alert-attributes-v2/list
/openapi/tags/alert-attributes-v2.json get /v2/alert_attributes
List alert attributes.
🔑 Requires the `alert_schema.view` scope.
# Show
Source: https://docs.incident.io/api-reference/alert-attributes-v2/show
/openapi/tags/alert-attributes-v2.json get /v2/alert_attributes/{id}
Show an alert attribute.
🔑 Requires the `alert_schema.view` scope.
# Update
Source: https://docs.incident.io/api-reference/alert-attributes-v2/update
/openapi/tags/alert-attributes-v2.json put /v2/alert_attributes/{id}
Update an alert attribute.
🔑 Requires the `alert_schema.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/alert-chat-message-template/created-v1
/openapi/audit-logs.json webhook alert_chat_message_template.created.1
This entry is created whenever an alert chat message template is created
# Deleted v1
Source: https://docs.incident.io/api-reference/alert-chat-message-template/deleted-v1
/openapi/audit-logs.json webhook alert_chat_message_template.deleted.1
This entry is created whenever an alert chat message template is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/alert-chat-message-template/updated-v1
/openapi/audit-logs.json webhook alert_chat_message_template.updated.1
This entry is created whenever an alert chat message template is updated
# Alert Events
Source: https://docs.incident.io/api-reference/alert-events-v2
API endpoints for alert events
Create alerts within incident.io.
The alerts API allows you to create alerts within incident.io by posting alert events. You
can use alerts to automatically trigger incidents.
To create an alert, you must first configure an alert source in the incident.io dashboard.
# Create
Source: https://docs.incident.io/api-reference/alert-events-v2/create
/openapi/tags/alert-events-v2.json post /v2/alert_events/http/{alert_source_config_id}
Create an alert event using an HTTP source.
# Alert Notes
Source: https://docs.incident.io/api-reference/alert-notes-v1
API endpoints for alert notes
Manage notes attached to alerts.
Notes let your team capture context, decisions, and investigation findings against
an individual alert without needing to declare an incident.
Note content is stored and returned as Markdown. The following formatting is
supported:
* **Headings** (`#`, `##`, `###`)
* **Bold** and *italic* text formatting
* ~~Strikethrough~~ text
* Inline `code` and fenced code blocks
* Bullet lists and numbered lists
* Blockquotes
* [Links](url) using Markdown link syntax — bare URLs are not auto-linked
* Tables (GitHub-flavoured Markdown)
* Horizontal rules (`---`)
Raw HTML, image syntax (``), task lists, and footnotes are not
supported, and will be stripped or rendered as plain text.
## The alert note object
# Create
Source: https://docs.incident.io/api-reference/alert-notes-v1/create
/openapi/tags/alert-notes-v1.json post /v1/alert_notes
Add a note to an alert.
🔑 Requires the `alerts.edit` scope.
# Delete
Source: https://docs.incident.io/api-reference/alert-notes-v1/delete
/openapi/tags/alert-notes-v1.json delete /v1/alert_notes/{id}
Delete an alert note.
🔑 Requires the `alerts.edit` scope.
# List
Source: https://docs.incident.io/api-reference/alert-notes-v1/list
/openapi/tags/alert-notes-v1.json get /v1/alert_notes
List alert notes attached to an alert.
🔑 Requires the `alerts.view` scope.
# Show
Source: https://docs.incident.io/api-reference/alert-notes-v1/show
/openapi/tags/alert-notes-v1.json get /v1/alert_notes/{id}
Get a single alert note.
🔑 Requires the `alerts.view` scope.
# Update
Source: https://docs.incident.io/api-reference/alert-notes-v1/update
/openapi/tags/alert-notes-v1.json put /v1/alert_notes/{id}
Replace the content of an alert note.
🔑 Requires the `alerts.edit` scope.
# Created v1
Source: https://docs.incident.io/api-reference/alert-priority/created-v1
/openapi/audit-logs.json webhook alert_priority.created.1
This entry is created whenever an alert priority is created
# Deleted v1
Source: https://docs.incident.io/api-reference/alert-priority/deleted-v1
/openapi/audit-logs.json webhook alert_priority.deleted.1
This entry is created whenever an alert priority is deleted
# Set as default v1
Source: https://docs.incident.io/api-reference/alert-priority/set-as-default-v1
/openapi/audit-logs.json webhook alert_priority.set_as_default.1
This entry is created whenever an alert priority is set as the default
# Updated v1
Source: https://docs.incident.io/api-reference/alert-priority/updated-v1
/openapi/audit-logs.json webhook alert_priority.updated.1
This entry is created whenever an alert priority is updated
# Created v1
Source: https://docs.incident.io/api-reference/alert-route/created-v1
/openapi/audit-logs.json webhook alert_route.created.1
This entry is created whenever an alert route is created
# Deleted v1
Source: https://docs.incident.io/api-reference/alert-route/deleted-v1
/openapi/audit-logs.json webhook alert_route.deleted.1
This entry is created whenever an alert route is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/alert-route/updated-v1
/openapi/audit-logs.json webhook alert_route.updated.1
This entry is created whenever an alert route is updated
# Create
Source: https://docs.incident.io/api-reference/alert-routes-v2/create
/openapi/deprecated-endpoints.json post /v2/alert_routes
Create a new alert route in your account.
🔑 Requires the `alert_route.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/alert-routes-v2/delete
/openapi/deprecated-endpoints.json delete /v2/alert_routes/{id}
Delete an existing alert route in your account.
🔑 Requires the `alert_route.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/alert-routes-v2/list
/openapi/deprecated-endpoints.json get /v2/alert_routes
List all alert routes in your account.
🔑 Requires the `alert_routes.view` scope.
# Show
Source: https://docs.incident.io/api-reference/alert-routes-v2/show
/openapi/deprecated-endpoints.json get /v2/alert_routes/{id}
Load details about a specific alert route in your account.
🔑 Requires the `alert_routes.view` scope.
# Update
Source: https://docs.incident.io/api-reference/alert-routes-v2/update
/openapi/deprecated-endpoints.json put /v2/alert_routes/{id}
Update an existing alert route in your account.
🔑 Requires the `alert_route.update` scope.
# Alert Routes
Source: https://docs.incident.io/api-reference/alert-routes-v3
API endpoints for alert routes
Configure your alert routes in incident.io.
Alert routes define how alerts from different sources are processed, grouped, and routed to the right teams and people.
## The alert route object
# Create
Source: https://docs.incident.io/api-reference/alert-routes-v3/create
/openapi/tags/alert-routes-v3.json post /v3/alert_routes
Create a new alert route in your account.
🔑 Requires the `alert_route.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/alert-routes-v3/delete
/openapi/tags/alert-routes-v3.json delete /v3/alert_routes/{id}
Delete an existing alert route in your account.
🔑 Requires the `alert_route.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/alert-routes-v3/list
/openapi/tags/alert-routes-v3.json get /v3/alert_routes
List all alert routes in your account.
🔑 Requires the `alert_routes.view` scope.
# Show
Source: https://docs.incident.io/api-reference/alert-routes-v3/show
/openapi/tags/alert-routes-v3.json get /v3/alert_routes/{id}
Load details about a specific alert route in your account.
🔑 Requires the `alert_routes.view` scope.
# Update
Source: https://docs.incident.io/api-reference/alert-routes-v3/update
/openapi/tags/alert-routes-v3.json put /v3/alert_routes/{id}
Update an existing alert route in your account.
🔑 Requires the `alert_route.update` scope.
# Updated v1
Source: https://docs.incident.io/api-reference/alert-schema/updated-v1
/openapi/audit-logs.json webhook alert_schema.updated.1
This entry is created whenever alert attributes are updated
# Alert Source Attributes
Source: https://docs.incident.io/api-reference/alert-source-attributes-v3
API endpoints for alert source attributes
# Validate
Source: https://docs.incident.io/api-reference/alert-source-attributes-v3/validate
/openapi/tags/alert-source-attributes-v3.json post /v3/alert_sources/{alert_source_id}/attributes/actions/validate
Check whether a binding would be accepted on this alert source, without writing it.
The binding is validated in the source as it stands today: merge strategy against the attribute's
type, values and expressions against the scope the source's type provides, and references against
your alert schema and catalog. Whether the attribute is already bound makes no difference, so the
same request answers for a new binding and a change to an existing one.
An expression this binding references has to already exist on the source, or be sent with the
binding. One you have yet to write is rejected.
🔑 Requires the `alert_sources.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/alert-source-config/created-v1
/openapi/audit-logs.json webhook alert_source_config.created.1
This entry is created whenever an alert source is created
# Deleted v1
Source: https://docs.incident.io/api-reference/alert-source-config/deleted-v1
/openapi/audit-logs.json webhook alert_source_config.deleted.1
This entry is created whenever an alert source is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/alert-source-config/updated-v1
/openapi/audit-logs.json webhook alert_source_config.updated.1
This entry is created whenever an alert source is updated
# Alert Sources
Source: https://docs.incident.io/api-reference/alert-sources-v2
API endpoints for alert sources
Configure your alert sources in incident.io.
Alert sources are the systems that send alerts to incident.io, which can then be routed to the right people and teams.
## The alert source object
# Create
Source: https://docs.incident.io/api-reference/alert-sources-v2/create
/openapi/tags/alert-sources-v2.json post /v2/alert_sources
Create a new alert source in your account.
🔑 Requires the `alert_source.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/alert-sources-v2/delete
/openapi/tags/alert-sources-v2.json delete /v2/alert_sources/{id}
Delete an existing alert source in your account.
🔑 Requires the `alert_source.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/alert-sources-v2/list
/openapi/tags/alert-sources-v2.json get /v2/alert_sources
List all alert sources in your account.
🔑 Requires the `alert_sources.view` scope.
# Show
Source: https://docs.incident.io/api-reference/alert-sources-v2/show
/openapi/tags/alert-sources-v2.json get /v2/alert_sources/{id}
Load details about a specific alert source in your account.
🔑 Requires the `alert_sources.view` scope.
# Update
Source: https://docs.incident.io/api-reference/alert-sources-v2/update
/openapi/tags/alert-sources-v2.json put /v2/alert_sources/{id}
Update an existing alert source in your account.
🔑 Requires the `alert_source.update` scope.
# Validate
Source: https://docs.incident.io/api-reference/alert-sources-v2/validate
/openapi/tags/alert-sources-v2.json post /v2/alert_sources/actions/validate
Check whether an alert source template is valid, without creating or updating anything.
This validates the template in the same way a create or update would: expressions are
compiled and checked against your alert schema and catalog, and merge strategies are checked
against the attributes they bind to. Values that are only known once an alert source exists
are not validated.
🔑 Requires the `alert_sources.view` scope.
# Created private
Source: https://docs.incident.io/api-reference/alert-v1/created-private
/openapi/webhooks.json webhook private_alert.alert_created_v1
This webhook is emitted whenever a new private alert is created.
# Created public
Source: https://docs.incident.io/api-reference/alert-v1/created-public
/openapi/webhooks.json webhook public_alert.alert_created_v1
This webhook is emitted whenever a new alert is created.
# Resolved private
Source: https://docs.incident.io/api-reference/alert-v1/resolved-private
/openapi/webhooks.json webhook private_alert.alert_resolved_v1
This webhook is emitted whenever a private alert is resolved.
# Resolved public
Source: https://docs.incident.io/api-reference/alert-v1/resolved-public
/openapi/webhooks.json webhook public_alert.alert_resolved_v1
This webhook is emitted whenever an alert is resolved.
# Scrubbed v1
Source: https://docs.incident.io/api-reference/alert/scrubbed-v1
/openapi/audit-logs.json webhook alert.scrubbed.1
This entry is created whenever sensitive data is permanently erased from an alert, its events, and linked escalations.
# Alerts
Source: https://docs.incident.io/api-reference/alerts-v2
API endpoints for alerts
Read your alerts in incident.io.
Alerts are events ingested from third parties by alert sources. They can trigger incidents and escalations, as configured in alert routes.
To view your alerts, you can list all alerts, or show a single alert.
If you'd like to view only alerts that are currently firing, you can filter by status.
To view the alert that was created for an event in your external system, filter by deduplication key.
If you'd like to view alerts connected to a particular incident, you can list incident alerts. You can filter by incident\_id to find all alerts attached to a particular incident, or by alert\_id to find the incident that a particular alert triggered.
## The alert object
# List
Source: https://docs.incident.io/api-reference/alerts-v2/list
openapi/tags/alerts-v2.json GET /v2/alerts
List all alerts for your account.
```bash
```
This endpoint supports a number of filters, which can help find alerts matching certain
criteria. These filters work similarly to the filters on the incidents endpoint, where
a field is specified alongside a comparison operator in the query string.
Note that:
- Filters may be used together, and the result will be alerts that match all filters.
- All query parameters must be URI encoded.
### By deduplication_key
Find all alerts with deduplication_key ABC:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'deduplication_key[is]=ABC'
```
### By status
Find all alerts in a firing state:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'status[one_of]=firing'
```
### By alert_source
Find all alerts from a specific alert source (by alert source ID):
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'alert_source[one_of]=01GBSQF3FHF7FWZQNWGHAVQ804'
```
Find all alerts not from a specific alert source:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'alert_source[not_in]=01GBSQF3FHF7FWZQNWGHAVQ804'
```
### By alert_group_id
Find all alerts in a specific alert group:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'alert_group_id[one_of]=01GBSQF3FHF7FWZQNWGHAVQ804'
```
### By created_at
Find all alerts that follow specified date parameters for created_at field.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date_range" (between two dates). The following example finds all alerts created after
2025-01-01:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'created_at[gte]=2025-01-01'
```
To find alerts created within a specific date range, use the date_range option with
tilde-separated dates:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'created_at[date_range]=2024-12-02~2024-12-08'
```
### By has_notes
Find all alerts that have notes attached:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'has_notes[is]=true'
```
Find all alerts that have no notes attached:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'has_notes[is]=false'
```
### By attributes
Alerts can be filtered by their attribute values. Each filter is keyed by the alert
attribute ID, followed by an operator and the values to match. The accepted operators
depend on the attribute's type.
Find all alerts where attribute 01GBSQF3FHF7FWZQNWGHAVQ804 is one of two catalog entries:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'attributes[01GBSQF3FHF7FWZQNWGHAVQ804][one_of]=01GBSQF3FHF7FWZQNWGHAVQ804' \
--data 'attributes[01GBSQF3FHF7FWZQNWGHAVQ804][one_of]=01ET65M7ZARSFZ6TFDFVQDN9AA'
```
You can filter on multiple attributes at once, and the result will be alerts that match
all of them.
### Maintenance windows
By default, all alerts are returned including those held by a maintenance window.
To exclude alerts that are held by a maintenance window:
```bash
curl --get 'https://api.incident.io/v2/alerts' \
--data 'include_maintenance_window[is]=false'
```
List all alerts for your account.
This endpoint supports a number of filters, which can help find alerts matching certain
criteria. These filters work similarly to the filters on the incidents endpoint, where
a field is specified alongside a comparison operator in the query string.
Note that:
* Filters may be used together, and the result will be alerts that match all filters.
* All query parameters must be URI encoded.
### By deduplication\_key
Find all alerts with deduplication\_key ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'deduplication_key[is]=ABC'
```
### By status
Find all alerts in a firing state:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'status[one_of]=firing'
```
### By alert\_source
Find all alerts from a specific alert source (by alert source ID):
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'alert_source[one_of]=01GBSQF3FHF7FWZQNWGHAVQ804'
```
Find all alerts not from a specific alert source:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'alert_source[not_in]=01GBSQF3FHF7FWZQNWGHAVQ804'
```
### By created\_at
Find all alerts that follow specified date parameters for created\_at field.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date\_range" (between two dates). The following example finds all alerts created after
2025-01-01:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'created_at[gte]=2025-01-01'
```
To find alerts created within a specific date range, use the date\_range option with
tilde-separated dates:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'created_at[date_range]=2024-12-02~2024-12-08'
```
### Maintenance windows
By default, all alerts are returned including those held by a maintenance window.
To exclude alerts that are held by a maintenance window:
```bash theme={null}
curl --get 'https://api.incident.io/v2/alerts' \
--data 'include_maintenance_window[is]=false'
```
### Pagination
The list endpoint is paginated. Every response includes a `pagination_meta` object, and
the field that drives paging is `after`:
* `page_size` — the maximum number of results in this page (defaults to 25, up to 250).
* `after` — the cursor for the next page. **If `after` is present there are more results
to fetch; if it's absent, you've reached the end.**
To page through every result, repeat the request with all filters unchanged and pass the
previous response's `after` value as the `after` parameter. Using the largest `page_size`
(250) minimises the number of requests:
```bash theme={null}
# First page
curl --get 'https://api.incident.io/v2/alerts' \
--data 'status[one_of]=firing' \
--data 'page_size=250'
# Next page: pass the `after` cursor returned in the previous response's pagination_meta
curl --get 'https://api.incident.io/v2/alerts' \
--data 'status[one_of]=firing' \
--data 'page_size=250' \
--data 'after=01FCNDV6P870EA6S7TK1DSYDG0'
```
Keep repeating until the response no longer contains an `after` cursor.
**An empty `alerts` array does not mean there are no matching alerts.**
When filters are applied, an individual page can return an empty `alerts` array while
`pagination_meta.after` is still present. That means "no matches on this page yet, but
there are more results to scan" — it does **not** mean there are no alerts.
Always keep requesting pages until `after` is absent. Stopping at the first empty page
will cause you to miss alerts. Note that `total_record_count` is not returned for this
endpoint, so the presence of `after` is the only signal that more results remain.
# Resolve
Source: https://docs.incident.io/api-reference/alerts-v2/resolve
/openapi/tags/alerts-v2.json post /v2/alerts/{id}/actions/resolve
Resolve a currently firing alert.
This marks the alert as resolved with the current time, attributing the resolution to the API key that made the request. Resolving an already-resolved alert is a no-op and returns the alert unchanged.
Some alert sources are 'externally resolved' (for example, Datadog) — those alerts can only be resolved by the third-party system itself, and this endpoint will return a 422 explaining that.
Private alerts: an API key without the 'view all alerts' scope can only resolve non-private alerts; private alerts will return a 404. Grant the API key a role that includes the global alerts access scope to resolve private alerts.
🔑 Requires the `alerts.resolve` scope.
# Show
Source: https://docs.incident.io/api-reference/alerts-v2/show
/openapi/tags/alerts-v2.json get /v2/alerts/{id}
Show a single alert for your account
🔑 Requires the `alerts.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/announcement-post-template/created-v1
/openapi/audit-logs.json webhook announcement_post_template.created.1
This entry is created whenever an announcement post template is created
# Created v2
Source: https://docs.incident.io/api-reference/announcement-post-template/created-v2
/openapi/audit-logs.json webhook announcement_post_template.created.2
This entry is created whenever an announcement post template is created
# Deleted v1
Source: https://docs.incident.io/api-reference/announcement-post-template/deleted-v1
/openapi/audit-logs.json webhook announcement_post_template.deleted.1
This entry is created whenever an announcement post template is deleted
# Set as default v1
Source: https://docs.incident.io/api-reference/announcement-post-template/set-as-default-v1
/openapi/audit-logs.json webhook announcement_post_template.set_as_default.1
This entry is created whenever an announcement post template is set as the default
# Updated v1
Source: https://docs.incident.io/api-reference/announcement-post-template/updated-v1
/openapi/audit-logs.json webhook announcement_post_template.updated.1
This entry is created whenever an announcement post template is updated
# Updated v2
Source: https://docs.incident.io/api-reference/announcement-post-template/updated-v2
/openapi/audit-logs.json webhook announcement_post_template.updated.2
This entry is created whenever an announcement post template is updated
# Created v1
Source: https://docs.incident.io/api-reference/announcement-rule/created-v1
/openapi/audit-logs.json webhook announcement_rule.created.1
This entry is created whenever a announcement rule is created
# Created v2
Source: https://docs.incident.io/api-reference/announcement-rule/created-v2
/openapi/audit-logs.json webhook announcement_rule.created.2
This entry is created whenever a announcement rule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/announcement-rule/deleted-v1
/openapi/audit-logs.json webhook announcement_rule.deleted.1
This entry is created whenever a announcement rule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/announcement-rule/updated-v1
/openapi/audit-logs.json webhook announcement_rule.updated.1
This entry is created whenever a announcement rule is updated
# Updated v2
Source: https://docs.incident.io/api-reference/announcement-rule/updated-v2
/openapi/audit-logs.json webhook announcement_rule.updated.2
This entry is created whenever a announcement rule is updated
# Created v1
Source: https://docs.incident.io/api-reference/api-key/created-v1
/openapi/audit-logs.json webhook api_key.created.1
This entry is created whenever a api key is created
# Deleted v1
Source: https://docs.incident.io/api-reference/api-key/deleted-v1
/openapi/audit-logs.json webhook api_key.deleted.1
This entry is created whenever a api key is deleted
# Rotated v1
Source: https://docs.incident.io/api-reference/api-key/rotated-v1
/openapi/audit-logs.json webhook api_key.rotated.1
This entry is created whenever an api key is rotated
# Updated v1
Source: https://docs.incident.io/api-reference/api-key/updated-v1
/openapi/audit-logs.json webhook api_key.updated.1
This entry is created whenever a api key is updated
# API Keys
Source: https://docs.incident.io/api-reference/api-keys-v1
API endpoints for api keys
Manage API keys for your organization.
This API lets you view, create, update, delete, and rotate API keys programmatically, including configuring account-level roles and roles scoped to specific teams.
Common use cases include:
* **API key rotation**: You can issue a new access token for any API key using the `Rotate` endpoint.
* **Managing keys at scale**: use the `Show`, `List`, `Create`, `Update`, and `Delete` endpoints to automate API key lifecycle management.
## Permissions model
To use these endpoints, your API key must have the `api_keys_manage` role granted at either the account level or for specific teams.
In addition, the following rules apply, when a "caller" API key is managing a "target" API key:
* A caller key can only assign roles whose scopes are a subset of its own scopes. For example, a key with `viewer` and `incident_creator` can assign those roles to a target key, but cannot assign the `incident_editor` role, since it has additional scopes.
* The same applies at the team level: A caller key with `schedules_editor` at the account level can create a target key with that role for a specific team, but a key with `schedules_editor` only for one team (Team A, say) cannot assign it at the account level or for another team, Team B.
* The `api_keys_manage` role cannot be assigned via the API. To create a key with that role, you must go to Settings → API keys in the dashboard, and click "Add new", creating a key with the "View, create, edit, delete or rotate API keys" role (`api_keys_manage`).
* The `Delete` endpoint does not check whether the calling API key holds the scopes of the key being deleted. However, a team-scoped key can only delete keys belonging to its teams.
* To rotate the token of an API key, use the Rotate endpoint or by clicking "Rotate token" on any API key listed in the dashboard. The same permissions limitations apply as when creating or updating an API key.
## Finding role names and team IDs
To find valid values for `role_names`, `team_ids`, and `team_role_names`, go to Settings → API keys in the dashboard. Click to either edit an existing key or create a new one, select the desired roles and teams, and then use the copy button to get hold of the role and team identifiers as JSON.
## The api key object
# Create
Source: https://docs.incident.io/api-reference/api-keys-v1/create
/openapi/tags/api-keys-v1.json post /v1/api_keys
Create a new API key. The calling API key can only assign roles whose scopes are a subset of its own. The `api_keys_manage` role cannot be assigned via the API. An organization can have a maximum of 5000 active API keys.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/api-keys-v1/delete
/openapi/tags/api-keys-v1.json delete /v1/api_keys/{id}
Delete an existing API key. The calling API key does not need to hold the scopes of the key being deleted, but a team-scoped key can only delete keys belonging to its teams.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/api-keys-v1/list
/openapi/tags/api-keys-v1.json get /v1/api_keys
List API keys visible to the calling API key, with pagination. An API key with account-level `api_keys_manage` access will see all keys, while a key with the `api_keys_manage` role scoped to specific teams will only see keys belonging to those teams.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.view` scope.
# Rotate
Source: https://docs.incident.io/api-reference/api-keys-v1/rotate
/openapi/tags/api-keys-v1.json post /v1/api_keys/{id}/actions/rotate
Rotate the access token for an API key. This generates a new bearer token and optionally keeps the old token valid for a configurable grace period (up to 60 minutes), allowing a seamless rollover without downtime. The calling API key must have all the scopes of the key being rotated.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.rotate` scope.
# Show
Source: https://docs.incident.io/api-reference/api-keys-v1/show
/openapi/tags/api-keys-v1.json get /v1/api_keys/{id}
Show details of a specific API key, including its roles, team assignments and when its token was last issued.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.view` scope.
# Update
Source: https://docs.incident.io/api-reference/api-keys-v1/update
/openapi/tags/api-keys-v1.json put /v1/api_keys/{id}
Update an existing API key's name, roles, or team assignments. All fields must be provided (PUT semantics). The calling API key can only assign roles whose scopes are a subset of its own. An API key cannot edit itself, and the `api_keys_manage` role cannot be assigned via the API.
This endpoint requires a valid API key with the `api_keys_manage` role at either the account level or team level.
🔑 Requires the `api_keys.update` scope.
# Introduction
Source: https://docs.incident.io/api-reference/audit-logs
Track configuration and permission changes across your incident.io account.
Audit logs give you visibility over the changes made within your incident.io account. They cover configuration changes and permission updates (e.g. a user being given a new role, or granted access to a private incident). Audit logs are available on the [Enterprise plan](https://incident.io/pricing) and powered by [WorkOS](https://workos.com).
Each entry conforms to a versioned schema, so you can parse older events even as the schema evolves. Entries are retained for one year (starting from 18 April, 2023).
## Viewing your audit log
You can view your audit log from [Settings > Security](https://app.incident.io/~/settings/security). From there you can:
* Browse entries with filters for target, event type, actor, and date
* Export entries for a given time period to CSV
* Set up a log stream to a provider of your choice (e.g. Splunk or Amazon S3)
## Understanding entries
Each audit log entry includes:
* **Actor** — who or what made the change (user, API key, system, workflow, external resource, or alert)
* **Action** — the event type (e.g. `api_key.created`)
* **Targets** — what was modified
* **Context** — location and user agent, where applicable
* **Version** — schema version for backwards compatibility
## Actor types
### Users
Changes triggered by a user in your account.
```json theme={null}
{
"type": "user",
"id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"name": "Kelsey Mills",
"metadata": {
"user_base_role_slug": "admin",
"user_custom_role_slugs": "engineering,security"
}
}
```
### API keys
Changes triggered by an API key.
```json theme={null}
{
"type": "api_key",
"id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"name": "Lisa's development key",
"metadata": {
"api_key_roles": "incident_creator,global_access"
}
}
```
### Systems
Changes triggered by a system — either a third-party integration (e.g. a user created via Slack) or an internal process (e.g. a severity created during setup).
```json theme={null}
{
"type": "system",
"id": "incident_setup",
"name": "incident.io (setup)",
"metadata": {}
}
```
### Workflows
Changes triggered by a workflow, such as auto-inviting users to a private incident.
```json theme={null}
{
"type": "workflow",
"id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"name": "Auto-invite security team to private incidents",
"metadata": {}
}
```
### External resources
Changes triggered by an [external resource](/api-reference/introduction) (also known as an attachment).
```json theme={null}
{
"type": "external_resource",
"id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"name": "#1234 Increased API latency",
"metadata": {
"external_resource_type": "pager_duty_incident",
"external_resource_external_id": "q1234"
}
}
```
### Alerts
Changes triggered by an alert (e.g. from Datadog or Grafana).
```json theme={null}
{
"type": "alert",
"id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"name": "Staging: pod CPU high",
"metadata": {
"alert_source_id": "01HB0ZG3B0HM04RCXNSPV1EDYG"
}
}
```
# Call Sessions
Source: https://docs.incident.io/api-reference/call-sessions-v2
API endpoints for call sessions
List Scribe call sessions.
Call sessions are the individual meetings Scribe attended: several can accumulate
over time. Use this endpoint together with Call Transcript Entries to export what
Scribe transcribed during each session.
## The call session object
# List
Source: https://docs.incident.io/api-reference/call-sessions-v2/list
/openapi/tags/call-sessions-v2.json get /v2/call_sessions
List Scribe call sessions, newest first, filtered by incident.
🔑 Requires the `call_transcripts.view` scope.
# Call Transcript Entries
Source: https://docs.incident.io/api-reference/call-transcript-entries-v2
API endpoints for call transcript entries
List the transcript entries Scribe captured during a call session.
Entries are returned oldest first, ordered by when each participant started
speaking. To export a full transcript, page through with 'page\_size' and 'after'
until the response no longer includes a 'pagination\_meta.after' value.
## The call transcript entry object
# List
Source: https://docs.incident.io/api-reference/call-transcript-entries-v2/list
/openapi/tags/call-transcript-entries-v2.json get /v2/call_transcript_entries
List transcript entries for a call session, oldest first.
Returns an empty list if your organisation has disabled viewing transcripts.
🔑 Requires the `call_transcripts.view` scope.
# Catalog Entries
Source: https://docs.incident.io/api-reference/catalog-entries-v3
API endpoints for catalog entries
## The catalog entry object
# Bulk Update Entries
Source: https://docs.incident.io/api-reference/catalog-entries-v3/bulk-update-entries
/openapi/tags/catalog-entries-v3.json post /v3/catalog_entries/actions/bulk_update
Update multiple catalog entries in a single operation. You can update up to 250 entries at once. This operation is atomic - either all entries are updated successfully, or none are updated.
🔑 Requires the `catalog_entries.edit` scope.
# Create Entry
Source: https://docs.incident.io/api-reference/catalog-entries-v3/create-entry
/openapi/tags/catalog-entries-v3.json post /v3/catalog_entries
Create an entry within the catalog. We support a maximum of 50,000 entries per type.
If you call this API with a payload where the external_id and catalog_type_id match an existing entry, the existing entry will be updated.
🔑 Requires the `catalog_entries.create` scope.
# Delete Entry
Source: https://docs.incident.io/api-reference/catalog-entries-v3/delete-entry
/openapi/tags/catalog-entries-v3.json delete /v3/catalog_entries/{id}
Archives a catalog entry.
🔑 Requires the `catalog_entries.destroy` scope.
# List Entries
Source: https://docs.incident.io/api-reference/catalog-entries-v3/list-entries
/openapi/tags/catalog-entries-v3.json get /v3/catalog_entries
List entries for a catalog type.
🔑 Requires the `catalog_entries.view` scope.
# Show Entry
Source: https://docs.incident.io/api-reference/catalog-entries-v3/show-entry
/openapi/tags/catalog-entries-v3.json get /v3/catalog_entries/{id}
Show a single catalog entry.
🔑 Requires the `catalog_entries.view` scope.
# Update Entry
Source: https://docs.incident.io/api-reference/catalog-entries-v3/update-entry
/openapi/tags/catalog-entries-v3.json put /v3/catalog_entries/{id}
Updates an existing catalog entry.
🔑 Requires the `catalog_entries.edit` scope.
# Updated v1
Source: https://docs.incident.io/api-reference/catalog-entry-attribute/updated-v1
/openapi/audit-logs.json webhook catalog_entry_attribute.updated.1
This entry is created whenever a restricted catalog entry attribute is updated
# Updated v2
Source: https://docs.incident.io/api-reference/catalog-entry-attribute/updated-v2
/openapi/audit-logs.json webhook catalog_entry_attribute.updated.2
This entry is created whenever a restricted catalog entry attribute is updated
# Catalog Resources
Source: https://docs.incident.io/api-reference/catalog-resources-v3
API endpoints for catalog resources
## The catalog resource object
# List Resources
Source: https://docs.incident.io/api-reference/catalog-resources-v3/list-resources
/openapi/tags/catalog-resources-v3.json get /v3/catalog_resources
List available engine resources for the catalog.
A resource represents a type of data that can be held within the catalog, so this
endpoint can be used to see what attribute types can be used when updating the
schema of a catalog type.
🔑 Requires the `catalog_types.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/catalog-type/created-v1
/openapi/audit-logs.json webhook catalog_type.created.1
This entry is created whenever a catalog type is created
# Deleted v1
Source: https://docs.incident.io/api-reference/catalog-type/deleted-v1
/openapi/audit-logs.json webhook catalog_type.deleted.1
This entry is created whenever a catalog type is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/catalog-type/updated-v1
/openapi/audit-logs.json webhook catalog_type.updated.1
This entry is created whenever a catalog type is updated
# Catalog Types
Source: https://docs.incident.io/api-reference/catalog-types-v3
API endpoints for catalog types
## The catalog type object
# Create Type
Source: https://docs.incident.io/api-reference/catalog-types-v3/create-type
/openapi/tags/catalog-types-v3.json post /v3/catalog_types
Create a catalog type. The schema must be updated using the UpdateTypeSchema endpoint.
🔑 Requires the `catalog_types.create` scope.
# Delete Type
Source: https://docs.incident.io/api-reference/catalog-types-v3/delete-type
/openapi/tags/catalog-types-v3.json delete /v3/catalog_types/{id}
Archives a catalog type and associated entries.
🔑 Requires the `catalog_types.destroy` scope.
# List Types
Source: https://docs.incident.io/api-reference/catalog-types-v3/list-types
/openapi/tags/catalog-types-v3.json get /v3/catalog_types
List all catalog types for an organisation, including those synced from external resources.
🔑 Requires the `catalog_types.view` scope.
# Show Type
Source: https://docs.incident.io/api-reference/catalog-types-v3/show-type
/openapi/tags/catalog-types-v3.json get /v3/catalog_types/{id}
Show a single catalog type.
🔑 Requires the `catalog_types.view` scope.
# Update Type
Source: https://docs.incident.io/api-reference/catalog-types-v3/update-type
/openapi/tags/catalog-types-v3.json put /v3/catalog_types/{id}
Updates an existing catalog type. The schema must be updated using the UpdateTypeSchema endpoint.
🔑 Requires the `catalog_types.edit` scope.
# Update Type Schema
Source: https://docs.incident.io/api-reference/catalog-types-v3/update-type-schema
/openapi/tags/catalog-types-v3.json post /v3/catalog_types/{id}/actions/update_schema
Update an existing catalog types schema, adding or removing attributes.
Updating the schema is handled separately from creating and updating types, so that you don't
have to worry about dependencies between types. For example, if type A has an attribute that
relies on type B, you would have to create type B first.
By allowing the creation of types without a schema, they can be created in any order, but it
means that you need to make a separate call to this endpoint to update the schema.
🔑 Requires the `catalog_types.edit` scope.
# Create
Source: https://docs.incident.io/api-reference/catalog-v2/create
/openapi/deprecated-endpoints.json post /v2/catalog_entries
Create an entry within the catalog. We support a maximum of 50,000 entries per type.
If you call this API with a payload where the external_id and catalog_type_id match an existing entry, the existing entry will be updated.
🔑 Requires the `catalog_entries.create` scope.
# Create
Source: https://docs.incident.io/api-reference/catalog-v2/create-1
/openapi/deprecated-endpoints.json post /v2/catalog_types
Create a catalog type. The schema must be updated using the UpdateTypeSchema endpoint.
🔑 Requires the `catalog_types.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/catalog-v2/delete
/openapi/deprecated-endpoints.json delete /v2/catalog_entries/{id}
Archives a catalog entry.
🔑 Requires the `catalog_entries.destroy` scope.
# Delete
Source: https://docs.incident.io/api-reference/catalog-v2/delete-1
/openapi/deprecated-endpoints.json delete /v2/catalog_types/{id}
Archives a catalog type and associated entries.
🔑 Requires the `catalog_types.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/catalog-v2/list
/openapi/deprecated-endpoints.json get /v2/catalog_entries
List entries for a catalog type.
🔑 Requires the `catalog_entries.view` scope.
# List
Source: https://docs.incident.io/api-reference/catalog-v2/list-1
/openapi/deprecated-endpoints.json get /v2/catalog_resources
List available engine resources for the catalog.
A resource represents a type of data that can be held within the catalog, so this
endpoint can be used to see what attribute types can be used when updating the
schema of a catalog type.
🔑 Requires the `catalog_types.view` scope.
# List
Source: https://docs.incident.io/api-reference/catalog-v2/list-2
/openapi/deprecated-endpoints.json get /v2/catalog_types
List all catalog types for an organisation, including those synced from external resources.
🔑 Requires the `catalog_types.view` scope.
# Show
Source: https://docs.incident.io/api-reference/catalog-v2/show
/openapi/deprecated-endpoints.json get /v2/catalog_entries/{id}
Show a single catalog entry.
🔑 Requires the `catalog_entries.view` scope.
# Show
Source: https://docs.incident.io/api-reference/catalog-v2/show-1
/openapi/deprecated-endpoints.json get /v2/catalog_types/{id}
Show a single catalog type.
🔑 Requires the `catalog_types.view` scope.
# Update
Source: https://docs.incident.io/api-reference/catalog-v2/update
/openapi/deprecated-endpoints.json put /v2/catalog_entries/{id}
Updates an existing catalog entry.
🔑 Requires the `catalog_entries.edit` scope.
# Update Type
Source: https://docs.incident.io/api-reference/catalog-v2/update-type
/openapi/deprecated-endpoints.json put /v2/catalog_types/{id}
Updates an existing catalog type. The schema must be updated using the UpdateTypeSchema endpoint.
🔑 Requires the `catalog_types.edit` scope.
# Update Type Schema
Source: https://docs.incident.io/api-reference/catalog-v2/update-type-schema
/openapi/deprecated-endpoints.json post /v2/catalog_types/{id}/actions/update_schema
Update an existing catalog types schema, adding or removing attributes.
Updating the schema is handled separately from creating and updating types, so that you don't
have to worry about dependencies between types. For example, if type A has an attribute that
relies on type B, you would have to create type B first.
By allowing the creation of types without a schema, they can be created in any order, but it
means that you need to make a separate call to this endpoint to update the schema.
🔑 Requires the `catalog_types.edit` scope.
# Created v1
Source: https://docs.incident.io/api-reference/connector-config/created-v1
/openapi/audit-logs.json webhook connector_config.created.1
This entry is created whenever a connector config is created
# Token generated v1
Source: https://docs.incident.io/api-reference/connector-config/token-generated-v1
/openapi/audit-logs.json webhook connector_config.token_generated.1
This entry is created whenever a connector config token is regenerated
# Updated v1
Source: https://docs.incident.io/api-reference/connector-config/updated-v1
/openapi/audit-logs.json webhook connector_config.updated.1
This entry is created whenever a connector config is updated
# Public
Source: https://docs.incident.io/api-reference/created-v1/public
/openapi/webhooks.json webhook schedule.created_v1
This webhook is emitted whenever a schedule is created.
# Custom Field Options
Source: https://docs.incident.io/api-reference/custom-field-options-v1
API endpoints for custom field options
Manage custom field options.
Single- and multi-select custom fields have a list of all available options,
which have a value, and a sort key. The value must be unique to the custom
field. For example, you might have an Incident Type custom field, with options
"Data breach", "Performance degradation", "API downtime", etc.
## The custom field option object
# Create
Source: https://docs.incident.io/api-reference/custom-field-options-v1/create
/openapi/tags/custom-field-options-v1.json post /v1/custom_field_options
Create a custom field option. If the sort key is not supplied, it'll default to 1000, so the option appears near the end of the list.
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/custom-field-options-v1/delete
/openapi/tags/custom-field-options-v1.json delete /v1/custom_field_options/{id}
Delete a custom field option
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/custom-field-options-v1/list
/openapi/tags/custom-field-options-v1.json get /v1/custom_field_options
Show custom field options for a custom field
🔑 Requires the `custom_fields.view` scope.
# Show
Source: https://docs.incident.io/api-reference/custom-field-options-v1/show
/openapi/tags/custom-field-options-v1.json get /v1/custom_field_options/{id}
Get a single custom field option
🔑 Requires the `custom_fields.view` scope.
# Update
Source: https://docs.incident.io/api-reference/custom-field-options-v1/update
/openapi/tags/custom-field-options-v1.json put /v1/custom_field_options/{id}
Update a custom field option
🔑 Requires the `organisation_settings.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/custom-field/created-v1
/openapi/audit-logs.json webhook custom_field.created.1
This entry is created whenever a custom field is created
# Deleted v1
Source: https://docs.incident.io/api-reference/custom-field/deleted-v1
/openapi/audit-logs.json webhook custom_field.deleted.1
This entry is created whenever a custom field is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/custom-field/updated-v1
/openapi/audit-logs.json webhook custom_field.updated.1
This entry is created whenever a custom field is updated
# Create
Source: https://docs.incident.io/api-reference/custom-fields-v1/create
/openapi/deprecated-endpoints.json post /v1/custom_fields
Create a new custom field
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/custom-fields-v1/delete
/openapi/deprecated-endpoints.json delete /v1/custom_fields/{id}
Delete a custom field
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/custom-fields-v1/list
/openapi/deprecated-endpoints.json get /v1/custom_fields
List all custom fields for an organisation.
🔑 Requires the `custom_fields.view` scope.
# Show
Source: https://docs.incident.io/api-reference/custom-fields-v1/show
/openapi/deprecated-endpoints.json get /v1/custom_fields/{id}
Get a single custom field.
🔑 Requires the `custom_fields.view` scope.
# Update
Source: https://docs.incident.io/api-reference/custom-fields-v1/update
/openapi/deprecated-endpoints.json put /v1/custom_fields/{id}
Update the details of a custom field
🔑 Requires the `organisation_settings.update` scope.
# Custom Fields
Source: https://docs.incident.io/api-reference/custom-fields-v2
API endpoints for custom fields
Manage custom fields.
Custom fields are used to attach metadata to incidents, which you can use when searching
for incidents in the dashboard, triggering workflows, building announcement rules or for
your own data needs.
Each field has a type:
* Single-select, single value selected from a predefined list of options (e.g. Detection Method)
* Multi-select, as above but you can pick more than one option (e.g. Affected Teams)
* Text, freeform text field (e.g. Customer ID)
* Link, link URL that is synced to Slack bookmarks on the incident channel (e.g. External Status Page)
* Number, integer or fractional numbers (e.g. # Customers Affected)
We may add more custom field types in the future - we'd love to hear any other types you'd like to use!
## The custom field object
# Create
Source: https://docs.incident.io/api-reference/custom-fields-v2/create
/openapi/tags/custom-fields-v2.json post /v2/custom_fields
Create a new custom field
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/custom-fields-v2/delete
/openapi/tags/custom-fields-v2.json delete /v2/custom_fields/{id}
Delete a custom field
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/custom-fields-v2/list
/openapi/tags/custom-fields-v2.json get /v2/custom_fields
List all custom fields for an organisation.
🔑 Requires the `custom_fields.view` scope.
# Show
Source: https://docs.incident.io/api-reference/custom-fields-v2/show
/openapi/tags/custom-fields-v2.json get /v2/custom_fields/{id}
Get a single custom field.
🔑 Requires the `custom_fields.view` scope.
# Update
Source: https://docs.incident.io/api-reference/custom-fields-v2/update
/openapi/tags/custom-fields-v2.json put /v2/custom_fields/{id}
Update the details of a custom field
🔑 Requires the `organisation_settings.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/debrief-invite-rule/created-v1
/openapi/audit-logs.json webhook debrief_invite_rule.created.1
This entry is created whenever a debrief invite rule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/debrief-invite-rule/deleted-v1
/openapi/audit-logs.json webhook debrief_invite_rule.deleted.1
This entry is created whenever a debrief invite rule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/debrief-invite-rule/updated-v1
/openapi/audit-logs.json webhook debrief_invite_rule.updated.1
This entry is created whenever a debrief invite rule is updated
# Public
Source: https://docs.incident.io/api-reference/deleted-v1/public
/openapi/webhooks.json webhook schedule.deleted_v1
This webhook is emitted whenever a schedule is deleted.
# Updated v1
Source: https://docs.incident.io/api-reference/email-otp-login-setting/updated-v1
/openapi/audit-logs.json webhook email_otp_login_setting.updated.1
This entry is created whenever the email OTP login setting is toggled for an organisation
# Created v1
Source: https://docs.incident.io/api-reference/escalation-path/created-v1
/openapi/audit-logs.json webhook escalation_path.created.1
This entry is created whenever an escalation path is created
# Deleted v1
Source: https://docs.incident.io/api-reference/escalation-path/deleted-v1
/openapi/audit-logs.json webhook escalation_path.deleted.1
This entry is created whenever an escalation path is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/escalation-path/updated-v1
/openapi/audit-logs.json webhook escalation_path.updated.1
This entry is created whenever an escalation path is updated
# Escalation Paths
Source: https://docs.incident.io/api-reference/escalation-paths-v2
API endpoints for escalation paths
## The escalation path object
# Create
Source: https://docs.incident.io/api-reference/escalation-paths-v2/create
/openapi/tags/escalation-paths-v2.json post /v2/escalation_paths
Create an escalation path.
An escalation path is a series of steps that describe how a page should be escalated,
represented as graph, supporting conditional branches based on alert priority and working
intervals.
We recommend you create escalation paths in the incident.io dashboard where our path
builder makes it easy to use conditions and visualise the path.
🔑 Requires the `escalation_paths.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/escalation-paths-v2/delete
/openapi/tags/escalation-paths-v2.json delete /v2/escalation_paths/{id}
Archives an escalation path.
We recommend you create escalation paths in the incident.io dashboard where our path
builder makes it easy to use conditions and visualise the path.
🔑 Requires the `escalation_paths.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/escalation-paths-v2/list
/openapi/tags/escalation-paths-v2.json get /v2/escalation_paths
List all escalation paths in your account.
An escalation path is a series of steps that describe how a page should be escalated,
represented as a graph, supporting conditional branches based on alert priority and
working intervals.
🔑 Requires the `escalation_paths.view` scope.
# Show
Source: https://docs.incident.io/api-reference/escalation-paths-v2/show
/openapi/tags/escalation-paths-v2.json get /v2/escalation_paths/{id}
Show an escalation path.
We recommend you create escalation paths in the incident.io dashboard where our path
builder makes it easy to use conditions and visualise the path.
🔑 Requires the `escalation_paths.view` scope.
# Update
Source: https://docs.incident.io/api-reference/escalation-paths-v2/update
/openapi/tags/escalation-paths-v2.json put /v2/escalation_paths/{id}
Updates an escalation path.
We recommend you create escalation paths in the incident.io dashboard where our path
builder makes it easy to use conditions and visualise the path.
🔑 Requires the `escalation_paths.update` scope.
# Updated private
Source: https://docs.incident.io/api-reference/escalation-status-v1/updated-private
/openapi/webhooks.json webhook private_escalation.escalation_status_updated_v1
This webhook is emitted whenever a private escalation changes status.
# Updated public
Source: https://docs.incident.io/api-reference/escalation-status-v1/updated-public
/openapi/webhooks.json webhook public_escalation.escalation_status_updated_v1
This webhook is emitted whenever an escalation changes status. See [escalation statuses](https://docs.incident.io/on-call/escalation-statuses) for details on each status value.
# Created private
Source: https://docs.incident.io/api-reference/escalation-v1/created-private
/openapi/webhooks.json webhook private_escalation.escalation_created_v1
This webhook is emitted whenever a private escalation is created.
# Created public
Source: https://docs.incident.io/api-reference/escalation-v1/created-public
/openapi/webhooks.json webhook public_escalation.escalation_created_v1
This webhook is emitted whenever an escalation is created.
# Scrubbed v1
Source: https://docs.incident.io/api-reference/escalation/scrubbed-v1
/openapi/audit-logs.json webhook escalation.scrubbed.1
This entry is created whenever sensitive data is permanently erased from an escalation.
# Escalations
Source: https://docs.incident.io/api-reference/escalations-v2
API endpoints for escalations
Create and manage escalation paths, and create, list and filter escalations.
With incident.io On-call you can create escalation paths that describe how a page should
be escalated to people and schedules.
## The escalation object
# Cancel
Source: https://docs.incident.io/api-reference/escalations-v2/cancel
/openapi/tags/escalations-v2.json post /v2/escalations/{id}/actions/cancel
Cancel an escalation.
Cancelling an escalation stops any further paging: notifications cease and the
escalation will not advance to further levels or repeat. This works on escalations
that are still paging (for example to silence a page when an incident is resolved
before anyone acknowledges it) as well as snoozed ones. Escalations that have already
resolved or expired cannot be cancelled, and cancelling an already-cancelled
escalation is a no-op.
To use this API, you will need an API key with the "Create and manage escalations" permission.
🔑 Requires the `escalations.cancel` scope.
# Create
Source: https://docs.incident.io/api-reference/escalations-v2/create
/openapi/tags/escalations-v2.json post /v2/escalations
Create an escalation.
An escalation pages people, either according to an escalation path, or directly to
specific users. You must provide either an escalation_path_id OR user_ids, but not both.
When escalating via an escalation path, the escalation will follow the configured path
with its levels and timeouts, using your default [alert
priority](https://app.incident.io/~/settings/alerts/configuration/priorities).
When escalating directly to users, they will receive a high-urgency
notification, based on their notification rules.
This endpoint is rate-limited to 60 requests per minute, since it is intended for
interactive use cases (for example someone clicking a "escalate to team" button
in your internal developer platform). To escalate based on automated alerts, we
recommend sending events to an alert source instead.
🔑 Requires the `escalations.create` scope.
# List
Source: https://docs.incident.io/api-reference/escalations-v2/list
openapi/tags/escalations-v2.json GET /v2/escalations
List all escalations for your account.
This endpoint supports a number of filters, which can help find escalations matching certain
criteria.
Note that:
- Filters may be used together, and the result will be escalations that match all filters.
- All query parameters must be URI encoded.
To use this API, you will need an API key with the "View data" or "Create and manage on-call resources" permission.
### By escalation_path
Find all escalations that escalated to escalation path with id=ABC:
```bash
curl --get 'https://api.incident.io/v2/escalations' \
--data 'escalation_path[one_of]=ABC'
```
### By status
Find all escalations with a current status of "triggered":
```bash
curl --get 'https://api.incident.io/v2/escalations' \
--data 'status[one_of]=triggered'
```
Possible values are "pending", "triggered", "acked", "resolved", "expired" and "cancelled".
Escalations are in "pending" when they are in a grace period when the related alert has
been grouped in an incident.
### By alert
Find all escalations that were created by alert with id=ABC:
```bash
curl --get 'https://api.incident.io/v2/escalations' \
--data 'alert[one_of]=ABC'
```
### By created_at and updated_at
Find all escalations that follow specified date parameters for created_at and updated_at fields.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date_range" (between two dates).
For example, to find all escalations updated after 2025-01-01:
```bash
curl --get 'https://api.incident.io/v2/escalations' \
--data 'updated_at[gte]=2025-01-01'
```
To find all escalations created between 2025-01-01 and 2025-01-31:
```bash
curl --get 'https://api.incident.io/v2/escalations' \
```
--data 'created_at[date_range]=2025-01-01~2025-01-31'
List all escalations for your account.
This endpoint supports a number of filters, which can help find escalations matching certain
criteria.
Note that:
* Filters may be used together, and the result will be escalations that match all filters.
* All query parameters must be URI encoded.
To use this API, you will need an API key with the "View data" or "Create and manage on-call resources" permission.
### By escalation\_path
Find all escalations that escalated to escalation path with id=ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/escalations' \
--data 'escalation_path[one_of]=ABC'
```
### By status
Find all escalations with a current status of "triggered":
```bash theme={null}
curl --get 'https://api.incident.io/v2/escalations' \
--data 'status[one_of]=triggered'
```
Possible values are "pending", "triggered", "acked", "resolved", "expired" and "cancelled".
Escalations are in "pending" when they are in a grace period when the related alert has
been grouped in an incident.
### By alert
Find all escalations that were created by alert with id=ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/escalations' \
--data 'alert[one_of]=ABC'
```
### By created\_at and updated\_at
Find all escalations that follow specified date parameters for created\_at and updated\_at fields.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date\_range" (between two dates).
For example, to find all escalations updated after 2025-01-01:
```bash theme={null}
curl --get 'https://api.incident.io/v2/escalations' \
--data 'updated_at[gte]=2025-01-01'
```
To find all escalations created between 2025-01-01 and 2025-01-31:
```bash theme={null}
curl --get 'https://api.incident.io/v2/escalations' \
--data 'created_at[date_range]=2025-01-01~2025-01-31'
```
# Show
Source: https://docs.incident.io/api-reference/escalations-v2/show
/openapi/tags/escalations-v2.json get /v2/escalations/{id}
Show a specific escalation.
🔑 Requires the `escalations.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/follow-up-category/created-v1
/openapi/audit-logs.json webhook follow_up_category.created.1
This entry is created whenever a follow up category is created
# Deleted v1
Source: https://docs.incident.io/api-reference/follow-up-category/deleted-v1
/openapi/audit-logs.json webhook follow_up_category.deleted.1
This entry is created whenever a follow up category is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/follow-up-category/updated-v1
/openapi/audit-logs.json webhook follow_up_category.updated.1
This entry is created whenever a follow up category is updated
# Created v1
Source: https://docs.incident.io/api-reference/follow-up-priority/created-v1
/openapi/audit-logs.json webhook follow_up_priority.created.1
This entry is created whenever a follow up priority is created
# Deleted v1
Source: https://docs.incident.io/api-reference/follow-up-priority/deleted-v1
/openapi/audit-logs.json webhook follow_up_priority.deleted.1
This entry is created whenever a follow up priority is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/follow-up-priority/updated-v1
/openapi/audit-logs.json webhook follow_up_priority.updated.1
This entry is created whenever a follow up priority is updated
# Created private
Source: https://docs.incident.io/api-reference/follow-up-v1/created-private
/openapi/webhooks.json webhook private_incident.follow_up_created_v1
This webhook is emitted whenever a follow-up for a private incident is created.
# Created public
Source: https://docs.incident.io/api-reference/follow-up-v1/created-public
/openapi/webhooks.json webhook public_incident.follow_up_created_v1
This webhook is emitted whenever a follow-up is created.
# Updated private
Source: https://docs.incident.io/api-reference/follow-up-v1/updated-private
/openapi/webhooks.json webhook private_incident.follow_up_updated_v1
This webhook is emitted whenever a follow-up for a private incident is updated.
# Updated public
Source: https://docs.incident.io/api-reference/follow-up-v1/updated-public
/openapi/webhooks.json webhook public_incident.follow_up_updated_v1
This webhook is emitted whenever a follow-up is updated.
# Created private
Source: https://docs.incident.io/api-reference/follow-up-v2/created-private
/openapi/webhooks.json webhook private_incident.follow_up_created_v2
This webhook is emitted whenever a follow-up for a private incident is created.
# Created public
Source: https://docs.incident.io/api-reference/follow-up-v2/created-public
/openapi/webhooks.json webhook public_incident.follow_up_created_v2
This webhook is emitted whenever a follow-up is created.
# Updated private
Source: https://docs.incident.io/api-reference/follow-up-v2/updated-private
/openapi/webhooks.json webhook private_incident.follow_up_updated_v2
This webhook is emitted whenever a follow-up for a private incident is updated.
# Updated public
Source: https://docs.incident.io/api-reference/follow-up-v2/updated-public
/openapi/webhooks.json webhook public_incident.follow_up_updated_v2
This webhook is emitted whenever a follow-up is updated.
# Follow-ups
Source: https://docs.incident.io/api-reference/follow-ups-v2
API endpoints for follow-ups
Manage incident follow-ups.
Incidents can have follow-ups associated with them, which track work that should be done
after an incident (e.g. improving some documentation, or upgrading a dependency). They can
also be exported to external issue trackers.
You can manage follow-ups in the incident Slack channel with /incident follow-ups, or on
the incident homepage.
## The follow-up object
# Connect external issue
Source: https://docs.incident.io/api-reference/follow-ups-v2/connect-external-issue
/openapi/tags/follow-ups-v2.json post /v2/follow_ups/{id}/actions/connect_external_issue
Connect a follow-up to an existing issue in an issue tracker, using the URL of the issue.
This will not work if the follow-up is already connected to an external issue.
🔑 Requires the `follow_ups.connect_external_issue` scope.
# Create
Source: https://docs.incident.io/api-reference/follow-ups-v2/create
/openapi/tags/follow-ups-v2.json post /v2/follow_ups
Create a new incident follow-up.
🔑 Requires the `follow_ups.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/follow-ups-v2/delete
/openapi/tags/follow-ups-v2.json delete /v2/follow_ups/{id}
Delete an incident follow-up.
🔑 Requires the `follow_ups.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/follow-ups-v2/list
/openapi/tags/follow-ups-v2.json get /v2/follow_ups
List all follow-ups for an organisation.
🔑 Requires the `actions.view` scope.
# Show
Source: https://docs.incident.io/api-reference/follow-ups-v2/show
/openapi/tags/follow-ups-v2.json get /v2/follow_ups/{id}
Get a single incident follow-up.
🔑 Requires the `actions.view` scope.
# Update
Source: https://docs.incident.io/api-reference/follow-ups-v2/update
/openapi/tags/follow-ups-v2.json put /v2/follow_ups/{id}
Update an existing incident follow-up.
🔑 Requires the `follow_ups.update` scope.
# Heartbeat
Source: https://docs.incident.io/api-reference/heartbeat-v2
API endpoints for heartbeat
Send heartbeat pings for dead man's switch monitoring.
Heartbeat alert sources expect periodic pings. If pings stop arriving, alerts
fire automatically. Use the ping endpoints to signal that your job or service
is still healthy.
# Ping (GET)
Source: https://docs.incident.io/api-reference/heartbeat-v2/ping-get
/openapi/tags/heartbeat-v2.json get /v2/heartbeat/{alert_source_config_id}/ping
Send a heartbeat ping for the specified alert source.
Records a ping, indicating that the monitored job or service is healthy. The
heartbeat monitor uses these pings to detect missed heartbeats and fire alerts.
Both GET and POST are accepted
# Ping (POST)
Source: https://docs.incident.io/api-reference/heartbeat-v2/ping-post
/openapi/tags/heartbeat-v2.json post /v2/heartbeat/{alert_source_config_id}/ping
Send a heartbeat ping for the specified alert source.
Records a ping, indicating that the monitored job or service is healthy. The
heartbeat monitor uses these pings to detect missed heartbeats and fire alerts.
Both GET and POST are accepted
# Created v1
Source: https://docs.incident.io/api-reference/holiday-user-feed/created-v1
/openapi/audit-logs.json webhook holiday_user_feed.created.1
This entry is created whenever a holiday user feed is created
# Deleted v1
Source: https://docs.incident.io/api-reference/holiday-user-feed/deleted-v1
/openapi/audit-logs.json webhook holiday_user_feed.deleted.1
This entry is created whenever a holiday user feed is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/holiday-user-feed/updated-v1
/openapi/audit-logs.json webhook holiday_user_feed.updated.1
This entry is created whenever a holiday user feed is updated
# Updated v1
Source: https://docs.incident.io/api-reference/hris-time-off-policy/updated-v1
/openapi/audit-logs.json webhook hris_time_off_policy.updated.1
This entry is created whenever the visibility of a HRIS time-off policy is updated
# Incident Alerts
Source: https://docs.incident.io/api-reference/incident-alerts-v2
API endpoints for incident alerts
## The incident alert object
# List
Source: https://docs.incident.io/api-reference/incident-alerts-v2/list
/openapi/tags/incident-alerts-v2.json get /v2/incident_alerts
List the connections between incidents and alerts
🔑 Requires the `alerts.view` scope.
# Incident Attachments
Source: https://docs.incident.io/api-reference/incident-attachments-v1
API endpoints for incident attachments
Create, list and delete incident attachments.
Incident Attachments allows you to connect resources from external systems into incidents.
Examples include: PagerDuty incidents and GitHub pull requests.
## The incident attachment object
# Create
Source: https://docs.incident.io/api-reference/incident-attachments-v1/create
/openapi/tags/incident-attachments-v1.json post /v1/incident_attachments
Attaches an external resource to an incident.
You must provide a resource with resource_type and either external_id or url, but not both.
When providing a url, the server will create the attachment from that link for the given resource type if the integration is installed and the link is valid.
To attach an arbitrary link that isn't backed by an integration, use the arbitrary_url resource type with a url, and optionally a title and emoji.
🔑 Requires the `attachments.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/incident-attachments-v1/delete
/openapi/tags/incident-attachments-v1.json delete /v1/incident_attachments/{id}
Unattaches an external resource from an incident
🔑 Requires the `attachments.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/incident-attachments-v1/list
/openapi/tags/incident-attachments-v1.json get /v1/incident_attachments
List all incident attachments for a given external resource or incident. You must provide either a specific incident ID or a specific external resource type and external ID.
🔑 Requires the `attachments.view` scope.
# Updated v1
Source: https://docs.incident.io/api-reference/incident-call-setting/updated-v1
/openapi/audit-logs.json webhook incident_call_setting.updated.1
This entry is created whenever an organisation's incident call settings are updated
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-call-transcription-session/deleted-v1
/openapi/audit-logs.json webhook incident_call_transcription_session.deleted.1
This entry is created whenever a calls notes (transcription session) are deleted
# Created v1
Source: https://docs.incident.io/api-reference/incident-duration-metric/created-v1
/openapi/audit-logs.json webhook incident_duration_metric.created.1
This entry is created whenever a incident duration metric is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-duration-metric/deleted-v1
/openapi/audit-logs.json webhook incident_duration_metric.deleted.1
This entry is created whenever a incident duration metric is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-duration-metric/updated-v1
/openapi/audit-logs.json webhook incident_duration_metric.updated.1
This entry is created whenever a incident duration metric is updated
# Incident Memberships
Source: https://docs.incident.io/api-reference/incident-memberships-v1
API endpoints for incident memberships
Manage private incident memberships
## The incident membership object
# Create
Source: https://docs.incident.io/api-reference/incident-memberships-v1/create
/openapi/tags/incident-memberships-v1.json post /v1/incident_memberships
Makes a user a member of a private incident
🔑 Requires the `incident_memberships.grant` scope.
# Revoke
Source: https://docs.incident.io/api-reference/incident-memberships-v1/revoke
/openapi/tags/incident-memberships-v1.json post /v1/incident_memberships/actions/revoke
Revoke a user's membership of a private incident
🔑 Requires the `incident_memberships.revoke` scope.
# Incident Participant Workloads
Source: https://docs.incident.io/api-reference/incident-participant-workloads-v2
API endpoints for incident participant workloads
## The incident participant workload object
# List
Source: https://docs.incident.io/api-reference/incident-participant-workloads-v2/list
/openapi/tags/incident-participant-workloads-v2.json get /v2/incident_participant_workloads
List the participants of an incident with their workload.
We calculate how much time each participant has spent working on the incident, aggregated
per participant. Each participant is annotated with their participant type and, if they have
left the incident, when they were archived.
Workload is calculated periodically, so values can lag real time and the most recent period
may still be filling. The metadata reports the time the figures are calculated up to.
Workload for private incidents is only returned to API keys with the
`incident_workloads.view_private` scope.
🔑 Requires the `incident_workloads.view` scope.
# Incident Participants
Source: https://docs.incident.io/api-reference/incident-participants-v2
API endpoints for incident participants
## The incident participant object
# List
Source: https://docs.incident.io/api-reference/incident-participants-v2/list
/openapi/tags/incident-participants-v2.json get /v2/incident_participants
List the participants of an incident with the role they took.
Participants are split into those who are actively helping with the incident and those who are
just observing. Each participant is annotated with their participant type.
🔑 Requires the `incidents.view` scope.
# Incident Relationships
Source: https://docs.incident.io/api-reference/incident-relationships-v1
API endpoints for incident relationships
View related incidents for an incident
## The incident relationship object
# List
Source: https://docs.incident.io/api-reference/incident-relationships-v1/list
/openapi/tags/incident-relationships-v1.json get /v1/incident_relationships
List related incidents for a specific incident.
🔑 Requires the `incidents.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/incident-role/created-v1
/openapi/audit-logs.json webhook incident_role.created.1
This entry is created whenever a incident role is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-role/deleted-v1
/openapi/audit-logs.json webhook incident_role.deleted.1
This entry is created whenever a incident role is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-role/updated-v1
/openapi/audit-logs.json webhook incident_role.updated.1
This entry is created whenever a incident role is updated
# Create
Source: https://docs.incident.io/api-reference/incident-roles-v1/create
/openapi/deprecated-endpoints.json post /v1/incident_roles
Create a new incident role
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/incident-roles-v1/delete
/openapi/deprecated-endpoints.json delete /v1/incident_roles/{id}
Removes an existing role
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/incident-roles-v1/list
/openapi/deprecated-endpoints.json get /v1/incident_roles
List all incident roles for an organisation.
🔑 Requires the `incident_roles.view` scope.
# Show
Source: https://docs.incident.io/api-reference/incident-roles-v1/show
/openapi/deprecated-endpoints.json get /v1/incident_roles/{id}
Get a single incident role.
🔑 Requires the `incident_roles.view` scope.
# Update
Source: https://docs.incident.io/api-reference/incident-roles-v1/update
/openapi/deprecated-endpoints.json put /v1/incident_roles/{id}
Update an existing incident role
🔑 Requires the `organisation_settings.update` scope.
# Incident Roles
Source: https://docs.incident.io/api-reference/incident-roles-v2
API endpoints for incident roles
Manage incident roles.
During an incident, you can assign responders to one of the incident roles that are
configured in your organisation settings.
Every organisation will have a special 'lead' role, which signifies the incident lead or
commander. This role cannot be deleted, but can be renamed in the incident.io dashboard.
## The incident role object
# Create
Source: https://docs.incident.io/api-reference/incident-roles-v2/create
/openapi/tags/incident-roles-v2.json post /v2/incident_roles
Create a new incident role
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/incident-roles-v2/delete
/openapi/tags/incident-roles-v2.json delete /v2/incident_roles/{id}
Removes an existing role
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/incident-roles-v2/list
/openapi/tags/incident-roles-v2.json get /v2/incident_roles
List all incident roles for an organisation.
🔑 Requires the `incident_roles.view` scope.
# Show
Source: https://docs.incident.io/api-reference/incident-roles-v2/show
/openapi/tags/incident-roles-v2.json get /v2/incident_roles/{id}
Get a single incident role.
🔑 Requires the `incident_roles.view` scope.
# Update
Source: https://docs.incident.io/api-reference/incident-roles-v2/update
/openapi/tags/incident-roles-v2.json put /v2/incident_roles/{id}
Update an existing incident role
🔑 Requires the `organisation_settings.update` scope.
# Updated public
Source: https://docs.incident.io/api-reference/incident-status-v2/updated-public
/openapi/webhooks.json webhook public_incident.incident_status_updated_v2
This webhook is emitted whenever an incident's status changes.
# Created v1
Source: https://docs.incident.io/api-reference/incident-status/created-v1
/openapi/audit-logs.json webhook incident_status.created.1
This entry is created whenever a incident status is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-status/deleted-v1
/openapi/audit-logs.json webhook incident_status.deleted.1
This entry is created whenever a incident status is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-status/updated-v1
/openapi/audit-logs.json webhook incident_status.updated.1
This entry is created whenever a incident status is updated
# Incident Statuses
Source: https://docs.incident.io/api-reference/incident-statuses-v1
API endpoints for incident statuses
Manage incident statuses.
Each incident has a status, picked from one of the statuses configured in your
organisations settings.
Statuses help communicate where an incident is in its lifecycle. You can use
statuses when filtering incidents in the dashboard, and in workflows and announcement
rules.
## The incident status object
# Create
Source: https://docs.incident.io/api-reference/incident-statuses-v1/create
/openapi/tags/incident-statuses-v1.json post /v1/incident_statuses
Create a new incident status
🔑 Requires the `incident_lifecycles.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/incident-statuses-v1/delete
/openapi/tags/incident-statuses-v1.json delete /v1/incident_statuses/{id}
Delete an incident status
🔑 Requires the `incident_lifecycles.update` scope.
# List
Source: https://docs.incident.io/api-reference/incident-statuses-v1/list
/openapi/tags/incident-statuses-v1.json get /v1/incident_statuses
List all incident statuses for an organisation.
🔑 Requires the `incident_statuses.view` scope.
# Show
Source: https://docs.incident.io/api-reference/incident-statuses-v1/show
/openapi/tags/incident-statuses-v1.json get /v1/incident_statuses/{id}
Get a single incident status.
🔑 Requires the `incident_statuses.view` scope.
# Update
Source: https://docs.incident.io/api-reference/incident-statuses-v1/update
/openapi/tags/incident-statuses-v1.json put /v1/incident_statuses/{id}
Update an existing incident status
🔑 Requires the `incident_lifecycles.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/incident-template/created-v1
/openapi/audit-logs.json webhook incident_template.created.1
This entry is created whenever an incident template is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-template/deleted-v1
/openapi/audit-logs.json webhook incident_template.deleted.1
This entry is created whenever an incident template is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-template/updated-v1
/openapi/audit-logs.json webhook incident_template.updated.1
This entry is created whenever an incident template is updated
# Created v1
Source: https://docs.incident.io/api-reference/incident-timestamp-set-by-rule/created-v1
/openapi/audit-logs.json webhook incident_timestamp_set_by_rule.created.1
This entry is created whenever an incident timestamp set by rule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-timestamp-set-by-rule/deleted-v1
/openapi/audit-logs.json webhook incident_timestamp_set_by_rule.deleted.1
This entry is created whenever an incident timestamp set by rule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-timestamp-set-by-rule/updated-v1
/openapi/audit-logs.json webhook incident_timestamp_set_by_rule.updated.1
This entry is created whenever an incident timestamp set by rule is updated
# Created v1
Source: https://docs.incident.io/api-reference/incident-timestamp/created-v1
/openapi/audit-logs.json webhook incident_timestamp.created.1
This entry is created whenever a incident timestamp is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-timestamp/deleted-v1
/openapi/audit-logs.json webhook incident_timestamp.deleted.1
This entry is created whenever a incident timestamp is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-timestamp/updated-v1
/openapi/audit-logs.json webhook incident_timestamp.updated.1
This entry is created whenever a incident timestamp is updated
# Incident Timestamps
Source: https://docs.incident.io/api-reference/incident-timestamps-v2
API endpoints for incident timestamps
View incident timestamps.
Each incident has a number of timestamps; some being defaults that we set on
each incident for you, and other being configured for your organisation within
settings.
Timestamps help to communicate when a given action was taken for a specific
incident, for example when it was reported, closed or fixed.
## The incident timestamp object
# List
Source: https://docs.incident.io/api-reference/incident-timestamps-v2/list
/openapi/tags/incident-timestamps-v2.json get /v2/incident_timestamps
List all incident timestamps for an organisation.
# Show
Source: https://docs.incident.io/api-reference/incident-timestamps-v2/show
/openapi/tags/incident-timestamps-v2.json get /v2/incident_timestamps/{id}
Get a single incident timestamp.
# Created v1
Source: https://docs.incident.io/api-reference/incident-type/created-v1
/openapi/audit-logs.json webhook incident_type.created.1
This entry is created whenever a incident type is created
# Created v2
Source: https://docs.incident.io/api-reference/incident-type/created-v2
/openapi/audit-logs.json webhook incident_type.created.2
This entry is created whenever an incident type is created
# Deleted v1
Source: https://docs.incident.io/api-reference/incident-type/deleted-v1
/openapi/audit-logs.json webhook incident_type.deleted.1
This entry is created whenever a incident type is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/incident-type/updated-v1
/openapi/audit-logs.json webhook incident_type.updated.1
This entry is created whenever a incident type is updated
# Updated v2
Source: https://docs.incident.io/api-reference/incident-type/updated-v2
/openapi/audit-logs.json webhook incident_type.updated.2
This entry is created whenever an incident type is updated
# Incident Types
Source: https://docs.incident.io/api-reference/incident-types-v1
API endpoints for incident types
View incident types.
With incident types enabled, you can tailor your process to the situation you're
responding to with different custom fields and roles for each incident type.
## The incident type object
# List
Source: https://docs.incident.io/api-reference/incident-types-v1/list
/openapi/tags/incident-types-v1.json get /v1/incident_types
List all incident types for an organisation.
🔑 Requires the `incident_types.view` scope.
# Show
Source: https://docs.incident.io/api-reference/incident-types-v1/show
/openapi/tags/incident-types-v1.json get /v1/incident_types/{id}
Get a single incident type.
🔑 Requires the `incident_types.view` scope.
# Incident Updates
Source: https://docs.incident.io/api-reference/incident-updates-v2
API endpoints for incident updates
List incident updates.
Incident Updates allows you to see all the updates that have been shared against a
particular incident. This will include any time that the Severity or Status of
an incident changed, alongside any additional updates that were provided.
## The incident update object
# List
Source: https://docs.incident.io/api-reference/incident-updates-v2/list
/openapi/tags/incident-updates-v2.json get /v2/incident_updates
List all incident updates for an organisation, or for a specific incident.
🔑 Requires the `incidents.view` scope.
# Created private
Source: https://docs.incident.io/api-reference/incident-v2/created-private
/openapi/webhooks.json webhook private_incident.incident_created_v2
This webhook is emitted whenever a new private incident is created.
# Created public
Source: https://docs.incident.io/api-reference/incident-v2/created-public
/openapi/webhooks.json webhook public_incident.incident_created_v2
This webhook is emitted whenever a new incident is created.
# Updated private
Source: https://docs.incident.io/api-reference/incident-v2/updated-private
/openapi/webhooks.json webhook private_incident.incident_updated_v2
This webhook is emitted whenever a private incident is updated.
# Updated public
Source: https://docs.incident.io/api-reference/incident-v2/updated-public
/openapi/webhooks.json webhook public_incident.incident_updated_v2
This webhook is emitted whenever an incident is updated.
# Create
Source: https://docs.incident.io/api-reference/incidents-v1/create
/openapi/deprecated-endpoints.json post /v1/incidents
Create a new incident.
🔑 Requires the `incidents.create` scope.
# List
Source: https://docs.incident.io/api-reference/incidents-v1/list
/openapi/deprecated-endpoints.json get /v1/incidents
List all incidents for an organisation.
🔑 Requires the `incidents.view` scope.
# Show
Source: https://docs.incident.io/api-reference/incidents-v1/show
/openapi/deprecated-endpoints.json get /v1/incidents/{id}
Get a single incident.
🔑 Requires the `incidents.view` scope.
# Incidents
Source: https://docs.incident.io/api-reference/incidents-v2
API endpoints for incidents
Create and read incidents.
Incidents are a core resource, on which many other resources (actions, etc) are created.
Care should be taken around these endpoints, as automation that creates duplicate
incidents can be distracting, and impact reporting.
## The incident object
# Create
Source: https://docs.incident.io/api-reference/incidents-v2/create
/openapi/tags/incidents-v2.json post /v2/incidents
Create a new incident.
Note that if the incident mode is set to "retrospective" then the new incident
will not be announced in Slack.
🔑 Requires the `incidents.create` scope.
# Edit
Source: https://docs.incident.io/api-reference/incidents-v2/edit
/openapi/tags/incidents-v2.json post /v2/incidents/{id}/actions/edit
Edit an existing incident.
This endpoint allows you to edit the properties of an existing incident: e.g. set the severity or update custom fields.
When using this endpoint, only fields that are provided will be edited (omitted fields
will be ignored).
# Import postmortem document
Source: https://docs.incident.io/api-reference/incidents-v2/import-postmortem-document
/openapi/tags/incidents-v2.json post /v2/incidents/{id}/actions/import_postmortem_document
Import a postmortem document from markdown into an incident.
The document content should be provided as GitHub-Flavored Markdown. It will be
parsed and converted into the collaborative editor format, and a new postmortem
document will be created for the incident.
If no main postmortem document exists for the incident, the imported document
will become the main document.
🔑 Requires the `in_app_postmortems.import` scope.
# List incidents
Source: https://docs.incident.io/api-reference/incidents-v2/list
openapi/tags/incidents-v2.json GET /v2/incidents
List all incidents for an organisation.
This endpoint supports a number of filters, which can help find incidents matching certain
criteria.
Filters are provided as query parameters, but due to the dynamic nature of what you can
query by (different accounts have different custom fields, statuses, etc) they are more
complex than most.
The maximum page size that can be requested is 250.
To help, here are some exemplar curl requests with a human description of what they search
for.
Note that:
- Filters may be combined using the filter_mode parameter: 'all' (default) requires all filters
to match (AND logic), while 'any' requires at least one filter to match (OR logic).
- IDs are normally in UUID format, but have been replaced with shorter strings to improve
readability.
- All query parameters must be URI encoded.
### By status
With status of id=ABC, find all incidents that are set to that status:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status[one_of]=ABC'
```
Or all incidents that are not set to status with id=ABC:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status[not_in]=ABC'
```
### By created_at or updated_at
Find all incidents that follow specified date parameters for created_at and updated_at fields.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date_range" (between two dates). The following example finds all incidents created before
or on 2021-01-02T00:00:00Z:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'created_at[lte]=2021-01-02'
```
To find incidents created within a specific date range, use the date_range option with
tilde-separated dates:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'created_at[date_range]=2024-12-02~2024-12-08'
```
### By status category
Find all incidents that are in a status category. Some categories use a different
name in the API than the one shown in the dashboard — most notably "live" (shown as
"Active") and "learning" (shown as "Post-incident"). The full mapping is:
| API value | Shown in app as |
| ---------- | --------------- |
| triage | Triage |
| live | Active |
| learning | Post-incident |
| paused | Paused |
| closed | Closed |
| declined | Declined |
| canceled | Canceled |
| merged | Merged |
For example, to find all incidents the dashboard shows as "Active", filter on the
"live" category:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status_category[one_of]=live'
```
Or all incidents that are not in a status category:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status_category[not_in]=live'
```
### By severity
With severity of id=ABC, find all incidents that are set to that severity:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[one_of]=ABC'
```
Or all incidents where severity rank is greater-than-or-equal-to the rank of severity
id=ABC:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[gte]=ABC'
```
Or all incidents where severity rank is less-than-or-equal-to the rank of severity id=ABC:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[lte]=ABC'
```
### By incident type
With incident type of id=ABC, find all incidents that are of that type:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_type[one_of]=ABC'
```
Or all incidents not of that type:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_type[not_in]=ABC'
```
### By incident mode
By default, we return standard and retrospective incidents. This means that test and
tutorial incidents are filtered out. To override this behaviour, you can use the
mode filter to specify which modes you want to get.
To find incidents of all modes:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'mode[one_of]=standard&mode[one_of]=retrospective&mode[one_of]=test&mode[one_of]=tutorial'
```
To find just test incidents:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'mode[one_of]=test'
```
### By incident role
Roles and custom fields have another nested layer in the query parameter, to account for
operations against any of the roles or custom fields created in the account.
With incident role id=ABC, find all incidents where that role is unset:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_role[ABC][is_set]=true'
```
Or where the role has been set:
```bash
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_role[ABC][is_set]=false'
```
### By option custom fields
With an option custom field id=ABC, all incidents that have field ABC set to the custom
field option of id=XYZ:
```bash
curl \
--get 'https://api.incident.io/v2/incidents' \
--data 'custom_field[ABC][one_of]=XYZ'
```
Or all incidents that do not have custom field id=ABC set to option id=XYZ:
```bash
curl \
--get 'https://api.incident.io/v2/incidents' \
--data 'custom_field[ABC][not_in]=XYZ'
```
### Sorting
By default, results are ordered by their creation date. You can use the sort_by parameter
to reverse this order:
```bash
curl \
--get 'https://api.incident.io/v2/incidents' \
--data 'sort_by=created_at_oldest_first'
```
List all incidents for an organization.
This endpoint supports a number of filters, which can help find incidents matching certain
criteria.
Filters are provided as query parameters, but due to the dynamic nature of what you can
query by (different accounts have different custom fields, statuses, etc) they are more
complex than most.
The maximum page size that can be requested is 250.
To help, here are some exemplar curl requests with a human description of what they search
for.
Note that:
* Filters may be combined using the filter\_mode parameter: 'all' (default) requires all filters
to match (AND logic), while 'any' requires at least one filter to match (OR logic).
* IDs are normally in UUID format, but have been replaced with shorter strings to improve
readability.
* All query parameters must be URI encoded.
### By status
With status of id=ABC, find all incidents that are set to that status:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status[one_of]=ABC'
```
Or all incidents that are not set to status with id=ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status[not_in]=ABC'
```
### By created\_at or updated\_at
Find all incidents that follow specified date parameters for created\_at and updated\_at fields.
Possible values are "gte" (greater than or equal to), "lte" (less than or equal to), and
"date\_range" (between two dates). The following example finds all incidents created before
or on 2021-01-02T00:00:00Z:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'created_at[lte]=2021-01-02'
```
To find incidents created within a specific date range, use the date\_range option with
tilde-separated dates:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'created_at[date_range]=2024-12-02~2024-12-08'
```
### By status category
Find all incidents that are in a status category. Possible values are "triage",
"declined", "merged", "canceled", "live", "learning" and "closed":
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status_category[one_of]=live'
```
Or all incidents that are not in a status category:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'status_category[not_in]=live'
```
### By severity
With severity of id=ABC, find all incidents that are set to that severity:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[one_of]=ABC'
```
Or all incidents where severity rank is greater-than-or-equal-to the rank of severity
id=ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[gte]=ABC'
```
Or all incidents where severity rank is less-than-or-equal-to the rank of severity id=ABC:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'severity[lte]=ABC'
```
### By incident type
With incident type of id=ABC, find all incidents that are of that type:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_type[one_of]=ABC'
```
Or all incidents not of that type:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_type[not_in]=ABC'
```
### By incident mode
By default, we return standard and retrospective incidents. This means that test and
tutorial incidents are filtered out. To override this behaviour, you can use the
mode filter to specify which modes you want to get.
To find incidents of all modes:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'mode[one_of]=standard&mode[one_of]=retrospective&mode[one_of]=test&mode[one_of]=tutorial'
```
To find just test incidents:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'mode[one_of]=test'
```
### By incident role
Roles and custom fields have another nested layer in the query parameter, to account for
operations against any of the roles or custom fields created in the account.
With incident role id=ABC, find all incidents where that role is unset:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_role[ABC][is_set]=true'
```
Or where the role has been set:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'incident_role[ABC][is_set]=false'
```
### By option custom fields
With an option custom field id=ABC, all incidents that have field ABC set to the custom
field option of id=XYZ:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'custom_field[ABC][one_of]=XYZ'
```
Or all incidents that do not have custom field id=ABC set to option id=XYZ:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'custom_field[ABC][not_in]=XYZ'
```
### Sorting
By default, results are ordered by their creation date. You can use the sort\_by parameter
to reverse this order:
```bash theme={null}
curl --get 'https://api.incident.io/v2/incidents' \
--data 'sort_by=created_at_oldest_first'
```
# Show
Source: https://docs.incident.io/api-reference/incidents-v2/show
/openapi/tags/incidents-v2.json get /v2/incidents/{id}
Get a single incident.
The ID supplied can be either the incident's full ID, or the numeric part of its
reference. For example, to get INC-123, you could use either its full ID or:
```bash
curl \
--get 'https://api.incident.io/v2/incidents/123
```
🔑 Requires the `incidents.view` scope.
# Installed v1
Source: https://docs.incident.io/api-reference/integration/installed-v1
/openapi/audit-logs.json webhook integration.installed.1
This entry is created whenever an integration is installed
# Uninstalled v1
Source: https://docs.incident.io/api-reference/integration/uninstalled-v1
/openapi/audit-logs.json webhook integration.uninstalled.1
This entry is created whenever an integration is uninstalled
# Created v1
Source: https://docs.incident.io/api-reference/internal-status-page/created-v1
/openapi/audit-logs.json webhook internal_status_page.created.1
This entry is created whenever an internal status page is created
# Deleted v1
Source: https://docs.incident.io/api-reference/internal-status-page/deleted-v1
/openapi/audit-logs.json webhook internal_status_page.deleted.1
This entry is created whenever an internal status page is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/internal-status-page/updated-v1
/openapi/audit-logs.json webhook internal_status_page.updated.1
This entry is created whenever an internal status page has its configuration updated
# Introduction
Source: https://docs.incident.io/api-reference/introduction
The incident.io API — endpoints, authentication, rate limits, and error handling.
This is the API reference for incident.io. It documents available API endpoints, provides examples of how to use them, and covers authentication, rate limits, and error handling.
The API is hosted at `https://api.incident.io/`, and you will need an API key from your [incident.io dashboard](https://app.incident.io/~/settings/api-keys) to make requests.
Download the full OpenAPI 3.0 spec to generate clients or feed to your tools.
Manage incidents, alerts, and schedules from your terminal with `inc`.
## Authentication
For all requests, you'll need an API key. To create one, visit [Settings → API keys](https://app.incident.io/~/settings/api-keys). When you create the key, you'll choose what actions it can take. Keys can have account-level permissions, [team-scoped permissions](/admin/api-keys#team-scoped-permissions), or both. We'll only show the token once, so store it somewhere safe.
API keys remain valid even if the creating user is deactivated. For more details on managing keys and permissions, see [API keys](/admin/api-keys).
Set the `Authorization` header using a Bearer scheme:
```
Authorization: Bearer
```
### Make your first request
Any key can call the [identity endpoint](/api-reference/utilities-v1/show-identity), which returns details of the key you authenticated with:
```bash theme={null}
curl --request GET https://api.incident.io/v1/identity \
--header 'Authorization: Bearer '
```
```json theme={null}
{
"identity": {
"name": "Alertmanager token",
"roles": ["viewer"],
"dashboard_url": "https://app.incident.io/my-org"
}
}
```
If you get a `401`, check the key is passed exactly as shown, with no quotes around the token.
## Rate limits
The default rate limit is **1,200 requests/minute** per API key. Some endpoints have lower limits documented below. Note that these limits are subject to change unless otherwise contracted:
| Endpoint | Burst | Sustained |
| ---------------------------------------------- | ----- | --------- |
| List incidents (v1 and v2), Show incident (v2) | 60 | 60/min |
| Bulk update catalog entries (v3) | 10 | 60/min |
| Update catalog entry (v3) | 25 | 300/min |
| Show post-mortem document content (v1) | 60 | 60/min |
| Preview schedule entries (v2) | 10 | 6/min |
| Create retrospective status page incident (v2) | 300 | 300/min |
| Update telemetry data source (v2) | 5 | 30/min |
Burst is how many requests you can make at once; sustained is the rate at which your allowance refills.
Creating incidents is limited separately: an API key can create **10 incidents per hour** where a chat channel is created, and **300 per hour** otherwise. If you're importing historical incidents, [contact support](mailto:support@incident.io) to raise this temporarily.
### Rate limit headers
Every response to a request made with an API key tells you where you stand, so you can slow down before you get a 429.
| Header | What it means |
| ----------------------- | -------------------------------------------------------------------------------------------- |
| `X-RateLimit-Limit` | The limit that applies to this request, then every limit we checked and the window it covers |
| `X-RateLimit-Remaining` | How many requests you have left right now |
| `X-RateLimit-Used` | How many requests you have used |
| `X-RateLimit-Reset` | Unix timestamp in seconds for when you are back to a full allowance |
For example:
```
X-RateLimit-Limit: 60, 1200;window=60, 60;window=60
X-RateLimit-Remaining: 59
X-RateLimit-Used: 1
X-RateLimit-Reset: 1785257176
```
More than one limit can apply to the same request. Here your API key allows 1,200 requests a minute and the endpoint allows 60 a minute. `X-RateLimit-Limit` lists both. `Remaining`, `Used` and `Reset` describe whichever has least left, because that is the one you will run into first.
Limits top up continuously rather than resetting at a set time. The window is in seconds and tells you the rate you can keep up. `1200;window=60` means 1,200 requests a minute, which is 20 requests a second that you can sustain indefinitely.
Two things to expect. `X-RateLimit-Remaining` can drop by more than the number of requests you made, because some limits are shared across all the API keys on your account. And the headers are left out entirely if we cannot work out your limits for a request, so treat them as missing rather than as zero.
### Exceeding a rate limit
When you go over a rate limit, the API responds with `429 Too Many Requests` and a `Retry-After` header giving the number of seconds to wait:
```
Retry-After: 10
X-RateLimit-Limit: 60, 60;window=60
X-RateLimit-Remaining: 0
X-RateLimit-Used: 60
X-RateLimit-Reset: 1785257176
```
Use `Retry-After` to decide how long to back off. It tells you when your next request will go through. `X-RateLimit-Reset` is later than that, because it is when your whole allowance is back.
The response body has the same information:
```json theme={null}
{
"type": "too_many_requests",
"status": 429,
"request_id": "b839a403-7704-41c1-bf6a-39a2d68caefa",
"rate_limit": {
"name": "api_key_name",
"limit": 1200,
"remaining": 0,
"retry_after": "2025-04-17T11:17:18Z"
},
"errors": [
{
"code": "too_many_requests",
"message": "Too many requests. We recommend exponential backoff."
}
]
}
```
## Pagination
List endpoints are cursor-paginated. Pass `page_size` to control how many records you get per request (default 25), and use the `after` cursor from `pagination_meta` to fetch the next page:
```json theme={null}
{
"incidents": [...],
"pagination_meta": {
"after": "01FCNDV6P870EA6S7TK1DSYDG0",
"page_size": 25
}
}
```
To iterate through all records, repeat the request with `after` set to the cursor from the previous response, until a response returns fewer records than `page_size`. The maximum `page_size` varies by endpoint and is documented on each endpoint's page.
## Errors
We use standard HTTP response codes. The response body is JSON with a `type`, `status`, `request_id`, and a list of `errors`:
```json theme={null}
{
"type": "validation_error",
"status": 422,
"request_id": "631766c4-4afd-4803-997c-cd700928fa4b",
"errors": [
{
"code": "is_required",
"message": "A severity is required to open an incident",
"source": { "field": "severity_id" }
}
]
}
```
The `request_id` can be provided to support to help debug issues.
## Compatibility
We won't make breaking changes to existing endpoints, but expect integrators to upgrade within 3 months of deprecation. Backwards-compatible changes include:
* Adding new endpoints
* Adding new properties to responses
* Reordering response properties
* Adding optional request parameters
* Altering the format or length of IDs
* Adding new enum values
When breaking changes are unavoidable, we create a new version on a separate path (e.g. `/v1/incidents` → `/v2/incidents`) and run them in parallel.
For questions, email [support@incident.io](mailto:support@incident.io).
# Updated v1
Source: https://docs.incident.io/api-reference/ip-allowlist/updated-v1
/openapi/audit-logs.json webhook ip_allowlist.updated.1
This entry is created whenever an IP allowlist is updated
# IPAllowlists
Source: https://docs.incident.io/api-reference/ipallowlists-v1
API endpoints for ipallowlists
Manage the IP allowlist.
When enabled, the IP allowlist restricts authenticated traffic from the dashboard, public API and mobile app.
## The ipallowlist object
# Show
Source: https://docs.incident.io/api-reference/ipallowlists-v1/show
/openapi/tags/ipallowlists-v1.json get /v1/ip_allowlists
Show the IP allowlist for your organisation
# Update
Source: https://docs.incident.io/api-reference/ipallowlists-v1/update
/openapi/tags/ipallowlists-v1.json put /v1/ip_allowlists
Update the IP allowlist for your organisation
🔑 Requires the `security_settings.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/maintenance-window/created-v1
/openapi/audit-logs.json webhook maintenance_window.created.1
This entry is created whenever a maintenance window is created
# Deleted v1
Source: https://docs.incident.io/api-reference/maintenance-window/deleted-v1
/openapi/audit-logs.json webhook maintenance_window.deleted.1
This entry is created whenever a maintenance window is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/maintenance-window/updated-v1
/openapi/audit-logs.json webhook maintenance_window.updated.1
This entry is created whenever a maintenance window is updated
# MaintenanceWindows
Source: https://docs.incident.io/api-reference/maintenancewindows-v1
API endpoints for maintenancewindows
Manage maintenance windows for temporarily overriding alert routing during planned maintenance.
Maintenance windows allow you to suppress or redirect alerts during scheduled maintenance periods, preventing unnecessary escalations and noise.
## The maintenancewindow object
# Create
Source: https://docs.incident.io/api-reference/maintenancewindows-v1/create
/openapi/tags/maintenancewindows-v1.json post /v1/maintenance_windows
Create a new maintenance window.
🔑 Requires the `maintenance_window.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/maintenancewindows-v1/delete
/openapi/tags/maintenancewindows-v1.json delete /v1/maintenance_windows/{id}
Archives a maintenance window. Cannot archive active windows.
🔑 Requires the `maintenance_window.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/maintenancewindows-v1/list
/openapi/tags/maintenancewindows-v1.json get /v1/maintenance_windows
List maintenance windows for your organisation.
🔑 Requires the `maintenance_windows.view` scope.
# Show
Source: https://docs.incident.io/api-reference/maintenancewindows-v1/show
/openapi/tags/maintenancewindows-v1.json get /v1/maintenance_windows/{id}
Show a particular maintenance window.
🔑 Requires the `maintenance_windows.view` scope.
# Update
Source: https://docs.incident.io/api-reference/maintenancewindows-v1/update
/openapi/tags/maintenancewindows-v1.json put /v1/maintenance_windows/{id}
Update an existing maintenance window.
🔑 Requires the `maintenance_window.update` scope.
# Granted private
Source: https://docs.incident.io/api-reference/membership-v1/granted-private
/openapi/webhooks.json webhook private_incident.membership_granted_v1
This webhook is emitted whenever a user is given access to a private incident.
# Revoked private
Source: https://docs.incident.io/api-reference/membership-v1/revoked-private
/openapi/webhooks.json webhook private_incident.membership_revoked_v1
This webhook is emitted whenever a user's access to a private incident is revoked.
# Notification Methods
Source: https://docs.incident.io/api-reference/notification-methods-v2
API endpoints for notification methods
## The notification method object
# List
Source: https://docs.incident.io/api-reference/notification-methods-v2/list
/openapi/tags/notification-methods-v2.json get /v2/users/{user_id}/notification_methods
List notification methods for a user. Phone numbers are partially redacted unless the API key holds the notification_methods.view_unredacted scope.
🔑 Requires the `notification_methods.view` scope.
# Notification Rules
Source: https://docs.incident.io/api-reference/notification-rules-v2
API endpoints for notification rules
## The notification rule object
# List
Source: https://docs.incident.io/api-reference/notification-rules-v2/list
/openapi/tags/notification-rules-v2.json get /v2/users/{user_id}/notification_rules
List notification rules for a user. Rules define how and when a user is notified for on-call pages. Only includes high_urgency and low_urgency rules; shift_changes rules are not returned.
🔑 Requires the `notification_rules.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/nudge/created-v1
/openapi/audit-logs.json webhook nudge.created.1
This entry is created whenever a nudge is created
# Deleted v1
Source: https://docs.incident.io/api-reference/nudge/deleted-v1
/openapi/audit-logs.json webhook nudge.deleted.1
This entry is created whenever a nudge is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/nudge/updated-v1
/openapi/audit-logs.json webhook nudge.updated.1
This entry is created whenever a nudge is updated
# Created v1
Source: https://docs.incident.io/api-reference/on-call-notification-method/created-v1
/openapi/audit-logs.json webhook on_call_notification_method.created.1
This entry is created whenever an on-call notification method is created by an actor that isn't the owning user
# Created v2
Source: https://docs.incident.io/api-reference/on-call-notification-method/created-v2
/openapi/audit-logs.json webhook on_call_notification_method.created.2
This entry is created whenever an on-call notification method is created by an actor that isn't the owning user
# Destroyed v1
Source: https://docs.incident.io/api-reference/on-call-notification-method/destroyed-v1
/openapi/audit-logs.json webhook on_call_notification_method.destroyed.1
This entry is created whenever an on-call notification method is destroyed by an actor that isn't the owning user
# Destroyed v2
Source: https://docs.incident.io/api-reference/on-call-notification-method/destroyed-v2
/openapi/audit-logs.json webhook on_call_notification_method.destroyed.2
This entry is created whenever an on-call notification method is destroyed by an actor that isn't the owning user
# Requested v1
Source: https://docs.incident.io/api-reference/on-call-upsell/requested-v1
/openapi/audit-logs.json webhook on_call_upsell.requested.1
This entry is created whenever a self-serve on-call seat upsell is submitted.
# Updated v1
Source: https://docs.incident.io/api-reference/organisation-settings/updated-v1
/openapi/audit-logs.json webhook organisation_settings.updated.1
This entry is created when certain organisation settings are updated
# Created v1
Source: https://docs.incident.io/api-reference/policy-report-schedule/created-v1
/openapi/audit-logs.json webhook policy_report_schedule.created.1
This entry is created whenever a policy report schedule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/policy-report-schedule/deleted-v1
/openapi/audit-logs.json webhook policy_report_schedule.deleted.1
This entry is created whenever a policy report schedule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/policy-report-schedule/updated-v1
/openapi/audit-logs.json webhook policy_report_schedule.updated.1
This entry is created whenever a policy report schedule is updated
# Created v1
Source: https://docs.incident.io/api-reference/policy/created-v1
/openapi/audit-logs.json webhook policy.created.1
This entry is created whenever a policy is created
# Created v2
Source: https://docs.incident.io/api-reference/policy/created-v2
/openapi/audit-logs.json webhook policy.created.2
This entry is created whenever a policy is created
# Deleted v1
Source: https://docs.incident.io/api-reference/policy/deleted-v1
/openapi/audit-logs.json webhook policy.deleted.1
This entry is created whenever a policy is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/policy/updated-v1
/openapi/audit-logs.json webhook policy.updated.1
This entry is created whenever a policy is updated
# Updated v2
Source: https://docs.incident.io/api-reference/policy/updated-v2
/openapi/audit-logs.json webhook policy.updated.2
This entry is created whenever a policy is updated
# Created v1
Source: https://docs.incident.io/api-reference/post-incident-task/created-v1
/openapi/audit-logs.json webhook post_incident_task.created.1
This entry is created whenever a post-incident task is created
# Deleted v1
Source: https://docs.incident.io/api-reference/post-incident-task/deleted-v1
/openapi/audit-logs.json webhook post_incident_task.deleted.1
This entry is created whenever a post-incident task is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/post-incident-task/updated-v1
/openapi/audit-logs.json webhook post_incident_task.updated.1
This entry is created whenever a post-incident task is updated
# Updated private
Source: https://docs.incident.io/api-reference/postmortem-document-status-v1/updated-private
/openapi/webhooks.json webhook private_incident.postmortem_document_status_updated_v1
This webhook is emitted whenever a postmortem's status, on a private incident, is updated
# Updated public
Source: https://docs.incident.io/api-reference/postmortem-document-status-v1/updated-public
/openapi/webhooks.json webhook public_incident.postmortem_document_status_updated_v1
This webhook is emitted whenever a postmortem's status is updated
# Created v1
Source: https://docs.incident.io/api-reference/postmortem-section/created-v1
/openapi/audit-logs.json webhook postmortem_section.created.1
This entry is created whenever a postmortem template section is created
# Created v2
Source: https://docs.incident.io/api-reference/postmortem-section/created-v2
/openapi/audit-logs.json webhook postmortem_section.created.2
This entry is created whenever a postmortem template section is created
# Deleted v1
Source: https://docs.incident.io/api-reference/postmortem-section/deleted-v1
/openapi/audit-logs.json webhook postmortem_section.deleted.1
This entry is created whenever a postmortem template section is deleted
# Deleted v2
Source: https://docs.incident.io/api-reference/postmortem-section/deleted-v2
/openapi/audit-logs.json webhook postmortem_section.deleted.2
This entry is created whenever a postmortem template section is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/postmortem-section/updated-v1
/openapi/audit-logs.json webhook postmortem_section.updated.1
This entry is created whenever a postmortem template section is updated
# Updated v2
Source: https://docs.incident.io/api-reference/postmortem-section/updated-v2
/openapi/audit-logs.json webhook postmortem_section.updated.2
This entry is created whenever a postmortem template section is updated
# Created v1
Source: https://docs.incident.io/api-reference/postmortem-template/created-v1
/openapi/audit-logs.json webhook postmortem_template.created.1
This entry is created whenever a postmortem template is created
# Created v2
Source: https://docs.incident.io/api-reference/postmortem-template/created-v2
/openapi/audit-logs.json webhook postmortem_template.created.2
This entry is created whenever a postmortem template is created
# Deleted v1
Source: https://docs.incident.io/api-reference/postmortem-template/deleted-v1
/openapi/audit-logs.json webhook postmortem_template.deleted.1
This entry is created whenever a postmortem template is deleted
# Deleted v2
Source: https://docs.incident.io/api-reference/postmortem-template/deleted-v2
/openapi/audit-logs.json webhook postmortem_template.deleted.2
This entry is created whenever a postmortem template is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/postmortem-template/updated-v1
/openapi/audit-logs.json webhook postmortem_template.updated.1
This entry is created whenever a postmortem template is updated
# Updated v2
Source: https://docs.incident.io/api-reference/postmortem-template/updated-v2
/openapi/audit-logs.json webhook postmortem_template.updated.2
This entry is created whenever a postmortem template is updated
# PostmortemDocuments
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1
API endpoints for postmortemdocuments
Manage post-mortem documents.
Post-mortem documents capture the learnings from an incident, and are associated with a specific
incident. Use this API to list and retrieve post-mortem documents, update their status, and fetch
the full document's content.
## The postmortemdocument object
# Attach
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1/attach
/openapi/tags/postmortemdocuments-v1.json post /v1/postmortem_documents/actions/attach
Link an externally-hosted post-mortem document to an incident.
Use this to attach a retrospective document you've created in your own provider (for example
Confluence, Notion, or Google Docs) to an existing incident. This is the API equivalent of
pasting a document link into the incident.io dashboard, and is useful for automating your
retrospective workflow - for example, creating a document in the right space with the right
permissions when an incident is opened, then linking it back to the incident.
Only one external post-mortem can be attached to an incident, and you cannot attach an external
document to an incident that already has an in-app post-mortem. Re-attaching the same incident
with a new permalink updates the existing link.
🔑 Requires the `external_postmortems.create` scope.
# List
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1/list
/openapi/tags/postmortemdocuments-v1.json get /v1/postmortem_documents
List post-mortem documents for the organisation.
Results can be filtered by incident and sorted by creation date. This endpoint returns document
metadata only. If you want to fetch the content of the post-mortem, use the ShowContent endpoint.
🔑 Requires the `incidents.view` scope.
# Show
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1/show
/openapi/tags/postmortemdocuments-v1.json get /v1/postmortem_documents/{id}
Get a single post-mortem document by ID.
This returns the document's metadata. To retrieve the content of the post-mortem, use the ShowContent endpoint.
🔑 Requires the `incidents.view` scope.
# Show Content
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1/show-content
/openapi/tags/postmortemdocuments-v1.json get /v1/postmortem_documents/{id}/content
Fetch the content of a post-mortem document, rendered as markdown.
The response contains the full document content as a single markdown string. The markdown
follows standard formatting and is structured to mirror the post-mortem as it appears in
the incident.io dashboard:
- **Headings** (`#`, `##`, `###`) for document title and sections
- **Bold** and *italic* text formatting
- Bullet lists and numbered lists
- [Links](url) to external resources, Slack threads, and pull requests
- Mentions of users, incidents, and catalog entries resolved to their display names
- Custom field values rendered as labelled bullet lists
- Timeline entries grouped by date with timestamps
- Follow-ups with assignees and descriptions
To preview what this markdown will look like for a given post-mortem, open the document
in the incident.io dashboard and use the "Copy to clipboard" button. The copied content
uses the same rendering pipeline as this endpoint.
If you only need document metadata, use the Show or List endpoints instead.
🔑 Requires the `in_app_postmortems.copy_as_markdown` scope.
# Update
Source: https://docs.incident.io/api-reference/postmortemdocuments-v1/update
/openapi/tags/postmortemdocuments-v1.json put /v1/postmortem_documents/{id}
Update the status of a post-mortem document.
🔑 Requires the `in_app_postmortems.update_status` scope.
# Access attempted v1
Source: https://docs.incident.io/api-reference/private-alert/access-attempted-v1
/openapi/audit-logs.json webhook private_alert.access_attempted.1
This entry is created whenever someone attempts to access a private alert.
# Access attempted v1
Source: https://docs.incident.io/api-reference/private-escalation/access-attempted-v1
/openapi/audit-logs.json webhook private_escalation.access_attempted.1
This entry is created whenever someone attempts to access a private escalation.
# Granted v1
Source: https://docs.incident.io/api-reference/private-incident-membership/granted-v1
/openapi/audit-logs.json webhook private_incident_membership.granted.1
This entry is created whenever someone is granted access to a private incident. If they have the 'manage private incidents' permission, then it'll appear that the system has given them access to the incident.
# Revoked v1
Source: https://docs.incident.io/api-reference/private-incident-membership/revoked-v1
/openapi/audit-logs.json webhook private_incident_membership.revoked.1
This entry is created whenever someone's access to a private incident is revoked.
# Upgraded to direct v1
Source: https://docs.incident.io/api-reference/private-incident-membership/upgraded-to-direct-v1
/openapi/audit-logs.json webhook private_incident_membership.upgraded_to_direct.1
This entry is created whenever someone's team-derived access to a private incident is upgraded to durable direct access, so it survives the covering team's access being revoked.
# Granted v1
Source: https://docs.incident.io/api-reference/private-incident-team-membership/granted-v1
/openapi/audit-logs.json webhook private_incident_team_membership.granted.1
This entry is created whenever a team is granted access to a private incident.
# Revoked v1
Source: https://docs.incident.io/api-reference/private-incident-team-membership/revoked-v1
/openapi/audit-logs.json webhook private_incident_team_membership.revoked.1
This entry is created whenever a team's access to a private incident is revoked.
# Access attempted v1
Source: https://docs.incident.io/api-reference/private-incident/access-attempted-v1
/openapi/audit-logs.json webhook private_incident.access_attempted.1
This entry is created whenever someone attempts to access a private incident.
# Access attempted v2
Source: https://docs.incident.io/api-reference/private-incident/access-attempted-v2
/openapi/audit-logs.json webhook private_incident.access_attempted.2
This entry is created whenever someone attempts to access a private incident.
# Access requested v1
Source: https://docs.incident.io/api-reference/private-incident/access-requested-v1
/openapi/audit-logs.json webhook private_incident.access_requested.1
This entry is created whenever someone requests access to a private incident.
# Accessed via bot v1
Source: https://docs.incident.io/api-reference/private-incident/accessed-via-bot-v1
/openapi/audit-logs.json webhook private_incident.accessed_via_bot.1
This entry is created whenever someone accesses a private incident via the incident bot.
# Exported v1
Source: https://docs.incident.io/api-reference/private-insights/exported-v1
/openapi/audit-logs.json webhook private_insights.exported.1
This entry is created whenever someone exports private Insights data.
# Measure queried v1
Source: https://docs.incident.io/api-reference/private-insights/measure-queried-v1
/openapi/audit-logs.json webhook private_insights.measure_queried.1
This entry is created whenever someone queries a private Insights measure.
# Underlying data queried v1
Source: https://docs.incident.io/api-reference/private-insights/underlying-data-queried-v1
/openapi/audit-logs.json webhook private_insights.underlying_data_queried.1
This entry is created whenever someone queries private Insights underlying data.
# Updated v1
Source: https://docs.incident.io/api-reference/qr-code-mobile-login-setting/updated-v1
/openapi/audit-logs.json webhook qr_code_mobile_login_setting.updated.1
This entry is created whenever the QR code mobile login setting is toggled for an organisation
# Created v1
Source: https://docs.incident.io/api-reference/rbac-role/created-v1
/openapi/audit-logs.json webhook rbac_role.created.1
This entry is created whenever a rbac role is created
# Deleted v1
Source: https://docs.incident.io/api-reference/rbac-role/deleted-v1
/openapi/audit-logs.json webhook rbac_role.deleted.1
This entry is created whenever a rbac role is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/rbac-role/updated-v1
/openapi/audit-logs.json webhook rbac_role.updated.1
This entry is created whenever a rbac role is updated
# Schedule Entries
Source: https://docs.incident.io/api-reference/schedule-entries-v2
API endpoints for schedule entries
## The schedule entry object
# List
Source: https://docs.incident.io/api-reference/schedule-entries-v2/list
/openapi/tags/schedule-entries-v2.json get /v2/schedule_entries
List the schedule entries for a schedule over a window of time.
Use this endpoint to find out who is on-call for a schedule, either right now or
at any point in the future. Common uses include:
- Building a calendar or timeline view of who is on-call.
- Looking up who was on-call at a particular moment (for example, when an
incident fired).
- Exporting upcoming shifts into another system, such as a payroll or
scheduling tool.
The response groups entries into three lists: `scheduled` (the entries the
rotation rules produce, before any overrides), `overrides` (any one-off
overrides that apply in the window) and `final` (the effective schedule
after overrides have been merged in — this is normally the list you want).
Each entry includes the `rotation_id` and `layer_id` it belongs to.
Schedules can be made up of multiple rotations (for example, a primary and
a secondary rotation) and each rotation can have several layers, and we
return entries for every rotation and layer on the schedule.
The endpoint returns all entries that overlap with the given window. If no
window is provided we default to a sensible range starting from now.
## Pagination
Responses are paginated. When more entries are available than fit on a single
page, the response includes a `pagination_meta` block with two fields:
- `after_url` — a fully-formed URL for the next page. The simplest way
to paginate is to keep following this URL until it is no longer present.
- `after` — an opaque cursor token. To fetch the next page manually,
re-issue the request with `entry_window_start` set to this value and
`entry_window_end` left unchanged from the original request. Treat
the token as opaque — do not parse or modify it.
Keep paginating until `pagination_meta` is absent from the response, at
which point you have received every entry in the window.
🔑 Requires the `schedules.view` scope.
# Preview
Source: https://docs.incident.io/api-reference/schedule-entries-v2/preview
/openapi/tags/schedule-entries-v2.json post /v2/schedules/{id}/actions/preview_entries
Preview the schedule entries that would be generated by a proposed schedule configuration.
Use this endpoint before updating a schedule to see who would be on-call if you
saved the supplied schedule payload. The request body uses the same `schedule`
payload shape as Update schedule, so you can send the configuration you intend
to save without persisting it.
The response uses the same `schedule_entries` envelope as List schedule entries:
`scheduled` contains entries produced by the rotation rules, `overrides`
contains matching overrides, and `final` contains the effective schedule after
overrides are applied.
The preview window is bounded to keep requests predictable. If you ask for more
than 91 days, the response is capped to 91 days from `entry_window_start`.
🔑 Requires the `schedules.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/schedule-override/created-v1
/openapi/audit-logs.json webhook schedule_override.created.1
This entry is created whenever a schedule override is created
# Created v2
Source: https://docs.incident.io/api-reference/schedule-override/created-v2
/openapi/audit-logs.json webhook schedule_override.created.2
This entry is created whenever a schedule override is created
# Deleted v1
Source: https://docs.incident.io/api-reference/schedule-override/deleted-v1
/openapi/audit-logs.json webhook schedule_override.deleted.1
This entry is created whenever a schedule override is deleted
# Deleted v2
Source: https://docs.incident.io/api-reference/schedule-override/deleted-v2
/openapi/audit-logs.json webhook schedule_override.deleted.2
This entry is created whenever a schedule override is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/schedule-override/updated-v1
/openapi/audit-logs.json webhook schedule_override.updated.1
This entry is created whenever a schedule override is updated
# Updated v2
Source: https://docs.incident.io/api-reference/schedule-override/updated-v2
/openapi/audit-logs.json webhook schedule_override.updated.2
This entry is created whenever a schedule override is updated
# Schedule Overrides
Source: https://docs.incident.io/api-reference/schedule-overrides-v2
API endpoints for schedule overrides
## The schedule override object
# Create
Source: https://docs.incident.io/api-reference/schedule-overrides-v2/create
/openapi/tags/schedule-overrides-v2.json post /v2/schedule_overrides
Create a new schedule override.
🔑 Requires the `schedule_overrides.create` scope.
# List
Source: https://docs.incident.io/api-reference/schedule-overrides-v2/list
/openapi/tags/schedule-overrides-v2.json get /v2/schedule_overrides
List the overrides on a schedule.
Overrides are one-off changes layered on top of the rotations, such as someone
covering a colleague's shift. This returns the overrides themselves: to see the
effective schedule with overrides already merged in, use the schedule entries
endpoint instead.
Overrides belong to a specific layer of a specific rotation, so you can narrow the
results with `rotation_id` and `layer_id`.
Archived overrides are not returned.
🔑 Requires the `schedules.view` scope.
# Schedule Replicas
Source: https://docs.incident.io/api-reference/schedule-replicas-v2
API endpoints for schedule replicas
## The schedule replica object
# Create
Source: https://docs.incident.io/api-reference/schedule-replicas-v2/create
/openapi/tags/schedule-replicas-v2.json post /v2/schedules/{schedule_id}/replicas
Create a new schedule replica.
🔑 Requires the `schedules.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/schedule-replicas-v2/delete
/openapi/tags/schedule-replicas-v2.json delete /v2/schedules/{schedule_id}/replicas/{id}
Archives a single schedule replica, stopping incident.io from syncing on-call shifts to the external provider.
As with disabling mirroring via the UI, this will remove any upcoming overrides that incident.io has created in the external schedule, restoring it to its original state. If multiple replicas target the same external schedule, overrides are only removed when the last replica pointing to that schedule is deleted.
Note: override cleanup is supported for PagerDuty and Jira Service Management. Opsgenie does not support programmatic override deletion, so overrides must be removed manually.
🔑 Requires the `schedules.update` scope.
# List
Source: https://docs.incident.io/api-reference/schedule-replicas-v2/list
/openapi/tags/schedule-replicas-v2.json get /v2/schedules/{schedule_id}/replicas
List all replicas for a schedule.
🔑 Requires the `schedules.view` scope.
# Show
Source: https://docs.incident.io/api-reference/schedule-replicas-v2/show
/openapi/tags/schedule-replicas-v2.json get /v2/schedules/{schedule_id}/replicas/{id}
Get a single schedule replica.
🔑 Requires the `schedules.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/schedule-sync-rule/created-v1
/openapi/audit-logs.json webhook schedule_sync_rule.created.1
This entry is created whenever a schedule sync rule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/schedule-sync-rule/deleted-v1
/openapi/audit-logs.json webhook schedule_sync_rule.deleted.1
This entry is created whenever a schedule sync rule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/schedule-sync-rule/updated-v1
/openapi/audit-logs.json webhook schedule_sync_rule.updated.1
This entry is created whenever a schedule sync rule is updated
# Schedule Sync Rules
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2
API endpoints for schedule sync rules
## The schedule sync rule object
# Create
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2/create
/openapi/tags/schedule-sync-rules-v2.json post /v2/schedules/{schedule_id}/sync_rules
Create a new sync rule linking a schedule to a sync target.
🔑 Requires the `schedule_sync_rules.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2/delete
/openapi/tags/schedule-sync-rules-v2.json delete /v2/schedules/{schedule_id}/sync_rules/{id}
Archive a sync rule, unlinking the schedule from the sync target.
🔑 Requires the `schedule_sync_rules.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2/list
/openapi/tags/schedule-sync-rules-v2.json get /v2/schedules/{schedule_id}/sync_rules
List the sync rules configured on this schedule.
🔑 Requires the `schedules.view` scope.
# Show
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2/show
/openapi/tags/schedule-sync-rules-v2.json get /v2/schedules/{schedule_id}/sync_rules/{id}
Get a single sync rule for a schedule.
🔑 Requires the `schedules.view` scope.
# Update
Source: https://docs.incident.io/api-reference/schedule-sync-rules-v2/update
/openapi/tags/schedule-sync-rules-v2.json put /v2/schedules/{schedule_id}/sync_rules/{id}
Update a sync rule's sync_type and permanent members in place. If the rule's sync target is shared with other schedules, a sync_type change propagates to every linked schedule and the entire operation aborts if the caller lacks edit permission on any of them. Permanent members are scoped to this rule and never propagate.
🔑 Requires the `schedule_sync_rules.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/schedule-sync-target/created-v1
/openapi/audit-logs.json webhook schedule_sync_target.created.1
This entry is created whenever a schedule sync target is created
# Deleted v1
Source: https://docs.incident.io/api-reference/schedule-sync-target/deleted-v1
/openapi/audit-logs.json webhook schedule_sync_target.deleted.1
This entry is created whenever a schedule sync target is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/schedule-sync-target/updated-v1
/openapi/audit-logs.json webhook schedule_sync_target.updated.1
This entry is created whenever a schedule sync target's add_bot_to_group flag is updated
# Schedule Sync Targets
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2
API endpoints for schedule sync targets
Manage schedule sync targets (Slack user groups that schedules can sync to).
## The schedule sync target object
# Create
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2/create
/openapi/tags/schedule-sync-targets-v2.json post /v2/schedule_sync_targets
Create a new schedule sync target for a Slack user group.
🔑 Requires the `schedule_sync_targets.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2/delete
/openapi/tags/schedule-sync-targets-v2.json delete /v2/schedule_sync_targets/{id}
Archive a schedule sync target. Will fail if any active sync rules reference this target.
🔑 Requires the `schedule_sync_targets.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2/list
/openapi/tags/schedule-sync-targets-v2.json get /v2/schedule_sync_targets
List all schedule sync targets for this organisation.
🔑 Requires the `schedules.view` scope.
# Show
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2/show
/openapi/tags/schedule-sync-targets-v2.json get /v2/schedule_sync_targets/{id}
Get a single schedule sync target.
🔑 Requires the `schedules.view` scope.
# Update
Source: https://docs.incident.io/api-reference/schedule-sync-targets-v2/update
/openapi/tags/schedule-sync-targets-v2.json put /v2/schedule_sync_targets/{id}
Update the add_bot_to_group flag on a sync target. The change propagates to every schedule with an active sync rule pointing at this target; the entire operation aborts if the caller lacks edit permission on any of those schedules.
🔑 Requires the `schedule_sync_targets.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/schedule/created-v1
/openapi/audit-logs.json webhook schedule.created.1
This entry is created whenever a schedule is created
# Deleted v1
Source: https://docs.incident.io/api-reference/schedule/deleted-v1
/openapi/audit-logs.json webhook schedule.deleted.1
This entry is created whenever a schedule is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/schedule/updated-v1
/openapi/audit-logs.json webhook schedule.updated.1
This entry is created whenever a schedule is updated
# Schedules
Source: https://docs.incident.io/api-reference/schedules-v2
API endpoints for schedules
View and manage schedules.
Manage your full schedule of on-call rotations, including the users and rotation configuration.
## The schedule object
# Create
Source: https://docs.incident.io/api-reference/schedules-v2/create
/openapi/tags/schedules-v2.json post /v2/schedules
Create a new schedule.
🔑 Requires the `schedules.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/schedules-v2/delete
/openapi/tags/schedules-v2.json delete /v2/schedules/{id}
Archives a single schedule. Will fail if the schedule has active replicas — remove all replicas before deleting.
🔑 Requires the `schedules.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/schedules-v2/list
/openapi/tags/schedules-v2.json get /v2/schedules
List configured schedules.
🔑 Requires the `schedules.view` scope.
# Show
Source: https://docs.incident.io/api-reference/schedules-v2/show
/openapi/tags/schedules-v2.json get /v2/schedules/{id}
Get a single schedule.
🔑 Requires the `schedules.view` scope.
# Update
Source: https://docs.incident.io/api-reference/schedules-v2/update
/openapi/tags/schedules-v2.json put /v2/schedules/{id}
Update a schedule.
Updating a schedule replaces its entire configuration with the one you send,
including any scheduled future versions of its rotations — fetch the schedule
first and include every version you want to keep.
To change who's in a rotation from a future date without affecting shifts
before then, keep the current version unchanged and add another version of the
same rotation with `effective_from` set to when the change should land —
ideally an upcoming handover, so nobody is swapped mid-shift. You can check the
effect of any configuration before saving it with Preview schedule entries.
🔑 Requires the `schedules.update` scope.
# Role mappings updated v1
Source: https://docs.incident.io/api-reference/scim-group/role-mappings-updated-v1
/openapi/audit-logs.json webhook scim_group.role_mappings_updated.1
This entry is created whenever a SCIM group is mapped to a new RBAC role
# Seat mappings updated v1
Source: https://docs.incident.io/api-reference/scim-group/seat-mappings-updated-v1
/openapi/audit-logs.json webhook scim_group.seat_mappings_updated.1
This entry is created whenever a SCIM group is mapped to new seat types
# Created v1
Source: https://docs.incident.io/api-reference/secret/created-v1
/openapi/audit-logs.json webhook secret.created.1
This entry is created whenever a secret is created
# Deleted v1
Source: https://docs.incident.io/api-reference/secret/deleted-v1
/openapi/audit-logs.json webhook secret.deleted.1
This entry is created whenever a secret is deleted
# Reference added v1
Source: https://docs.incident.io/api-reference/secret/reference-added-v1
/openapi/audit-logs.json webhook secret.reference_added.1
This entry is created whenever a secret is referenced by a workflow for the first time
# Reference removed v1
Source: https://docs.incident.io/api-reference/secret/reference-removed-v1
/openapi/audit-logs.json webhook secret.reference_removed.1
This entry is created whenever a secret stops being referenced by a workflow
# Rotated v1
Source: https://docs.incident.io/api-reference/secret/rotated-v1
/openapi/audit-logs.json webhook secret.rotated.1
This entry is created whenever a secret's value is rotated
# Updated v1
Source: https://docs.incident.io/api-reference/secret/updated-v1
/openapi/audit-logs.json webhook secret.updated.1
This entry is created whenever a secret's metadata is updated
# Secrets
Source: https://docs.incident.io/api-reference/secrets-v2
API endpoints for secrets
Manage secrets: named credentials that workflows can reference. A secret's value can be set and rotated but is never returned by the API.
## The secret object
# Create
Source: https://docs.incident.io/api-reference/secrets-v2/create
/openapi/tags/secrets-v2.json post /v2/secrets
Create a new secret with its initial value.
🔑 Requires the `secrets.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/secrets-v2/delete
/openapi/tags/secrets-v2.json delete /v2/secrets/{id}
Delete a secret, permanently removing its value. Fails if the secret is still referenced by a workflow.
🔑 Requires the `secrets.delete` scope.
# List
Source: https://docs.incident.io/api-reference/secrets-v2/list
/openapi/tags/secrets-v2.json get /v2/secrets
List all secrets for this organisation. Returns metadata only, never values.
🔑 Requires the `secrets.view_metadata` scope.
# Rotate
Source: https://docs.incident.io/api-reference/secrets-v2/rotate
/openapi/tags/secrets-v2.json post /v2/secrets/{id}/actions/rotate
Rotate a secret's value, replacing the current value with a new one. The previous value is retired and can no longer be read.
🔑 Requires the `secrets.update` scope.
# Show
Source: https://docs.incident.io/api-reference/secrets-v2/show
/openapi/tags/secrets-v2.json get /v2/secrets/{id}
Show a single secret's metadata, including its version history. Never returns values.
🔑 Requires the `secrets.view_metadata` scope.
# Update
Source: https://docs.incident.io/api-reference/secrets-v2/update
/openapi/tags/secrets-v2.json put /v2/secrets/{id}
Update a secret's metadata. Does not change the value: use the rotate action for that.
🔑 Requires the `secrets.update` scope.
# Severities
Source: https://docs.incident.io/api-reference/severities-v1
API endpoints for severities
Manage incident severities.
Each incident has a severity, picked from one of the severities configured in your
organisations settings.
Severities help categorise incidents, and communicate urgency/impact. You can use
severities when filtering incidents in the dashboard, and in workflows and announcement
rules.
## The severity object
# Create
Source: https://docs.incident.io/api-reference/severities-v1/create
/openapi/tags/severities-v1.json post /v1/severities
Create a new severity
🔑 Requires the `organisation_settings.update` scope.
# Delete
Source: https://docs.incident.io/api-reference/severities-v1/delete
/openapi/tags/severities-v1.json delete /v1/severities/{id}
Delete a severity
🔑 Requires the `organisation_settings.update` scope.
# List
Source: https://docs.incident.io/api-reference/severities-v1/list
/openapi/tags/severities-v1.json get /v1/severities
List all incident severities for an organisation.
🔑 Requires the `severities.view` scope.
# Show
Source: https://docs.incident.io/api-reference/severities-v1/show
/openapi/tags/severities-v1.json get /v1/severities/{id}
Get a single incident severity.
🔑 Requires the `severities.view` scope.
# Update
Source: https://docs.incident.io/api-reference/severities-v1/update
/openapi/tags/severities-v1.json put /v1/severities/{id}
Update an existing severity
🔑 Requires the `organisation_settings.update` scope.
# Created v1
Source: https://docs.incident.io/api-reference/severity/created-v1
/openapi/audit-logs.json webhook severity.created.1
This entry is created whenever a severity is created
# Deleted v1
Source: https://docs.incident.io/api-reference/severity/deleted-v1
/openapi/audit-logs.json webhook severity.deleted.1
This entry is created whenever a severity is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/severity/updated-v1
/openapi/audit-logs.json webhook severity.updated.1
This entry is created whenever a severity is updated
# Change public
Source: https://docs.incident.io/api-reference/shift-v1/change-public
/openapi/webhooks.json webhook schedule.shift_change_v1
This webhook is emitted whenever the on-call user(s) change on a schedule.
# Status Page Incident Updates
Source: https://docs.incident.io/api-reference/status-page-incident-updates-v2
API endpoints for status page incident updates
## The status page incident update object
# Create
Source: https://docs.incident.io/api-reference/status-page-incident-updates-v2/create
/openapi/tags/status-page-incident-updates-v2.json post /v2/status_page_incident_updates
Post an update on a Status Page incident.
This is the endpoint to use when resolving an incident - set incident_status to "resolved" to end the incident. There is a limit of 100 updates per incident.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# Status Page Incidents
Source: https://docs.incident.io/api-reference/status-page-incidents-v2
API endpoints for status page incidents
## The status page incident object
# Create
Source: https://docs.incident.io/api-reference/status-page-incidents-v2/create
/openapi/tags/status-page-incidents-v2.json post /v2/status_page_incidents
Create a status page incident.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# Create retrospective
Source: https://docs.incident.io/api-reference/status-page-incidents-v2/create-retrospective
/openapi/tags/status-page-incidents-v2.json post /v2/status_page_retrospective_incidents
Create a retrospective (historical) status page incident.
Use this to backfill a completed incident with a reconstructed timeline of past updates, for example when migrating from another status page provider. Every update's published_at must be in the past, the updates must be ordered chronologically (earliest first), and the final update must set incident_status to "resolved".
Retrospective incidents never notify subscribers.
As this endpoint is intended for bulk historical backfill, it has a dedicated rate limit of 5 requests per second (with a burst allowance of 300 requests) per API key. If you exceed it you'll receive a 429 response with a Retry-After header; back off and retry to resume your backfill.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# List
Source: https://docs.incident.io/api-reference/status-page-incidents-v2/list
/openapi/tags/status-page-incidents-v2.json get /v2/status_page_incidents
List status page incidents.
This endpoint requires a valid API key but no specific scopes.
# Show
Source: https://docs.incident.io/api-reference/status-page-incidents-v2/show
/openapi/tags/status-page-incidents-v2.json get /v2/status_page_incidents/{status_page_incident_id}
Show a status page incident.
This endpoint requires a valid API key but no specific scopes.
# Update
Source: https://docs.incident.io/api-reference/status-page-incidents-v2/update
/openapi/tags/status-page-incidents-v2.json put /v2/status_page_incidents/{status_page_incident_id}
Update a status page incident.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# Status Page Maintenance Updates
Source: https://docs.incident.io/api-reference/status-page-maintenance-updates-v2
API endpoints for status page maintenance updates
## The status page maintenance update object
# Create
Source: https://docs.incident.io/api-reference/status-page-maintenance-updates-v2/create
/openapi/tags/status-page-maintenance-updates-v2.json post /v2/status_page_maintenance_updates
Post an update on a Status Page maintenance window.
This is the endpoint to use when completing a maintenance window - set maintenance_status to "maintenance_complete" to end the maintenance. There is a limit of 100 updates per maintenance window.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# Status Page Maintenances
Source: https://docs.incident.io/api-reference/status-page-maintenances-v2
API endpoints for status page maintenances
## The status page maintenance object
# Create
Source: https://docs.incident.io/api-reference/status-page-maintenances-v2/create
/openapi/tags/status-page-maintenances-v2.json post /v2/status_page_maintenances
Schedule a Status Page maintenance window.
This endpoint requires an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
🔑 Requires the `status_pages.publish_updates` scope.
# List
Source: https://docs.incident.io/api-reference/status-page-maintenances-v2/list
/openapi/tags/status-page-maintenances-v2.json get /v2/status_page_maintenances
List status page maintenances.
This endpoint requires a valid API key but no specific scopes.
# Show
Source: https://docs.incident.io/api-reference/status-page-maintenances-v2/show
/openapi/tags/status-page-maintenances-v2.json get /v2/status_page_maintenances/{status_page_maintenance_id}
Show a status page maintenance window.
This endpoint requires a valid API key but no specific scopes.
# Status Page Response Incidents
Source: https://docs.incident.io/api-reference/status-page-response-incidents-v1
API endpoints for status page response incidents
## The status page response incident object
# List
Source: https://docs.incident.io/api-reference/status-page-response-incidents-v1/list
/openapi/tags/status-page-response-incidents-v1.json get /v1/status-pages/{id}/incidents/{incident_id}/response-incidents
List the linked Response incidents for a status page incident.
# Created v1
Source: https://docs.incident.io/api-reference/status-page-sub-page/created-v1
/openapi/audit-logs.json webhook status_page_sub_page.created.1
This entry is created whenever a status page sub-page is created
# Deleted v1
Source: https://docs.incident.io/api-reference/status-page-sub-page/deleted-v1
/openapi/audit-logs.json webhook status_page_sub_page.deleted.1
This entry is created whenever a status page sub-page is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/status-page-sub-page/updated-v1
/openapi/audit-logs.json webhook status_page_sub_page.updated.1
This entry is created whenever a status page sub-page has its configuration updated
# Created v1
Source: https://docs.incident.io/api-reference/status-page-template/created-v1
/openapi/audit-logs.json webhook status_page_template.created.1
This entry is created whenever a status page template is created
# Deleted v1
Source: https://docs.incident.io/api-reference/status-page-template/deleted-v1
/openapi/audit-logs.json webhook status_page_template.deleted.1
This entry is created whenever a status page template is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/status-page-template/updated-v1
/openapi/audit-logs.json webhook status_page_template.updated.1
This entry is created whenever a status page template is updated
# Created v1
Source: https://docs.incident.io/api-reference/status-page/created-v1
/openapi/audit-logs.json webhook status_page.created.1
This entry is created whenever a status page is created
# Deleted v1
Source: https://docs.incident.io/api-reference/status-page/deleted-v1
/openapi/audit-logs.json webhook status_page.deleted.1
This entry is created whenever a status page is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/status-page/updated-v1
/openapi/audit-logs.json webhook status_page.updated.1
This entry is created whenever a status page has its configuration updated
# Status Pages
Source: https://docs.incident.io/api-reference/status-pages-v2
API endpoints for status pages
Manage and publish to status pages.
Before using these endpoints, you must create a status page in the incident.io dashboard (find Status Pages in the left navigation bar). You can then use the ListStatusPages endpoint to find your status page IDs, and the ShowStatusPageStructure endpoint to find component IDs and group IDs for your status page.
For read-only access (listing status pages, viewing structure, incidents, and maintenance windows), any valid API key will work. For write requests (creating incidents, maintenance windows, and publishing updates), you will need an API key with the "Create status page incidents, status page maintenance windows, and publish status page updates" scope.
## The status page object
# List
Source: https://docs.incident.io/api-reference/status-pages-v2/list
/openapi/tags/status-pages-v2.json get /v2/status_pages
List all status pages for your organisation.
This endpoint requires a valid API key but no specific scopes. Use this to find status page IDs for use in other endpoints.
# Show
Source: https://docs.incident.io/api-reference/status-pages-v2/show
/openapi/tags/status-pages-v2.json get /v2/status_page_structures/{status_page_id}
Show the structure of a status page.
This endpoint requires a valid API key but no specific scopes. Returns the components and component groups configured on a status page. Use this to find component IDs when specifying affected components for incidents or maintenance windows.
# Created v1
Source: https://docs.incident.io/api-reference/team-role/created-v1
/openapi/audit-logs.json webhook team_role.created.1
This entry is created whenever a team role is created
# Deleted v1
Source: https://docs.incident.io/api-reference/team-role/deleted-v1
/openapi/audit-logs.json webhook team_role.deleted.1
This entry is created whenever a team role is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/team-role/updated-v1
/openapi/audit-logs.json webhook team_role.updated.1
This entry is created whenever a team role is updated
# Updated v1
Source: https://docs.incident.io/api-reference/team-settings/updated-v1
/openapi/audit-logs.json webhook team_settings.updated.1
This entry is created whenever team settings are updated
# Teams
Source: https://docs.incident.io/api-reference/teams-v3
API endpoints for teams
Manage teams.
Teams are groups of users that can be associated with incidents, escalation paths, and other
resources. Teams are built on top of catalog entries, allowing you to enrich them with
custom attributes.
## The team object
# List
Source: https://docs.incident.io/api-reference/teams-v3/list
/openapi/tags/teams-v3.json get /v3/teams
List all teams in the organisation.
🔑 Requires the `catalog_entries.view` scope.
# Show
Source: https://docs.incident.io/api-reference/teams-v3/show
/openapi/tags/teams-v3.json get /v3/teams/{id}
Get a single team.
🔑 Requires the `catalog_entries.view` scope.
# Installed v1
Source: https://docs.incident.io/api-reference/telemetry-data-source/installed-v1
/openapi/audit-logs.json webhook telemetry_data_source.installed.1
This entry is created whenever a telemetry data source is connected
# Uninstalled v1
Source: https://docs.incident.io/api-reference/telemetry-data-source/uninstalled-v1
/openapi/audit-logs.json webhook telemetry_data_source.uninstalled.1
This entry is created whenever a telemetry data source is disconnected
# Write access granted v1
Source: https://docs.incident.io/api-reference/telemetry-data-source/write-access-granted-v1
/openapi/audit-logs.json webhook telemetry_data_source.write_access_granted.1
This entry is created whenever tools on a connector are allowed to change the connected system
# Write access revoked v1
Source: https://docs.incident.io/api-reference/telemetry-data-source/write-access-revoked-v1
/openapi/audit-logs.json webhook telemetry_data_source.write_access_revoked.1
This entry is created whenever tools on a connector lose permission to change the connected system
# Telemetry
Source: https://docs.incident.io/api-reference/telemetry-v2
API endpoints for telemetry
Manage telemetry data source integrations.
## The telemetry object
# Update
Source: https://docs.incident.io/api-reference/telemetry-v2/update
/openapi/tags/telemetry-v2.json put /v2/telemetry/data_sources/{id}
Update the credentials or configuration of a telemetry data source. Provide only the config block that matches your data source type (e.g. grafana_config for Grafana, datadog_config for Datadog). New credentials are validated against the provider before being saved.
🔑 Requires the `organisation_settings.update` scope.
# Deleted v1
Source: https://docs.incident.io/api-reference/timeline-item/deleted-v1
/openapi/audit-logs.json webhook timeline_item.deleted.1
This entry is created whenever a timeline item is deleted
# Public
Source: https://docs.incident.io/api-reference/updated-v1/public
/openapi/webhooks.json webhook schedule.updated_v1
This webhook is emitted whenever a schedule's configuration is updated.
# Created v1
Source: https://docs.incident.io/api-reference/user/created-v1
/openapi/audit-logs.json webhook user.created.1
This entry is created whenever a user is created
# Deactivated v1
Source: https://docs.incident.io/api-reference/user/deactivated-v1
/openapi/audit-logs.json webhook user.deactivated.1
This entry is created whenever a user is deactivated
# Logged in v1
Source: https://docs.incident.io/api-reference/user/logged-in-v1
/openapi/audit-logs.json webhook user.logged_in.1
This entry is created whenever a user successfully logs in
# Reinstated v1
Source: https://docs.incident.io/api-reference/user/reinstated-v1
/openapi/audit-logs.json webhook user.reinstated.1
This entry is created when a user is reinstated after being deactivated
# Role memberships updated v1
Source: https://docs.incident.io/api-reference/user/role-memberships-updated-v1
/openapi/audit-logs.json webhook user.role_memberships_updated.1
This entry is created whenever a user's role memberships are changed.
# Updated v1
Source: https://docs.incident.io/api-reference/user/updated-v1
/openapi/audit-logs.json webhook user.updated.1
This entry is created whenever a user is updated
# Users
Source: https://docs.incident.io/api-reference/users-v2
API endpoints for users
View users.
Users all have a single base role, and can be assigned multiple custom roles. They can be managed via your Slack workspace or SAML provider.
## The user object
# List
Source: https://docs.incident.io/api-reference/users-v2/list
/openapi/tags/users-v2.json get /v2/users
List users in your account.
🔑 Requires the `users.view` scope.
# Show
Source: https://docs.incident.io/api-reference/users-v2/show
/openapi/tags/users-v2.json get /v2/users/{id}
Get a single user.
🔑 Requires the `users.view` scope.
# ShowPagingProvider
Source: https://docs.incident.io/api-reference/users-v2/showpagingprovider
/openapi/tags/users-v2.json get /v2/users/{user_id}/paging_provider
Show the paging provider that would be used to escalate to this user. Reflects their explicit preference if set; otherwise resolves to the effective fallback (typically `native` for on-call seat users, or a linked external provider otherwise). May be omitted only when the user cannot be escalated to at all (no seat and no linked external user).
🔑 Requires the `user_preferences.view` scope.
# UpdatePagingProvider
Source: https://docs.incident.io/api-reference/users-v2/updatepagingprovider
/openapi/tags/users-v2.json post /v2/users/{user_id}/paging_provider
Update a user's preferred paging provider.
🔑 Requires the `users.preferred_paging_provider.edit` scope.
# Utilities
Source: https://docs.incident.io/api-reference/utilities-v1
API endpoints for utilities
Miscelaneous utility endpoints.
Collection of utility functions that can help build integrations against this API.
# Show Identity
Source: https://docs.incident.io/api-reference/utilities-v1/show-identity
/openapi/tags/utilities-v1.json get /v1/identity
Test if your API key is valid, and which roles it has.
# Show OpenAPI V3 Spec
Source: https://docs.incident.io/api-reference/utilities-v1/show-openapi-v3-spec
/openapi/tags/utilities-v1.json get /v1/openapiV3.json
Get the OpenAPI (v3) definition.
# Introduction
Source: https://docs.incident.io/api-reference/webhooks
Receive notifications when events occur in incident.io.
Webhooks let you receive notifications when certain events occur in incident.io. This might be useful for annotating graphs in a monitoring tool with incidents, keeping track of follow-ups in another system, or syncing on-call data like alerts, escalations, and schedule changes to external tools. Our webhooks are powered by [Svix](https://svix.com).
## Getting started
To start using webhooks, you'll need to create a webhook endpoint. You can do this in the same way that you'd create any other endpoint in your application. If you'd like to play around with our webhooks, we'd recommend using [Svix Play](https://www.svix.com/play/) which lets you set up an endpoint and inspect payloads via their web interface. There are also other services (e.g. [ngrok](https://ngrok.com/)) which have great debugging tools.
Once you have a webhook endpoint set up, head to [Settings → Webhooks](https://app.incident.io/~/settings/webhooks) to configure it. From there you can choose which event types to receive, send test events, see recent deliveries, and retry any failed events.
## Status codes, errors and retries
When processing webhooks, return a 2xx status code (e.g. `200 OK` or `204 No Content`). If your endpoint returns a non-2xx status code, we'll retry with exponential backoff over the next 24 hours. If delivery attempts repeatedly fail over a 5 day period, we'll disable the endpoint and notify you by email.
If you miss some messages (e.g. due to unexpected downtime), Svix offers options for [replaying messages](https://docs.svix.com/receiving/using-app-portal/replaying-messages) which you can access via [Settings → Webhooks](https://app.incident.io/~/settings/webhooks).
## IP allowlisting
If your endpoint sits behind a firewall, see [Webhook IP addresses](/admin/webhook-ips) for the addresses these webhooks are delivered from. Note that this list covers webhooks configured in Settings → Webhooks; HTTP requests sent by workflow steps originate from different addresses.
## Verifying webhooks
To verify that a webhook came from incident.io, check the signature in the request headers using the **Signing secret** from your webhook endpoint settings. Each webhook includes three headers:
```json theme={null}
{
"webhook-id": "123",
"webhook-timestamp": 1676033031,
"webhook-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="
}
```
The signature is an HMAC of:
```
$WEBHOOK_ID.$WEBHOOK_TIMESTAMP.$REQUEST_BODY
```
You can verify the signature using the [Svix client libraries](https://docs.svix.com/receiving/verifying-payloads/how) or [manually](https://docs.svix.com/receiving/verifying-payloads/how-manual).
## Keeping another system in sync
A common use case is keeping another system up to date with incident.io. Since we deliver webhooks individually over HTTPS, they may not arrive in order. We recommend building your integration to:
1. Receive a webhook about a resource (incident, alert, escalation, or schedule)
2. Fetch the latest state from the API
3. Save that state to your system
This way you don't rely on webhook ordering for correctness.
## Private resources
For private incidents, alerts, and escalations, webhook payloads only include the resource ID — not the full details. If your integration needs the full data, [create an API key](/integrations/api-overview) with private access and use it to fetch the details. This prevents leaking private information to systems that shouldn't have access.
# Workflow Runs
Source: https://docs.incident.io/api-reference/workflow-runs-v2
API endpoints for workflow runs
## The workflow run object
# List
Source: https://docs.incident.io/api-reference/workflow-runs-v2/list
/openapi/tags/workflow-runs-v2.json get /v2/workflow_runs
List workflow runs, newest first. Cancelled runs are never returned.
The webhook delivery on each step omits the headers and bodies. Fetch a single run to see them.
You can filter on when a run was created:
```
# Runs created on or after a date
curl 'https://api.incident.io/v2/workflow_runs?created_at[gte]=2026-07-01'
# Runs created on or before a date
curl 'https://api.incident.io/v2/workflow_runs?created_at[lte]=2026-07-31'
# Runs created between two dates
curl 'https://api.incident.io/v2/workflow_runs?created_at[date_range]=2026-07-01~2026-07-31'
```
Paginate by passing the last run's ID as `after`. The response's
`pagination_meta.after` carries the value to send next, and is absent on the last page.
An `after` that isn't a run in your organisation returns 404.
🔑 Requires the `workflows.view` scope.
# Show
Source: https://docs.incident.io/api-reference/workflow-runs-v2/show
/openapi/tags/workflow-runs-v2.json get /v2/workflow_runs/{id}
Show a single workflow run, including the full webhook delivery for any step that sent one.
A delivery is kept for 7 days. After that `webhook_delivery_state` becomes
`expired` and the delivery itself is absent: the step still ran and may well have
succeeded, so an expired delivery must not be read as a failure.
This may return a cancelled run, in which case `cancelled_at` is set.
🔑 Requires the `workflows.view` scope.
# Created v1
Source: https://docs.incident.io/api-reference/workflow/created-v1
/openapi/audit-logs.json webhook workflow.created.1
This entry is created whenever a workflow is created
# Deleted v1
Source: https://docs.incident.io/api-reference/workflow/deleted-v1
/openapi/audit-logs.json webhook workflow.deleted.1
This entry is created whenever a workflow is deleted
# Updated v1
Source: https://docs.incident.io/api-reference/workflow/updated-v1
/openapi/audit-logs.json webhook workflow.updated.1
This entry is created whenever a workflow is updated
# Workflows
Source: https://docs.incident.io/api-reference/workflows-v2
API endpoints for workflows
Manage workflows.
Workflows allow you to automate certain actions and behaviors based on specific triggers.
## The workflow object
# Create
Source: https://docs.incident.io/api-reference/workflows-v2/create
/openapi/tags/workflows-v2.json post /v2/workflows
Create a new workflow
🔑 Requires the `workflows.create` scope.
# Delete
Source: https://docs.incident.io/api-reference/workflows-v2/delete
/openapi/tags/workflows-v2.json delete /v2/workflows/{id}
Archives a workflow
🔑 Requires the `workflows.destroy` scope.
# List
Source: https://docs.incident.io/api-reference/workflows-v2/list
/openapi/tags/workflows-v2.json get /v2/workflows
List all workflows
🔑 Requires the `workflows.view` scope.
# Show
Source: https://docs.incident.io/api-reference/workflows-v2/show
/openapi/tags/workflows-v2.json get /v2/workflows/{id}
Show a workflow by ID
🔑 Requires the `workflows.view` scope.
# Update
Source: https://docs.incident.io/api-reference/workflows-v2/update
/openapi/tags/workflows-v2.json put /v2/workflows/{id}
Updates a workflow
🔑 Requires the `workflows.update` scope.
# Automatically setting custom fields
Source: https://docs.incident.io/catalog/auto-custom-fields
It can be useful to automatically set custom fields to reduce the mental overhead for your responders.
## Common use cases
**1. Speed up responders**
Using [Catalog](/catalog/catalog-setup), it's possible to 'guess' what the right value is for a custom field. For example, if the affected service is `Data Pipeline`, the affected team is **probably** `Data`. The Catalog can figure this out for you, without the responder having to fill in yet another dropdown during the incident.
**2. Improve reporting**
If you're a larger org, you might have hundreds of teams. When it comes to reporting and insights, it's often useful to cut the data in a less granular way: perhaps by **Division** or **Function**.
To enable this, you can create another custom field `Affected Functions` and use the Catalog to automatically set this based on the `Affected Teams` field that the responder has set above.
You would never even need to show this field to a responder, but it would then be available for you to slice and dice data going forwards.
## How to create an automated custom field
When creating a custom field, select Automated, and then Add an expression.
Then, use the Expression Builder to navigate through your Catalog to automatically derive a custom field based on the value of another custom field.
You can also decide whether users are able to override the value of the custom field. For our `Affected teams` use-case, we probably do want users to be able to choose another value - this is more of a 'sensible default'.
However, for our `Affected functions` use-case (i.e. for reporting) there's no need: there's always a consistent relationship between team and function.
# Backstage
Source: https://docs.incident.io/catalog/backstage
We offer the ability to import Backstage catalog data into the incident.io Catalog, either by pulling entries directly from the Backstage API or by loading catalog-info.yaml files.
To learn more, **go to our** [GitHub repository](https://github.com/incident-io/catalog-importer/tree/master/docs/backstage) **and follow the steps outlined in the README.**
# Using the Catalog
Source: https://docs.incident.io/catalog/catalog-setup
## Introducing Catalog
The Catalog is a connected map of “everything” that exists in your organization that you can easily navigate and is available across features like Workflows, Insights, and Triggers to level up your incident response.
## Getting started with Catalog
The best place to get started is by following [this hands-on lab session on YouTube](https://www.youtube.com/watch?v=aW0AY3jhdJE).
## Integrating with an existing Service Catalog
Already using a Service Catalog? No problem! We support a number of [Integrations](/catalog/backstage).
## What can I do with Catalog?
Many things! Including, but not limited to:
* [Populating Custom Fields with Catalog data](/catalog/catalog-setup)
* [Automatic Custom Fields](/catalog/catalog-setup)
* [Using the Catalog in Workflows](/catalog/catalog-setup)
* [Powering your Status Page Sub-pages](/catalog/catalog-setup)
### Populating Custom Fields with Catalog data
Fed up with manually maintaining options for custom fields? When configuring [custom fields](/incidents/custom-fields), select "From a catalog type" as an option for how the field should be managed. This means that any updates made to a Catalog type will be updated in this custom field.
If you want to migrate an existing custom field to be managed from a Catalog type, go to the existing custom field that you would like to migrate and follow the migration wizard.
### Automatic Custom Fields
Want to update the value of a custom field based on the value of another custom field? For example, when selecting the Affected Service, using the Catalog you could derive the Affected Team without having an Incident Responder select anything.
When creating a custom field, select Automated, and then Add an expression.
Then, use the Expression Builder to navigate through your Catalog to automatically derive a custom field based on the value of another custom field.
### Using the Catalog in Workflows
Once you've set up custom fields for the relevant Catalog types, you can use those custom fields in [Workflows](https://app.incident.io/~/workflows). For example:
* Escalate incidents to the right on-call engineers when certain business functionality is impacted.
* Invite Customer Success Managers to incidents when their customers are mentioned.
* Notify the executive team when an aggregate amount of revenue across impacted customers crosses a threshold.
### Powering your Status Page sub-pages
Sub-pages are part of our status page offering, and allow you to create a page that is specific to different services, systems, products, or regions. In short, if you operate across multiple countries (UK, US, France), you can have one status page per region.
Catalog supercharges sub-pages by allowing you to associate components/services/systems with regions. For instance, you can say that the API is only used in the UK and France, whilst the Website is used in all regions. This means when you author an update, we can automatically route that update to the relevant sub-pages.
To find out more about setting up sub-pages, visit [this helpful article](/status-pages/sub-page-setup).
### Visualize with Catalog Graph
Use the Catalog Graph to visualize how different catalog entries connect to each other. You can build up a graph from any catalog entry, and share the URL so colleagues see the same view.
# Adding connected users to Catalog
Source: https://docs.incident.io/catalog/connected-users
Users of incident.io — your incident responders — are core to the incident management process. Those responders likely have accounts across many daily-use services, including services that you can (and should!) integrate with incident.io, like PagerDuty, Sentry, Linear and more.
Connecting third-party users to incident.io lets you build powerful integrations that *just work* with your existing tools - link Sentry users to identify the relevant people when you receive a Sentry alert and then notify them via Slack. The more you connect, the more you can do.
In most cases, when you connect a new integration, these *external users* will be added to Catalog and where we can, we'll link them to the relevant incident.io user via a *catalog attribute*.
To see this in action, navigate to the catalog type for an external user type (e.g. PagerDuty User) and click on any of the entries to see information about the external user, and the incident.io user that they're connected to.
If an integration has a concept of users, we'll perform the import and link process automatically when you set up your integration.
Be aware that some integrations e.g. Github and Jira, don't support automatic user linking as we're not able to uniquely identify a matching user from an external user's email address.
If you need to create, edit or remove any connections between an incident.io user and a third-party user, you can do this via the *Users* catalog type. Click on the user you'd like to edit and use the *Connected accounts* list to manage connections.
## FAQs
These two areas of the product serve different purposes:
* **Settings → Users** is where you manage people who can sign in to incident.io and their permissions. You add users via Slack, SAML/SCIM, or manual invite, and assign roles (Standard, Admin, or Owner) along with any custom roles for access control. See [User management](/admin/user-management) and [User permissions](/admin/user-permissions) for more.
* **Catalog → User** is a catalog record that represents a person and can be linked to their accounts in other tools (e.g. Slack, Jira, GitHub, Notion, Salesforce). It's used to connect and reference external identities — you can manage these links via *Connected accounts* on the User catalog entry. See [Migrating teams and users](/catalog/migrate-team-users) for more.
Someone can appear in the User catalog type without being a signed-in user in Settings, and vice versa. If you're looking to manage who has access to incident.io, head to **Settings → Users**. If you're looking to link a person's external accounts, use the **User** catalog type.
# Cortex
Source: https://docs.incident.io/catalog/cortex
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
2. **Press "Install" next to Cortex**
3. **Fetch your API key from Cortex**
You'll need to create an API key by heading to the settings page of [your Cortex account](https://app.getcortexapp.com/login).
4. **Press "Save"**
5. **Go to** [Catalog](https://app.incident.io/~/catalog) **to view connected Catalog entities**
Once connected, you can also import custom metadata from Cortex into your catalog types. Head to the catalog type settings and look for "Import from Cortex" to pull through additional attributes.
Cortex syncs parent team relationships as a catalog attribute, so you can set up [team structure](/catalog/team-structure) without any additional configuration.
# Datadog
Source: https://docs.incident.io/catalog/datadog
Catalog Importer is a great way to sync data from all your other systems to incident.io. A popular source is Datadog, below are the steps needed to run the catalog importer to create Datadog teams and services.
1. Download the `catalog-importer` tool [following the instructions here](https://github.com/incident-io/catalog-importer)
2. Create an incident.io [API key with read/write access to the Catalog here](https://app.incident.io/~/settings/api-keys) and set it as an environment variable called `INCIDENT_API_KEY`
3. Run `catalog-importer` init to create a new folder/config
4. Drop the `importer.jsonnet` file I've attached below in the folder you created above (if you are using Datadog's EU tenant – [app.datadoghq.eu](http://app.datadoghq.eu/), please update [api.datadoghq.com](https://api.datadoghq.com/) to [api.datadoghq.eu](http://api.datadoghq.eu/) )
5. Head to Datadog and create an [Application Key](https://app.datadoghq.com/organization-settings/application-keys) and [API key](https://app.datadoghq.com/organization-settings/api-keys).
6. Set the `DATADOG_APPLICATION_KEY` environment variable to the app key and `DATADOG_API_KEY` as the API key
7. Run `catalog-importer sync --config=importer.jsonnet`
8. See all the data in your incident.io Catalog!
Please find below the config file for creating Datadog services and teams.
Please reach out if you run into any issues!
[datadog-importer.jsonnet](https://incident.io/docs/files/datadog-importer.jsonnet)
# How do you use enums in the Catalog Importer?
Source: https://docs.incident.io/catalog/enum-imports
**What is an enum?**
Enums are a way to better support categorical attribute types. This allows you to create child catalog types from a parent catalog type.
```json theme={null}
{
"outputs": [
{
"name": "Teams",
"description": "Team in org",
"type_name": "Custom[\"Teams\"]",
"source": {
"name": "goal",
"external_id": "external_id"
},
"attributes": [
{
"id": "description",
"name": "Description",
"type": "Text",
"source": "description"
},
{
"id": "email",
"name": "Email list",
"source": "emails",
"array": true,
"enum": {
"name": "List of emails",
"type_name": "Custom[\"ListOfEmails\"]",
"description": "List of all team members"
}
},
{
"id": "name",
"name": "Goal",
"type": "Text",
"source": "goal"
}
]
}
]
}
```
In the sample above a `Team` catalog type will be created with `name`, `description`, and `email` attributes. The `List of emails` attribute will be created as a child attribute catalog type from the parent `Teams`.
#### Why does this matter?
Having child catalog types for these attributes allows workflows to know which options that attribute supports and gives you a drop-down instead of being textual.
# Managing team memberships outside of incident.io
Source: https://docs.incident.io/catalog/external-memberships
Derived attributes in Catalog let you manage team memberships outside of incident.io. This article will walk you through how to do this with Slack User Groups, but this approach will also work with teams synced via our integrations with:
* Cortex
* GitHub
* Linear
* OpsLevel
First, you'll need to create a Team type in the catalog if you don't already have one. Once you've done that, edit the type and add a data attribute with type Slack User Group.
You can now add a derived attribute based off of that which pulls in team members via the Slack User Group.
Your team catalog type should now look something like this. You may have more attributes if you already had a team type.
Save your type, and then find or create a new entry and set the "Slack User Group" attribute. In this example I've set it to "Incident Responders".
Save that entry, and you'll see that the members attribute for the team is now populated.
Those team members are the users that are in the Slack User Group "Incident Responders". We sync this data regularly, so if that group changes in Slack, the changes will be reflected in the catalog.
You can now follow the instructions in [Setting up teams](/catalog/teams) to set up the Team type to unlock the ability to filter incidents by team, and explore insights by team.
# Filter custom fields based on another custom field
Source: https://docs.incident.io/catalog/filter-custom-fields
It can be useful to filter on a custom field based on the value of another custom field.
Take the following example, of an organization with multiple divisions, where each division has multiple teams.
An area where this is very useful is in building forms. You can have a form field (say "Affected Teams") to require another field to be previously set (say "Division") before you can set it.
Let's walk through how this works in practice using those example fields.
1. Configure your "Affected Teams" field to filter options based on the value of the "Division" field.
2. Change the form so that we only show an "Affected Teams" dropdown if an incident has a "Division" set.
3. Try your new incident form to see how it plays out.
## Configure your "Affected Teams" field
Go to Settings > Custom fields > Edit "Affected Teams".
Set the **Filter options based on the value of another custom field** to the custom field you want to depend on. In this case, we have an attribute "Division" in the catalog entry for "Affected Teams" so that is what we select.
## Change a form to only show "Affected Teams" when "Division" is set
Say you have the following form setup, which is getting a bit long. What you want is to show the user the picker for "Affected Teams" only when "Division" has been set.
The way we filter a custom field ("Affected Teams") based on another custom field ("Division") is to edit the "Affected Teams" field so that it only shows when the incident has "Division" set.
## Try your new incident form to see how it plays out
Below you'll see that "Affected Teams" won't appear until a "Division" has been selected.
# Managing Catalog Types in GitHub
Source: https://docs.incident.io/catalog/github-managed-types
This feature is useful when you want to version control catalog types you've created in the incident.io dashboard.
This feature will generate all the files you need, and configure GitHub to automatically sync changes you make from the repository to the catalog in incident.io.
Once you've configured a catalog type to be managed in GitHub, you'll no longer be able to edit it through the dashboard.
## Can I use it?
If you have access to custom types in the catalog, you can also use the manage in GitHub feature.
## How do I use it?
On the catalog homepage, above your custom types, there's a "Manage in GitHub" button. Clicking it will take you through the process of configuring one or more catalog types to be managed in GitHub.
## How do I change catalog types once they're managed in GitHub?
To change catalog types, edit the [jsonnet](https://jsonnet.org/) files in your repository and open a pull request.
A GitHub action will run and show you the changes that will be made to the catalog.
If you're happy with the changes, merge the pull request and another action will run and sync the change to your incident.io catalog.
## How does it work?
Under the hood, this feature uses our [catalog importer](https://github.com/incident-io/catalog-importer). This is a flexible tool for syncing external data in to the catalog. If you're looking to do more complex things with external data in the catalog, the examples included with the catalog importer are a great place to start.
# How do I get data into Catalog?
Source: https://docs.incident.io/catalog/importing-data
After identifying [what data we want to bring into the catalog](/catalog/what-data), we can now consider how we can push it into incident.io.
There are four ways we can do this, with the decision of which to use very much being dependent on where and how your data is currently stored:
## Native integrations
### When should I use these?
If the data you want to bring into Catalog lives in an integration we natively support, you'll almost always want to set it up.
The only limitation to consider here is that we only sync your data once a day, so if you need super fresh data, then it might be worth considering using our [catalog importer](https://github.com/incident-io/catalog-importer).
### How do I get started?
You can find a list of all the integrations we support [here](https://incident.io/integrations). Where appropriate, we'll then automatically create catalog types when you connect an integration, such as GitHub repositories or PagerDuty services and teams.
### How much effort is required?
Minimal, almost all of our integrations are one-click setups and we'll take care of all the syncing behind the scenes.
## Catalog Importer
### When should I use it?
The Catalog Importer gives you complete control over what you bring into the catalog and how often that data is being brought in.
It's the perfect tool to use if you have large datasets stored in tools that we don't already support with native integrations, whilst also giving you much more control over the relationships and lookups within your catalog.
### How do I get started?
You can find the documentation for our catalog importer [here](https://github.com/incident-io/catalog-importer), along with some example importers.
### How much effort is required?
The catalog importer does require some technical uplift to use, however the time investment is usually hugely worthwhile given the impact this can have on your MTTX (mean time to x) metrics.
Take the train station example [here](/catalog/what-data) 5-6 hours to build out, but given how frequently this incident can occur and the time it can take off our mean time to resolution, the investment can pay itself off within weeks.
## Manually adding the data
### When should I use it?
If you have small datasets or just want to test / play around with the catalog, you can simply manually add catalog types and entries within our dashboard.
### How do I get started?
Just head over to the [catalog](https://app.incident.io/~/catalog) section of your dashboard. Here you can add new types and entries with just a few clicks.
### How much effort is required?
For small datasets this shouldn't take too long and also won't require any technical resource.
## Our API
### When should I use it?
Primarily, our API serves as a robust solution for importing data into your catalog. However, we recommend considering our [catalog importer](https://github.com/incident-io/catalog-importer) as your go-to choice. It not only utilizes the same API but also provides a more streamlined integration experience.
We encourage opting for the catalog importer whenever possible. Nevertheless, we acknowledge that there could be specific scenarios where a direct integration with the API is preferred. In such cases, the option is at your disposal.
### How do I get started?
Our API docs can be found [here](https://docs.incident.io/api-reference/catalog-v3/).
### How much effort is required?
Similar to the [catalog importer](https://github.com/incident-io/catalog-importer), this will require some technical uplift to use but the time investment is usually hugely worthwhile.
# Teams in Catalog: Migrating from SlackUsers to Users
Source: https://docs.incident.io/catalog/migrate-team-users
This article is relevant if you've [set up a Team catalog type](https://incident-io-knowledge-base.help.usepylon.com/articles/4629305061-setting-up-teams-in-catalog), and that catalog type has an attribute (e.g. Team Members) with the SlackUser resource type. *If you're unsure, head to* [Catalog](https://app.incident.io/~/catalog) *, search for Team, then Edit type, and check the Resource Type is not SlackUser. If your catalog type is externally managed (e.g. not editable), continue reading this article for more information.*
## Background
In January 2024, we [shipped a powerful new feature](https://incident.io/changelog/adding-connected-users-to-the-catalog) allowing you to represent Users in Catalog. This new User catalog type can be linked to other user accounts across various systems, like Slack, Jira, Notion, Salesforce, Github, and so on. By connecting user accounts in Catalog, a whole host of [powerful User-based workflows](https://incident.io/changelog/adding-connected-users-to-the-catalog) can be unlocked.
Building on our Users in Catalog release, in March 2024 [we released Teams in Catalog](https://incident.io/changelog/teams-in-catalog). This feature is a way for you to flexibly model your organization (e.g. Users) in Catalog. By being able to model Team Members, Managers, Tech Leads, and more, you (yet again) unlock some really [powerful Team-based workflows](https://incident.io/changelog/teams-in-catalog).
## What is this migration?
Before these exciting changes to Users and Teams, it was possible to build your own version of Teams in Catalog: by linking SlackUsers to Teams. However, to get the most out of our recent changes, we strongly recommend moving away from using SlackUsers (e.g. to represent Team Members), and migrating to our new first-class representation of a User within your Teams catalog type.
## Migration path
The migration path depends on how you manage your Team catalog type:
* [Managed via the UI](/catalog/migrate-team-users)
* [Managed via Catalog Importer](/catalog/migrate-team-users)
* [Managed via Terraform](/catalog/migrate-team-users)
## Managed via the UI
If you aren’t using an attribute of the SlackUser anywhere (e.g. grabbing the email of a SlackUser in Workflows) you can simply change the attribute type from SlackUser → User in the ‘edit type’ screen in the catalog type.
In the unlikely case that you're "using" an attribute of the SlackUser that isn't available in the User type, this’ll be prevented by our ‘deletion protection’ checks designed to stop you breaking your catalog & dependent workflows.
*An example of a "usage" is within a Workflow Expression, navigating from Team > SlackUser > Job Title, where Job Title may not exist on your User catalog type.*
In this case, you will need to:
1. Manually look at all the ‘usages’
2. Temporarily remove those ‘usages’
3. Add the required attributes to the new User catalog type
4. Add the required ‘usages’ back
*If you still have issues or questions on this migration, please reach out to us via your Slack Connect channel, or* [support@incident.io](mailto:support@incident.io) *.*
## Managed via Catalog Importer
You can change the schema of your Team type in the Catalog Importer, by changing `type: SlackUser` to be `type: User`.
If when running the Catalog Importer after this change you hit the "a catalog attribute couldn't change type as it is in use by other resources" error, it's likely that you have dependencies on attributes of the SlackUser that are not available in the User type.
In this case, please reach out to us via your Slack Connect channel or [support@incident.io](mailto:support@incident.io), and we can assist you in identifying those dependencies and getting you unblocked.
## Managed via Terraform
You can change the schema of your Team type in the Terraform provider, by changing `type=SlackUser` to be `type=User`.
If when running the Terraform provider after this change you hit the "a catalog attribute couldn't change type as it is in use by other resources" error, it's likely that you have dependencies on attributes of the SlackUser that are not available in the User type.
In this case, please reach out to us via your Slack Connect channel or [support@incident.io](mailto:support@incident.io), and we can assist you in identifying those dependencies and getting you unblocked.
# Opslevel
Source: https://docs.incident.io/catalog/opslevel
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
2. **Press "Install" next to Opslevel**
3. **Fetch your API key from Opslevel**
You'll need to create an API key by heading to the settings page of [your Opslevel account](https://app.opslevel.com/api_tokens).
4. **Press "Save"**
5. **Go to** [Catalog](https://app.incident.io/~/catalog) **to view connected Catalog entities**
OpsLevel syncs parent team relationships automatically, so you can set up [team structure](/catalog/team-structure) without any additional configuration.
# How to re-sync Catalog data
Source: https://docs.incident.io/catalog/resync-data
Catalog is powerful because it allows you to bring data from any source system into incident.io. There are multiple ways to keep that data in sync.
When you update your upstream data e.g. your Slack users, or your Salesforce customers; Catalog will need to be synced before the upstream changes are visible.
Syncs can happen in any of the following ways:
1. Automatic sync (e.g: Github, Slack)
2. Manually force a sync (e.g: Slack)
3. Re-run `catalog-importer` (e.g: Backstage)
## 1. Automatic sync
We keep lots of data sources in-sync with a scheduled automatic sync. Typically this runs every three hours and doesn't require any input from you.
In the dashboard, when you open a specific Catalog type, you'll see a button called `Sync`. If you hover, we'll tell you when the type was last synced.
## 2. Manually force a sync
We've already given away how you can force a sync - Pressing the sync button mentioned above will trigger a sync for that catalog type. This does the same work as the automatic sync job; but can be useful if you want to get upstream changes into your catalog quickly. Be aware that sync jobs can take a few minutes for very large collections of upstream resources.
## 3. Re-run the catalog-importer
If you're managing your catalog type externally, e.g. with `catalog-importer`; just trigger another run.
It'll be clear if you're managing your catalog types externally as we'll show you in the UI, you won't be able to make edits directly via the UI.
If you need a refresher, you can find documentation on how to run the `catalog-importer` in its repository [README](https://github.com/incident-io/catalog-importer/blob/master/README.md) file.
# Linking Salesforce Accounts and Opportunities in Catalog
Source: https://docs.incident.io/catalog/salesforce
For most Salesforce organizations, an Account can be linked to many Opportunities, but each Opportunity only references a single Account. In Salesforce, this relationship must be modelled by your Opportunity having an Account ID field, rather than the other way around.
However, thanks to our recent addition of [Backlinks](/internal/catalog-teams), Catalog can model the relationship *both* ways, meaning you can go from your Account to Opportunity, and also Opportunity to Account in a single-click. Here's how to set that up.
## Adding the Opportunity type
First, you'll need to sync the Opportunity object to Catalog. Head to the Salesforce section of the Catalog home, click the "Import another type" button, and search for Opportunity.
You'll be redirected to the edit page of the new Salesforce Opportunity Catalog type. Scroll down to the attributes section and click "Add new attribute" to open a menu of all the fields on your Opportunity object in Salesforce.
Add Account ID and any other fields you'd like to sync to Catalog here.
## Setting up the Backlink
Finally, return to the Catalog homepage, select your Salesforce Account type, and click Edit. Scroll to the Attributes section and click "Add new attribute" again. This time, scroll right to the bottom of the list and you'll see Salesforce Opportunity under the available Backlinks.
Now just click "Submit" and you'll easily be able to see which Opportunities reference each of your accounts.
# Using SCIM to create a Team catalog type
Source: https://docs.incident.io/catalog/scim-teams
Catalog is a powerful tool for driving automation across the product. By modelling the relationships between entities in your organization, you can route alerts and updates to the right people, get insights broken down by team, and reduce the manual work associated with incidents.
If you use SCIM groups as the source of truth for team membership, you can use our team creation wizard to sync your SCIM groups with Catalog and create a Team catalog type that mirrors your SCIM configuration.
## Getting started
### Step 1: Connecting SCIM
Firstly, you'll want to head over to [Settings > Integrations](https://app.incident.io/~/settings/integrations), and then select your SCIM provider. Some examples of providers we support are:
* Microsoft Entra ID (formerly Azure AD)
* CyberArk
* Google
* JumpCloud
* Okta
* OneLogin
* PingFederate
* Rippling
In this example, we'll use Okta as the SCIM provider that we want to use to power our Team catalog type. Click the Okta integration tile, and a drawer will open:
Next, press "Connect Teams" under the "Manage teams in Catalog (SCIM)" section.
Now, you'll enter into the wizard for setting up your Team catalog type.
From this list you can select Okta (or your desired SCIM provider).
* If you haven't installed this provider before, a drawer then opens asking you to "Connect" your Okta provider. After pressing "Connect" you'll be guided through a setup process for connecting SCIM. *Note: You can follow the instructions* [in this guide](/admin/okta-scim) *on how to connect your SCIM provider correctly.*
* If you've already installed, this you'll proceed straight to Step 2 (below).
### Step 2: Selecting your teams
Once you have a SCIM provider connected (or if you've already configured it), you'll then be presented with the option to choose from the relevant groups that have been pushed to incident.io from your SCIM provider. If you do not see the groups you'd expect, please [read the FAQ](/catalog/scim-teams).
Select all of the entries that you'd like to make a team for in incident.io.
### Step 3: Adding attributes
Now it's time to associate information from other integrations with our new Team catalog type.
Let's start with "Slack Channel".
We'll use AI to suggest Slack Channels for each of the Teams you've created. Feel free to accept those suggestions, or make tweaks where necessary.
When you're done, hit save. Add as many attributes as you want. You can always add more later.
To wrap everything up, hit finish. You'll now see your newly created Team catalog type which can be used to drive automation across our entire application. For more information on what you can do with Catalog, check out [incident.io/catalog](https://incident.io/catalog).
## FAQs
SCIM is a push-based protocol and incident.io will only ever be able to sync the groups that you choose to push. Creating new groups in your SCIM provider will typically require an additional step to push them to incident.io.
* For [Okta](https://workos.com/docs/integrations/okta-scim/5-assign-users-and-groups-to-your-application), you can follow this article.
* For [Google Groups](https://workos.com/docs/integrations/google-directory-sync/4-select-which-groups-to-sync-to-your-application), you can follow this article.
* For others, please check the help center for your given provider.
Once your SCIM groups are pushed to incident.io, membership of your SCIM groups in catalog will be kept in sync with group membership in your SCIM provider. As a result, membership of your Team catalog type will also remain in-sync.
Note that pushing a new SCIM group to incident.io will sync the group and its membership to the catalog (e.g. a new entry will be added to "Okta Groups") but it will not create a new entry in your Team catalog type, and this will need to be configured manually by navigating to your Team catalog type, and hitting "Create entry".
# Team resources
Source: https://docs.incident.io/catalog/team-resources
See which resources can be owned by a team, and what that ownership controls
Once you've [set up teams](/catalog/teams), many resources in incident.io can be **owned** by one or more of them. Each resource can be owned by a different team, so, for example, one alert route might belong to Team A while another belongs to Team B.
Ownership only applies once you have teams. If your organization doesn't use teams yet, start with [Setting up
teams](/catalog/teams).
## What can be owned
Which resources you can give an owning team depends on the products you use:
* **Response**: incident types and lifecycles, announcement rules, and announcement post templates
* **On-call**: escalation paths, schedules, alert routes, and alert sources
* **Cross-cutting**: workflows, API keys, and catalog types (which also controls who can edit that type's entries)
Alerts are also associated with a team, via their **Team attribute**, which decides which team owns each alert.
## What ownership does
Giving a resource an owning team affects two separate things:
* **Team views and routing.** Owned resources appear under that team in their team views, float to the top of the relevant lists, and drive things like [alert routing](/alerts/team-routing). This happens whether or not you use team roles.
* **Who can manage it.** If your organization uses [team roles](/admin/team-roles), ownership also decides who can manage the resource: members of an owning team with the right permission, plus anyone who holds that permission account-wide.
Owned resources are labelled with their owning team wherever they're listed. For example, on the [Announcements](/admin/announcements) settings page, each template and rule shows a badge for the team that owns it:
## Setting an owning team
Where you set the owner depends on the resource (for example the **Owned by** control on a workflow, the **Announcement rule owner** field on a rule, or the **Incident type owner** field on an incident type). The [Team permissions](/admin/team-roles) pages walk through each resource in turn, including which permission governs it.
# Team structure
Source: https://docs.incident.io/catalog/team-structure
Organize teams into parent and sub-teams to see everything in one place.
Teams can be organized into parent and sub-teams. When you view a parent team's page, information about that team (including incidents, on-call schedules, and follow-ups) from all sub-teams are rolled up into a single view.
This is useful for managers and directors who need visibility across multiple teams without having to check each team individually.
## What changes when you set up team structure
* **Team pages show sub-team data.** A parent team's page shows incidents, schedules, follow-ups, post-mortems, and alerts from all teams beneath it.
* **"Is part of" filter.** The team filter gains an "is part of" operator. Selecting a team shows results for that team and all of its sub-teams.
* **Org chart.** A **View structure** button appears in **Settings → Teams → Configure** and on individual team pages, showing your teams as an interactive diagram.
* **Users belong to parent teams automatically.** A user's Team attribute now includes not just their direct team, but all parent teams up the hierarchy. This means expressions that reference a user's teams will automatically account for the full team structure.
* **Permissions flow down the hierarchy.** Roles assigned to a parent team are automatically inherited by all sub-teams beneath it. This means you can grant access or responsibilities at a higher level without having to duplicate role assignments across every sub-team.
## Setting it up
Team structure is powered by the catalog. To define your hierarchy, your Team catalog type needs a "Parent team" attribute that references itself - i.e., an attribute on the Team type whose value is also a Team. This is how incident.io knows which teams sit beneath which.
You only need to set each team's direct parent — incident.io builds the full hierarchy from there.
### Configure the parent attribute
1. Navigate to **Settings → Teams → Configure**
2. Under **Team parent attribute**, select the attribute on your team type that stores parent teams
The attribute must reference the same team type. Both singular and array attributes are supported.
If you're importing teams from an external source, the parent attribute likely already exists on your team type. Check
your team type's schema in **Catalog** before creating a new one.
### Import sources
The parent attribute is a catalog attribute, so however you get data into catalog works here.
Several integrations sync a `parent_team` attribute automatically when the external source has its own team hierarchy:
* [GitHub](/catalog/github)
* [Linear](/catalog/linear)
* [OpsLevel](/catalog/opslevel)
* [PagerDuty](/catalog/pagerduty)
* [Cortex](/catalog/cortex) (syncs as `parent_teams`, supporting multiple parents)
If your teams come from one of these, you likely already have the attribute — just select it in the parent attribute setting above.
For other sources, set the parent attribute value to the parent team's external ID or catalog entry ID:
* **[catalog-importer](/catalog/importing-data)**
* **[Terraform](https://registry.terraform.io/providers/incident-io/incident/latest)**
* **Manual**: Edit the attribute directly in **Catalog** or from a team's settings page.
### View the org chart
Once configured, click **View structure** in **Settings → Teams → Configure** to see the full team tree. You can expand and collapse nodes to explore, and click any team to see its details.
On individual team pages, click the team structure button in the header to see where that team sits in the tree.
## Use case: manager role inheritance
Parent and sub-team relationships work with [team roles](/admin/team-roles) to give managers access across sub-teams without being added to each one individually.
**To set this up:**
1. Navigate to **Settings → Teams → Team roles**
2. Create a **Manager** role with the permissions you want (e.g. manage members, view private incidents)
3. Go to the parent team and add the manager as a member with the Manager role
The manager now has those permissions for the parent team and all sub-teams beneath it. A VP assigned as Manager on the top-level Engineering team can manage members, view private incidents, and perform other role actions across every child team — without being explicitly added to any of them.
Assign managers once at the appropriate level and permissions flow down. No need to maintain role assignments on every
sub-team.
## Use case: simplifying on-call schedule ownership
Without team structure, the only way to see all of a division's on-call schedules in one place was to assign every schedule to both its owning team and the parent team. This meant maintaining duplicate assignments and keeping them in sync whenever teams or schedules changed.
With parent and sub-teams, the parent team's on-call page automatically includes schedules from all sub-teams. Assign each schedule to the team that owns it — the parent team page rolls them up.
**If you've been duplicating schedule assignments to get a unified view:**
1. Go to each schedule that's assigned to both a team and its parent
2. Remove the parent team assignment — the schedule only needs its owning team
3. The parent team's on-call page still shows all schedules from sub-teams
# Setting up teams
Source: https://docs.incident.io/catalog/teams
incident.io is designed to help you handle all kinds of incidents across your business, from disks running out of space, to laptops getting lost on a train. However, most of the time, most people want to *only* see incidents, as well as configuration, for their team(s). Essentially, only show items that are most relevant to their day-to-day work.
So, if you tell us about your teams and who is in each team within [Catalog](/catalog/catalog-setup), you'll be able to leverage:
* Escalation paths belonging to a team are automatically linked in Catalog, so each team can control what it means to page them
* With alert routes and workflows, you don't need to set up loads of new configuration for each team; Instead, use attributes on your teams to adjust where alerts and messages go. Learn more about [alert routing](/alerts/escalations-from-alerts) and [workflows](/workflows/getting-started).
* When viewing escalation paths and schedules, those owned by your team will always appear at the top of the list — super useful if you're a manager who's not on-call but wants to keep an eye on your team's rota!
* When browsing incidents and alerts, we'll only show those related to your team
* Resources like schedules, escalation paths, and workflows can be owned by a team, so each team can manage their own config without managing everyone else's. See [Team resources](/catalog/team-resources) and [Team roles](/admin/team-roles).
## Creating teams
In [Settings → Teams](https://app.incident.io/~/settings/teams), jump into the three-step team setup wizard.
First, tell us about any existing teams configuration you have, that you'd like us to use. If you're already managing team memberships in another system, we can sync them across.
You can sync teams and their members from:
* An identity provider or HR system like Okta or HiBob [using SCIM](/catalog/scim-teams)
* [Backstage](/catalog/backstage)
* Cortex
* Linear
* Opslevel
* Slack
* Microsoft Teams
If you manage teams and their members somewhere else, let us know!
If you want to just create a few teams to try things out, you can manage membership manually instead:
Finally, you can add any extra attributes to your Team type. These can be really useful in Workflows and Alert Routes, for example to send messages to a different channel for each team. If you're not sure, you can always come back later to set up new attributes!
If you want to migrate to using SCIM to manage team memberships later, you can run this wizard again, from [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure).
## Parent and sub-teams
If your organization has teams within teams — like an Engineering division with Platform, Backend, and Frontend teams — you can set up parent and sub-team relationships. A parent team's page automatically shows incidents, schedules, and other data from all of its sub-teams.
Set this up by configuring a parent attribute in **Settings → Teams → Configure**. Read more in [Team structure](/catalog/team-structure).
## Managing your teams
There are three different ways you can manage teams:
### 1. Manually in incident.io
If you just have a few teams, this is the quickest way to get started. You can add, remove, and manage members of teams from [Settings → Teams](https://app.incident.io/~/settings/teams), and change which schedules and escalation paths they own:
### 2. With SCIM, or another integration
If you've got your team memberships managed in a SCIM-compatible provider like Okta, Google Workspace, or Microsoft Entra ID, we will automatically sync changes to team members.
You can create new teams linked to SCIM Groups in [Settings → Teams](https://app.incident.io/~/settings/teams), and change which schedules and escalation paths they own, but you'll need to add and remove members in your SCIM provider.
### 3. Using catalog-importer or Terraform
If you're already using [catalog-importer](https://github.com/incident-io/catalog-importer) or [Terraform](https://registry.terraform.io/providers/incident-io/incident/latest) to manage your Catalog, you can also use this to manage teams and their members! This is really powerful if you have this data in code already, and want to manage relationships between teams, services, and other infrastructure components in code.
You can read more about using catalog-importer [here](/catalog/importing-data#catalog-importer-17).
You won't be able to manage your teams and their members in [Settings → Teams](https://app.incident.io/~/settings/teams), but you can still link them to schedules and escalation paths here.
## Attributes that power teams
When you set up teams, some attributes on your Team catalog type start powering team features across incident.io: the attribute holding each team's members, and the one linking teams to their escalation paths. These are usually called **Members** and **Escalation paths**. Filtering by team, routing escalations to the right place, and team-based permissions all depend on them.
To protect your team configuration, we lock the schema of these attributes while they're in use. You can't delete them or change their type, whether you're working in the dashboard, the API, [catalog-importer](https://github.com/incident-io/catalog-importer), or Terraform. Attempting it returns an error like `Cannot update attribute "Members" as it's used to power teams`. Renaming them is fine.
If you've hit this error, you have three options:
* **Keep the attribute powering teams**: update your catalog-importer or Terraform config so it no longer manages that attribute's schema. You can carry on managing the rest of your Team type in code.
* **Change which attributes power teams**: choose different attributes in [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure). Once an attribute is no longer powering teams, you can change it freely.
* **Undo a setup you didn't intend**: if teams got turned on while you were testing, review what's configured in [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure), or contact support and we'll help you unwind it.
## Filtering by team
Once you've set up teams, you can use team filters to focus incident and alert lists on the teams you care about. For example, filtering by the "Payments" team shows incidents and alerts associated with Payments.
### Incidents and alerts
Incident filters use the "Affected teams" custom field, and alert filters use the "Team" attribute. You can change which custom field and alert attribute we use, or disable this entirely, in [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure).
### Escalation paths and schedules
If you're using incident.io [On-call](https://incident.io/on-call), you can link your teams to escalation paths and schedules when setting them up. You can change this later when editing the schedule or escalation path, or when editing the team.
If you're managing schedules or escalation paths with Terraform, you'll need to also set the `team_ids` attribute, and you won't be able to manage this in the incident.io dashboard.
## Routing alerts and escalations to teams
To make alert routing to escalation paths easier, when you attach an escalation path to a Team, we'll automatically link that back in Catalog:
You can use this to automatically route alerts to teams:
If your alerts are tagged by *service*, you can route escalations based on the service's owning team. Read more about how to route alerts in [📄 Creating escalations and incidents from alerts](/alerts/escalations-from-alerts).
The Team attribute on an alert doesn't just decide where it routes. It also determines which team *owns* the alert. If you want to keep actions like resolving alerts or acknowledging escalations within the responsible team, you can use this ownership to set up [team-based permissions](/alerts/team-routing#owning-teams-and-permissions).
## Tracking your team's work
Each team has its own page in incident.io. The **Overview** tab pulls together what the team needs to act on, with two summary panels:
* **Follow-ups**: open follow-ups from the team's incidents, grouped by incident, including how many are in violation of a follow-up policy.
* **Open tasks**: outstanding post-incident tasks and policy violations for the team, with a breakdown by team and policy.
For a fuller view, head to the **Tasks** tab. It lists every open task in a filterable table — including the due date, assignee, team, and associated policy for each one — so you can find a specific slice of work, like all tasks due today or all violations of a particular policy.
# Teams in incident.io
Source: https://docs.incident.io/catalog/teams-faq
## Should I manage teams in settings, or in Catalog?
You can manage teams and their members in Settings → Teams, or directly in Catalog.
The only exception is the **Escalation paths** attribute: we set this for you, based on which escalation paths have been attached to each team.
If you add additional attributes to your teams, such as their team Slack channel, you can only manage these in Catalog.
If you're managing your team type in code (for example with [catalog-importer](https://github.com/incident-io/catalog-importer), or [Terraform](https://registry.terraform.io/providers/incident-io/incident/latest) ), you won't be able to edit teams in the incident.io dashboard at all, since we can't keep your catalog-importer or Terraform config in sync.
## How are incidents filtered by team?
Incidents are filtered by a team custom field. When you sign up, we'll create an "Affected teams" custom field automatically, and filter on this field by default.
You can change which field we use to filter incidents by team in [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure).
If you don't have a team custom field you can read how to set one up in our [guide to Catalog-powered custom fields](/catalog/catalog-setup)
## How are alerts filtered by team?
Alerts are filtered by a team attribute. When you sign up, we'll create a "Team" attribute automatically, and filter on this field by default.
You can change which attribute we use to filter alerts by team in [Settings → Teams → Configure](https://app.incident.io/~/settings/teams/configure).
If you tag your alerts by service, you can add a team attribute which gets set based on which team(s) own the service for the alert. See how to configure alert attributes in [our guide here](/alerts/attributes-and-priorities)
## Can I filter escalations by team?
Escalations aren't filtered by team. You can navigate from either alerts or incidents to escalations.
# Teams in Insights: Troubleshooting
Source: https://docs.incident.io/catalog/teams-insights
This page is an FAQ for any issues you're facing with the Teams dashboard in Insights.
### I've set up Teams in Catalog, but I'm still seeing the welcome screen in Insights. What have I done wrong?
If you see this screen when you open Insights:
It generally means you haven't followed the [📄 Setting up teams](/catalog/teams) guide, as we require you to have a link from your [incident.io](http://incident.io/) **User** to a **Team** !
# What data should I bring into Catalog?
Source: https://docs.incident.io/catalog/what-data
[The Catalog](/catalog/catalog-setup) is a connected map of “everything” that exists in your organization that you can easily navigate and is available across features like Workflows, Insights, and Triggers to level up your incident response.
Having great catalog data can supercharge your incident response process
so understanding how you can import data and what data to import about your organization is incredibly important.
So what data should you bring into catalog? This is something that will depend on your type of business and what you're using incident management for e.g. If I were a railway network, it would make sense for me to model all of my rail stations in a catalog type, but this wouldn't make any sense for a business in the finance sector.
We'll explore how to navigate this in a later section , but before that let's look at the common catalog types that most organizations will want to have set up.
## Common catalog types
When declaring the vast majority of incidents, you'll likely want to be able to automatically bring in the teams/individuals responsible for resolving and communicating with stakeholders during an incident and so you'll likely want to model three catalog types:
### Features
In large organizations, it's unreasonable to expect someone declaring an incident to know who to specifically escalate something to. By adding a catalog type for features, you can therefore allow someone to just select the feature that's impacted and escalate accordingly based on the team that owns that feature.
### Teams
As part of the above, you'll probably want to know a bit more about the team you're escalating to e.g. What's their escalation policy? Who's the team lead? Who are the members? etc.
### Customers
It's often helpful to know more information about a customer when they're affected by an incident in order to inform relevant internal stakeholders or set priorities e.g. who is their customer success manager? What pricing package or tier are they on?
The combination of these three catalog types can be really powerful. For instance, if a critical incident is declared for a VIP customer where a specific feature is affected, we could automatically bring the Tech Lead(s) of the team(s) owning that feature and the Customer Success Manager for that customer into the incident channel.
To do this, we need to create a couple of new custom fields backed by our new catalog types to allow users to select Features and Customers impacted when declaring an incident. For example the Features custom field would look like this:
We can then do the same with the Customer catalog type and configure our [incident declaration form](/admin/incident-forms) to have these two fields available.
You can see an example of how to configure the workflow below:
## Organization-specific catalog types
It can often be difficult to know where to start when it comes to building a catalog that's tailored to your business but it's best to begin by identifying what your colleagues will know is broken when declaring an incident e.g. in a software business everyone understands the features / services we offer, whereas in a logistics company everyone will likely be referencing shipments or deliveries.
Let's jump into a more in-depth example by imagining I'm responsible for incident management for a rail network. Our most common incident is when hardware (a signal failure point) fails on the network, meaning we have to send engineers to fix the issue and keep customers & drivers informed.
My ideal flow here would be to select the component that's failing when declaring an incident, which should then automatically dispatch engineers to the component, assign a relevant comms lead and push a status page update.
To do this, I'd need the following catalog types:
#### Signal Failure Point
All of the points that can fail on a network will be represented in this type, storing a lookup to the rail line it's on, the start and end stations and the type of component.
#### Line
Every tube line can be modeled in this type, with lookups to the status page for that line, the teams associated with the lines and the stations on that line.
#### Station
Having a station catalog type is needed to maintain a list of station options and also have the same station associated with multiple lines (we could also use this in reports e.g. show me all incidents that have involved station x).
#### Team
Our team catalog type here holds all of the information I want to know about my teams i.e. who's the lead, what's their slack channel etc.
These catalog types allow us to then [have a custom field](/catalog/catalog-setup) related when declaring an incident to give us access to all the information in the lookups to other catalog types in automations and workflows.
For example, if we wanted to get to the customer service team of the line that a signal failure point is on, we can do so by using an [expression](/workflows/expressions) within a workflow (Signal Failure Point → Line → Customer Service Team):
Using this principle, we could then consider building out a more comprehensive workflow to automatically publish an update to our status page letting customers know we're having issues with line x between station y and z.
You can quickly see how this becomes very powerful. We can give a huge amount of additional context and take manual actions away from responders simply by having one field selected on incident declaration.
# Importing historical incidents
Source: https://docs.incident.io/getting-started/importing-historical-incidents
Bring your incident history into incident.io using the API, so your reporting and insights cover more than just the incidents you declare from now on.
If you're moving to incident.io from another tool, you probably have a history of incidents you'd like to keep: for reporting, for insights, and so that the record of what happened lives in one place. This guide covers importing that history through the API.
If you're coming from Blameless, FireHydrant, or ServiceNow, we have importer tools that can do this for you. They aren't self-serve yet, so [contact support](mailto:support@incident.io) and we'll run the import with you.
This is about historical data only. If you're migrating your live setup (schedules, escalation policies, alert sources) see the guides for [PagerDuty](/getting-started/migrate-from-pagerduty) and [Opsgenie](/getting-started/migrate-from-opsgenie).
## Before you start
* **Decide what to bring over.** For each incident you'll want a name, a severity, and the timestamps that matter to your reporting (when it was reported, when it was resolved). Summaries and custom fields are worth mapping too. Skip anything that doesn't map cleanly. A sparse but accurate record beats a complete but messy one.
* **Cleaning up a bad import is tedious.** There's no delete via the API. If an import goes wrong, you can select the incidents in the dashboard and mark them as test incidents to get them out of your reporting, but for a large batch that's a chore you'd rather avoid. Import a small batch first, maybe five incidents, and check them in the dashboard before running the rest.
* **Check your channel creation settings.** Depending on your settings, each imported incident can create a Slack or Microsoft Teams channel. Five hundred imported incidents creating five hundred empty channels is not what anyone wants, and channel creation also determines which rate limit applies to you (see below). You can configure this per incident mode under channel creation settings in the dashboard.
* **Talk to us about rate limits.** Incident creation is deliberately rate limited to protect your account from runaway automations, which matters when you're intentionally creating thousands of records. [Contact support](mailto:support@incident.io) before a large import and we can temporarily raise the limits for your key.
## Create the incidents
Use the [create incident endpoint](/api-reference/incidents-v2/create) with `mode` set to `retrospective`:
```bash theme={null}
curl --request POST https://api.incident.io/v2/incidents \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"idempotency_key": "import-jira-4521",
"visibility": "public",
"mode": "retrospective",
"name": "Database connection pool exhausted",
"summary": "Connection pool hit its limit during the evening peak.",
"severity_id": "01FCNDV6P870EA6S7TK1DSYDG0",
"incident_timestamp_values": [
{
"incident_timestamp_id": "01FCNDV6P870EA6S7TK1DSYDG0",
"value": "2024-03-02T18:22:00Z"
}
]
}'
```
A few things to know about the payload:
* **`idempotency_key`** is required, and it's your friend during an import: retrying a failed request with the same key won't create a duplicate. Use something stable from your source system, like the original ticket reference.
* **`incident_timestamp_values`** is how you record when the incident actually happened. List your organization's timestamps with the [incident timestamps endpoint](/api-reference/incident-timestamps-v2/list) to find the IDs, then set the values that matter for your reporting. Without these, the incident is dated by when you imported it.
* **`custom_field_entries`** works the same as for any other incident, so you can carry over things like affected services or teams.
There are also a few options specific to retrospective incidents, set under `retrospective_incident_options`:
* **`slack_channel_id`** attaches an existing Slack channel to the incident instead of creating a new one. Useful if the original incident was run in Slack and the channel still exists.
* **`postmortem_document_url`** links an existing post-mortem document to the incident.
* **`external_id`** sets the incident number to match your previous system, so links and references keep making sense. This option needs enabling for your organization, so [contact support](mailto:support@incident.io) first if you'd like to use it.
### What retrospective mode does
Retrospective incidents are built for exactly this use case, and behave differently from incidents you declare live:
* They start in your closed status, rather than going through triage or active response.
* They skip the post-incident flow, so no post-incident tasks are created for them.
* Workflows don't run on them by default.
The result is an incident that exists in your history and your reporting without paging anyone or generating follow-up work.
## Pace the import
An API key can create 10 incidents per hour where a Slack or Microsoft Teams channel is created, and 300 per hour otherwise. Basically everyone hits this during an import, so it's worth understanding why the limits are shaped this way:
* Creating channels draws on Slack's own rate limits, which are aggressive. An import that creates hundreds of channels can exhaust that allowance and stop channels being created for *real* incidents happening at the same time, so incidents that create channels are limited hard.
* The broader creation limit protects your account from runaway automations. A misconfigured script creating incidents in a loop can do a lot of damage. A limit that a human import finds slow is one that stops a machine doing real harm.
This is why the channel creation settings above matter: an import that doesn't create channels runs at 300 per hour instead of 10. When you hit the limit, the API responds with `429 Too Many Requests`:
```json theme={null}
{
"type": "rate_limit_reached",
"status": 429,
"errors": [
{
"code": "rate_limit_reached",
"message": "You cannot create more than 10 incidents per hour. Please try again later."
}
]
}
```
The limit counts incidents created over the last hour, so there's no fixed reset time: write your import script to run sequentially, and on a 429 wait a few minutes before retrying (your `idempotency_key` makes retries safe). You may also hit the general request limit, which returns `type: "too_many_requests"` with a `retry_after` timestamp you can wait on directly.
Do the arithmetic before you start: at the default limits, a thousand incidents is either a long afternoon or several days depending on your channel settings, which is why we recommend [contacting support](mailto:support@incident.io) for a temporary raise first.
## Check the result
List your imported incidents by filtering on mode:
```bash theme={null}
curl --request GET 'https://api.incident.io/v2/incidents?mode%5Bone_of%5D=retrospective&page_size=25' \
--header 'Authorization: Bearer '
```
Spot-check a few in the dashboard: the timestamps should reflect when the incident happened, severities and custom fields should be populated, and they should appear in your [Insights](https://app.incident.io/~/insights) with their historical dates.
## Import the rest of your history
Incidents are usually the biggest piece, but not the only one:
* **Post-mortem documents**: import existing write-ups as post-mortems with the [import endpoint](/api-reference/incidents-v2/import-postmortem-document), which accepts markdown.
* **Status page history**: recreate your public status page timeline with [retrospective status page incidents](/api-reference/status-page-incidents-v2/create-retrospective).
* **Catalog**: for services, teams, and other catalog data, use the [catalog importer](/catalog/importing-data).
* **Alerts**: there's currently no way to import historical alerts.
If you get stuck or your import is unusually large, [get in touch](mailto:support@incident.io) and we'll help you plan it.
# Installing incident.io in 30 seconds
Source: https://docs.incident.io/getting-started/installing
There are just **3 steps** :
1. Sign Up (via Slack)
2. Select your integrations
3. Add incident.io to Slack
**A couple of notes** *You will need a Slack admin to install us due to Slack's permissioning model.* *The app uses* `/inc` *and* `/incident` *as slash commands. If you already have an app installed or install one after ours that uses either of these commands*, *then just note that Slack will default to using the most recently installed app when that command is run.*
***
## 1. Sign Up (via Slack)
From the [sign-up page](https://app.incident.io/), you'll be asked to ' *Sign in with Slack* '.
We'll create an account for you and store some basic information, like your name and avatar. We'll also ask for a restricted set of permissions in order for [incident.io](http://incident.io/) to work. Read more in our [Security FAQs](/admin/security-faqs).
## 2. Select your integrations
This is just so we get a sense of the most-used tools in our user base. We explain how to set up your integrations → [here](/integrations/api-overview).
## 3. Add incident.io to Slack
Last step: ' *Add incident.io to Slack* '.
When you've done this, we'll create you an #incidents channel, and install the incident.io app into your workspace.
...all done!
**Everyone in your Slack workspace can now use** [incident.io](http://incident.io/) — they simply need to go through the same '[Login with Slack](http://app.incident.io/)' flow. They will not be asked to '*Add incident.io to Slack*' - that step only happens once.
Let's go declare some incidents!
***
**Having issues installing?** [Email our support team directly](mailto:support@incident.io) or [jump on a 1:1 call](https://incident.io/demo) and we'll get it sorted in no time!
***
## Troubleshooting
Signing up to incident.io is restricted to those using a corporate or company email address. Our product is designed for companies rather than individuals, and this helps us avoid abuse.
If you see a sign-up error, try again using your company email address. If you're still having trouble, [get in touch](mailto:support@incident.io).
incident.io has two slash commands: `/inc` and `/incident`. Slack only lets one application listen to a particular command, so if you have an existing app that uses either of these, incident.io will take over those commands when installed (the most recently installed app wins).
Installing incident.io won't remove the other application. If you're migrating from an app that uses `/inc` and want to avoid disruption, re-install that application after installing incident.io.
You can find a cheatsheet of all `/inc` commands [here](/incidents/shortcuts).
incident.io needs to create channels in your Slack workspace — a main `#incidents` announcement channel during install, and individual `#inc-...` channels for each incident. If your workspace restricts channel creation, installation will be blocked.
**You'll need a workspace admin to fix this.**
**Option 1: Allow all members to create channels**
Go to your Slack workspace settings and set *People who can create public channels* to *Everyone except guests*. Then select "I've changed channel creation permissions" and complete the installation.
**Option 2: Use a Slack admin account**
If you'd prefer to keep your channel management settings, you can connect a Slack admin user for incident.io to use when creating and managing incident channels. We recommend creating a dedicated user account for incident.io, as this user will appear as the channel creator and will appear to archive channels.
Once you've created the user, log in to Slack as that user in your browser, then select "I'd like to use a Slack admin user" and click "Continue".
This error appears when you try to sign in with a Slack Enterprise (organization) instead of a Slack Workspace.
To fix it, click the dropdown in the top right of the Slack sign-in screen and select a Workspace rather than an Organization.
If you don't see any Workspaces, log in to Slack in your browser first, then try again.
This usually means the incident's Slack channel has been archived. There are two ways to resolve it:
**Option 1: Unarchive the channel**
In Slack, click the channel name and select "Unarchive channel" in the Settings tab. Then refresh the incident page.
**Option 2: Store incident channel messages in incident.io**
Under [Settings > Security](https://app.incident.io/~/settings/security#store-incident-channel-messages), enable "Store incident channel messages". This keeps a copy of pinned messages in incident.io so you can review the timeline even after a channel is archived.
To import messages from already-archived channels, enable [privileged Slack access](/getting-started/slack-privileged-access). incident.io will temporarily unarchive those channels to import the messages, then re-archive them.
# Installing incident.io in Microsoft Teams
Source: https://docs.incident.io/getting-started/installing-teams
To sign up for incident.io using Microsoft Teams, please visit [this](https://app.incident.io/setup-msteams/login) link.
You can read more about [the permissions we ask for](/getting-started/teams-permissions).
## Signing up
## Step 1: Sign in with Microsoft
## Step 2: Consent to permissions
We need these permissions to identify you, so you don’t need to tick “Consent on behalf of your organization”.
## Step 3: Select a plan
Select a plan that would be a good fit for your organization. This will help us connect you with the right people on our team.
## Step 4: Grant “global permissions”
You must be a Microsoft admin to proceed with this step. If you'd like [to learn more](/getting-started/teams-permissions) about our permissions, we have an article.
This is the first of two steps that both look fairly similar, beware!
## Installing our Teams app
## Automatically
**Step 1: Grant us temporary permissions**
In this part, we temporarily ask for permission to create a new “Incidents” team in Teams, and install our app to it. This may take a few minutes.
## Manually
If you don't want to give us permission, or your Microsoft tenant doesn't allow us to install the application automatically, then:
1. Create a new "Incidents" team — or choose a team you wish to reuse.
2. Right click on the team, and choose "Manage team".
3. Go to the "Apps" tab and click "Get more apps".
4. Search for "incident.io" and click through to our listing.
5. In the "Add" dropdown, click "Add to team".
6. Choose the team to install us into.
7. Click "Set up" at the bottom right.
Once that's done, you should be able to go back to [https://app.incident.io](https://app.incident.io/), and declare an incident.
***
## Troubleshooting
If you encounter a sign-in error while setting up incident.io with Microsoft Teams:
1. Go to [portal.azure.com](https://portal.azure.com/)
2. Go to **Enterprise applications** and find the incident.io app
3. Check the **Sign-in logs** and **Access reviews** sections for details about why the sign-in failed — your admin may be able to help resolve these
If that doesn't help, go to the **Diagnose and solve problems** section in the sidebar and use the correlation ID from the error to diagnose the problem.
If you're still stuck, reach out to your support contact.
For incident.io to DM a Microsoft Teams user (e.g. to notify an incident lead), the incident.io app must be installed at the user level. We request the `TeamsAppInstallation.ReadWriteAndConsentSelfForUser.All` permission to handle this automatically, but sometimes the installation still fails.
**Verify whether the app is installed for a user**
Microsoft doesn't provide a UI for this, but you can use PowerShell:
```powershell theme={null}
Install-Module Microsoft.Graph.Teams -Scope CurrentUser
Connect-MgGraph -Scopes "TeamsAppInstallation.ReadForUser.All"
Get-MgUserTeamworkInstalledApp -UserId "user@domain.com" -ExpandProperty "teamsAppDefinition"
```
If incident.io doesn't appear in the output, we won't be able to DM that user. Compare the output against a user who does receive DMs to identify differences.
**Install the app manually via PowerShell**
```powershell theme={null}
Connect-MgGraph -Scopes "TeamsAppInstallation.ReadWriteForUser.All"
$appId = "c878d453-b147-49d6-aab9-b912dcaee5ec"
$body = @{
"teamsApp@odata.bind" = "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/$appId"
}
New-MgUserTeamworkInstalledApp -UserId "user@domain.com" -BodyParameter $body
```
Any error returned here will indicate why the automatic installation failed.
**Ensure the app is installed via a Teams app policy**
To prevent this issue across your organization:
1. Sign in to [admin.teams.microsoft.com](https://admin.teams.microsoft.com/)
2. Navigate to **Teams apps → Setup policies**
3. Edit the **Global policy** (for all users) or create a new policy for specific users
4. Under **Installed apps**, click **Add apps**, search for incident.io, and add it
5. Save and assign the policy to the relevant users or groups
If a user loses their assigned role (for example, a Responder being reverted to Viewer) or appears as deactivated in incident.io despite still being active in Microsoft, this is most likely because we can't tell that they're still an active user in your Microsoft tenant.
This doesn't necessarily mean the user won't be able to log in — but it does mean that they'll periodically appear as deactivated and/or lose any roles they've been granted above Viewer.
To make sure incident.io accounts get deactivated when the corresponding user leaves your Microsoft tenant or is deactivated in Microsoft, we periodically check each incident.io user against your Microsoft tenant. We do this by looking at the members of the Microsoft Teams team(s) where the incident.io bot is installed. If a user doesn't appear in any of those teams — for example, because they only sign in to the incident.io dashboard, or only DM the bot — we won't see them, and we'll treat them as no longer active and deactivate their incident.io account.
To resolve this, make sure the affected user is a member of a Microsoft Teams team that has the incident.io bot installed. You can do this either by:
* Adding the user to a team where the bot is already installed, or
* Installing the bot into a team that the user is already a member of.
Once they appear as a member of a team where our bot is installed, we'll recognize them as still active and stop deactivating their account.
If you continue to see users being deactivated after applying this, reach out to your support contact.
## You're done!
There should be a new “Incidents” team with a “General” channel and an incident.io tab where you can declare an incident.
## Installing our Teams app into an existing team
Once you've installed our app for the first time (e.g. you have followed the [Installing our Teams app](/getting-started/installing-teams) section and have an 'Incidents' team), you're also able to install us into other teams in your Teams workspace.
By installing incident.io into your other teams, you'll be able to:
* Declare incidents from the incident.io tab from within that team
* Create [Announcement rules](/incidents/change-announcements) to send incident updates to that team
To add our app to another team:
1. Choose a team you wish to add us into.
2. Right click on the team, and choose "Manage team".
3. Go to the "Apps" tab and click "Get more apps".
4. Search for "incident.io" and click through to our listing.
5. In the "Add" dropdown, click "Add to team".
6. Choose the team to install us into.
7. Click "Set up" at the bottom right.
# Microsoft's 'admin consent' flow
Source: https://docs.incident.io/getting-started/microsoft-admin-consent-flow
To sign up to incident.io we ask you to log in using your Microsoft account. We then need our application to be granted a set of permissions in Microsoft Entra ID (formerly Azure AD). To do this, we send you through the "Admin consent" flow.
If you're unfamiliar with this flow, you should read [Microsoft's documentation about admin consent](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/user-admin-consent-overview#admin-consent). You need to be a **Privileged Administrator** to do this, or you will need one to do this on your behalf.
During signup, we show you a "Grant Microsoft admin consent" button. There are two ways to progress here. Click the button, and you will be taken to Microsoft.
If you **are** able to consent to the permissions, then you can complete the admin consent flow here. Once finished, you'll be able to click "Install to Microsoft Teams".
If you **are not able** to consent to the permissions, then you will see one of two things: either a message saying you can't consent, or a dialog that allows you to request consent from an administrator. For both of these situations, you will need to find a user who is a privileged administrator, and they will need to go through the steps detailed below.
## Consenting through Microsoft Entra ID
They should sign in to [https://entra.microsoft.com/](https://entra.microsoft.com/) and go to Applications → Enterprise Applications. Search for "incident.io", and go to "Permissions" on the left, in the "Security" section. Once here, they should click the "Grant admin consent for ..." button. This will take them through the flow where they consent to our permissions.
If a request was submitted, follow the instructions in Microsoft's documentation on [reviewing admin consent requests](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/review-admin-consent-requests).
Once you've done this, you'll need to go back through the admin consent flow in our app, so that we re-check whether consent has been granted. This step is important!
## Further reading
* [Configure the admin consent workflow](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/configure-admin-consent-workflow)
* [Overview of admin consent in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/user-admin-consent-overview#admin-consent)
# Migrating Datadog monitors to incident.io
Source: https://docs.incident.io/getting-started/migrate-datadog-monitors
## Background
Many organizations use Datadog as an [alert source](/incidents/auto-create) to trigger incident creation and/or escalations.
If you are migrating from another paging provider to [incident.io](http://incident.io/) On-call, you'll need your Datadog monitors to point from your old provider to incident.io. This can be done using either:
1. **Terraform**
2. **Our migration tool (currently in beta)**
## Terraform
All you will need to do is update your monitor descriptions. Anywhere there is a tag referencing a paging provider (ie. @pagerduty-SERVICENAME), you can replace with @webhook-incident-io.
If you are tagging your monitors with services, you can send all your monitors to one alert source and then parse the Datadog payload to get the service as an alert attribute.
See more details on setting up your alert sources [here](/incidents/auto-create) .
## Migration tool (currently in beta)
If you do not use Terraform, you can use our migration tool which automatically updates your Datadog configuration to point to [incident.io](http://incident.io/).
This is a tool you can download and plug in your Datadog API keys. The tool itself will:
* Analyze all your monitors and creating a file for them to fill out that maps PagerDuty or Opsgenie services, for example, to [incident.io](http://incident.io/) teams
* Talk you through the options for one webhook in Datadog or multiple webhooks
* Automatically create the webhook configurations in Datadog
* Automatically update their monitors to point to [incident.io](http://incident.io/)
* Automatically remove PagerDuty or Opsgenie when we are successful
This can be accessed via Github [here](https://github.com/incident-io/datadog-migrator). Also, see a complementary Loom for help [here](https://www.loom.com/share/1f0a862752054bb0a1a8830f5bd9c500?sid=dad2a390-81bd-4ad6-bd42-78ab97526aa3).
# Tools to make migrating from Opsgenie easier
Source: https://docs.incident.io/getting-started/migrate-from-opsgenie
## Overview
We know that migrating from Opsgenie to [incident.io](http://incident.io/) can feel intimidating, as there can be a lot of configuration that you have in place that you don’t want to lose. So, we’ve built (and continue to build) tooling to make this process easier for you.
Below is a list of tools that you can leverage to make your testing phase and official migration / onboarding easier, including:
* Opsgenie alert source
* Pull Opsgenie information into Catalog
* Importing schedules
* Importing escalation paths
* Importing user notification preferences
* Terraform provider
* Datadog migration tool
* On-call readiness support
* Preferred provider for manual escalations
Also, let us know if there is something else that you’d need help with migrating! We are here to make this as painless as possible - so we can always work together to figure out what else we can provide.
## Opsgenie alert source
You are able to connect your Opsgenie instance directly to [incident.io](http://incident.io/) as an alert source. What this allows you to do is test our On-call features such as schedules and escalation paths without having to move over your alert providers (ie. Datadog, Grafana), which can decrease the time to testing.
So, you can have a simplified testing set-up like:
Grafana → Opsgenie → escalate via [incident.io](http://incident.io/)
Once you are ready to fully migrate or onboard, you would move to a set-up that looks like:
Grafana → escalate via [incident.io](http://incident.io/)
Related help docs:
[Opsgenie help docs](/integrations/opsgenie)
[Extracting alert source information help doc](/alerts/json-alert-data)
## Pull Opsgenie information into Catalog
If you have connected Opsgenie into [incident.io](http://incident.io/), we will automatically pull in your Opsgenie schedules, services, teams, and users into the Catalog.
This allows you to use the Opsgenie catalog with the rest of your catalog data. For example, you can determine what should still be paged via Opsgenie vs. [incident.io](http://incident.io/).
Related help docs:
[How to get data into the catalog help doc](/catalog/importing-data)
[Using the catalog help doc](/catalog/catalog-setup)
## Importing schedules
We allow you to import (including bulk import!) schedules directly from Opsgenie.
## Importing escalation paths
We allow you to import (including bulk import!) escalation policies directly from Opsgenie.
### Skipping onboarding notifications during import
When you import schedules or escalation paths, any users going on-call for the first time will normally receive an onboarding notification (via email, Slack, and push notification) letting them know they've been added to on-call and prompting them to set up their contact methods and notification preferences.
If you'd prefer not to send these notifications during import, you can turn them off. When confirming the import and promoting users to on-call responders, you'll see a **Send onboarding email notifications** toggle. Turn this off to skip sending the onboarding notification.
Even when notifications are skipped, users are still marked as onboarded internally — so they won't receive duplicate
notifications if you import additional schedules later. Users will still receive the standard "You are currently on
call" notification at the start of their first on-call shift, whenever that may first happen.
This option is not available for SCIM customers, as users need to be imported manually before they can be added to
schedules.
## Importing user notification preferences
You can import a users notification preferences either individually or in bulk. To import in bulk, click the banner on the users page or when viewing
a teams members. Users can individually import their own settings if they wish using the button in their notification preferences.
Please note that we do not support conditions such as Opsgenie's Criteria or Time Restrictions on a users preferences and as such these will not be imported.
We will also create rules for all methods for both high and low urgency. We recommend individual users check their settings and edit accordingly.
This is useful for organisations that have a short time to migrate over to [incident.io](http://incident.io/)
## Terraform provider support
If you use Terraform to manage your on-call configuration, we also support Terraform for alert sources, alert routes, escalation paths and schedules.
Additionally, Terraform can help with migrating alert sources. For example: If you have loads of monitors in Datadog that point to Opsgenie. You can quickly and easily update the Terraform config to have those monitors point to [incident.io](http://incident.io/) instead.
Related docs:
[Terraform documentation](https://registry.terraform.io/providers/incident-io/incident/latest/docs)
## Datadog migration tool (beta)
If you do not use Terraform, and have loads of Datadog monitors, you can leverage our migration tool to update everything to point to [incident.io](http://incident.io/).
Download the tool from us, plug in your Datadog API keys and you’ll be able to:
* Talk you through the options for one webhook in Datadog or multiple webhooks
* Automatically create the webhook configurations in Datadog
* Automatically update your monitors to point to [incident.io](http://incident.io/)
* Automatically remove Opsgenie when we are successful
It's on GitHub [here](http://github.com/incident-io/datadog-migrator) (currently private until out of beta), and have a helpful Loom for reference [here](https://www.loom.com/share/1f0a862752054bb0a1a8830f5bd9c500).
## On-call readiness report
You can use the On-call readiness report to understand how prepared your team is to start receiving pages from [incident.io](http://incident.io/). These insights will help you track your migration and onboarding of new responders going on-call. At a glance, you can see responder adoption with different notification methods:
* How people are reachable (via the app, phone, etc.)
* What percentage of your on-call responders are reachable through different methods
You’ll also be able to drill down into individual responder setups so that you can contact the right people if necessary.
We also have on-call readiness available via the Members tab of your teams page(s), and you can leverage On-call readiness [policies](/admin/policies) to enforce a particular set up.
## Preferred provider for manual escalations
If you have connected Opsgenie to your account, we will now allow individual users to identify if they want to be paged via Opsgenie or [incident.io](http://incident.io/). Previously, we made the person initiating the manual escalation decide which provider to use - which wasn’t a great experience, as they wouldn’t have a way to know which one to use (ie. is that user set up with [incident.io](http://incident.io/) ? what is Opsgenie?).
This work will allow individuals to configure which paging solution they want to be paged by, so when a manual escalation comes through they are appropriately paged via that solution.
Once Opsgenie is removed from [incident.io](http://incident.io/), we will default all escalations to [incident.io](http://incident.io/).
Related help docs:
[How do I manually escalate?](/on-call/manual-escalation)
# Tools to make migrating from PagerDuty easier
Source: https://docs.incident.io/getting-started/migrate-from-pagerduty
## Overview
We know that migrating from PagerDuty to [incident.io](http://incident.io/) can feel intimidating, as there can be a lot of configuration that you have in place that you don’t want to lose. So, we’ve built (and continue to build) tooling to make this process easier for you.
Below is a list of tools that you can leverage to make your testing phase and official migration / onboarding easier, including:
* PagerDuty alert source
* Pull PagerDuty information into Catalog
* Importing schedules
* Mirroring schedules into PagerDuty
* Importing escalation paths
* Importing notification rule settings
* Terraform provider
* Datadog migration tool
* On-call readiness support
* Preferred provider for manual escalations
Also, let us know if there is something else that you’d need help with migrating! We are here to make this as painless as possible - so we can always work together to figure out what else we can provide.
## PagerDuty alert source
You are able to connect your PagerDuty instance directly to [incident.io](http://incident.io/) as an alert source. What this allows you to do is test our On-call features such as schedules and escalation paths without having to move over your alert providers (ie. Datadog, Grafana), which can decrease the time to testing.
So, you can have a simplified testing set-up like:
Grafana → PagerDuty → escalate via [incident.io](http://incident.io/)
Once you are ready to fully migrate or onboard, you would move to a set-up that looks like:
Grafana → escalate via [incident.io](http://incident.io/)
Related help docs:
[PagerDuty integration help docs](/integrations/pagerduty)
[Extracting alert source information help doc](/alerts/json-alert-data)
## Pull PagerDuty information into Catalog
If you have connected PagerDuty into [incident.io](http://incident.io/), we will automatically pull in your PagerDuty services, teams, users, escalation policies and schedules into the Catalog.
This allows you to use the PagerDuty catalog with the rest of your catalog data. For example, you can determine what should still be paged via PagerDuty vs. [incident.io](http://incident.io/).
Related help docs:
[How to get data into the catalog help doc](/catalog/importing-data)
[Using the catalog help doc](/catalog/catalog-setup)
## Importing schedules
We allow you to import (including bulk import!) schedules directly from PagerDuty. See details [here](/on-call/import-pagerduty).
## Importing escalation policies
We allow you to import (including bulk import!) escalation policies directly from PagerDuty. See details [here](/on-call/import-pagerduty).
### Skipping onboarding notifications during import
When you import schedules or escalation paths, any users going on-call for the first time will normally receive an onboarding notification (via email, Slack, and push notification) letting them know they've been added to on-call and prompting them to set up their contact methods and notification preferences.
If you'd prefer not to send these notifications during import, you can turn them off. When confirming the import and promoting users to on-call responders, you'll see a **Send onboarding email notifications** toggle. Turn this off to skip sending the onboarding notification.
Even when notifications are skipped, users are still marked as onboarded internally — so they won't receive duplicate
notifications if you import additional schedules later. Users will still receive the standard "You are currently on
call" notification at the start of their first on-call shift, whenever that may first happen.
This option is not available for SCIM customers, as users need to be imported manually before they can be added to
schedules.
## Importing notification rule settings
We allow you to import either in bulk, at a team level, or individually notification rule settings directly from PagerDuty.
This is useful for organizations that have a short time to migrate over to [incident.io](http://incident.io/)
## Mirroring schedules into PagerDuty
We have built out the ability to mirror an [incident.io](http://incident.io/) schedule into a PagerDuty schedule(s). This allows organizations to test out cover requests and overrides in earnest within [incident.io](http://incident.io/), and have that reflect back into PagerDuty.
This is great for organizations that are in a testing phase, and might not be able to migrate quickly after a trial and will need to go back to using PagerDuty until onboarding has officially started.
## Terraform provider support
If you use Terraform to manage your on-call configuration, we also support Terraform for alert sources, alert routes, escalation paths and schedules.
Additionally, Terraform can help with migrating alert sources. For example: If you have loads of monitors in Datadog that point to PagerDuty. You can quickly and easily update the Terraform config to have those monitors point to [incident.io](http://incident.io/) instead.
See documentation [here](https://registry.terraform.io/providers/incident-io/incident/latest).
## Datadog migration tool (beta)
If you do not use Terraform, and have loads of Datadog monitors, you can leverage our migration tool to update everything to point to [incident.io](http://incident.io/).
Download the tool from us, plug in your Datadog API keys and you’ll be able to:
* Analyze all your monitors and create a file to fill out that maps PagerDuty services to [incident.io](http://incident.io/) teams
* Talk you through the options for one webhook in Datadog or multiple webhooks
* Automatically create the webhook configurations in Datadog
* Automatically update your monitors to point to [incident.io](http://incident.io/)
* Automatically remove PagerDuty when we are successful
It's on GitHub [here](http://github.com/incident-io/datadog-migrator) (currently private until out of beta), and have a helpful Loom for reference [here](https://www.loom.com/share/1f0a862752054bb0a1a8830f5bd9c500).
## On-call readiness report
You can use the On-call readiness report to understand how prepared your team is to start receiving pages from [incident.io](http://incident.io/).
These insights will help you track your migration and onboarding of new responders going on-call. At a glance, you can see responder adoption with different notification methods:
* How people are reachable (via the app, phone, etc.)
* What percentage of your on-call responders are reachable through different methods
You’ll also be able to drill down into individual responder setups so that you can contact the right people if necessary.
We also have on-call readiness available via the Members tab of your team page, and you can leverage On-call readiness [policies](/admin/policies) to enforce a particular set up.
## Preferred provider for manual escalations
If you have connected PagerDuty to your account, we allow you to control whether each individual user is paged via PagerDuty or [incident.io](http://incident.io/). Previously, we made the person initiating the manual escalation decide which provider to use - which wasn’t a great experience, as they wouldn’t have a way to know which one to use (ie. is that user set up with [incident.io](http://incident.io/) ? what is PagerDuty?).
There are two places this is configured:
* **As an admin**, go to [Settings → Forms](https://app.incident.io/~/settings/forms) and open your **Escalate** form. Under **Create escalation**, find **Escalation target**, then the **Users** row, and click the **edit (pencil)** icon. This opens the **Configure escalations to users** drawer, where you can set which paging provider is used for each user in your organization.
* **As an individual user**, you can set your own preference from your **User Preferences → On-call notifications → Paging provider**.
Note that this only applies to manual escalations where a user is *explicitly chosen* - so when a manual escalation comes through, that user is appropriately paged via their preferred provider.
Once PagerDuty is removed from [incident.io](http://incident.io/), we will default all escalations to [incident.io](http://incident.io/). See more details [here](/on-call/manual-escalation).
# Creating a Slack admin for privileged Slack access
Source: https://docs.incident.io/getting-started/slack-admin-setup
If you need to [give incident.io privileged Slack access](/getting-started/slack-privileged-access), we recommend creating a Slack account just for that purpose, because:
* channels created by this user will still say 'Created by incident.io', keeping things nice and clear
* if this user is invited to private incidents, it will not expose private data to anyone, since no one should log in with this Slack account
* this user will receive 'channel archived' notifications for all incidents
Neither incident.io nor Slack will charge for this account. Slack does not charge for accounts that have not been logged in to for more than 14 days (see their [fair billing policy](https://slack.com/intl/en-gb/help/articles/218915077-Slacks-fair-billing-policy) ). This type of account is sometimes referred to as a 'service account' in Slack's documentation.
***
Here's how to create a Slack user for incident.io:
1. **Create a new user in Slack**
Follow Slack's latest guide [here](https://slack.com/intl/en-gb/help/articles/201330256-Invite-new-members-to-your-workspace). We recommend using an email list address, such as `it+incidentio@example.com`.
2. **Accept the invitation**
Make sure to set the name to "incident.io Admin", so it's clear to everyone what the account is for.
3. **Upgrade the account's role**
Log in as a Workspace Owner or Admin and upgrade the new account's role, using [Slack's guide](https://slack.com/intl/en-gb/help/articles/218124397-Change-a-member%E2%80%99s-role#manage-owner-and-admin-roles).
4. **Connect the user to incident.io**
Make sure you're logged in to Slack with the `incident.io Admin` account, then open your [Security settings](https://app.incident.io/~/settings/security) and click "Connect" next to "Privileged Slack access".
Click "Add to Slack", then "Allow".
That's it - you're connected
# Slack Enterprise Grid
Source: https://docs.incident.io/getting-started/slack-enterprise-grid
Organizations on our [Enterprise plan](https://incident.io/pricing/) will be able to have our Slack app installed into a Slack Enterprise Grid. By doing so, a single incident.io account can be used for multiple Slack workspaces under the same Slack Enterprise Grid.
## What have we built?
* We have ported all our Slack app features to work the same as a Slack Workspace level install
* The incident.io Slack app can be accessed in any Slack Workspaces within the same Slack Enterprise Grid. You can also configure which Slack Workspaces do and do not have access.
* The Web Dashboard experience has been improved to cater for a Slack Enterprise Grid install with the following features:
* Organization name and logo is set to Slack Enterprise Grid name and logo
* Homepage shows Incidents from workspaces you have access to by default. Also able to view incidents from other workspaces.
* Filter by Workspace in Incidents, Followups and Insights pages
* Set Incident Workspace as a Workflow condition
* Define Incident Workspaces for Incident Triggers (PagerDuty, Opsgenie, etc)
* Public API
* Creating incidents now accept a Slack Team ID to define which Workspace to declare an incident in
* Incidents will include Slack Team ID of the Workspace that an incident was declared in
## Criteria for Installing into Slack Enterprise Grid
To be able to install incident.io into a Slack Enterprise Grid, your organization needs to fulfill the following criteria:
1. Be on an incident.io Enterprise plan
2. Have exactly one Slack Workspace have incident.io installed within a Slack Enterprise Grid. We currently don't support the merging of incident.io accounts.
Please get in touch with us if you are unsure.
## How to install incident.io into a Slack Enterprise Grid
Please contact us to configure Slack Enterprise Grid on your account.
## Configuring incident channel workspaces
By default, for organizations with incident.io installed into Slack Enterprise Grid, incident channels are created in the first workspace that incident.io was installed into. If you have installed incident.io into multiple workspaces, you can change this behavior in **Settings → Slack Enterprise Grid**, under **Incident channel workspaces**.
With **Automatically select workspaces** enabled (the default), incident.io chooses the workspaces for you:
* **Route based on incident details**: Use expressions to route different incident types to different workspaces (e.g., route production incidents to your engineering workspace).
* **Create channels in multiple workspaces**: Set up rules to create channels across several workspaces simultaneously, letting teams collaborate from wherever they work.
To let responders pick the workspace instead, disable **Automatically select workspaces**. Responders then choose a workspace from a dropdown when declaring an incident.
# Slack Enterprise Grid migrations
Source: https://docs.incident.io/getting-started/slack-enterprise-grid-migrations
### Do I need to do anything?
No, we handle [Slack Enterprise Grid migrations](https://slack.com/intl/en-gb/help/articles/115002532808-Migrate-workspaces-to-an-Enterprise-organisation) automatically. Slack send an event to our application when an Enterprise Grid migration begins and ends, and we use this as a signal to pause user syncing.
### Why do you pause user syncing?
Grid migrations can result in user IDs changing, so we pause our user syncing process during the migration. We do this because Slack is often a source of truth for authentication, and these migrations can sometimes result in user IDs changing. By pausing the user syncing, we eliminate the risk of users becoming deactivated during the process and losing access to incident.io.
### Do you automatically update user IDs if they change?
Yes. When a Grid migration is taking place, we attempt to exchange the old user ID every time a user signs in. We also run a "bulk exchange" of user IDs every day. For both of these processes, we use Slack's [migration.exchange](https://docs.slack.dev/reference/methods/migration.exchange/) API endpoint.
### Do I need to re-install the incident.io app?
Grid migrations should involve a step where the [incident.io](http://incident.io/) Slack application is re-installed, either at the Grid level or to the individual workspace. We handle both of these cases transparently: however, if you want to install us at a Grid level and have **another** workspace already using incident.io, there is some configuration we need to do on our side to map the workspaces to the correct accounts on our side.
See [this article](/getting-started/slack-enterprise-grid) for details on which plans can install [incident.io](http://incident.io/) at the Grid level.
# Why does incident.io need a Slack Owner account?
Source: https://docs.incident.io/getting-started/slack-owner-account
If you've connected a Slack admin account for privileged Slack access, but you're seeing this message, here's how to resolve it:
## Why am I seeing this message?
There are two reasons you might see this message:
1. **We need privileged Slack access to manage private incident channels.**
To manage private incident channels, the connected Slack user must be a Workspace Owner. We'll never automatically invite Slack Admins to private incidents.
2. **Your workspace settings restrict actions to only Workspace Owners**
If your workspace settings are set to "Workspace owners only", the connected admin account won't be able to take those actions. Check out our [guide to privileged Slack access](/getting-started/slack-privileged-access) for more information on these workspace settings.
# What does incident.io need privileged Slack access for?
Source: https://docs.incident.io/getting-started/slack-privileged-access
Depending on your Slack workspace settings, bots and regular users may be restricted from taking certain actions and one should ensure two sections of settings are set in a specific way: **Channel Management** and **User Groups**. Let's tackle them one at a time below!
## Channel Management
You can check these settings at [https://app.slack.com/admin/permissions/account-types](http://slack.com/admin/permissions/account-types).
Alternatively you can access the settings directly from Slack if you click on the workspace per se → **Tools\&settings** → **Workspace settings.** On the left side of the screen select **Administration** → **Manage permissions**. Proceed with selecting **Account types**.
Using the filtering option on the right side, you should search for:
* Create private channels - Workspace admins and owners only
* Create public channels - Everyone (except guests by default)
* Archive channels - Workspace admins and owners only
* Remove users from private channels - Workspace admins and owners only
* Remove users from public channels - Workspace admins and owners only (by default)
* Edit channel posting permissions - Everyone (except guests by default)
In this section the most relevant settings for [incident.io](http://incident.io/) are:
## People who can create private channels
If this is set to "Workspace admins and owners only" or "Workspace owners only", we won't be able to create private incident channels. If you'd like to use [private incidents](/incidents/private-incidents) you'll need to connect a Slack Workspace Owner.
The connected user will be invited to all private incidents, so we recommend creating a Slack user just for this purpose. [Learn how here](/getting-started/slack-admin-setup).
## People who can create public channels
If this is set to "Workspace admins and owners only" or "Workspace owners only", we won't be able to create incident channels. You'll need to connect a Slack Workspace Admin or Workspace Owner to get started.
The connected user will be invited to all incidents, and appear as the "channel creator" in Slack:
To avoid confusion, we recommend creating a Slack user just for this purpose. [Learn how here](/getting-started/slack-admin-setup).
## People who can archive channels
If this is set to "Workspace admins and owners only" or "Workspace owners only", we won't be able to automatically archive old incident channels. Connect a Slack admin or owner to enable this feature.
The connected Slack admin will be added to incident channels to archive them, so we recommend creating a Slack user just for this purpose. [Learn how here](/getting-started/slack-admin-setup).
The connected Slack user will only be invited to private incidents if they are a Slack Workspace Owner.
## People who can remove users from private channels
If this is set to "Workspace admins and owners only" or "Workspace owners only" the incident.io bot won't be able to remove access to private incidents automatically: they must be removed from the channel first, either by an admin, or by leaving voluntarily.
Connect a Slack Workspace Owner to have incident.io automatically remove private incident participants with `/incident revoke`.
Note that the connected Workspace Owner will be invited to private incidents. We recommend creating a Slack user just for this purpose. [Learn how here](/getting-started/slack-admin-setup).
***
## User groups
You can check these settings at [https://app.slack.com/admin/user\_groups](http://slack.com/admin/user_groups)
Alternatively you can access the settings directly from Slack if you click on the workspace per se → **Tools\&settings** → **Workspace settings.** On the left side of the screen select **Administration** → **User groups**.
The settings under User groups are also relevant to [incident.io](http://incident.io/) :
## People who can create and disable user groups
If this is set to "Workspace admins and owners only" or "Workspace owners only", we won't be able to create user groups that reflect the responders currently on call for a schedule.
You'll need to connect a Slack admin or owner to enable [this feature](/on-call/sync-slack-groups).
## People who can modify/edit user groups
If this is set to "Workspace admins and owners only" or "Workspace owners only", we won't be able to sync the user groups that reflect the current on call responders when there's a shift change.
You'll need to connect a Slack admin or owner to enable [this feature](/on-call/sync-slack-groups).
# Permissions in Microsoft Teams
Source: https://docs.incident.io/getting-started/teams-permissions
incident.io for Microsoft Teams requests three sets of permissions:
1. Global permissions: these give us access to resources across your Microsoft tenant.
2. Team-specific permissions: these allow us to manage the 'Incidents' team where the incident.io bot is installed.
3. Install and upgrade permissions: optionally, these permissions allow us to automate setting up incident.io in your Microsoft account.
## Global permissions
Before you can install the incident.io app to Microsoft Teams, we first need access to view information about your Microsoft tenant.
The permissions here are for app-only access, and allow us to perform certain operations against Microsoft's API without a user being present. This is called [app-only access](https://learn.microsoft.com/en-gb/entra/identity/enterprise-apps/user-admin-consent-overview#admin-consent). When you sign up for incident.io, or when we need to add new permissions, you'll have to go through [the admin consent process](https://learn.microsoft.com/en-gb/entra/identity/enterprise-apps/user-admin-consent-overview#admin-consent).
| **Permission** | **Description** | **Purpose** |
| --------------------------------- | --------------------------------------------------------- | -------------------------------------------------------- |
| `OrganizationalBranding.Read.All` | See the name and logo configured in your Microsoft tenant | This lets us show your logo in the incident.io dashboard |
| `Chat.Create` | Create chats within Microsoft Teams | We use this to create group chats for private incidents. |
## Team-specific permissions
When you install the incident.io app for Microsoft Teams, we'll gain additional access to the Team the app is installed to, but not other Teams or Chats within your Microsoft tenant.
**Note**: these permissions only apply inside the Team that the incident.io app is installed to. No access is granted to other Teams in your account.
| **Permissions** | **Description** | **Purpose** |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Channel.Create.Group Channel.Delete.Group ChannelSettings.ReadWrite.Group | Create, rename, archive and delete channels | Create a channel for each incident, and keep its name in sync with the incident's name. Once resolved, the channel can be archived based on your settings. |
| ChannelMessage.Read.Group | View messages posted to public channels where the incident.io app is installed (excluding private or shared channels) | Build the incident timeline based on messages in the incident channel. Generate a summary and suggest actions based on conversation in the incident channel. Track who is working on the incident and for how long. |
| TeamsTab.Create.Group TeamsTab.ReadWrite.Group | View, create, and update tabs in channels within the Team | Add the incident.io tab to the 'General' channel. Add the incident.io tab to each incident channel. |
| TeamSettings.Read.Group TeamSettings.ReadWrite.Group | View and change settings for the Team | Allows us to view & update the name and description of the incidents team |
| TeamsAppInstallation.Read.Group | View apps installed to the Team | Check which version of the incident.io app is installed. |
## Chat-specific permissions
When we create a chat and install the incident.io app for Microsoft Teams into it, we'll gain additional access to the chat we created, but not other Teams or Chats within your Microsoft tenant.
**Note**: these permissions only apply inside the chat that the incident.io app is installed to. No access is granted to other chats in your account.
| **Permissions** | **Description** | **Purpose** |
| --------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| ChatSettings.ReadWrite.Chat | Update the topic of chats | Keep the topic of an incident's chat in sync with the incident's name. |
| TeamsTab.ReadWrite.Chat | View, create, and update tabs in chats | Add the incident.io tab to each incident channel |
| Chat.Manage.Chat | Add and remove members in chats | Invite selected users to private incident chats. Remove users from private incident chats if access is revoked. |
## Install & upgrade permissions
These permissions allow us to create the Incidents Team and install the incident.io app to it on your behalf.
We only ask for these permissions for one hour at a time, after which we won't be able to use these permissions without your explicit consent.
| **Permission** | **Description** | **Purpose** |
| ----------------------------------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Team.Create | Create a team | Create the 'Incidents' team, where incident channels will be created. |
| TeamsAppInstallation.ReadWriteAndConsentForTeam | Install an app to a Team, and grant it permissions within that Team | Install or upgrade the incident.io app within the 'Incidents' team. |
If you would prefer not to grant us these permissions, you can take these actions manually from within Microsoft Teams. Please get in touch and we'll help you get set up manually.
# Using private incidents in Microsoft Teams
Source: https://docs.incident.io/getting-started/teams-private-incidents
Handling an incident is hard. Even more so when you’re worried about discussing a sensitive topic in a public forum such as an incident channel. Perhaps it is a sensitive legal question, an HR complaint, or a security hole that needs closing.
Private incidents help solve this. If there is any doubt over the nature of an incident users can now declare an incident as private in Microsoft Teams. Locking it down both in visibility and access pulling in users as and when required, and only when invited.
## How private incidents work
Previously, all incidents were run in a Teams Channel, which, while great for communication and organization across your whole team, could lead to issues if the incident was of a sensitive nature.
Now, when creating a private incident, we instead use private group chats inviting only those granted access. This allows organizations to control access and visibility of an incident to a subset of specific users.
Once invited into the group chat that user becomes authorized to interact and view the incident. They have access to all the same great features available in a public incident, allowing your responders to quickly and easily get on with resolving the problem and not having to worry about what they do or do not say in any discussion.
## Enabling private incidents
Private incidents are not enabled by default. In order to turn them on [navigate to your security settings](https://app.incident.io/~/settings/security) and tick the box to enable them.
Once enabled you will be able to add the option to make an incident private into your incident forms.
If you use incident types you can also set it so a certain type is *always* private. An example use case would be setting all security type incidents to be private to ensure they are handled securely.
## Re-authorizing your account
If you have previously installed [incident.io](https://app.incident.io/) you may be required to update our bot as well as re-authenticate using an admin account to add additional permissions.
We need additional permissions in order to create and manage the private group-chats. To read more about the permissions we require and what we use them for [see our permissions article.](/getting-started/teams-permissions)
If this is required you will see the following notification when trying to turn on private incidents:
Follow the link to grant new permissions as well as update the version of the bot to the latest.
Once updated you should now be able to enable private incidents! If you face issues with re-authorizing or installing the new version please reach out and we will help you get set-up correctly.
# What's incident.io?
Source: https://docs.incident.io/getting-started/what-is-incident-io
The all-in-one platform for on-call, incident response, Investigations and status pages.
## Getting started
Getting started with incident.io almost couldn't be easier. Pick your communications platform below and you'll be up and running in minutes.
If your team uses Slack, follow our [Slack installation guide](/getting-started/installing) and start declaring and
managing incidents directly from Slack.
If your team uses Microsoft Teams, follow our [Microsoft Teams installation
guide](/getting-started/installing-teams) to get up and running.
## Products
We have four core products that work together across the incident lifecycle:
Alert routing, on-call schedules, and smart escalation paths so the right people are notified when something needs
attention. Integrates with your existing monitoring tools. [Learn more](/on-call/getting-started)
Declare and run incidents directly in Slack or Microsoft Teams. incident.io creates a channel, assigns roles, and
tracks actions. AI handles the repetitive work: writing summaries, drafting status updates, and suggesting
follow-ups. After the incident, generate postmortems, track follow-ups, and identify patterns to prevent recurrence.
[Learn more](/incidents/declaring)
Keep customers and stakeholders informed during incidents. Public, private, and internal status pages that update
automatically as your incident progresses. [Learn more](/status-pages/overview)
An AI teammate that investigates incidents alongside your engineers. It automatically finds problematic code
changes, queries your observability tools, and suggests causes directly in your incident channel — so your team can
resolve issues faster. **Coming soon**
## Migrating from another tool
Already using an on-call or incident management tool? We've got guides to help you move across.
Follow our [PagerDuty migration guide](/getting-started/migrate-from-pagerduty) to bring your schedules, escalation
policies, and services across to incident.io.
Follow our [Opsgenie migration guide](/getting-started/migrate-from-opsgenie) to move your on-call configuration
over to incident.io.
# Why does incident.io require a communications platform?
Source: https://docs.incident.io/getting-started/why-comms-platform
In order to use incident.io, you must have either Slack or Microsoft Teams connected. This is true whether you are using our Response product, our On-call product, or both. Even if you are not creating channels for incidents, we use these platforms to communicate with users, so we still require our bot to be installed to one of these two platforms.
For **On-call,** there are a number of features which make use of these communications platforms, for example:
* Being able to have Slack channels a destination for on-call escalations. For example, configuring low severity alerts to route to a Slack channel during office hours.
* Configuring Slack or Microsoft Teams DMs as a notification mechanism on top of SMS, WhatsApp, push notification and email. This method is incredibly convenient for dealing with escalations with minimal friction. This comes as a default for all users.
* Sending shift reminders for users before their shifts
* Linking On-call schedules to Slack groups, where we keep the members in the group fully in-sync with whoever is on-call. This allows users across your organization to interface with people that are on-call natively in Slack (e.g. `@platform-on-call can you help here?`).
* Requesting cover, by using our `/inc cover` command within Slack, as well as having users respond to those cover requests, which are sent as DMs.
* Creating channels for incidents, if your alert route is configured to do this.
For **Response,** this also includes (but is not limited to):
* Creating public and private channels for incidents.
* Being able to post messages into those channels.
* Being able to DM users with notifications about role assignments, actions, follow-ups, and much more.
* Populating data from Slack and Microsoft Teams into Catalog types.
# Contact us
Source: https://docs.incident.io/help/contact
Unlike other companies who optimize for self-serve customer service (i.e. fix your own problems), we optimize for talking to as many of our users (you!) as possible.
## Slack or Microsoft Teams
Customers on our Pro or Enterprise plan get a dedicated Slack or Microsoft Teams channel with our support team. This is the fastest way to get help, just message us!
## In-app
If you're already a customer but you're not in one of our plans that provides a direct Slack/MS Teams channel with us, you can open your organization selector, where you'll find a "Contact support" button.
## Email
Our support team is available at [help@incident.io](mailto:help@incident.io).
# Actions
Source: https://docs.incident.io/incidents/actions
We believe there are two types of action you create during an incident – those that **need doing now**, and those that should be **followed-up** after an incident has been closed.
Actions that **need doing now** might be:
* Reboot that server
* Send some comms to an affected customer
While **follow-ups** could be:
* Improve test coverage of a given codepath
* Do some investment to make a service more stable
You can learn more about follow-ups [here](/post-incident/follow-ups).
## How do I create actions?
There's two ways you can do this:
1. **React** with the `:boom:` emoji to any Slack message within the incident channel
You can then either assign this action to yourself, or to someone else and they'll be notified.
2. Use the command **/inc action,** to create new actions and post any open actions within the channel
## What can I do with actions?
After you've assigned actions to either yourself or someone else, you can:
* Edit the action
* Mark it as completed
* Reassign it to yourself
* Unassign it from a team member
## What if I want to do these actions after an incident?
If you want to complete these actions after an incident, they will become [follow-ups](/post-incident/follow-ups) and can even be exported to issue trackers such as [Jira](/integrations/jira-follow-ups), [Linear](/integrations/linear), and many more.
When you go to mark the incident as resolved, any uncompleted actions will appear in the modal, and you'll be able to convert these to follow-ups.
You can also use the *:fast\_forward:* emoji on any Slack message to convert it to a follow-up too!
***
Any questions, we'd love to hear from you at [hello@incident.io](mailto:hello@incident.io)
# Announcing private incidents
Source: https://docs.incident.io/incidents/announcing-private-incidents
Announce private incidents to a controlled audience.
By default, [private incidents](/incidents/private-incidents) are never announced. Both announcement rules and workflows skip them, so sensitive details don't end up in a channel everyone can read.
But there are good reasons to announce a private incident to a **controlled** audience. A security team might keep a private `#security-incidents` channel where every private security incident is announced, so members can see what's happening and [self-join](/incidents/private-incidents#grant-access-to-a-team) the ones they need to, all without exposing the incident to the wider organization.
You can announce private incidents across three surfaces: [announcement rules](#announcement-rules), [workflows](#workflows), and using [`/inc announce`](#inc-announce).
Announcing a private incident posts it to whatever channel you choose. **Anyone in that channel can see the
announcement, including people who aren't part of the incident**. Choose a channel whose members should be allowed to
know about the incident. We recommend a private channel scoped to the team that has access.
## Permissions
Configuring an announcement rule or workflow to announce private incidents requires the **Manage announcement rules that run on private incidents** permission. People without it can still create and edit ordinary announcement rules and workflows. They just can't turn on private-incident announcements, or edit a rule or workflow that already has it enabled.
Announcing manually with `/inc announce` is available to anyone who's already a member of the incident. See [user roles and permissions](/admin/user-permissions).
## Announcement rules
[Announcement rules](/incidents/change-announcements) decide where incidents get announced. To control whether a rule announces private incidents, set its private-incident scope when you create or edit it in **Settings → [Announcements](https://app.incident.io/~/settings/announcements)**. You have three options:
* **No private incidents** (the default): the rule only announces public incidents.
* **Private incidents for owning teams**: the rule also announces any private incident that at least one of its [owning teams](/admin/restrict-announcement-management) can access.
* **All private incidents**: the rule announces every incident, public and private.
If an [incident type](/incidents/incident-types) is private by default, its incidents are only announced by rules
whose private-incident scope includes them (**Private incidents for owning teams** or **All private incidents**).
Otherwise they're announced only if they're later made public.
## Workflows
Use the **Post an incident announcement** [workflow step](/incidents/private-incident-workflows) to announce incidents as part of a workflow. By default the step skips private incidents; turn on **Announce private incidents** to include them.
This is useful when you want to announce based on conditions, or alongside other automated actions (like granting a team access at the same time). See [workflows on private incidents](/incidents/private-incident-workflows).
## `/inc announce`
To announce a private incident manually, run `/inc announce` in the incident channel and choose where to post it. This is handy for one-off announcements that aren't covered by a rule, like looping in a specific team's channel as an incident develops.
## Control how updates are shared
When you announce an incident, you also choose how its [status updates](/incidents/status-updates) are shared afterward. This matters even more for private incidents, where you may want the announcement to be discoverable without streaming every update into the channel.
| Option | What happens |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| **Don't share incident updates** | Only the initial announcement is posted. Updates stay in the incident channel. |
| **Share incident updates to thread only** | Updates are added as replies in the announcement's thread. |
| **Share incident updates to channel and thread** | Updates are posted to the channel and the thread, so they're visible without expanding the thread. |
You can set this on announcement rules and on the **Post an incident announcement** workflow step.
## Related
* [Private incidents](/incidents/private-incidents): make incidents private and manage access
* [Workflows on private incidents](/incidents/private-incident-workflows): announce and grant access via workflows
* [Announcement rules](/incidents/change-announcements): control where incidents get announced
* [Announcement posts](/admin/announcements): customize what an announcement contains
# How do I add attachments to incidents?
Source: https://docs.incident.io/incidents/attachments
Currently, you can attach PagerDuty Incidents, Opsgenie Alerts, GitHub Pull Requests, GitLab Merge Requests, Sentry tickets and Zendesk tickets to an incident.
Attachments allows you to connect something from another system into incident.io.
To attach something, you simply need to:
1. Make sure you're connected to the provider (e.g. GitHub) on the [integration settings](https://app.incident.io/~/settings/integrations) page
2. Paste a link into an incident channel, like below
3. Or, from the dashboard, use the **Links** action dropdown or the attachment drawer on the incident page
You can view attachments in Slack (via `/incident attachments`) and in the Web UI:
Once it's attached, we'll help you out wherever we can.
For example, if it's a GitHub PR, we'll comment on the PR (if it's in a private repo) with a connection back to the incident, so it's easy to find in the future:
Additionally, when a Pull Request gets closed or merged, we'll let you know in the channel:
To start using the feature, set up your integration and paste a link into an incident channel. We'll do the rest!
# Alerts and automatic incident creation
Source: https://docs.incident.io/incidents/auto-create
Yes! We support automatically creating incidents from many sources including Datadog, Sentry, Grafana, and more! To see if we support the source you want, try [creating an alert source](https://app.incident.io/~/alerts/sources/create) to see which options are available.
**Can't see the source you want?** You can use our HTTP source to connect with most tools that provide webhooks.
## Setting Up
## 1. Connect an alert source
1. Create an alert source to receive alerts
* Navigate to [Alerts > Create alert source](https://app.incident.io/~/alerts/sources/create)
* Select the source that you want to import
2. Connect your source to receive alerts
* Follow the steps provided for your chosen source to connect it and receive your first alert
* You'll see live alerts come in once you start receiving them, you can try sending a test alert from your source to check your configuration
3. Configure your alerts
When connecting your alert sources to [incident.io](http://incident.io/), you can add custom attributes to provide more context to your alerts. Examples include: team, affected customer, affected feature or environment. This allows you to pull values from your alert payload into rich data on your incidents.
These can provide helpful clues for responders when digging into the alert issue. Plus, it will be a helpful way of grouping and filtering your alerts into incidents via alert routes.
**Every alert source is rate limited** We apply a rate limit of **120 events/minute** for each alert source. This means that if you have two alert sources, we will process up to 240 events every minute. When the rate limit is exceeded, we will respond with an HTTP 429 `Too Many Requests`. Organization-level limits are also applied to ensure reasonable use.
***
## 2. Create an alert route
Now that you have an alert source that's receiving alerts, you need to connect it to an alert route to start creating incidents from your alerts.
1. Select alert sources
* Select any alert sources which should trigger incidents
* You can filter which specific alerts should create incidents later
2. Filter and group
* Filter out alerts which should not auto-create incidents for (i.e. low priority alerts)
* Group alerts, so when an alert fires, we find active incidents with similar alerts and give responders the ability to attach the alert to an incident or create a new incident from that alert (ie. grouping alerts by the team or service that owns the alert). [More on that later.](/incidents/auto-create)
3. Configure incidents
* Choose how you want the incidents created from your alerts to look
* You can select title and summary from the alert details you have available to you
* Add any custom fields which should be set based on details on your alert
***
## How does it work?
Once auto-creation is switched on, incidents will be automatically created in a **triage** state. We'll try our best to pull the right people into the incident channel.
When joining a triage incident, you'll be met with this:
**Accept it** This will accept this **triage** incident as a real incident.
* You will be asked if you'd like to rename the incident, and you'll be able to set any custom fields you have configured
* All your workflows will kick off once the incident is accepted, and you can get to work
* The incident which triggered this will become an **attachment** of your incident.
**Merge it into another** Was this alert caused by an incident with an existing channel that you already know about? If so, you can **merge** the other incident to any open incident channel. The incident that was created in triage will be **declined**, and the channel will be archived after a short delay.
**Decline it** Selecting this will **decline** the incident, and archive the channel. Declined incidents are excluded from any metrics or workflows that you have set up. It's like they never existed at all.
***
## Grouping
Sometimes multiple incidents or alerts in a short space of time are caused by the same underlying problem. To avoid creating unnecessary noise, we recommend configuring a **grouping window**. This allows us to check in with you before we spin up new incidents automatically. We'll continue to use HTTP source for our example, but the same applies to other alerts and the like:
1. An incident is auto-created from a HTTP incident
2. A second HTTP incident is triggered **within the grouping window,** with a matching service
3. The next step depends on the **grouping behavior** you've configured. For this example, we'll use **suggested** as this is our recommended setting. See [below](/incidents/auto-create) for more details on **automatic grouping.**
4. Instead of creating a new incident, we will post the below message in **all** open incidents with matching HTTP services created **within the grouping window.**
**Merge it into another** This will **attach** this HTTP incident to the existing incident.
* Any other grouping suggestion messages will be deleted from other channels, it's unlikely it's linked to multiple incidents
**Decline** This will reject the HTTP incident from this channel, and remove all references to it. If the incident is declined in the channel from **all incident channels**, we'll archive the channel in 5 minutes.
## Automatic grouping
Automatic grouping automatically attaches related grouped alerts into the same active incident without asking for manual confirmation via the incident channel or dashboard.
The alert can be unlinked from the incident via the dashboard.
## FAQs
Deduplication keys are one way to indicate that some events are the same alert: If your alert events have the same deduplication key, we won't create new alerts in [incident.io](http://incident.io/) for them - if it's different we create a new alert.
If an alert is marked as unrelated to an incident, it will trigger a new incident based on the alert route. The creation time for the new incident is set to the time the alert is marked as unrelated.
Grouping logic can be defined for an alert route for alerts to be grouped into an incident. If one then marks it as unrelated, we assume it might need its own incident. This triggers it to be raised in Triage, following the Alert Route rules (check the Triage mode setting at the bottom to determine if incidents should be created or not).
In **some cases** to prevent this, one might want to enable the option underneath the Triage condition in the Alert Route to be enabled:
# Can we change where incidents get announced?
Source: https://docs.incident.io/incidents/change-announcements
Absolutely.
By default, we'll announce new incidents and their updates in a single channel:
* **Slack**: your `#incidents` channel.
* **Microsoft Teams**: the General channel of your Incidents team.
But you can redirect all announcements to a different channel (e.g. `#engineers`), or add conditional rules to call out specific incidents in a separate channel (e.g. announcing critical incidents in `#customer-support` too).
You do this with **announcement rules**, configured in [Settings → Announcements](https://app.incident.io/~/settings/announcements). Rules work the same way on both Slack and Microsoft Teams. See [Announcements](/admin/announcements) for the full guide to setting up templates and rules.
Don't delete whichever channel you're using for default announcements. On Slack, if you already had an `#incidents`
channel when you installed our app, we'll have created a channel called `#incident-io-incidents` instead, which you
can rename to whatever you'd like.
# How do I change a custom field from fixed list to user-defined options?
Source: https://docs.incident.io/incidents/change-field-type
## Context
When creating a multi-select custom field, you have the option to either use a fixed list of options or allow users to add their own options. Once a custom field has been created with a fixed list, the UI prevents direct modification to change it to user-defined options.
## Answer
While you cannot directly modify an existing fixed-list custom field to allow user-defined options, you can create a new custom field and migrate the existing data. Here's how to transfer your data:
1. Create a new custom field with user-defined options enabled
2. Go to the incidents tab
3. Filter for incidents that contain a specific value in the old custom field
4. Use the bulk update feature to set the new custom field value
5. Repeat this process for each distinct value in your old custom field
Note: If you encounter generic errors during bulk updates, this may be due to rate-limiting. To work around this, try reducing the size of your bulk update batch.
# Incidents without channels
Source: https://docs.incident.io/incidents/channelless-incidents
By default, we create a channel in Slack or Microsoft Teams for every incident as a dedicated space to collaborate and coordinate response.
We understand that for some low severity incidents, creating a channel might not be necessary - so we've introduced the flexibility to configure whether to create channels per [Incident Type.](/incidents/incident-types)
If you realise part way through the incident that it does need a channel after all, no worries! You can manually create a channel directly from the dashboard or incident announcement.
## Setting Up
To configure this feature, navigate to Settings > [Incident Types](https://app.incident.io/~/settings/incident-types).
For your chosen Incident Type, toggle on 'Skip channel creation' and optionally set extra conditions, for example only skipping channel creation for Minor incidents.
To skip channel creation for all incidents regardless of type, use the global setting in **Settings → Slack channel** or **Settings → Teams channel**.
## Manually creating channels
If you decide your incident does warrant a channel after all, you can trigger channel creation from the dashboard, or the incident announcement post.
# Can we create conditional Custom Fields?
Source: https://docs.incident.io/incidents/conditional-fields
Want to create a [custom field](/incidents/custom-fields) that only reveals itself based on a set of conditions (e.g. a specific severity field only for cyber incidents)?
Absolutely! Using [configurable forms](/admin/incident-forms), you can choose to hide or show a field depending on another field's value. Further details can be found [here](/admin/incident-forms#h_b87cf099f8).
# Using incident.io and Slack to convert public channels to private ones
Source: https://docs.incident.io/incidents/convert-channels
When you discover that an incident should be private, you want to get it locked down, quick. In some organizations, not many people have the permissions to convert a channel to private, so finding the person with the right permissions can waste valuable time while trying to contain information.
Unfortunately, Slack only allows us to access these permissions if your workspace is inside an **Enterprise Grid**. If you aren't part of a Grid, this flow won't work for you.
## Using Privileged Slack Access
To make the flow work, you'll need to connect our app via `Privileged access` to your Grid workspace. You can find this in [Security → Settings](https://app.incident.io/~/settings/security).
We recommend using a dedicated Service Account when connecting to Slack via this flow: you can find out more [here](/getting-started/slack-admin-setup).
The account that you connect with **also** needs to have access to 'manage public channels for the whole organization'. That means they need to be either an Org Owner or an Org Admin (note that this permission is controlled for the whole grid, not just a single workspace).
This can be configured at the Enterprise Grid level, in Settings → Channel Management:
Once you've taken those two steps, you can then make a channel private from Slack by doing `/inc private` in an incident channel. We'll make the channel private on your behalf, as well as making the incident private.
# Can we create incidents or actions from an existing Slack message?
Source: https://docs.incident.io/incidents/create-from-slack
Yes!
***
## Creating incidents from a Slack message
You might have some messages that come through in e.g. :
* your *#customer-support* or *#legal* channels;
* a Slack Connect channel with your customers; or
* a direct message from a colleague or client
that should actually be the basis of declaring an incident.
To turn a message into an incident, simply **click on the 3 dots in the top-right corner of the message** and select '*Create an incident*'.
*Note: If this option does not show, you might need to click on 'More message shortcuts' (Slack orders your shortcuts based on usage, so incident shortcuts will become visible only if they're in your most-used).*
***
## Creating actions from a Slack message
In the heat of the incident, responders will usually quick-fire Slack messages you might want to turn into to-dos.
From the incident's channel ( *#inc-...* ), all you need to do is **react with the :boom: emoji** to that message, and it'll automatically create an action out of the message.
Alternatively, you can use the same 3 dots shown in the previous section: just select ' *Create an action* ' instead of ' *Create an incident'* !
Remember you can also export those actions to your favorite issue tracker (Jira, GitHub, Linear etc.).
# Can we create incidents from a Linear ticket?
Source: https://docs.incident.io/incidents/create-from-tickets
Yes and no (famous last words)
We currently do not have the ability to create incidents off the back of Linear tickets (if this is something that you want, [get in touch](http://incident.io/community) !). For example, if you log a bug into a Linear board and wish to escalate that ticket into an incident, there is no way to do this from incident.io.
However, where there is a will there is a way, right?
As a temporary hack, you could **funnel your Linear tickets into a dedicated Slack channel, and 'Create an incident' from there**, like so👇🏼
# Customizing your incident creation form using Custom Fields
Source: https://docs.incident.io/incidents/custom-fields
You've [declared your first incident](/incidents/declaring) with our default settings and now you're wondering if you can **edit the incident declaration form to categorize incidents and track additional dimensions** such as which teams were involved, what systems were affected, or how many customers were impacted.
You've come to the right place, and yes you can!
***
## Using Custom Fields
Maybe you have different teams that look after different products, customer journeys or different systems? All these can be turned into custom fields, and there are a few reasons incident.io customers use custom fields.
## Enriching their retros & reporting
You might be looking to enrich your understanding of your incidents and narrow down on systemic issues. Or you might just need additional information for compliance or internal reporting purposes.
Either way, custom fields can help you answer questions like:
* *'Which system is most incident-prone?'*
* *'Which customers suffer the most incidents?'*
* *'Which team reacts to incidents the fastest?'*
* *'Which product is most vulnerable?'*
* ' *How many incidents involved personal data?* '
* ...
You can capture and visualize all this directly from the [incident.io Insights](https://app.incident.io/~/insights), by applying filters off the back of custom fields in the [Incidents tab](https://app.incident.io/~/incidents), and when you export a CSV of your incidents.
## Triggering specific automation
A very popular use case for custom fields is to use them as triggers in [Workflows](https://app.incident.io/~/workflows).
For example:
* [Escalate to specific teams/teammates](/incidents/escalating) based on the severity of an incident, or the product it affects
* Send an email to only the 3rd parties affected by an incident
* Message the `#customer-support` channel [when high-value customers are affected by an incident](/incidents/customer-updates)
* Send a Slack message to a specific Account Executive [when their customer is affected by an incident](/incidents/customer-updates)
***
## Setting Up Custom Fields
*Only* [Admins and Owners](/admin/user-permissions) *can edit custom fields.*
1. **Head to Settings >** [Custom Fields](https://app.incident.io/~/settings/custom-fields)
2. **Add and tweak your custom field**
Clicking on `Add New Custom Field` will pop up a creation modal from which you can control:
1. What information to collect
2. How custom field options are managed (From catalog, fixed list, dynamic list)
3. Where the custom field will be available
`Field Types`
The field types we support are:
* Single-select
* Multi-select
* Text
* Link
* Number
If there are any more you'd like us to add, please let us know!
`Name`
The title will appear on the incident declaration form. The shorter and more explicit, the better!
`Description`
This will appear as a tooltip for your team in the modal, like so 👇🏼
3. Conditionally require or show this custom field - This can be found within [Incident Forms](https://app.incident.io/~/settings/forms), more information in this [article](/admin/incident-forms). Here you can set conditions to conditionally render the fields in Forms such as create, accept, update, or resolve forms.
## FAQs
Check out this article on [Automatically setting custom fields](/catalog/auto-custom-fields).
# Creating custom incident roles
Source: https://docs.incident.io/incidents/custom-roles
Incident Lead not enough? Want to add and create your own roles, like Incident Manager, or Communications Lead?
You can!
***
1. **Go to Settings >** [Incident Roles](https://app.incident.io/~/settings/incident-roles)
2. **Click** `Add Role`
This will pop up the Role creation modal
`Name`
What role are you creating? For example, ' *Communications Lead* '.
`Slack reference`
Set the Slack command that will assign this role. For example, `/inc role lead @dinesh` sets \[Dinesh] as the \[Lead]. The Communication Lead's could be `comms`, such that `/inc role comms @Erlich` assigns Erlich to the Communication Lead role.
`Description`
This is the sub-text that will appear to guide your team in the Roles modal.
`Instructions`
This is the instructions we'll send to the person that has been assigned to the role, letting them know what they should do.
`Require this role to be assigned before an incident is resolved`
When ticked , we won't allow an incident to be marked as resolved without someone having been assigned this role. This is key for debriefs and reporting/compliance.
*The Incident Lead is compulsory by default in incident.io, and thus always required.*
# Keeping your customers in the loop
Source: https://docs.incident.io/incidents/customer-updates
Good incident management is about good communications. Sharing updates regularly to keep your customers. incident.io gives you two main ways to keep customers informed during incidents.
## Status pages
[Status pages](/status-pages/overview) let your customers see what's going on and subscribe to updates. You can create public pages for all customers, customer-specific pages for key accounts, or use workflows to [automatically publish incidents](/status-pages/auto-publishing) or prompt your team to update the page when conditions are met.
If you're already using Atlassian Statuspage, you can [connect it to incident.io](/integrations/statuspage) and update it directly from your incident channel with `/incident statuspage`.
For full details, see the [status pages documentation](/status-pages/overview).
***
## Targeted updates via incident.io workflows
For more control over who gets notified and when, [workflows](/workflows/getting-started) let you send targeted customer communications based on conditions. For example:
* Send a customized message (email, SMS, Slack message etc.) to a specific customer when an incident affecting them is declared, updated or closed
* Send an email to all your customers when an incident's severity crosses a certain threshold
* Send an incident update to a Slack Connect channel with your customer
* ...
Building a Workflow is very simple! Let's use the first case above as an example
1. **Pick the communication trigger**
Do you want the customer communication (email, Slack message etc.) to be sent when:
* An incident is created, or its details (severity, status etc.) are updated; or
* When a teammate shares a status update message?
*Note: you can of course use the other 2 triggers, though those tend to be for more internal uses.*
In this example, we'll pick ' *When an incident is created or changed* ', as we want to inform our customer when someone creates an incident affecting them.
2. **Select some conditions that need to be met for the comms to go out**
For example, you might want customers to only be informed of Critical incidents. Or you might have a [custom field](/incidents/custom-fields) that tracks affected customers, systems or customer journeys - so you can pick a condition that fires comms only when specific values of those fields are met.
For our example, we'll use our custom field ' *Customer* ' to alert our customer Globex Corporation that an incident affected them has arisen. We'll also add an extra condition to only update them if the incident is Major or Critical, so we don't make them hit the panic button for small issues.
3. **Add your communication channel and personalise your message**
You can now add the communication channel (or channels - you can add multiple Steps!) you'd like to use for your customer communication, and use our editor to customize your message with the right information.
For this example, we'll choose to send an email to our example client. We'll use handy variables to automatically fill out the right Affected Component and Incident Lead values
4. **Hit** `Create` **and you're all set**
Check out the end result for our example!
If you need any help setting those up or are looking for triggers, conditions or steps you can't see, [get in touch](http://incident.io/community) !
# Decision Flows
Source: https://docs.incident.io/incidents/decision-flows
It isn't always clear what should be done during an incident. That's why we created Decision Flows, a set of steps that helps you make a decision in an incident.
You might use Decision Flows to help choose whether to update your public status page, or whether something needs to be reported to a regulator.
***
1. You can find [Decisions Flows](https://app.incident.io/~/settings/decision-flows) under settings on your incident.io page.
2. Click "+ New Decision Flow"
You'll have the option of choosing a blank decision flow or working from our Data Breach (GDPR) template. For this example, we will choose to work from the template.
3. Name the decision flow, and add a description.
We recommend taking the time to go into some detail for the description to provide context around when and how to use this workflow. You have the option of applying this workflow for All Incidents or Test incidents only.
4. You can now build your decision flow. By filling out the following for each branch of the tree:
* **Node**, this is displayed in the UI to help the decision maker navigate the process (Keep it short and sweet!)
* **Prompt**, This will be shown to the user when they are going through the decision flow. You can use Slack [mrkdwn](https://api.slack.com/reference/surfaces/formatting#basics) in this field.
* **Options**, these are the options the decision maker can choose from.
5. When you have completed creating your decision flow, simply click Save Changes.
6. Create a Workflow to trigger your Decision Flow.
Navigate to [Workflows](https://app.incident.io/~/workflows) and click "+ New Workflow". For this Workflow, we are going to select the trigger 'When an incident is created or changed'.
7. You can now name your Workflow and add a condition that makes sense for the Decision Flow you created. For this example, we will choose Incident Severity 'is one of' Critical. Other helpful conditions might be Incident Type or an Impacted Team custom field.
8. You can now choose Prompt a Decision Flow as the Step. We have now created a workflow that will show our Decision Flow for all Critical incidents.
9. You will now provide a Prompt (to provide additional context) and can choose which Decision Flow you'd like triggered. We have now created a workflow that will show our Decision Flow for all Critical incidents.
***
Decision Flows can be a great way to guide someone during an incident. If you have any additional questions about Decision Flows or Workflows, feel free to reach out to us on Slack!
# Declaring incidents
Source: https://docs.incident.io/incidents/declaring
Declaring an incident takes seconds, and you can do it right from where your team already works, whether that's Slack or Microsoft Teams.
You can declare three types of incident: a **live** incident for something happening right now, a [**retrospective**](/incidents/retrospective-incidents) incident to document something that already happened, and a [**test**](/incidents/test-incidents) incident to practice without affecting production.
Whichever type you declare, the form is fully customizable, so your team captures exactly the context it needs. See [incident forms](/admin/incident-forms) to tailor which fields appear.
#### Declare with /incident or /inc
From any channel in Slack, type `/incident` or `/inc` and press `Enter` to open the incident declaration form. To pre-fill the title, add it after the command (e.g. `/inc Website is down`).
#### Declare from an existing message
Sometimes the first sign of an incident is a message that's already been posted, such as a report in your `#customer-support` or `#legal` channel, a heads-up in a Slack Connect channel with a customer, or a direct message from a colleague. You can declare an incident straight from that message so the context comes with it.
Click the three dots in the top-right corner of the message, choose **Connect to apps**, then **Create an incident**.
If you don't see it, choose **More message shortcuts** from the same menu.
#### Declare from your browser
Head to [inc.new](https://inc.new) to create a new incident. Fill out the details and hit **Declare**, just as if you'd used the slash command. You can switch between live, retrospective, and test incidents from the tabs at the top of the form.
#### What happens next
As soon as you declare, we automatically set up your incident response workspace:
* A dedicated Slack channel that brings responders, updates, and actions together in one place.
* A [video call](/incidents/video-calls) for a digital war room, using Google Meet, Zoom, or another provider.
* A linked ticket in your issue tracker, like [Jira](/integrations/jira) or [Linear](/integrations/linear), keeping the work visible where your engineers already are.
* A heads-up in your announcements channel, `#incidents` by default.
From there, [workflows](/workflows/getting-started) automate the rest of your process, like assigning roles, posting status updates, and more.
#### Declare from the incident.io tab
To declare an incident, open the incident.io tab, fill out the form, and hit **Declare**. You'll usually find this tab in the **General** channel of your **Incidents** team, which we [create automatically](/getting-started/installing-teams) at install. It's also available in any other channel the app has been added to.
#### Declare from your browser
Head to [inc.new](https://inc.new) to create a new incident. Fill out the details and hit **Declare**, just as if you'd used the incident.io tab. You can switch between live, retrospective, and test incidents from the tabs at the top of the form.
It's also a great way to let people across your organization declare an incident without needing access to the Incidents team.
#### What happens next
As soon as you declare, we automatically set up your incident response workspace:
* A dedicated Teams channel that brings responders, updates, and actions together in one place.
* A [video call](/incidents/video-calls) for a digital war room, using Microsoft Teams, Zoom, or another provider.
* A linked ticket in your issue tracker, like [ServiceNow](/integrations/servicenow), keeping the work visible where your engineers already are.
* A heads-up in your announcements channel, the **General** channel of your Incidents team by default.
From there, [workflows](/workflows/getting-started) automate the rest of your process, like assigning roles, posting status updates, and more.
## FAQs
By default, anyone can declare an incident. Admins can [restrict who can declare a particular incident
type](/admin/role-restrictions), for example limiting a security incident to your security team.
You can configure which fields are required and which are optional, so an incident can be declared with just a few
details. Anything filled in is easy to change later during the incident.
Yes, if private incidents are enabled for your workspace. The declaration form will include an option to make the
incident private, visible only to invited responders.
# Can I delete or hide an incident?
Source: https://docs.incident.io/incidents/delete-incidents
We feel very strongly about keeping your data safe, and preserving its integrity. As such, **we don't currently support deleting incidents**.
However, we also know it's easy to press the wrong button and pollute your data!
So, if you want to 'hide' an incident, you can **simply cancel it** from the incident's page! 👇🏼
You can also use `/incident cancel` within an incident's slack channel
Cancelled incidents won't appear in your [Insights](https://app.incident.io/~/insights), and you can **filter them out in the dashboard too**.
# How does the duplicate incident prevention feature work?
Source: https://docs.incident.io/incidents/duplicate-prevention
The incident creation modal includes a feature that displays recent incidents to help prevent duplicate incident reports. This feature automatically shows relevant recent incidents when you use the `/inc` command under specific conditions.
## How it works
The duplicate prevention feature will display recent incidents in the incident creation modal when all of the following conditions are met:
* Recent incidents were created within the last 10 minutes
* The previous incidents are in **Triage** or **Active** state
* You use the `/inc` command without any additional text following it
When these conditions are satisfied, you'll see a list of recent incidents that might be related to the new incident you're about to create, helping you determine if a similar incident already exists, sample screenshot below:
## Important notes
The 10-minute time window is a product-wide setting and cannot be customized on a per-workspace basis. This timeframe is designed to catch incidents that are likely related while avoiding showing outdated incidents that may no longer be relevant.
If you have use cases that require a longer time window for duplicate detection, you can contact support to submit a feature request with details about your specific needs.
# Can we edit the timeline?
Source: https://docs.incident.io/incidents/edit-timeline
Yes! Our timeline is completely customizable. We generate a simple timeline based on key events, but you can always add your own narrative or events that happened in an external system.
→ Check out [this article](/post-incident/timeline) for a full walk through of how to do this.
# Escalating incidents
Source: https://docs.incident.io/incidents/escalating
Sometimes, you just need to pull in someone else to help resolve an incident, or when you realise the blast radius is a little larger than anticipated...
There are 2 ways you can escalate in incident.io:
* **Hard escalation** : if you're managing an on-call rota, we can help you page someone directly from within Slack or via automations
* **Soft escalation** : you can send an email, SMS, Slack Direct Message or Slack ephemeral message to the right person
***
## Hard escalations
incident.io's [On-call](https://incident.io/on-call) solution is your best friend here and allows you to configure schedules and escalation paths which can then be used to page someone to help resolve an incident.
It's then as simple as typing `/incident escalate` or `/incident page` within an incident channel to manually escalate to the right individual or team that you need. You can also escalate from the web dashboard — and if an escalation is already in progress, click **Escalate to next level** to advance to the next tier in the escalation path with a preview of who will be paged.
For more information on getting started with On-call including how to automate these escalations, please take a look at [this article](/on-call/getting-started).
If you already use a tool like [OpsGenie](/integrations/opsgenie), [PagerDuty](/integrations/pagerduty) or [Splunk](/integrations/splunk) as your on-call solution, you can also install an integration for either which would then let you do exactly the same thing.
Where we can, **we'll show whatever is configured in OpsGenie and PagerDuty**, so if you've set different escalation policies for different services, we'll show you those by default.
Once you've escalated, we **keep you updated on what we've done**, and when you can expect someone to join.
If you're using PagerDuty, and want to hide some Services and/or Escalation Policies from the available options, you can do that by adding the tag `incident-io-ignore`. This might be useful if you have certain services or escalation policies that you only use for testing. You can read more about tagging in PagerDuty's documentation [here](https://support.pagerduty.com/docs/contextual-search).
***
## Soft escalations via email/SMS/DMs
Sometimes, an escalation can be as simple as sending someone a text message or a direct Slack message.
You can do that with incident.io's [Workflows](https://app.incident.io/~/workflows) directly: the `Trigger` might be e.g. the severity of the incident (Critical incidents get escalated), and the `Steps` might be an SMS to the CTO, an email to the Director of Platform...or all at the same time!
# Importing existing incident channels to incident.io
Source: https://docs.incident.io/incidents/import-channels
You may start using [incident.io](https://incident.io/) after having already run incidents within Slack in the past. If so, you'll want to bring all the data with you when starting to use our product to make sure your team has the relevant information to hand, and to track trends in your incidents using our Insights.
## How to import
You'll be using our API following the same steps outlined in the [Creating your first incident using the API](/integrations/api-create-incident) help article
When making the API call to create the incident, make sure to:
* Set `mode` within the request payload to `"retrospective"`
* Set `retrospective_incident_options.slack_channel_id` within the request payload to the Slack channel ID
* Include the `idempotency_key` and `visibility` fields, which are required when creating any incident
For example, the payload might look like:
```json theme={null}
{
"idempotency_key": "import-C01DZSENFFT",
"visibility": "public",
"mode": "retrospective",
"retrospective_incident_options": {
"slack_channel_id": "C01DZSENFFT"
},
"severity_id": "01G0J1EXE7AXZ2C93K61WBPYEH"
}
```
After the incident has been created, the main events that occurred in the Slack channel will be used to generate the [incident timeline](/post-incident/timeline), and your insights will be updated within an hour.
## FAQs
Bots can't view the contents of archived channels, so you'll need to enable [privileged Slack access](/getting-started/slack-privileged-access), which lets us temporarily unarchive the channel and read its contents. We'll re-archive it once the import is complete.
No. incident.io creates a dedicated channel for each incident — there's no way to convert an existing channel into one. To capture what happened in an existing channel, use the API import described above. To start a new incident from a specific message, use the [three-dot menu shortcut](/incidents/create-from-slack).
# How does the 'Rate this incident' feedback feature work?
Source: https://docs.incident.io/incidents/incident-feedback
## Context
The "Rate this incident" feature allows users to provide feedback after an incident is closed via a button that appears in the final Slack message. Understanding where this feedback data is stored and how it can be accessed is important for teams wanting to track incident feedback.
## Answer
The "Rate this incident" feature currently has the following functionality:
* A feedback button appears in Slack after an incident is closed
* Team members can provide feedback through a modal in Slack
* The feedback responses are included in exported post-mortems (to platforms like Google Docs, Notion, or Confluence), but only if the Feedback section is enabled in your post-mortem template.
Important limitations to note:
* The feedback data is not currently visible within the incident.io application interface
* The Slack modal cannot be customized
* There is no way to configure when the feedback button appears (it shows by default)
* If you use incident.io as your post-mortem location rather than exporting, the feedback will not be visible
To view incident feedback, make sure you have enabled the Feedback section in your post-mortem template before exporting to external platforms.
# How to use images in incidents
Source: https://docs.incident.io/incidents/incident-images
We know that it's often useful to be able to use images to help illustrate what has caused, or is contributing to an incident.
You can easily add images to incidents, by adding an 'Images' field on your Declare, Update or Resolve forms in [Settings -> Forms](https://app.incident.io/~/settings/forms). Once your forms have an images field, you can post images through a Slack form, the app dashboard, or the Microsoft Teams incident tab.
Once images have been added, we will then:
* Post them as a reply to the incident declaration or update
* Show them on the incident timeline
* Make them available in the post-mortem editor (use /images).
You can add 8 images at once, and each image must be below 5MB. We support jpg and png.
We also consume any images that are posted to the incident channel, and they are also available on the incident timeline and for use in post-mortems.
We don't support pasting images into incident summaries through the dashboard.
# Incident Modes
Source: https://docs.incident.io/incidents/incident-modes
incident.io offers four incident modes to help your team effectively manage and respond to various situations. These are different to [Incident types](/incidents/incident-types), which can be used to tailor your response process to the situation you're responding to e.g. you could create a security incident type with a completely different incident lifecycle & form to your standard default incidents.
Below, we'll explore the details of each incident mode:
## Tutorial Incident
The Tutorial Incident mode is a quick 5-minute guide to cover the basics of using incident.io and is an excellent way for users to familiarize themselves with the platform and its features. To initiate a Tutorial Incident, simply type `/inc tutorial` in any of your Slack channels.
Learning is free at incident.io. Everyone in your company can - and should! - learn the ropes of incident.io without you getting penalized by it and billed.
So, don't worry: your teammates [won't be considered Responders](/admin/seat-types) (paid users) if they go through our tutorial flow
## Test Incident
The [Test Incident mode](/incidents/sandbox-incidents) is designed for testing new automations and conducting dry runs with your configuration without affecting production systems or unnecessarily bothering your colleagues. To create a Test Incident, type `/incident test` from any Slack channel or use the declare incident button in our dashboard and switch to the Test incident tab.
While Test Incidents share similarities with normal incidents, they are distinguished by the fact that they won't be announced in the `#incidents` channel, won't be included in your incident library, and won't be calculated as part of Insights.
## Real Incident
The Real Incident mode is used for live incidents when something has gone wrong, and immediate response is required. There are three ways to manually declare a Real Incident:
**Slack Command** : Type `/incident` or `/inc` from any Slack channel.
**Slack Message** : Turn a Slack message into an incident by clicking the three built-in dots and selecting 'create an incident.'
**Dashboard** : Create an incident directly from the incident.io dashboard.
## Retrospective Incident
[Retrospective Incidents](/incidents/retrospective-incidents) are used to record incidents after they have occurred. You can declare them from Slack using `/inc retro`, from [the dashboard](https://app.incident.io/~/declare), or [via the API](https://docs.incident.io/api-reference/incidents-v2/create).
There's a dedicated Retrospective form that you can customize in **Settings > Forms** — this is separate from the Resolve form.
## FAQs
To keep things tidy, we only show your real incidents by default within the incidents section of the dashboard. To view a list of incidents in any other mode, you can simply filter by incident mode wherever appropriate:
You can create an incident in any of these modes [via the API](https://docs.incident.io/api-reference/incidents-v2/create) by passing the `mode` parameter.
# Knowing who's in charge
Source: https://docs.incident.io/incidents/incident-roles
One of the most important aspects of good incident management is knowing who the key people in the room are, so you can turn to the right person for leadership and help.
With incident.io's [Roles](https://app.incident.io/~/settings/incident-roles), you can easily make clear:
* What the responsibilities of a given role are
* Who is currently playing that role
***
## Managing roles during an incident
The easiest way to view and assign roles is to type `/inc roles` in an incident's channel.
This brings up a modal showing all available roles and who's currently assigned to each one.
Want to do this more quickly? Type `/inc role [role name] [@user]` to assign directly — for example, `/inc role lead
@bea` sets Bea as the Lead.
When a role is assigned, we'll post an update into the incident channel to make it clear.
We'll also update the incident's announcement post to reflect the new roles.
***
## Sending Instructions
Incidents are stressful. We want to make it easy for people that are playing a role to know what they have to do in that role.
When someone is assigned to a role, we'll **privately send instructions to the person that has been assigned to the role, letting them know what they should do**.
You can [customize those instructions](https://app.incident.io/~/settings/incident-roles) when you `Edit` each role.
*We'd recommend adding a short description which makes the primary responsibilities clear, and links to external documentation where people can read more.*
***
## Creating new roles
If you want to [create your own roles](/incidents/custom-roles), you absolutely can! The only default role in incident.io is the Incident Lead.
# Incident Types
Source: https://docs.incident.io/incidents/incident-types
Tailor your response process to the situation you're responding to with custom configurations using **incident types**.
Incident types are only available on our Pro or Enterprise plan.
## Setting Up
To switch this feature on, navigate to Settings > [Incident Types](https://app.incident.io/~/settings/incident-types)
After enabling, you'll be directed to edit an existing incident type: this is the **default** incident type that all your existing incidents are associated with.
As the default incident type, this will be **pre-selected** on incident creation. It's a good idea to make this your most common type of incident, or once you create a more frequent type, change that to be the default.
The name of your incident type is what people will select from a dropdown when declaring an incident from Slack or the web dashboard. We recommend making this short, for example "Production Outage" or "Data Breach".
The description will be displayed whenever the incident type is selected, helping provide context about this incident type so the reporter knows they've selected the right type.
An example description for a "Data Breach" might be:
*Customer data has been exposed, or is at risk of being exposed.*
It's easy to go back and edit this type later, so don't worry about setting everything up immediately.
***
## Using Incident Types
Now you've created some incident types, reporters will be asked to pick an incident type whenever declaring an incident.
That means we'll ask for a type in:
* Slack app, after running `/inc`
* Web dashboard, when clicking "Declare incident"
It is important to realise that having now enabled incident types, selecting a type is **mandatory** whenever creating new incidents.
You can however change the incident type later on, if you find that another type is more appropriate.
Here's an example of the Slack app when declaring an incident:
For **triage** incidents that are auto-created, such as those we create from PagerDuty integrations, we won't select a type right away.
Once you accept a triage incident, you'll be asked to select the type and fill in any associated custom fields.
***
## Custom Fields
Custom fields can apply to a specific subset of incident types, which you can configure either by:
1. Selecting existing custom fields in the **incident type** create/edit flow:
2. Adding a **condition** on incident type to the **custom field** in the create/edit flow:
Both flows achieve the same thing, which is adding conditions to the custom field to select the appropriate incident types. You don't need to worry about keeping these two in-sync, as it's all custom field conditions under-the-hood.
Any properties of the custom field (whether it's required, the field type, the description) will be consistent across all incident types.
***
## Roles
Roles can also be configured to only apply to certain incident types.
Roles are configured in the same two ways as custom fields, via the incident types flow, or through conditions on the roles edit route.
You can also [restrict who can be assigned to each role](/admin/role-restrictions) based on user attributes like team membership or job title.
***
## Severities
Incident types allow you to customize how incident severities appear, if you need a severity (eg. Major) to have different descriptions depending on the type.
Before we explain how to change the description, it's important to understand that even with customized severity descriptions, **severities are shared across incident types and their order will remain consistent.**
This ensures you can compare the severities of different incident types, and the fact that severity names remain the same helps your organization leverage a consistent terminology.
So, how do you customize severities? You'll do this in the incident type create/edit flow:
**Override Descriptions**
In the above screenshot, we have **overridden the Critical severity description** so that when our incident type is selected, we'll show:
*Outages affecting major flows of our application, requiring immediate response.*
This replaces the default description for that severity, which helps people select the severity that is appropriate given the incident type.
**Hiding Severities**
Perhaps some incident types should never be a particular severity: is a Product Outage where the whole site is down ever Minor, for example?
In the example screenshot, we've hidden the Minor severity by clicking the toggle visibility button to the right of the severity panel. It will no longer be visible as an option when creating or updating incidents.
It is worth noting that at least one severity level needs to remain per incident.
**Restricting who can set a severity**
You can restrict which users are allowed to select a particular severity for a given incident type. For example, you might want only members of your Security team to be able to declare a Critical incident during a Security Breach.
To configure this, click the edit button on any severity within the incident type, then use the **Who can set this severity?** section to build your restriction. You can restrict based on user attributes such as team membership, or any custom catalog type connected to users.
Once configured, users who don't meet the restriction won't be able to declare an incident of that type with that severity, or change an existing incident of that type to it.
***
## Team ownership and permissions
By default, managing incident types requires the account-level **Manage incident types** permission, which is usually held by admins. As you grow, you might want to restrict the number of people with that global permission, instead allowing individual teams to configure their own incident types.
To do this, give a type an **owning team**. In the incident type create/edit flow, use the **Incident type owner** field to choose which team (or teams) own it.
Once a type has an owning team, only the following can edit, create, or delete it (or override its [forms](/admin/incident-forms)):
* Anyone with the **Manage incident types** permission granted globally, such as an admin
* Members of an owning team who have the permission granted to that [team](/admin/team-roles)
Reassigning ownership always requires the permission granted globally. A team can manage a type they own, but can't hand it to another team or remove their own team from it.
Each team's incident types also appear under the **Types** tab of their settings page, so a team can see what they own and jump straight to the configuration.
For how to lock down management to owning teams, see [Restrict incident type management to a team](/admin/restrict-incident-type-management).
***
## Workflows
Workflows can be configured to run only on incidents that match a specific type, just as you can configure other workflow conditions.
To use this, visit [Workflows](https://app.incident.io/~/workflows) and edit the workflow you want to make conditional on the incident type.
Once in the edit page, click "Add condition" to open the condition modal, and create a condition on incident type:
You can also filter workflows by the incident types they apply to, from the Workflows page. This helps you see which automations are configured for your incident types, and can be useful when managing workflows across multiple teams, if each team has their own incident type.
# Inviting teammates to incidents
Source: https://docs.incident.io/incidents/inviting-teammates
***
## Inviting new members to incident.io
Pulling your team into incident.io is very simple:
* **Slack -** add them to the `#incidents` channel
* **Web App -** invite them through the [Users list](http://app.incident.io/~/settings/users)
They will receive a private message from us to get them started 👇🏼
*If you want to give new members specific* [roles and permissions](/admin/user-permissions) *, you can do so in the* [Settings > Users](http://app.incident.io/~/settings/users) *section.*
***
## Inviting teammates to a specific incident
Once you've declared an incident, we'll create a dedicated #inc-... channel for it. From there, you can invite your team of responders by simply adding them to that incident's Slack channel.
They'll receive a message to help them get going and follow our tutorial
If you run into any issue, [get in touch](http://incident.io/community)
# Incident Lifecycle
Source: https://docs.incident.io/incidents/lifecycle
Your incidents go through a lifecycle, for example:
Declared → Investigating → Fixing → Monitoring → Closed
You can customize the lifecycle of your incidents, to match your organization's process at [Settings > Respond > Lifecycle](https://app.incident.io/~/settings/lifecycle)
There are three main stages of the incident lifecycle you can configure: **triage**, **active**, and **post-incident**.
You can also configure how **timestamps** are set when an incident moves between statuses.
***
## 1. Triage
You can learn more about triage incidents [here](/incidents/triaging). Incidents created [automatically from an alert](/incidents/auto-create) or via [our API](/integrations/api-overview) will start in triage. You can configure whether or not incidents created manually can go through triage [here](https://app.incident.io/~/settings/lifecycle).
***
## 2. Active
These statuses indicate the condition of your incident at a single point in time, while there's still ongoing impact and responders are working towards a resolution. The default statuses are: Investigating, Fixing, and Monitoring.
## 3. Post-incident
Once the immediate impact is over, an incident can then enter a [post-incident flow](/post-incident/post-incident-flow), where you can define tasks for responders to complete now that there's time to reflect on what went wrong, and how to prevent it happening again.
Define your process in [Settings > Improve > Post-incident flow](https://app.incident.io/~/settings/post-incident-flow), and set the rules for which incidents should automatically enter the flow. Responders can always opt-in or opt-out of the flow.
***
## Team ownership and permissions
If you run different lifecycles for different teams, you can give a lifecycle an **owning team** so that only that team can change it. When editing a lifecycle, use the **Lifecycle owner** field to choose which team (or teams) own it.
Once a lifecycle has an owning team, only the following can change its statuses, post-incident flow, and other configuration:
* Anyone with the **Manage incident lifecycles** permission granted globally, such as an admin
* Members of an owning team who have the permission granted to that [team](/admin/team-roles)
Your **default** lifecycle can't be owned by a team: it applies to every incident across your organization, so changes to it always require the permission granted globally. The same goes for reassigning ownership of any lifecycle.
For how to set this up, see [Restrict incident type management to a team](/admin/restrict-incident-type-management), which covers lifecycles too.
***
## 4. Timestamps and metrics
**Timestamps** are a way to store structured data about your incidents. These are useful for reporting and analysis.
By default, there's a corresponding **timestamp** for each **status**. For example, "Fixed At" is set to the first time the incident changed to the "Monitoring" status.
**Timestamps** can be set in two ways:
1. **Manually** - set by a responder, [from the Incident Homepage](/incidents/edit-timeline)
2. **Automatically** - based on an incident status transition
Often, the impact will begin sometime before an incident is declared, so a good example of an additional timestamp could be "Impact Started At", which would be manually set by a human. So, if you wish to calculate the time to resolution for your incidents, it would be more accurate to measure from when the impact started, as opposed to when the incident was declared.
You can define **custom metrics** here too, as the difference between two timestamps:
These are available in the MTTX tab in [Insights](https://app.incident.io/~/insights).
# Merging incidents
Source: https://docs.incident.io/incidents/merging
Triage and active incidents can be merged into other active incidents. Read up on [how to use triage incidents](/incidents/triaging) if you've not come across these before.
## How can I merge a triage incident?
In the incident channel, you'll see a message saying that the incident is in triage. If you select "Merge", you'll be asked which incident you would like to merge the incident into.
The message looks like this:
You can also do this from our Dashboard, by selecting "Share update", and then choosing the "Merge" option.
## How can I merge an active incident?
You can merge an active incident when doing an incident update (as above), or by using the `/inc merge` Slack command.
You can also bulk select and merge multiple incidents together from the web dashboard — useful when a major issue has created several related incidents.
## What happens to merged incidents?
First, we update the incident to say it's been merged:
We then move across all attachments from the old incident to the new one, and then post a message into the new incident to say it has had another incident merged into it.
The old incident will no longer appear in insights, and other incident statistics.
If the merged incident had pending grouped alerts (alerts not yet confirmed as related), you'll be asked whether to include them in the merge or leave them as a separate incident.
## Do severities or custom fields get moved across?
Currently, we don't do anything with properties of the old incident (e.g. severities, custom fields) — the new incident will retain all of its existing properties.
# Active Participants vs Observers
Source: https://docs.incident.io/incidents/participants-vs-observers
## Who is considered an Active Participant of an incident?
Any user that is considered a [responder](/admin/seat-types) of an incident is considered an Active Participant, meaning they have done any of the specified attributes mentioned in the above article for that specific incident.
Additionally, any user that has posted a message in an incident Slack channel is considered an Active Participant even if they are not actively involved in running or managing the incident.
## Who is considered an Observer of an incident?
Observers are those users who have joined the incident Slack channel but have not made any posts to the Slack channel and are only following along to stay updated on what is happening.
# Pausing incidents
Source: https://docs.incident.io/incidents/pausing
While an incident is ongoing, there are many reasons you might need to put it on hold for a moment. Whether that's waiting on a third-party to get back to you, or simply because it's outside the team's working hours.
## Why pause incidents?
Pausing an incident will clearly communicate through announcements and the dashboard that an incident is not currently being worked on.
While an incident is paused, we won't send [rule-based suggestions](/incidents/rule-based-suggestions) to the incident channel. Workflows configured to run on active incidents will not run until the incident is resumed.
Time an incident spends in the paused status also won't count towards duration metrics, giving more accurate reporting on when an incident was being worked on.
## How do I use it?
The `/inc pause` command allows you to pause an incident, setting the date & time it should be paused until, and a message explaining why it's been paused.
The incident will automatically be resumed at the time specified, and put into the status it was in prior to pausing .
You can always resume it before then using `/inc update`, as well as change what time it's paused until.
We've included a few handy shortcuts to pause more quickly such as
`/inc pause until tomorrow` to pause until 09:00 the following morning
`/inc pause until working hours` to pause until the nearest weekday at 09:00
`/inc pause for 45` to pause the incident for 45 minutes
# Workflows on private incidents
Source: https://docs.incident.io/incidents/private-incident-workflows
Automate response on private incidents, including granting team access and announcing them.
By default, workflows **don't run on [private incidents](/incidents/private-incidents)**. Some steps could bypass the protections that keep them private, like emailing incident details to a mailing list or inviting people to the channel, so we hold workflows back unless you opt in.
## Run workflows on private incidents
To run a workflow against private incidents, open the workflow's **Advanced settings** and set **Run on private incidents**. You have three options:
* **No private incidents** (the default): the workflow only runs on public incidents.
* **Private incidents for owning teams**: the workflow also runs on any private incident that at least one of its [owning teams](/admin/restrict-workflow-management) can access. This follows each team's own access, not your team hierarchy, so a grant to a parent or child team doesn't count.
* **All private incidents**: the workflow runs on every incident, public and private.
A common use case is automatically granting access to private incidents. For example, you can add your security team to every private security incident, so the right people have visibility without manual invitation.
When a workflow runs on private incidents, the responsibility is on you to make sure it's safe and doesn't expose more
of the incident than you intend.
Running on private incidents needs the **Manage workflows that run on private incidents** permission. For **Private incidents for owning teams** you can hold it account-wide, or through a team role for every owning team. **All private incidents** always requires it account-wide. See [restricting workflow management](/admin/restrict-workflow-management).
## Steps that act on private incidents
Some steps are designed specifically for private incidents. On public incidents they do nothing, so the workflow needs **Run on private incidents** enabled to use them.
Because each of these steps widens who can see a private incident, **adding one to a workflow requires the matching permission to save the workflow**, on top of being able to edit workflows.
Adds a user as a member of a private incident, granting them access whether or not there's a channel. If there is a
channel, they're added to it.
Requires the **Manage private incident membership** permission.
Grants one or more teams visibility of a private incident. Members of the team can view the incident and join the
channel, but they're **not** added automatically. Useful for granting a team access based on incident conditions, like
giving your security team access to anything tagged as a security issue.
Requires the **Manage private incident team access** permission. See [confidential
incidents](/incidents/private-incidents#set-default-team-access) for the other ways to set default team access.
Announces an incident in a Slack channel. By default it skips private incidents; turn on **Announce private
incidents** to include them. You can also choose how incident updates are shared once it's announced.
Requires the **Manage announcement rules that run on private incidents** permission. See [announcing private
incidents](/incidents/announcing-private-incidents).
## What people without permission see
Anyone can see a workflow that runs on private incidents, but only people with the right permission can change it. Without it, we show a banner explaining that the workflow runs on private incidents, and disable the actions to edit it.
## Related
* [Private incidents](/incidents/private-incidents): make incidents private and manage access
* [Announcing private incidents](/incidents/announcing-private-incidents): announce private incidents safely
* [Workflows](/workflows): build and configure workflows
# Private incidents
Source: https://docs.incident.io/incidents/private-incidents
Lock sensitive incidents down to the people and teams who need them.
We're strong proponents of [normalizing incidents](https://incident.io/blog/why-more-incidents-is-no-bad-thing): when everyone can see what's happening, everyone has the information they need to do their best work. That's why **incidents in incident.io are public by default**.
But sometimes privacy isn't optional. Compliance or legal obligations, security breaches, HR matters, or securities law can all call for an incident to be locked down. For those cases, you can make an incident **private**, so only the people and teams you choose can see it.
If only part of an incident needs to be confidential, consider a [private stream](/incidents/private-streams) within a public incident instead.
## What private incidents do
Private incidents hold sensitive information, so we apply some extra protections by default:
* **They're visible only to people and teams with access.** That means people you invite directly, [members of teams you've granted access](#grant-access-to-a-team), and anyone with the org-wide **Manage private incidents** permission. Everyone else can't see the incident at all.
* **They aren't announced by default.** Private incidents are skipped by [announcement rules](/incidents/announcing-private-incidents) unless you explicitly opt a rule, workflow, or `/inc announce` into announcing them.
* **Workflows don't run by default.** You can [enable workflows on private incidents](/incidents/private-incident-workflows) when you need them.
* **They're excluded from CSV exports and most Insights.** A few private-aware dashboards can include them, but only for people who can already see every private incident.
* **Escalations don't leak details.** When you escalate a private incident, we include only a link to the dashboard, not the incident's information.
Because private incidents are meant to be discreet, you may need to turn on the **Include private incidents** option to see the ones you have access to.
## Enabling private incidents
If you're an [Admin or Owner](/admin/user-permissions), opt in to private incidents from **Settings → [Security](https://app.incident.io/~/settings/security)**.
Using Microsoft Teams? Private incidents run as private group chats, and enabling them may require re-authorizing our
bot. See [using private incidents in Microsoft Teams](/getting-started/teams-private-incidents).
## Making an incident private
You can make an incident private when you declare it, automatically from an alert, or by converting an existing public incident.
### Declare a private incident
Declare an incident using the `/incident` Slack command (or any [other method](/incidents/declaring)). In the declaration form, set **Who should be able to see this incident?** to **Only invited users (private)**.
Use [incident types](/incidents/incident-types) to make an entire category of incident private by default, such as
every Security incident. You can also pre-authorize the teams that should see them. See [default team
access](#set-default-team-access).
### Create a private incident from an alert
You can create private incidents automatically from alerts using private alert routes. Any incoming alerts then create private incidents by default. See [private alerts](/alerts/private-incidents).
### Convert between public and private
If you're not sure whether an incident should be private when you declare it, you can change your mind later:
* **Public to private:** make the incident's `#inc-...` channel private in Slack, and we'll lock the incident down to match.
* **Private to public:** [convert the channel back to public](https://slack.com/intl/en-gb/help/articles/213185467-Convert-a-channel-to-private-or-public), and we'll do the same to the incident.
## Who can see a private incident
A person can see a private incident if any of the following are true:
| Access | How they get it |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **Direct access** | They were invited to the incident individually. |
| **Team access** | They belong to a [team that's been granted access](#grant-access-to-a-team) (including its [sub-teams](/catalog/team-structure)). |
| **Org-wide access** | They hold the **Manage private incidents** permission, which grants access to every private incident in your organization. |
| **Slack workspace admin** | Slack workspace admins can access all private channels, so they can reach any private incident regardless of their incident.io role. |
Direct and team access sit alongside each other. Someone might have access because they were invited directly, because one of their teams was granted access, or both.
## Managing access
Open the incident and select **Manage access** to see who has access and to grant or revoke it. The incident's homepage also shows who has taken part: **Active participants** and **Observers** remain listed even if their access is later revoked.
### Grant access to a person
Invite individual users from **Manage access**. People you invite are added to the incident's Slack channel automatically and can view the incident homepage.
When you revoke someone's access, they're removed from the Slack channel and can no longer see the incident or find it on their dashboard.
If your Slack workspace restricts who can remove people from channels, we can't automatically remove a user. You'll
need to ask them to leave, or have a workspace admin remove them, before their access is fully revoked.
### Grant access to a team
Instead of inviting people one at a time, you can grant access to a whole team. This is useful when a team routinely handles confidential work, like a security team that owns every sensitive incident. Grant the team once, and new members get access automatically without anyone having to remember to invite them.
Team access gives members **visibility**, not an automatic seat in the Slack channel. People aren't pulled in. They
add themselves from the [announcement post](/incidents/announcing-private-incidents) or from the incident's dashboard
when they need to get involved.
When a team is granted access:
* Every member of the team, and of its [sub-teams](/catalog/team-structure), can view the incident in the dashboard.
* Members can self-join the incident's Slack channel, but aren't added automatically.
* The incident can be [announced](/incidents/announcing-private-incidents) to a channel the team watches, so they can discover incidents they have access to.
To grant team access, open **Manage access**, add the teams (and any individual users) you want, then select **Grant access**.
Before access is granted, we show a preview of exactly who will be affected, so you can be confident you're sharing with the right people:
* A per-team breakdown of how many members each team has.
* The people who will newly gain access.
* Members who **already have access**, annotated with how: directly, via another team, or because they hold the **Manage private incidents** permission (shown as **Global**).
The **Manage access** dialog lists everyone with access, showing whether each person has it directly or via a team, so you can revoke when needed.
### Revoke a team
Revoke a team from **Manage access**, or via the [API](#public-api). As with granting, we preview who's affected first.
Revoking a team removes its members' access, including removing them from the incident's Slack channel. We won't remove anyone who still has another valid route to the incident, though: a direct invitation, another team that still has access, or the org-wide **Manage private incidents** permission. Those people keep their access, and the revoke preview shows you exactly who.
To remove someone who keeps access through another route, revoke that route too. For example, revoke their direct access individually.
If you revoke a team you belong to and you have no other route to the incident, you'll lose your own access. Check the
revoke preview before confirming.
## Set default team access
Rather than granting the same team access to every incident of a kind, you can pre-authorize teams so they get access automatically. There are three ways to do this.
### Incident types
Make every incident of a given type private, and choose which teams get access by default.
Navigate to **Settings → [Incident types](https://app.incident.io/~/settings/incident-types)**, edit a type, and under **Privacy** enable **Private by default**. Then add the teams that should be able to view private incidents of this type. We show a running count of how many people across how many teams that covers.
Once default teams are configured, you can't turn off **Private by default** unless you hold the **Manage default team
access for incident types** permission, because doing so would silently remove those teams' access.
### Workflows
Use the **Grant team access to private incident** [workflow step](/incidents/private-incident-workflows) to grant teams access based on incident conditions. For example, grant your security team access to any incident tagged as a security issue. See [workflows on private incidents](/incidents/private-incident-workflows).
### Public API
Grant and revoke team access programmatically with the [Incident Team Memberships API](https://docs.incident.io/api-reference), so you can wire private-incident access into your own tooling. **Create** grants a team access to a private incident; **Revoke** removes it.
## Requesting access
Only people who already have access can see a private incident, so private incidents are undiscoverable to everyone else. If someone outside the incident is [paged about it](/incidents/escalating), or sent a link to the channel, they can request access from a placeholder page.
Requesting access sends a message to the incident channel, where someone with access can approve or deny it.
If you deny a request, we won't tell the user. A user can only request access once every 15 minutes.
## Permissions
| Action | Permission required |
| ----------------------------------------------- | ----------------------------------------------------------------------- |
| Grant or revoke access for an individual | **Manage private incident membership** (or the relevant incident role) |
| Grant or revoke access for a team | **Manage private incident team access** (or the relevant incident role) |
| Configure default teams on an incident type | **Manage default team access for incident types** |
| Announce private incidents | **Manage announcement rules that run on private incidents** |
| Run workflows on private incidents | **Manage workflows involving private incidents** |
| View every private incident in the organization | **Manage private incidents** |
See [user roles and permissions](/admin/user-permissions) for how permissions are assigned to roles.
## FAQs
If a member leaves a private channel on their own, we send a message to the channel asking whether you'd like to
remove their access to the incident. If you dismiss it, they keep their access and can rejoin from the incident
homepage at any time.
No. **Active participants** and **Observers** reflect anyone who has taken part or observed at any stage, so they
remain in the list even after their access is revoked.
Yes. You can opt specific announcement rules, workflows, or `/inc announce` into announcing private incidents, most
often to a private channel watched by the team that has access. Anyone in the channel you choose will see the
announcement, so choose carefully. See [announcing private incidents](/incidents/announcing-private-incidents).
## Related
* [Announcing private incidents](/incidents/announcing-private-incidents): announce private incidents safely
* [Workflows on private incidents](/incidents/private-incident-workflows): automate response on private incidents
* [Private alerts](/alerts/private-incidents): create private incidents automatically from alerts
* [Team structure](/catalog/team-structure): how teams and sub-teams work
# Private incident streams
Source: https://docs.incident.io/incidents/private-streams
You can manage the complexity of incidents by breaking large scale incidents into 'Streams', each of which will have its own Slack channel, Zoom/Meet call, and distinct leads and participants. Read more about managing incidents using streams [here](/incidents/streams).
We are strong proponents of making incidents visible to all, so everyone has access to the information they need to do their job the best they can. As such, **incidents and streams in** [incident.io](http://incident.io/) **are public by default**.
Nonetheless, we are also conscious that **in some circumstances, privacy is required**. Sensitive discussions may need to be locked down due to regulations around data privacy, cyber breaches, tip-off or securities law etc.
Those discussions can be managed from a private stream, while the main incident and any of its public streams remain visible.
***
## What do private streams do?
Private streams are by nature full of sensitive information. To keep that information safe, there are some restrictions and exceptions we’ve put in place:
1. Private streams are **by-invitation only**
2. Updates from private streams **will not be shared** to the incident channel
3. Private streams are **not included** in the incident timeline, exports or Insights tabs
4. When you escalate a private stream, we **won’t include any information about the stream**, other than a link to the dashboard, in the escalation.
*Remember that* [incident.io](http://incident.io/) *Workspace owners AND Slack Workspace owners have access to all private incidents and streams, even those they are not actively invited to!*
Unlike private incidents, users without access to a private stream will still be shown some basic information about it (stream name and lead) in order to know which stream of work they should request access to.
***
## Enabling private streams
If you are an [Admin or Owner](/admin/user-permissions) of your company's [incident.io](http://incident.io/) workspace, you can opt-in to Private Streams from Settings > [Security.](https://app.incident.io/~/settings/security)
***
## Creating a private stream
You can make an stream private from the start when you declare it, or turn a public stream private.
### Declaring a private stream
To create a private stream, simply **use the usual** `/incident stream` **Slack Command** (or create a new stream through the dashboard).
We will add a drop-down labeled ' *Who should be able to access this stream?* '. To make the stream private, select ' *Only invited users (private)* '.
### Turning a public stream private
Sometimes, you might not know if a stream should be private when you declare it - you might still be investigating and it's not quite clear what the issue and its impact is.
Nothing to worry about! You can very easily convert a public stream into a private one by simply **making the streams** `#inc-...` **channel private from Slack**. We'll take care of locking it down for you from here.
This will remove all of the stream’s updates from the incident channel. The stream name and stream lead will still be visible from Slack and the dashboard when viewing the incident.
### Turning a public incident with streams private
If you convert a public incident with streams to private, we’ll restrict access to all streams in the dashboard, and filter it out from any queries and insights, however:
**We aren’t able to change the visibility of slack channels, so you’ll also need to make any stream channels private from Slack.**
We’ll send a message to any stream channels and tag the stream lead to remind them to lock down the stream channel.
### Turning a private stream into a public stream
If you ever find the need to revert a private stream back to a public one, you can simply [convert the incident's slack channel to public](https://slack.com/intl/en-gb/help/articles/213185467-Convert-a-channel-to-private-or-public#convert-to-public-1:~:text=From%20your%20desktop%2C%20open%20the%20channel%20that%20you%20want%20to%20make%20public.). We'll then do the same to the stream.
### Turning a private incident with streams into a public incident
If you ever find the need to revert a private incident back to a public one, you can simply [convert the incident's slack channel to public](https://slack.com/intl/en-gb/help/articles/213185467-Convert-a-channel-to-private-or-public#convert-to-public-1:~:text=From%20your%20desktop%2C%20open%20the%20channel%20that%20you%20want%20to%20make%20public.).
This won’t impact the streams associated with the incident, which will remain private. You can individually change their visibility by converting the stream’s slack channels to public.
***
## Requesting access to a private stream
Only people who are in a private stream’s `#inc-...` channel will have access to it:
* **If a stream is created as private from the start**, this includes the stream’s creator, the stream lead, and anyone they actively invite into the private channel;
* **If you turn a public stream private**, this includes anyone who was on the public-turned-private channel, and anyone invited to the private channel hereafter.
Unlike private incidents, private streams **are discoverable** by users who are not in the private stream already, but all stream content is hidden. They’ll be able to see the existence of the stream in the dashboard, and request access to it.
***
## Managing access
The stream drawer will show you who has participated in the private stream ( *Active Participants* ) and who has been a member ( *Observers* ). Granting and revoking access can be done through the ' *Manage Access* ' button.
Participants and Observers indicate members who **at any stage** have participated or observed, so even if their access has been revoked they’ll remain in the list.
Clicking the `Manage Access` button will allow you to:
* **Grant access** : users you invite will be added automatically to the stream Slack channel, and will be able to view stream information in the dashboard
* **Revoke access** : revoking someone’s access will mean they are removed from the Slack channel and they will no longer be able to see the stream details drawer. They’ll see the stream name and lead listed, but won’t have access to any of the information in the stream details drawer
If your Slack workspace restricts who can remove people from channels, **we won’t be able to automatically remove a user from a channel**. In this case, you’ll need to ask the user to leave the channel, or have a workspace admin remove them, before you can revoke their access.
*If a member leaves a private channel voluntarily, we’ll send a message to the channel asking if you’d like to remove their access to the stream. If you dismiss it, they will keep their access, and can rejoin the stream at any time.*
***
# How do I convert a private Slack incident channel to public?
Source: https://docs.incident.io/incidents/private-to-public
## Context
When managing incidents in Slack, you may need to convert a private incident channel to a public one. This conversion changes the visibility of the incident channel and makes it accessible to more team members.
## Answer
To convert a private incident channel to a public one, the channel's privacy settings in Slack need to be changed. However, this action can only be performed by users with specific permissions:
* Only Slack Workspace Admins or Owners can change a private channel to public
* Regular users or channel members cannot make this change, even if they are channel admins
If you need to convert a private incident channel to public and don't have the necessary permissions, you will need to:
1. Contact your Slack Workspace Admin or Owner
2. Request them to change the channel's privacy settings to public
3. Once the channel is made public, the incident will automatically be converted to a normal (public) incident
# Quick Actions
Source: https://docs.incident.io/incidents/quick-actions
Quick Actions are a helpful tool for getting your incident response off the ground quickly. These actions often represent the first steps needed in an incident such as assigning key roles, escalating to an expert, or joining an incident call in progress.
In this article, we will show you how to create your own custom Quick Actions.
***
1. You can find the [Quick Actions](https://app.incident.io/~/settings/slack-channel) in Slack Channel section of your settings.
2. To create a new quick action, click the "+ Add new button", or edit an existing action by clicking the pencil icon. When you create a new Quick Action, you will be asked to choose between a Pre-Defined or Custom Link quick action.
* **Pre-Defined** Quick Actions come from our list of useful actions.
* **Custom Link** Quick Actions allow you to create a quick action that links you to URL, maybe to an internal document or a useful tool.
In this example, we are going to choose the Pre-Defined option, and the Type 'Make me Comms Lead'.
3. You can add a condition to limit when this Quick Action appears. For this example, we will only use this Quick Action when the incident severity is critical. We can configure that by adding a condition to our Quick Action.
4. Now, when you declare a critical incident in Slack, you will be given the 'Make me Comms Lead' quick action.
***
Whether using the Pre-Defined or Custom Link Quick Actions, the goal is to jump start your incident.
If you have any questions about Quick Actions or workflows, feel free to reach out to us on Slack or live chat. Thank you!
# Setting reminders and suggestions in incident.io
Source: https://docs.incident.io/incidents/reminders
You can easily set reminders with [Workflows](https://app.incident.io/~/workflows), or use [rule-based suggestions](/incidents/rule-based-suggestions) to prompt responders to take an action.
# Can I rename an incident?
Source: https://docs.incident.io/incidents/rename-incidents
For sure!
Just go to the Slack channel for that incident, type in `/inc rename`, and press enter.
To rename an incident from the Incident Homepage, open the menu in the top right and click "Rename incident".
# Can I reopen an incident?
Source: https://docs.incident.io/incidents/reopen-incidents
Yes - it's very simple!
* Go to the incident slack channel
* Use the command `/inc update`
* Update the incident status to the relevant "open" status
You can also do this within the dashboard. Just head to the incident's homepage and click *Share update.* You'll then see the pop-up shown below where you can re-open the incident.
## If your incident channel has been archived:
* Go to the slack channel
* Go to settings
* Unarchive the channel
* Then complete the above steps!
# Can I create retrospective incidents?
Source: https://docs.incident.io/incidents/retrospective-incidents
Sometimes, you may want to record an incident after it has happened, to include it in your reporting and help inform your post-incident processes.
You can choose whether you'd like to announce a retrospective incident so you don't need to worry about worrying folks unnecessarily! By default, workflows don't run on retrospective incidents, but this can be configured in advanced settings.
***
The quickest way to create a retrospective incident is with `/inc retro` in Slack, which opens a dedicated Retrospective form. You can customize this form in **Settings > Forms**. If you're using Microsoft Teams, you can create retrospective incidents from the incident.io tab in your Teams channel.
You can also create one from the dashboard:
1. Head to [your incident.io dashboard](https://app.incident.io/~/dashboard) and hit **Declare incident.**
2. You'll then choose what type of incident at the top of the form, and select **Retrospective incident.**
3. At this point, you'll be asked to supply some information about the retrospective incident. This will include any custom fields associated with incident types that you have set.
You can also choose whether you'd like to announce the incident by checking the box at the bottom of the modal.
4. You will then be able to add in any timestamps (you'll be able to see any custom timestamps here too!) that will help you in your post-incident process and contribute to your incident analytics.
It will be reflected in your incident.io dashboard that this is a retrospective incident, for any folks who are looking into recent incidents!
## Creating retrospective incidents via the API
You can create retrospective incidents programmatically with the [create incident endpoint](/api-reference/incidents-v2/create) by setting `mode` to `retrospective` — useful when importing historical incidents from another system. Use `incident_timestamp_values` to set when the incident actually happened.
Retrospective incidents created via the API start in your closed status and skip the post-incident flow —
post-incident tasks won't be created for them. When creating them in the dashboard you can choose to enter the
post-incident flow, but this option isn't available via the API.
We'd love any feedback you have on this feature or any issues, you can always get in touch with us at [help@incident.io](mailto:help@incident.io) !
# Why can't I see all my team in the drop-down of incident roles?
Source: https://docs.incident.io/incidents/role-dropdown
You might declare an incident and realise you need to hand over the Lead role (or any other custom role) to one of your teammates...only to realise you can't find them in the drop-down! Urgh, confusing right?
2 potential fixes:
1. **Type the first few letters of their name** : the users we show in the drop-down are just a selection of incident.io users, so that team member might just not be visible
2. [Invite them](/incidents/inviting-teammates) **to the** `#incidents` **channel** : we don't auto-add all your Slack users into incident.io, so they might not appear because they've never been invited to incident.io before!
Check out this video for a walk-through👇🏼
# Rule-based suggestions
Source: https://docs.incident.io/incidents/rule-based-suggestions
Rule-based suggestions remind responders to take a certain action, such as providing an incident update, on a schedule that you can define. We post a message to the incident channel with buttons to complete the action. They're available in Slack, and you can configure them from [Settings → Suggestions](https://app.incident.io/~/settings/suggestions).
**incident.io** comes out of the box with a number of pre-set suggestions. We'll prompt you to:
* Set an incident lead.
* Provide an internal incident update.
* Update your status page, if you have one.
* Set an incident summary.
* Accept or decline incidents that are being triaged.
* Create a stream.
* Escalate or ask for help in Slack.
* Mark an incident as resolved, if the channel has been inactive.
If you're on **Pro** or **Enterprise**, you'll be able to create new suggestions, and edit existing ones, or disable them entirely. Editing includes the ability to **customize the message** that is sent in incident channels, and to configure the frequency with which those suggestions are repeated.
By default, we run suggestions using **smart scheduling**, which is designed to minimize the noise within your incident channels. We do this by adapting the schedule that the suggestion is run on based on activity within the incident. For example: if another suggestion was just sent, we might delay the next one by a few minutes.
# Shortcuts cheatsheet
Source: https://docs.incident.io/incidents/shortcuts
There are quite a few handy shortcuts in incident.io....
***
## The One Command to Rule Them All
If you have to learn just one command, it's `/inc` **while in an incident's** `#inc-...` **Slack channel** - it will pop up a menu of all the actions you can run on that incident
`/inc` *in any other channel will pop up the incident creation form*
***
## Other super-commands
## Emojis
From an incident's `#inc-...` Slack channel, you can react to messages with:
| Emoji | Action |
| --------------------------------------------------- | ---------------------------------------------------------------------- |
| `:boom:` | Turns the message into an [Action](/incidents/task-tracking) |
| `:fast_forward:` | Turns the message into a [Follow-up](/incidents/task-tracking) |
| `:pushpin:` `:bookmark:` `:round_pushpin:` `:star:` | Pins the message to the incident's [timeline](/post-incident/timeline) |
| `:mega:` `:speech_balloon:` | Turns the message into an [Update](/incidents/status-updates) |
## Slack Commands
| Command | Description |
| --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **GENERAL** | |
| `/incident help` | See information on how to get help |
| `/incident workflow` | Trigger a workflow from an incident channel |
| **CREATING/UPDATING INCIDENTS** | |
| `/incident` `/inc` | Create an incident |
| `/inc retro` | Create a retrospective incident directly from Slack |
| `/incident lead` | Make someone the incident lead. `/incident lead [me \| @user]` to auto-fill the lead |
| `/incident resolve` | Mark a live incident as resolved. Once you've done this, you can choose to close the incident or enter the post-incident flow. |
| `/incident close` | Skip the post-incident flow and close the incident |
| `/incident cancel` | Mark the incident as canceled. Use this if you've realised that the incident is not actually a problem. |
| `/incident severity` `/incident sev` | Upgrade and downgrade severities. `/incident {severity \| sev} [level]` to auto-fill the severity |
| `/incident roles` `/incident role` | View, assign and unassign roles during the incident |
| `/incident field` `/incident fields` `/incident customfield` `/incident customfields` | Manage custom fields for this incident |
| `/incident summary` | Update the top level summary of the incident. `/incident summary [description]` to auto-fill the summary |
| `/incident overview` | See a summary of the incident's history so far |
| `/incident action` `/incident actions` | Create and manage Actions. `/incident {action \| actions} [description]` to auto-fill an action's title |
| `/incident followup` `/incident followups` `/incident follow-up` `/incident follow-ups` | Create an incident follow-up item. |
| `/incident rename` | Change the title of the incident. `/incident rename [name]` to auto-fill |
| `/incident status` `/incident state` | Update the incident status. `/incident {status \| state} [level]` to auto-fill the status |
| `/incident accept` | When an incident is in triage, it'll open the 'accept incident' modal |
| `/incident merge` | When an incident is in triage, it'll open a modal to help you merge the incident into another one |
| `/incident decline` | When an incident is in triage, it'll open a modal to let you decline the incident and provide an update |
| `/incident related` | Link a related incident |
| `/inc alerts` | View all alerts related to this incident |
| `/inc private` | Find out how to make the incident private. |
| `/inc handover` | Hand over responsibilities in an incident to another user. |
| `/inc decision` | Browse/Trigger decision flows |
| `/inc pause` | Temporarily pause an ongoing incident |
| `/inc stream` | Create a stream under the current active incident |
| `/inc test` | Create a test incident to try out incident.io without affecting real data |
| **COMMUNICATION** | |
| `/incident update` | Provide an internal status update to your team about the incident. `/incident {update} [message]` to auto-fill the update message |
| `/incident request` `/incident request-update` | Request an internal status update from the incident lead |
| `/incident statuspage` `/incident sp` | Create and update your public [Statuspage](/integrations/statuspage) |
| `/incident escalate` `/incident page` | Pull in other teammates for help. `/incident page` can be used outside of incidents! |
| `/incident whoisoncall` `/incident oncall` | See who is currently on-call for a given team or escalation path |
| `/incident coverme` `/incident cover` `/incident cover me` | Request on-call cover for an upcoming shift |
| `/incident call` | Set a call link. `/incident call [link]` to auto-fill the link |
| `/incident shoutout` | Recognize your team for their work |
| `/incident announce` | Announce the incident in another channel |
| `/incident revoke` `/inc revoke me` `/inc revoke @user` | Choose a user to remove from a private incident, leave the channel and remove yourself from a private incident, or revoke a specified user passed as an argument from a private incident |
| **POST-MORTEM** | |
| `/incident doc` `/incident document` | View and set post-mortem docs. `/incident {doc \| document} [link]` to auto-fill the post-mortem link |
| `/inc timestamp` | View and update an incident's timestamp values |
| `/inc attachments` | Opens a modal showing all the attachments for this incident |
| `/inc attach [link]` | Adds a link as an attachment to the incident (only works for links related to enabled [integrations](https://app.incident.io/~/settings/integrations)) |
## FAQs
No, Slack does not allow applications to create custom slash commands as they require explicit approval and need to be consistent across all users of the application.
# What's happened to my Slack bookmarks?
Source: https://docs.incident.io/incidents/slack-bookmarks
Slack are [rolling out an update](https://slack.com/intl/en-gb/help/articles/32368498524691-A-new-layout-for-channels-and-DMs) to the layout of channels and DMs, which put bookmarks into a folder. We know how powerful bookmarks can be for seeing the most important aspects of your incidents — this article is here to explain the change that Slack are making, to suggest some alternatives, and to talk about how we might use Canvases in the future.
## What's changed?
Everything that was previously in the top bar will now be in a "Bookmarks" folder, and your incident channel will now look like this:
The "Bookmarks" tab looks like this, and at larger screen widths will appear as a dropdown:
## What can I do instead?
We know that moving these bookmarks one click deeper is frustrating, because it's always there at the top of the channel. There's a few options here:
* The incident homepage will always contain all your incident details.
* Announcement posts also contain an overview of the incident, and will be kept up to date with these changes.
* Incident update messages also contain details of things like status changes.
* We recently made call links more prominent within Slack channels.
We are not currently aware of any way of reverting this change.
## Are you going to make any changes in response?
The short answer is yes, but we're currently working out what this looks like. If you have thoughts on what this might look like then we'd love to hear from you.
This change makes canvases more prominent, and Slack have recently released an API for Slack Canvas. This is something we are currently exploring, and provides us with a way of providing you with a much richer overview of an incident within Slack — so we're excited about what we can do here.
Otherwise, there is currently no way for us to add arbitrary information at the top of a Slack channel, but we're always keeping our eyes on changes to the Slack platform.
# Can I set a custom field directly from Slack using a command?
Source: https://docs.incident.io/incidents/slack-custom-fields
## Context
When managing incidents in Slack, users may want to update specific custom fields directly using Slack commands, similar to how they can update fields using Slack buttons in the interface.
## Answer
Whilst it is not currently possible to set a single specific custom field directly, using a dedicated Slack command, there are 3 approaches you can use that will help:
1. Use the general `/inc update` command to modify incident details, including custom fields.
2. View all custom fields and update using the `/inc fields` command.
3. Create a custom fields form [here](https://app.incident.io/~/settings/forms) to include any custom fields you regularly might want to edit on an incident, then use the `/inc customfields` command to bring this form up!
# Can multi-channel slack guest users interact with the incident.io bot?
Source: https://docs.incident.io/incidents/slack-guest-users
Organizations often have external contractors, partners, or vendors who are added as guest users in their Slack workspace. These guests may need to participate in incident management, including declaring incidents, being assigned roles, or being part of on-call rotations.
Currently, Slack guest users (including multi-channel guests) have limited functionality within incident.io:
**What guest users CAN do** (if [SAML](/admin/saml-sso) authentication is configured for them) **:**
* Log into the incident.io platform
* Declare incidents
* View incidents
**What guest users CANNOT do:**
* Become a [responder](/admin/seat-types) / take any responder actions.
* Use the /inc command or interact with the incident.io Slack bot
* Be assigned incident roles (such as Incident Lead)
* Be added to incident workflows that auto-invite users
* Be part of on-call rotations
Support for having guest users as responders is being tracked as a feature request, and can be enabled in certain scenarios for customers on our Enterprise plan provisioning users via SCIM. If you'd like to explore this, please contact your Customer Success Manager or [help@incident.io](mailto:help@incident.io).
# Sharing status updates with your team
Source: https://docs.incident.io/incidents/status-updates
Good incident response is about good communication. Sharing updates regularly to keep your stakeholders ( [and customers](/incidents/customer-updates) !) updated is a great practice to get into.
We built **Updates** to make this easy. Updates are a lightweight way to keep people in the loop, and progress the state of an incident.
***
## Adding an update
To create an update, simply type `/incident update` in an incident channel.
You'll be presented with a modal that:
* Asks if there's any changes with the severity or the status of the incident
* Allows you to provide a **short message** to update people with what's going on (' *Can you share any more details* ')
* Lets you **set a** [reminder](/incidents/reminders) for your next update: no need to remind yourself manually! We will come back and remind you when an update is due.
Updates will get posted in the incident's channel (see GIF), and as a thread on the original announcement post .
***
## Using Updates to trigger automations
You might want to automatically send an email enclosing your update to, say, senior management, affected partners or the Account Executive of the affected client.
You can do all this (and more) with a [Workflow](https://app.incident.io/~/workflows) - just select ' *An incident update is shared* ' as a trigger!
# Incident streams
Source: https://docs.incident.io/incidents/streams
Major incidents can have hundreds of responders, and even more following updates along the way. In incidents like these there are lots of moving parts:
* Teams like engineering, communications, legal...
* Different impacts across products, services or regions with different groups working on mitigations
* Groups exploring independent approaches towards resolution, or investigations on root causes
Manage the complexity by breaking large scale incidents into 'Streams', each of which will have its own Slack channel, Zoom/Meet call, and distinct leads and participants.
***
## Creating a stream
To create a stream, simply type `/incident stream` in an incident channel.
You'll be presented with a modal to:
* Set a **name** for the stream
* Assign someone as the **stream lead** - this will usually be a different person to the main incident lead to avoid splitting their focus
* Invite anyone else who should collaborate on the stream
You can also create streams from the incident dashboard, or automatically via [workflows](/workflows/getting-started) — including specifying initial participants when the stream is created.
We'll create a new Slack channel for the stream, and invite the stream lead and any participants.
If you've [configured automatic call links](/incidents/video-calls) we'll also create one for your stream. If not, you can also manually link a video call from the stream channel, just [like in an incident channel](/incidents/video-calls).
***
## Updating a stream
To create an update, simply type `/incident update` in a stream channel, just like you would in an incident channel.
You'll be presented with a modal that:
* Allows you to provide a **short message** to update people with what's going on (' *Can you share any more details* ')
* Lets you **set a reminder** for your next update: no need to remind yourself manually! We will come back and remind you when an update is due.
Alternatively, you can share an update from the stream in the dashboard.
Any updates shared here will be posted in the stream channel, and also announced in the incident channel for anyone following along there.
***
## Actions in a stream
Track the work happening in a stream by creating actions, just like you would in an incident. Actions are the things that **need doing now** to move the stream forward — reboot a server, draft customer comms, pull a list of affected accounts.
You can create and manage actions from the stream channel in Slack, or from the stream's dashboard page:
* **In Slack**, run `/incident action` in the stream channel. With no message we'll show the open actions for that stream; add a description (e.g. `/incident action draft customer comms`) to jump straight to creating one. You can also react to any message with `:boom:` to turn it into an action.
* **In the dashboard**, open the stream and use the **Actions** section on the **Overview** tab. Select the **+** button to add an action, then assign it, mark it complete, edit, or delete it.
Actions you create in a stream stay scoped to that stream, so each stream keeps its own focused list of work without cluttering the main incident. For public streams, action activity also flows into the parent [incident timeline](/post-incident/timeline), labeled with the stream it came from.
Actions in a stream don't convert into [follow-ups](/post-incident/follow-ups) — streams don't have their own post-incident flow. Once a stream is closed you can still update or tidy up its existing actions, but you won't be able to create new ones.
***
## Closing a stream
Once a stream of work is complete, type `/incident close` in the stream channel.
You'll be presented with a modal that asks you to provide a final update on the stream.
The stream will be marked as closed, and the final update will be posted in the incident channel to keep everyone up to speed.
You can also close a stream from the dashboard the same way you provide an update.
***
## Roles in streams
Just like incidents, you should nominate a person to lead each stream. We recommend you have a separate lead for each stream to the incident, as they cover different areas of work in different Slack channels.
If you have set up [custom incident roles](/incidents/custom-roles), we’ll also make those available in streams. Any role available in the parent will be available in its streams.
From within the stream channel you can use commands such as `/inc lead` and `/inc handover` just as you would in an incident to reassign the roles in that stream.
***
## Streams in your incident timeline
Activity that occurred in a stream will be included in your [incident timeline](/post-incident/timeline) in both the dashboard, and your exported post-mortem. We’ll highlight which stream each item occurred in.
We’ll detect the same types of events automatically as incidents, for example updates and role changes within a stream. You can also pin messages in a stream channel and these will be pinned to the incident timeline.
***
## Restricting access to streams
This can be done by making a private stream from a public incident. Read more about that [here](/incidents/private-streams).
***
## Streams shortcuts cheatsheet
If you've [learnt just one command](/incidents/shortcuts) you can use it in streams too!
`/inc` while in a stream's Slack channel will pop up a menu of all the actions you can run in a stream.
## Emojis
From a stream's Slack channel, you can react to messages with:
| Emoji | Action |
| --------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `:pushpin:` `:bookmark:` `:round_pushpin:` `:star:` | Pins the message from the stream to the incident's [timeline](/post-incident/timeline) |
| `:mega:` `:speech_balloon:` | Turns the message into an [Update](/incidents/status-updates) |
| `:boom:` | Turns the message into an [Action](/incidents/actions) |
## Slack Commands
| Command | Description |
| ---------------------------------------------- | ---------------------------------------------------------------------------------- |
| **ROLES** | |
| `/incident lead` | Make someone the stream lead. `/incident lead [me \| @user]` to auto-fill the lead |
| `/incident roles` `/incident role` | View, assign and unassign roles in the stream |
| `/inc handover` | Hand over responsibilities in a stream to another user. |
| **WORK** | |
| `/incident action` `/incident actions` | Create and manage actions for the stream |
| **COMMUNICATION** | |
| `/incident update` | Provide an internal status update to your team about the stream |
| `/incident close` | Provide a closing update, and mark the stream as closed |
| `/incident request` `/incident request-update` | Request an internal status update from the stream lead |
| `/incident escalate` `/incident page` | Pull in other teammates for help |
| `/incident call` | Set a call link `/incident call [link]` to auto-fill the link |
| `/incident statuspage` | Post or update an incident on your status page |
# Subscribing to Incidents
Source: https://docs.incident.io/incidents/subscribing
## What are incident subscriptions?
Incident subscriptions are a way to stay up-to-date with changes to an incident, without having to dig through the noise happening in its slack channel. Once you're subscribed, when the incident gets an update you'll be notified through whichever channels you've chosen: a Slack direct message, an email, a mobile app push notification, or an SMS.
## How do I subscribe to an incident?
There are two places you can subscribe to an incident: on the web (via the **incident homepage** ) and in Slack (in the incident **announcement post** ). Click the "subscribe" button in the dashboard, the incident slack channel, or an announcement post and you'll be notified of any future updates on that incident.
The first time you do this, you'll be prompted to configure how you want to receive notifications. You can choose any combination of a Slack direct message, an email, a mobile app push notification, or an SMS.
To receive notifications via the mobile app, you'll need the incident.io app installed and signed in. To receive them
via SMS, you'll need a verified phone number set on your [User
Preferences](https://app.incident.io/~/user-preferences) page.
## Can you subscribe me to certain incidents automatically?
Yes! You can set up a variety of auto-subscription rules on the [User Preferences](https://app.incident.io/~/user-preferences) page, which you can find by clicking on your avatar in the dashboard.
Click "add auto-subscribe rule" and configure which conditions should auto-subscribe you to an incident.
You can add as many rules as you'd like, and if an incident matches any of them, you'll be subscribed automatically.
## What if I change my mind about how I want to receive subscriptions?
The [User Preferences](https://app.incident.io/~/user-preferences) page allows you to choose how you receive subscription notifications — via Slack direct message, email, mobile app push notification, SMS, or any combination of these.
## I want to remove all of my subscriptions. Is there a convenient way to do that?
The bottom section of the [User Preferences](https://app.incident.io/~/user-preferences) page contains an "Unsubscribe from All" button that will remove all your subscriptions at once. Bear in mind that if you have auto-subscription rules set up, you will still be subscribed to any new incidents that match their criteria.
# Keeping track of who's doing what
Source: https://docs.incident.io/incidents/task-tracking
In the confusion of an incident, it's easy to miss (or simply forget!) who's fixing what. And once the incident is closed, we stack up to-dos during debriefs, just to find them alive and well 3 months down the line when you just 'feel like you've seen this before'...
With Actions and Follow-Ups, incident.io helps you:
* Jot down and keep track of what's being done - and who's doing it - during an incident instead of keeping it all in someone's head (usually that of the incident lead...)
* Capture to-dos and export/sync them to your issue tracker post-incident
***
## Capturing an Action/Follow-Up
New actions can be added in 3 ways.
| Method | Details |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| **Slack command** `/incident action Do a thing` (to turn into a Follow-Up, simply pick ' *After the Incident* ' from the ' *When does it need to be done?* ' drop-down) | |
| **Reacting with the** `:boom: emoji ` to a Slack message to create an action | |
| **Reacting with the `:fast_forward:` emoji** to a Slack message to create a follow-up | |
| Via the **incident's homepage** in the web app | |
When an action is created, we show the whole channel an `I'm on it!` button, allowing teammates to quickly assign the action to themselves.
***
## Getting a quick overview of who's doing what
Key in `/incident actions` to quickly list and edit all actions/follow-ups, their status, owners, and more.
*Every interaction with your incident actions appears on your incident* [timeline](/post-incident/timeline) *, too.*
***
## Exporting to issue trackers
Although issue trackers are not *quite* what you need when you're looking for some fast lightweight coordination in the middle of an incident, they should be (and probably are!) your central hub for to-dos.
Once you've added the [integrations](https://app.incident.io/~/settings/integrations), you can export follow-ups from incident.io to your issue tracker from the Post-incident tab. We support:
* [Asana](/integrations/asana)
* [ClickUp](/integrations/clickup)
* [GitHub](/integrations/github)
* [GitLab](/integrations/gitlab)
* [Jira](/integrations/jira), including [Jira Server and Data Center](/integrations/jira-server)
* [Linear](/integrations/linear)
* [Notion](/integrations/notion-follow-ups)
* [ServiceNow](/integrations/servicenow)
* [Shortcut](/integrations/shortcut)
**We will sync the status of your follow-ups**, so you don't need to worry about updating that manually in incident.io!
***
# Why are my incidents not being announced?
Source: https://docs.incident.io/incidents/test-incident-announcements
## Context
When creating incidents, you may notice that some incidents are not being announced in your configured announcement channels. This can happen when incidents are created in test mode, tutorial, or Private incident, even though the incident channel is created.
## Answer
Tests, tutorials, and private incidents are excluded from announcement rules by default. This prevents cluttering announcement channels or exposing sensitive private incident data.
To ensure your incidents are announced in configured channels:
1. Verify that the incident is not set to Test, tutorial, or private when creating it
2. Use Test mode only when you want to practice or test incident workflows without triggering announcements
3. For real incidents that need to be announced, make sure to create them in standard active (non-test) mode.
Private incidents *can* be announced if you explicitly opt in, to a controlled audience, like a private channel a team
watches. See [announcing private incidents](/incidents/announcing-private-incidents).
# Test incidents
Source: https://docs.incident.io/incidents/test-incidents
Run practice incidents without affecting your real data or notifying the whole company.
Sometimes you just want to practice without the whole company knowing, and without cluttering your incident library with fake data. Test incidents are built for exactly this.
Test incidents work almost exactly like normal incidents: you can set summaries, leads, escalate to others, create [workflows](http://app.incident.io/~/settings/workflows), and receive [rule-based suggestions](/incidents/rule-based-suggestions).
The key differences are:
* They won't be announced in any announcement channels
* They won't appear in your dashboard or insights
* You won't be able to update your status page
* Workflows won't automatically run, but you can configure them to run on a case-by-case basis in the advanced settings within a workflow
**Our Statuspage integration is disabled in test incidents.** This is a safety measure to avoid updating public status pages when you're just trying the tool out.
### Creating a test incident
Type `/incident test` from any Slack channel to start a test incident.
If you need a fully isolated environment to test configuration changes, integrations, and workflows, consider setting
up a [sandbox environment](/admin/sandbox-environments) instead.
# Triaging your incidents
Source: https://docs.incident.io/incidents/triaging
Occasionally you might be presented with a problem you don't fully understand - you think it has the potential to be an incident, but you need to confirm this first. That's why we have **triage incidents**.
## What makes triage incidents special?
When you create an incident in `Triage`, it is not considered "live" yet. The `Triage` incident status is managed by us and denotes incidents which are being triaged ie. someone is deciding whether or not they're looking at a problem.
Once a responder has made their decision (perhaps by bringing other users into the incident channel or using decision flows), they can then either:
* **Accept** the incident - this means it will move to the first live status and can start being investigated
* **Decline** the incident - this should be chosen if a responder concludes that the triage incident is not actually a problem
* **Merge** the incident - this should be chosen if the incident is a duplicate of another one
Note that by declining or merging a triage incident, it never enters a "live" status and is removed from your metrics. For accepted incidents, Insights metrics (such as duration and time-to-acknowledge) are calculated from the "Accepted at" timestamp — time spent in triage is not counted.
An existing incident lifecycle might look like this:
But an incident going through triage has extra stages before being promoted to live:
This flow might be familiar to you if you already use our [PagerDuty auto-create feature](/incidents/auto-create). During auto-create, we'll spin up a triage incident when a PagerDuty incident fires, and you decide whether or not its worth opening an incident for. Our new offering is the same but we're just letting you create those triage incidents *manually*.
## How can I create a triage incident?
You'll only be able to create (or auto-create) triage incidents if you're on our Pro plan.
If this is you, next time you declare an incident from within Slack, you'll notice some radio buttons for configuring whether or not the incident should start from the `Triage` status.
Once you've filled out the form and hit "Create", we'll announce the incident in your default announcements channel, highlighting that it is the `Triage` state.
Your incident will look and act similar to a normal "Live" incident, for example you can escalate or assign roles, and workflows will run (unless you configure them not to). But there are a few key differences:
* **You won't be able to use the full range of commands**. For example, we won't let you update your StatusPage from a triage incident, or create actions or follow-ups. We believe these should be reserved for incidents that are confirmed issues.
* Every now and then we'll **nudge the channel to make a decision**. This stops you from accidentally getting stuck into fixing the issue without moving the incident through the lifecycle.
* After the usual welcome message at the beginning of the channel, we'll send you **some options for quickly making a decision** :
As an alternative to using these buttons, you can accept/merge/decline a triage incident at any time by calling `/inc update`.
If you choose to merge or decline the triage incident, we'll update the announcement post so it takes up less space:
If you've declined an incident and later realise it does need attention, you can move it back to triage from the Slack channel.
## What are the benefits of using this feature?
### You can discover problems faster
It's common for our customers to discover an a issue, but not have enough context to know what type of incident they're dealing with or how severe it is. Discussion to ascertain whether it's a problem can be slow and exclude the right people. Equally (and quite understandably), many users are wary of declaring a live incident in this case because it could be a false alarm.
Triage incidents lower the bar to creating an incident channel - they don't require an incident type or severity to be set during creation, and you can easily remove the incident from your metrics if it turned out to be nothing to worry about.
### More insights
We track a timestamp associated with each of these decisions: `Accepted at`, `Declined at`, and `Merged at`. They'll appear on an incident homepage to help you piece together what happened.
You can also create a custom duration like "Time to accept" from the [lifecycle settings page](https://app.incident.io/~/settings/lifecycle) and use our [MTTX insights dashboard](https://app.incident.io/~/insights?tab=mttx) to track how well you're doing at triaging your incidents.
### Quality control
For some of our customers, there's a very high bar for a problem to be declared an incident. That's why we're letting you enforce all incidents to start in triage, if you wish.
This is configured per incident type to support different processes in different teams. Just head to Settings → Types and flip the toggle for the relevant incident type.
### Completeness
When the discussion takes place within an incident channel, you don’t lose any context that might have taken place elsewhere in Slack. You make it easier for yourself to curate the timeline (by pinning messages) and for anyone in the future to understand what happened.
## Can I disable this feature?
If you like, you can prevent users from creating triage incidents. To do this, you'll need to be an organization owner or admin. Head over to the [lifecycle page](https://app.incident.io/~/settings/lifecycle) and scroll down to `Triage`, then disable the toggle.
# Updating an incident's status and details
Source: https://docs.incident.io/incidents/updating-incidents
Want to update specific incident details (e.g. severity, status, roles, summary etc.) without broadcasting a full-blown status update?
You can do this from the incident's Slack channel (`#inc-...`) at the speed of light, with just a few handy Slack commands ( [there are more](/incidents/shortcuts) !)
***
**The One Command to Rule Them All**:
`/incident`
From the incident's Slack channel (`#inc-...`), this will make a drop-down appear of everything you need to update an incident's details.
Easy peasy lemon squeezy
***
For the power users out there, you can also use the following quick shortcuts:
| Action | Command |
| ------------------------------------------------ | ----------------------------------------------------------------------------------- |
| Update the incident's **severity** | `/incident severity` |
| Update the incident's **status** | `/incident status` (or `/inc resolve` to directly mark a live incident as resolved) |
| Update the incident's **summary** | `/incident summary` |
| Update the **roles/lead** | `/incident roles` or `/incident lead` |
| Update [custom fields](/incidents/custom-fields) | `/incident fields` |
| Update [Actions](/incidents/task-tracking) | `/incident actions` |
*Some (and soon all!) details are also editable from the web app on the incident's Homepage.*
# Pre-filling 'declare incident' fields using URL parameters
Source: https://docs.incident.io/incidents/url-parameters
You might want to provide people with links to declare an incident from other places (like internal systems) where you already know something about the incident. In cases like this, you can use URL parameters to speed up the declaration of incidents.
The base URL is [https://app.incident.io/\~/incidents?createIncident=true](https://app.incident.io/~/incidents?createIncident=true). The tilde (`~`) can be replaced with your organization's slug. If you don't replace this, you'll be redirected to the organization that you are currently logged in as.
The following URL parameters are supported:
* `name` : taken as a string.
* `summary` : also taken as a string.
* `severity` : this can be either a severity ID, or name.
* `status` : this can be either a status ID, or name. We will infer whether the incident should be "active" or "triage" based on this.
* `incident_type` : this can be either an incident type ID.
## Custom fields
You can also pre-fill custom fields via URL parameters. We currently support single-select and multi-select fields (including catalog backed).
Specifying the custom field is done by prefixing the name or ID of the custom field with: `custom_field_`. For example, to set a custom field called Service with ID `ABC123`, the parameter name would be `custom_field_Service`, or `custom_field_ABC123`
Specifying the custom field value can be done using either the option's:
* name (e.g `custom_field_Service=Backend`)
* ID (e.g `custom_field_Service=ID2`)
* external ID (in the case of catalog backed custom fields) (e.g `custom_field_Service=EXTID2`)
Multi-select custom fields values can be passed by repeating the parameter multiple times with different values. For example, `custom_field_Service=Backend&custom_field_Service=Frontend`
# Creating and linking video call URLs for digital 'war rooms'
Source: https://docs.incident.io/incidents/video-calls
Especially in a remote world, you'll usually want to set up a video call for incidents, to act as your online 'war room'.
There are 3 ways to do this with incident.io.
***
## Automatically create a call link
We can automatically generate and pin a dedicated call link for each new incident via the Zoom or Google Meet integration.
Once you've [set up Zoom](/integrations/zoom) or [Google Meet](/integrations/google-meet), toggle on the `Automatically Create Incident Call` setting in the [Zoom](https://app.incident.io/~/settings/integrations/zoom) or [Google](https://app.incident.io/~/settings/integrations/google_meet) integration.
***
## Copy-pasting an existing link
If you already have a Zoom/Google Meet video call link, **paste it into an incident's (** `#inc-...` **) channel.**
We will recognize it as a call link, and ask you if you'd like to pin it as the go-to link for everyone working on the incident.
*You can also use* `/incident call` *for this* !
***
## Using the same fixed link for all incidents
If you have a unique call link you use for all your incidents, you can attach that link as a default from the [Automation page within Settings](https://app.incident.io/~/settings/automation)
# Insights: Custom Dashboards
Source: https://docs.incident.io/insights/custom-dashboards
Custom dashboards are a powerful feature of Insights that let you build exactly the dashboard that you want to see. You can also [schedule reports to be sent based on a custom dashboard](/insights/scheduled-reports).
## Creating a custom dashboard
To create a new custom dashboard, go to the [Insights homepage](https://app.incident.io/~/insights), and click the "Create dashboard" button in the top right.
Give your custom dashboard a name, choose an icon and color, and then click Create.
## Adding panels
You can add panels containing either charts or text to your custom dashboard, simply click the corresponding button on your empty dashboard:
You can add any panel from one of the core insights dashboards to your custom dashboard by selecting it from the drawer:
## Filtering the whole dashboard
You can add filters to the dashboard, and **they will affect all panels on the dashboard**. For example, you can filter so that you only see data for major incidents by using the "Add filter" button in the header bar:
## Filtering a panel
If you want to filter just a single panel in a custom dashboard, click the "Add filter" button in the header of the panel you want to filter:
The filters you add to a panel **will be applied in addition** to the filters that are added to the whole dashboard.
# Using Insights
Source: https://docs.incident.io/insights/overview
## Insights date range filtering
When filtering for date range inside the `insights` [page](https://app.incident.io/~/insights), you can choose to include data from the current Week/Month/Quarter by selecting the "Include this Week/Month/Quarter" configuration found under the custom relative range.
You can also compare with the previous period by toggling it on.
## How often is Insights' data refreshed?
Insight data is refreshed roughly every three hours, this means that recently created incidents will not show up in insights.
Yes. There is a **View Insights** permission that controls who can access Insights in the dashboard. To restrict
access, adjust this permission in [**Settings → Users → Roles**](https://app.incident.io/~/settings/roles).
# Saved Views
Source: https://docs.incident.io/insights/saved-views
Saved views let you save a collection of filters and quickly apply them later. They're great for navigating to data you check often, and for sharing useful views with your teammates.
They're available on the [incidents](https://app.incident.io/~/incidents), [alerts](https://app.incident.io/~/on-call/alerts), [escalations](https://app.incident.io/~/on-call/escalations), [follow-ups](https://app.incident.io/~/follow-ups), and tasks pages. Within [teams](/catalog/teams), you can also create them for incidents, alerts, and escalations - these are separate from org-wide views and scoped to that team's data.
To create one, apply the filters you want, click "Save view", and give it a name. That's it! Once created, you can rename or delete it, or grab a shareable link to send to a colleague.
All saved views are visible to everyone in your organization.
# Insights scheduled reports
Source: https://docs.incident.io/insights/scheduled-reports
Our insights scheduled reports allow you to get snapshots of your custom dashboards, delivered to whoever you need on a regular cadence. Reports are delivered by email and can be sent to as many email addresses as you'd like.
To create a scheduled report, [navigate to the custom dashboard](https://app.incident.io/~/insights) that you'd like to send (or create a new custom dashboard). Click the *Schedule* button in the top right and the drawer will open. Enter the slack channels or email addresses of the people you'd like to send the report to and select how often you'd like to receive the report.
You can send insights reports to a slack channel(s) and/or any email address, inside or outside of your organization.
Click the *Send a test report* button at the bottom of the drawer to send a test report to your email address. Be aware that reports can take up to a minute to generate. If you're happy with the results, click the confirmation button and your report will be sent according to your selected schedule.
You can only send scheduled reports for **custom dashboards**. Core dashboards (those that appear as tiles on the insights homepage) are not supported. If you want to schedule a report based on a core dashboard, you can create a custom dashboard with the same panels as the core dashboard you're interested in and schedule it as above.
# Supported measures
Source: https://docs.incident.io/insights/supported-measures
Every measure you can chart in an Insights panel, including incident volume, MTTR/MTTA duration metrics, alerts, pager load, follow-ups and time spent
Insights [custom dashboards](/insights/custom-dashboards) are built from **panels**. When you
add a panel, you choose from a set of pre-built panels grouped by area. This page lists every
panel available.
Most panels let you filter the data, split it by an attribute or
[custom field](/incidents/custom-fields), and
[compare with the previous period](/insights/overview). Numeric measures such as duration
metrics, time to acknowledge and time spent can be aggregated as a **count**, **mean** or
**median**.
## At a glance
Incident volume and where incidents are coming from.
| Panel | What it shows |
| --------------------------- | ---------------------------------------------------------------- |
| Incident creation | The number of incidents created over time |
| Incident creation by source | Where your incidents are coming from (e.g. alert sources, users) |
| Incident creation by user | The number of incidents created by a specific user over time |
| Group by a custom field | The number of incidents grouped by a custom field |
## MTTX (duration metrics)
[Duration metrics](/admin/incident-timestamps) measure the time between two incident
timestamps. You use them to track **MTTR**, **MTTA**, **MTTD** and other response-time metrics,
reported as a mean or median. Because you define the timestamps, you're not limited
to a fixed set: the panels below report on the duration metrics your organization has configured.
| Panel | What it shows |
| -------------------------------- | ----------------------------------------------------------------- |
| Duration metrics | Compare all your duration metrics |
| Duration metric breakdown | Statistics for a single duration metric over time |
| Duration metrics by custom field | Statistics for a single duration metric grouped by a custom field |
## Alerts
How your alerts are firing and being handled.
| Panel | What it shows |
| ---------------- | --------------------------------------------------- |
| Alerts created | Which alerts and sources are firing most frequently |
| Alert acceptance | Which alerts are being declined, and how frequently |
## Pager load
How often and when people are being paged. Native pager load requires the
[On-call](/on-call/overview) product; the PagerDuty and Opsgenie panels require a connected
[external on-call provider](/integrations/pagerduty).
| Panel | What it shows |
| ------------------------------------- | -------------------------------------------------------------------------------------------- |
| Pages | How often and when people are being paged (incident.io On-call) |
| Pages (PagerDuty / Opsgenie) | How often people are being paged, optionally filtered by escalation policy, team, or service |
| Pages per user (PagerDuty / Opsgenie) | How often a particular person is being paged, broken down by time of day |
## On-call readiness
| Panel | What it shows |
| ------------------ | ------------------------------------------------------------------------------------------- |
| Notification setup | Your On-call responders' notification setups, so you can check they're reachable when paged |
For a deeper look at reachability, mobile-app adoption and readiness over time, see [On-call readiness
insights](/on-call/on-call-readiness-insights).
## Follow-ups
Follow-up creation and completion.
| Panel | What it shows |
| -------------------------- | ---------------------------------------------------------------------------- |
| Follow-ups created | Follow-up creation over time, split by status, assignment, or a custom field |
| Follow-ups by user | Follow-up status broken down by assignee |
| Follow-ups by custom field | Follow-up statuses and time to complete, grouped by a custom field |
## Post-incident flow
| Panel | What it shows |
| ------------------- | ---------------------------------------------------------------------- |
| Post-incident flow | Which incidents enter your post-incident flow and what happens to them |
| Post-incident tasks | The outcomes of post-incident tasks, grouped by a custom field |
## Teams
| Panel | What it shows |
| ----------------------- | ------------------------------------------------------------------------- |
| Post-incident | The status of post-incident tasks and follow-ups, grouped by team or user |
| Time spent on incidents | How much time is spent on incidents, broken down by user or team |
## Time spent on incidents
How [workload](/insights/workload-metrics) is distributed. Time an incident spends
[paused](/incidents/pausing) is excluded, so these figures reflect active effort.
| Panel | What it shows |
| -------------------------- | ----------------------------------------------------------------------- |
| Time spent on incidents | Time spent on incidents across your company, categorised by time of day |
| Time spent by custom field | Time spent on incidents, grouped by a custom field |
## Text
| Panel | What it shows |
| ---------- | ---------------------------------------------------------------------------- |
| Text panel | A rich-text panel for adding headings, context and commentary to a dashboard |
# Workload metric calculations
Source: https://docs.incident.io/insights/workload-metrics
#### Calculating workload
We generate workload by watching activity taken in an incident — inferring activity as a signal that someone was actively working on that incident.
The rules are:
1. If we see incident activity, such as a message in the incident channel, or work in integrations like issue trackers, we'll assume the related person has spent 10 minutes working on this incident.
2. If the same user takes another action for the same incident within 20 minutes of the last, we'll assume they've been working on this incident continuously since the last time we saw them.
As an example, if we see someone message the incident channel at 10:11 am, we'll immediately assign them 10 minutes of workload. When we have access to participant data, we also include being a participant in an incident call as workload.
If that person were to update a Zendesk ticket attached to this incident at 10:15 am, we'll adjust to assume 4 min of activity (from 10:11 to 10:15) and allocate another 10 minutes after, for a total sum of 14 mins of work.
For the average responder focused on specific incidents, this provides an accurate picture of their time. But for incident managers who work across many incidents at a time, we apply a final calculation to trim their workload to ensure we never overlap workloads across incidents, preventing us from calculating more than one hour of work in any hour.
We're confident this calculation is representative of individual contributions and can be used as a valuable proxy for effort put into an incident.
#### Calculating working hours
The workload chart splits hours by:
* Working: 8 am-7 pm
* Late: 7 pm-11 pm
* Sleeping: 11 pm-8 am
This is a dimension we apply to the calculated workload to understand when a period of work happened relative to the user's timezone, which we align with their Slack timezone at the point this workload is seen to have occurred.
Note: Working hours are not customizable.
# Closing incidents via the API
Source: https://docs.incident.io/integrations/api-close-incidents
Automatically close incidents once follow-up work wraps up in your own systems, without waiting on manual review.
Incidents in a post-incident status can be closed via [our API](https://docs.incident.io/api-reference/).
This is particularly useful for teams that carry out follow-up actions from incidents in external tools, and want to automatically close the incident in incident.io once those tasks are complete.
### Prerequisites
To use this feature, you must use an API Key with a specific scope. This ensures that incidents aren't accidentally closed without a proper review unless explicitly authorized.
1. Navigate to **Settings > API keys**
2. Create a new API Key
3. Ensure the key has the **Close incidents by opting out of the post-incident flow** permission enabled
### How to use it
You can transition the incident by using the [Edit Incident endpoint](https://docs.incident.io/api-reference/incidents-v2/edit) (`POST /v2/incidents/{id}/actions/edit`).
* **From:** The incident must currently be in a valid post-incident status (e.g., `Resolved`, `Fixing`)
* **To:** The target status must be `Closed`
When you successfully close an incident via the API:
* The incident status moves to **Closed**
* The incident is marked as "opted out" of the post-incident flow
### Resolving incidents
You can resolve active incidents using the same [Edit Incident endpoint](https://docs.incident.io/api-reference/incidents-v2/edit) by setting the status to a post-incident or closed status:
* **To a post-incident status** (e.g. `Resolved`): the incident enters the post-incident flow and tasks are created as normal. The status must belong to the post-incident flow that applies to this incident.
* **Directly to closed**: any configured post-incident flow is skipped entirely. This requires the same **Close incidents by opting out of the post-incident flow** permission described above.
Once an incident is in the post-incident flow, its status is managed automatically based on task completion. Moving between post-incident statuses via the API is not recommended, as the system will recalculate the correct status when tasks are updated.
# Creating your first incident using the API
Source: https://docs.incident.io/integrations/api-create-incident
Trigger incidents directly from your monitoring or ticketing tools instead of starting them by hand.
Our API gives you the power to automatically create an incident from another system, such as a monitoring tool like DataDog, or a ticketing system like Zendesk. This is valuable because it means you spend less time starting your incident process, and more time resolving the issue.
To show how easy this can be to set up, we'll walk you through a simple example where we create an incident through the API.
## Step 1: generate an API key in incident.io.
Head to Settings → API keys in the dashboard and generate a key with `Create incidents` enabled.
## Step 2: fetch your severity configuration.
We require you to declare the severity of your incident during creation, by supplying a severity ID in the payload. Because severities are custom to each organization, you’ll have to make a call to fetch your severities first.
This will be in the form of a HTTP GET request, using the API key you generated earlier for Bearer token authentication.
```plaintext theme={null}
GET https://api.incident.io/v1/severities
// Response
{
"severities": [
{
"name": "Minor",
"description": "It's not that bad, everyone chill.",
"id": "01FCNDV6P870EA6S7TK1DSYDG0",
"rank": 1,
"created_at": "2021-08-17T13:28:57.801578Z",
"updated_at": "2021-08-17T13:28:57.801578Z"
},
{
"name": "Major",
"description": "It's quite bad.",
"id": "01FXNA5TFQXZRM3K1JDVTWXV4X",
"rank": 2,
"created_at": "2021-08-17T13:28:57.801578Z",
"updated_at": "2021-08-17T13:28:57.801578Z"
}
]
}
```
Let’s say the incident you are handling is of the lowest severity - you’d make a note of the ID for the “Minor” severity.
## Step 3: create your incident!
Using the same authentication, you then need to make a HTTP POST request to create the incident. You can find our required fields in the [API docs](https://docs.incident.io/api-reference/incidents-v2/create), but at the time of writing this includes:
* **Idempotency key.** This needs to be unique for every incident, to ensure we don’t accidentally create duplicate incidents.
* **Severity ID.** This is what you obtained in step 2.
* **Visibility.** This is an enum of either `public` (anyone can access the incident) or `private` (only invited users have access).
```plaintext theme={null}
POST https://api.incident.io/v2/incidents
// Payload
{
"name": "Testing incident.io's API",
"idempotency_key": "test1",
"severity_id": "01FCNDV6P870EA6S7TK1DSYDG0",
"visibility": "public",
}
```
Et voila! The incident has been created in our system. The response will contain the incident body, which now includes the ID we have assigned your incident, along with other defaults.
**In a real life scenario, you probably want to create incidents that are more complex than this, for example declare the incident type or any custom fields. In this case, you need to make preliminary calls to the** [incident types endpoint](https://docs.incident.io/api-reference/incident-types-v1/list) **or** [custom fields endpoint](https://docs.incident.io/api-reference/custom-fields-v2/list) **respectively, to obtain the relevant ID's like you did in step 2.**
We’d love to hear what you build using our API, and how you’d like us to extend it. So please drop any feedback you have in the `#api` channel in the [incident.io Community](https://incident.io/community)
# Our API
Source: https://docs.incident.io/integrations/api-overview
Trigger incidents from anywhere in your stack, and pull your incident data into the tools you already use.
We’re building incident.io as the single place you turn to when things go wrong. When an issue is disrupting your business-as-usual, the last thing you want is to start opening ten different tools to diagnose and fix it!
As your central incident hub, we need to give you two powers:
1. Replicating (and possibly automating) your existing processes in incident.io; and
2. Embedding incident.io in your existing tool stack.
We do the former with [Workflows](https://incident.io/blog/workflows-your-process-automated). We do the latter with our API and our [native integrations](/alerts/alert-sources).
[API docs](https://docs.incident.io/api-reference/)
***
## What does the incident.io API do?
At the highest level, [our API](https://docs.incident.io/api-reference/) lets you connect incident.io to any tool in your stack (or even to your own application), and give us instructions via that connection.
Common use cases include:
1. **Automatically creating an incident from another system**, such as a monitoring tool like Datadog, or a ticketing system like Zendesk
2. **Exporting incidents and follow-ups into a data warehouse or BI tool** (Looker, Tableau etc.) to analyze
3. **Managing your configuration as code**, including custom fields, incident roles, severities, and catalog entries, for example using [Terraform](/admin/terraform)
4. **Creating escalations programmatically**, triggering on-call escalation paths directly from external systems via the [Escalations API](https://docs.incident.io/api-reference/escalations-v2/create)
See the full [API reference](https://docs.incident.io/api-reference/) for everything that’s available.
***
## Where can I find the API Keys?
You can create your API Keys from the [API section](https://app.incident.io/~/settings/api-keys) of your incident.io Settings.
***
## Example use case: declaring an incident from Zendesk
You might use a ticketing system like Zendesk (or Freshservice; or Intercom) to manage your customer support. Inbound tickets are typically triaged by customer support teammates, and escalated to engineering teams based on specific criteria (e.g. a certain severity, or a particular incident type such as data breaches).
With our API, a support agent can declare an incident with one click, straight from within Zendesk. We’ll take care of the rest, from declaring the incident in incident.io to pulling in the right teammates, notifying the relevant internal and external stakeholders, spinning up your public Statuspage and much more.
Here are the few key steps to bringing this flow to life.
1. [Generate an API Key](https://app.incident.io/~/settings/api-keys) **in incident.io**
You’ll want to generate a key with `Create incidents` enabled. Keep this safe - we’ll need it in a minute.
2. [Configure a Zendesk Support trigger](https://support.zendesk.com/hc/en-us/articles/4408886797466)
This lets you choose when Zendesk should escalate a ticket. In this case, we might use a checkbox custom field, which will declare an incident when it’s ticked.
3. **Add a** [Zendesk webhook](https://support.zendesk.com/hc/en-us/articles/4408839108378#topic_dlc_lsz_2pb) **as the action to take when the trigger fires**
Configure it to make an HTTP POST request to `https://api.incident.io/v2/incidents`. The API Key we generated earlier is used for Bearer token authentication. The request body needs to be JSON that looks like:
There’s a couple of special IDs in there you’ll need:
1. The `custom_field_id` references a “Zendesk Ticket Link” custom field we’ve configured. You can find the IDs of your custom fields using the [List Custom Fields API](https://docs.incident.io/api-reference/custom-fields-v2/list).
2. The `severity_id` references our “Minor” severity. You can find the IDs of your severities using the [List Severities API](https://docs.incident.io/api-reference/severities-v1/list).
**That’s it!** Whenever that trigger fires, you’ll get a new incident declared in Slack. Nice.
Even nicer: you can **configure workflows that only run on your API-generated incidents.**
For example, you could build a workflow that automatically adds the support agent that declared the incident in Zendesk to the incident’s Slack channel. To do that, add a Condition based on the API Key that reported the incident. This would look like:
***
## Exporting incident data to your warehouse
Data is always more powerful when you can link it together, which is why most organizations want to have all their different systems synced into a data warehouse where things can be analyzed in one place.
With our API, you can get all your incident, action, and follow-up data out of incident.io and into your warehouse. There are two key APIs here:
1. [Listing all your incidents](https://docs.incident.io/api-reference/incidents-v2/list); and
2. [Listing actions](https://docs.incident.io/api-reference/actions-v2/list) (which includes follow-ups!)
By scraping each of these once an hour, you can pull in everything we know about all your incidents and link that with any other data in your warehouse. If you have your Jira data there you can link followups in incident.io with the corresponding ticket in Jira, for example.
***
## Keeping in sync with your service catalog
One of the most common uses of custom fields is to tag incidents with which teams and services were involved. You can keep those lists in sync with your service catalog, using the [Custom Field Options API](https://docs.incident.io/api-reference/custom-field-options-v1/list).
This API lets you manage options for any custom field. Beyond custom fields, you can also manage custom [Incident Roles](https://docs.incident.io/api-reference/incident-roles-v2/update) and [Severities](https://docs.incident.io/api-reference/severities-v1/update) using the API, if you want to keep all your configuration in a central location, for example using Terraform.
***
## Over to you!
We’d love to hear what you build with our API. There’s an `#api` channel in the [incident.io Community](https://incident.io/community), or reach out to our support team at [help@incident.io](mailto:help@incident.io).
# Asana
Source: https://docs.incident.io/integrations/asana
Send incident follow-ups to Asana and keep their status updated automatically.
Using Asana to track your team's tasks? Want to export [your incident follow-ups](/incidents/task-tracking) to Asana to keep everything centralized?
This is how.
***
## What we can do with Asana
Our current integration is a fairly simple setup for now. In its present state, the integration lets you:
1. **Export** [your incident follow-ups](/incidents/task-tracking) to Asana; and
2. **Sync the status of your tasks between Asana and incident.io**, so you can work in Asana without worrying about updating statuses manually in incident.io!
3. [Auto-export follow-ups](/integrations/auto-export-follow-ups) to an Asana project, based on pre-configured rules
If there's more you'd like to do with incident.io and Asana, [get in touch](http://incident.io/community) to give us your wishlist!
*Note: Due to technical limitations with Asana, tasks that do not exist within a project will sync daily, not in real time.*
***
## Getting Set Up
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
Hit `Install` on Asana.
2. **Generate an Asana Access Token**
Log in to Asana, and go to [https://app.asana.com/0/my-apps](https://app.asana.com/0/my-apps). Under **Personal access tokens**, click **Create new token**. Use "incident.io" as the token name and click **Create token**.
You'll be shown the token just once. Click **Copy**, then head back to the incident.io dashboard.
3. **Copy-Paste the generated API key into the incident.io pop-up**
That's it
If you run into any issues, [get in touch](http://incident.io/community)
# Auto-exporting follow-ups
Source: https://docs.incident.io/integrations/auto-export-follow-ups
Send follow-ups to the right project automatically, based on the details of each incident.
Eliminate the hassle of manually exporting follow-ups by configuring them to export automatically to your issue tracker.
This guide walks through the configuration process and demonstrates how to auto-export follow-ups to specific projects based on incident details, like custom field values.
## Setup Integrations
Before configuring the auto-export rules, ensure that you have the correct issue tracker providers installed as integrations.
Navigate to [Settings → Integrations](https://app.incident.io/~/settings/integrations), and install your issue tracker.
## Configure Export Templates
When auto-exporting a follow-up, an **export template** will be used to set certain properties of the issue, for example:
* The project the issue is assigned to
* The user that owns the issue
* Labels that are added to the issue
Navigate to [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups), and add a new **export template**.
## Configure Conditions
Navigate to [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups), and enable **auto-export**.
Out of the box, the **export template** you just created will be used to automatically export all follow-ups from all non-private incidents.
If you would like to configure when follow-ups should be automatically exported, and which **export template** should be used, then you will need to add a new condition.
In the example below:
* If the incident's `Affected Team` custom field is set to `ProductOps`
* Then automatically export the incident's follow-ups using the `ProductOps Team Export Template`
* If the custom field does not match, then do not automatically export follow-ups for the incident
## Fallback Behavior
The example above has configured the fallback behavior to not automatically export follow-ups if conditions do not match, however you can instead select a default template to be used.
This will ensure that follow-ups will always be automatically exported for each incident.
## Private Incidents
By default, auto-exporting of follow-ups is disabled for private incidents, however you can enable this on the [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups) page.
# Syncing incidents with Azure DevOps
Source: https://docs.incident.io/integrations/azure-devops-sync
Keep a live record of every incident in Azure DevOps, without anyone updating it by hand.
incident.io allows you to automatically track your incidents in Azure DevOps by creating and maintaining "Issue" work items.
This is helpful if Azure DevOps is your source of truth, and you need everything to be in one place.
Each issue will be updated in real-time with the latest title and description, and comments will be added for each incident update. We will also sync any comments added to your Azure DevOps work item back into incident.io.
You can also use templates and conditions to create different issues in different projects depending on custom fields and incident types within incident.io. For example:
* Create issues in your Security project where Incident Type = Security
* Create issues in your Engineering project where Incident Type = Production
## Getting started
First, you'll need to enable the integration. Ensure you are logged in as an Azure DevOps user with access to the relevant projects.
Navigate to Settings > Integrations, locate Azure DevOps via the search bar, and click **Connect**.
A modal will appear. Click **Sign in with Microsoft** to be redirected to Microsoft for the authorization flow.
We do not support authentication via Azure service accounts due to differences in API behavior. We suggest creating a personal account under a shared "service" email for authentication purposes
## Service Hooks
1. Go to your project, select **Project settings**, and then select **Service hooks**.
2. Select **Create subscription**.
3. Select **Web Hooks** and then click **next**
4. Change the trigger to be **Work item updated** and then click **next**
5. Copy the service hooks details from the dashboard into the service hook config
6. Click **Test** and you should see a success in the dashboard
7. Click **Finish** in azure devops to complete the setup
## Creating a template
Next, we need to define what the contents of each issue should be.
Navigate to Settings > Incident Tickets, and click **+ Add a new template**
The issue template determines which project the issue will be created in, and who it should be assigned to. It also allows for customization of the issue title and description, using variables and custom fields on the incident.
## Enabling the feature
Once your template has been configured, use the toggle to **Create tickets for incidents**.
If there are no conditions specified we will use the first template in the list and create a ticket for all new, active incidents.
Conditions can be used to control which template should be used for any given incident. For example, incidents of type "Security" may need to be directed to a security-specific Azure DevOps project.
## Private incidents
If you wish to create tickets for private incidents, then tick this checkbox.
Note: Anyone with access to the chosen Azure DevOps project will be able to see these tickets.
# Using a bot account for integrations
Source: https://docs.incident.io/integrations/bot-account
Keep integrations working even after the person who set them up leaves your organization.
**What are bot accounts?**
Bot accounts are dummy accounts on the system you wish to integrate with, allowing you to connect integrations with your systems without them being attached to a specific user.
**When should you use bot accounts?**
Bot accounts are recommended to be used with any of our third-party integrations that require you to Authenticate via a user's account.
**When Bot accounts are recommended:**
For example, with our [Jira integration](/integrations/jira) you are prompted to give permissions for incident.io to take action on Jira's side.
In this case, utilizing a Bot account would be useful to ensure that regardless of company user changes, the integration will continue to work as expected and not be tied to a specific user that would cause the integration to fail if that user leaves the company.
**When are bot accounts not needed:**
In the case of **Opsgenie** [integration](/integrations/opsgenie), we ask you to set up an API key on the account and copy-paste it into our settings page, which is globally set to the **Opsgenie** account and is not tied to a user, so no Bot account is needed as the integration will not lose permission if the user leaves the company.
**Challenges of not Using Bot Accounts**
The user account used for the integration gets deactivated:
* This would cause the integration to break as the user is no longer an active user in the third-party app, causing disruption to your incident management process.
## FAQs
No. incident.io supports connecting only one account per integration type per organization. For example, you can only have one Sentry account connection, one GitHub account connection, one Notion account connection, or one Google account connection.
If different teams in your organization use separate accounts for the same service, you'll need to choose one primary account to integrate with incident.io.
# Scheduling an event in a specific calendar
Source: https://docs.incident.io/integrations/calendar-events
Fix the permission and subscription issues that stop you scheduling events in a shared calendar.
## What should this look like?
When you're successfully set up, you should be able to schedule an event within a specific shared calendar, such as `Incident debriefs` :
## What if I don't see this?
There are two reasons you might not be able to do this:
1. You're not subscribed to the calendar
2. You don't have the correct permissions to create an event within this calendar
### 1. Checking you're subscribed
Head to Google Calendar. If you can see the calendar you're required to create the debrief in in the sidebar (under `Other calendars` or `My calendar`), you are successfully subscribed.
If you cannot see the correct calendar, copy the calendarID we provided in the app.
Then head back to Google Calendar and hit `+` next to `Other calendars` and choose `Subscribe to calendar`. Paste the calendar ID here.
### 2. Checking you have the right permission
Click the three dots next to the specific calendar and choose `Settings`. You'll have the correct permission if it says you can `Make changes to events`. If you see something else, you'll need to ask the calendar owner to grant permission to you (or more helpfully, your whole user group) - instructions are in [scheduling debriefs in a specific calendar](/integrations/debrief-calendar).
# Using the incident.io CLI
Source: https://docs.incident.io/integrations/cli
Manage incidents, alerts, schedules, and more from your terminal with inc, the official incident.io command-line interface.
`inc` is the official command-line interface for the incident.io API. Use it to list and manage incidents, page people, inspect schedules, and script against your incident data without leaving the terminal. It's built for both humans and LLM agents: every command supports JSON output, and the full command schema is machine-discoverable.
The CLI is open source at [github.com/incident-io/inc](https://github.com/incident-io/inc).
**Note that we recommend the [MCP](/ai/remote-mcp) as the primary integration tool**.
## Install
```bash theme={null}
# Homebrew
brew install incident-io/tap/inc
# mise
mise use -g ubi:incident-io/inc
```
Or download a binary for your platform from [GitHub Releases](https://github.com/incident-io/inc/releases).
## Authenticate
Create an API key in [Settings → API keys](https://app.incident.io/~/settings/api-keys), then either export it or save it to the CLI's config:
```bash theme={null}
# Option 1: environment variable
export INCIDENT_API_KEY=inc_abc123...
# Option 2: save to config
inc auth login
```
Verify it works:
```bash theme={null}
inc auth status
```
The CLI can only do what the API key allows, so scope keys to what your scripts need. Read-only keys are a good default for reporting and exploration.
## Everyday commands
```bash theme={null}
# What's live right now
inc incidents list --status-category live
# Create an incident
inc incidents create --name "Database outage" --visibility public --severity-id 01ABC...
# Page someone
inc escalations create --title "Database latency spike" --escalation-path-id 01ABC...
# Who's on call for a schedule
inc schedules entries 01ABC... --from 2026-07-20T00:00:00Z --until 2026-07-21T00:00:00Z
# Pull a post-mortem as markdown
inc post-mortems content 01ABC... > postmortem.md
```
Run `inc --help` for the full command list, covering incidents, alerts, catalog, escalations, schedules, severities, users, roles, custom fields, post-mortems, and follow-ups.
## Scripting and JSON output
When you pipe output, the CLI automatically switches to JSON. Use the built-in `--jq` flag to filter responses without installing anything else:
```bash theme={null}
# Closed incidents this month, counted by severity
inc incidents list --status-category closed --jq 'group_by(.severity.name) | map({severity: .[0].severity.name, count: length})'
# Just the fields you need
inc incidents list --fields id,name,reference --output json
```
Errors are structured JSON too, with a `retryable` field to gate retries on and a `request_id` you can share with our support team. Rate-limited requests retry automatically.
## Call any endpoint
If a dedicated command doesn't exist yet, `inc api` can call any endpoint in the [API reference](https://docs.incident.io/api-reference) with authentication pre-configured:
```bash theme={null}
inc api GET /v2/incidents --field 'status_category[one_of]=live' --jq '.incidents[].name'
inc api GET /v2/alerts --paginate --jq '.alerts[].title'
```
## For LLM agents
The CLI supports agent use as well. `inc describe` outputs a JSON schema of every command and flag, and `--dry-run` previews any request without sending it:
```bash theme={null}
inc describe incidents.create
inc incidents create --name "Test" --visibility public --dry-run
```
See [AGENTS.md](https://github.com/incident-io/inc/blob/master/AGENTS.md) in the repository for detailed agent integration guidance.
# ClickUp
Source: https://docs.incident.io/integrations/clickup
Keep task tracking in ClickUp without manually copying incident follow-ups back and forth.
Using ClickUp to track your team's tasks? Want to export [your incident follow-ups](/incidents/task-tracking) to ClickUp to keep everything centralized?
This is how.
***
## What we can do with ClickUp
Our current integration is a fairly simple setup for now. In its present state, the integration lets you:
1. **Export** [your incident follow-ups](/incidents/task-tracking) to ClickUp; and
2. **Sync the status of your tasks between ClickUp and incident.io**, so you can work in ClickUp without worrying about updating statuses manually in incident.io!
3. [Auto-export follow-ups](/integrations/auto-export-follow-ups) to ClickUp, based on pre-configured rules
If there's more you'd like to do with incident.io and ClickUp, [get in touch](http://incident.io/community) to give us your wishlist!
***
## Getting Set Up
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
Hit `Install` on ClickUp.
2. **Generate a ClickUp Access Token**
Log in to ClickUp, click on your profile photo in the bottom-left, then **Apps**. Generate an API Token, and copy it to your clipboard.
Now head back to the incident.io dashboard.
3. **Paste the generated API key into the incident.io pop-up**
That's it
If you run into any issues, [get in touch](http://incident.io/community)
# Confluence
Source: https://docs.incident.io/integrations/confluence
Export post-mortems to Confluence, with support for routing different teams to different destinations.
You can now add multiple destinations for post-mortems, using different Confluence folders.
## Setting up
We connect to Confluence as a specific user. That means that actions taken by incident.io in Confluence will show up as by the connecting user.
We therefore recommend you create a Confluence user called something like "incident.io", and sign in to Confluence with that account before you begin (you can remain signed in to incident.io as your usual account!)
1. Head to [Settings → Integrations → Confluence](https://app.incident.io/~/settings/integrations/confluence)
2. Click **Connect**: you'll be redirected in to Confluence to approve our access
If you run into any issues, [get in touch](https://incident.io/community)
We also support Confluence on Atlassian GovCloud. The setup process is the same as for standard Confluence Cloud
instances.
## Getting started
## 1. Add Confluence as your document destination for post-mortems
Within the [Post-Mortem setting tab](https://app.incident.io/~/settings/post-mortem), add Confluence as your document destination by clicking **Add destination**.
2. You can then configure the default destination for your post-mortems - we'll then create post-mortems as children of the page you select. This will be the default destination for your post-mortems.
Can't see the page destination you are looking for? You can simply search the page name in the drop-down to find the right one!
***
## Creating custom post-mortem destinations for different teams or services
You can create different post-mortem destinations for different teams or services by adding further destinations.
When you go to create and export a post-mortem, you can choose the correct destination depending on the team or service. Your default post-mortem destination will be used if you don't select a different destination!
## FAQs
The trick is that you need to hit **Get it now** twice:
1. Visit our [Atlassian Marketplace listing](https://marketplace.atlassian.com/apps/1233901/incident-io?tab=overview\&hosting=cloud).
2. Click **Get it now** to install our app into your Confluence site.
3. Select the Confluence site and hit **Review**.
4. You should see the Review and install section with permissions required, where you'll need to hit **Get it now** again.
5. You should see the incident.io app on this page. Click the row to expand it, then click **Get it now** once more.
6. Select the Confluence site and hit **Review** again to reach another set of permissions, where you'll need to click **Get it now** a third time.
7. A pop-up in the bottom-left corner shows progress. Once you see *incident.io completed successfully*, hit **Manage apps**.
8. Click **Take me there** to land on the Connected Apps section, then search for incident.io and hit **View app details** for the Confluence one. You might see two similar results including the Jira one, but focus on the Confluence one.
9. On the redirected page, click the three dots next to **Uninstall** and choose **Get started**.
10. You'll be taken to a page with a **Link an incident.io organization** button. Click it to go to the incident.io dashboard.
11. Verify the incident.io organization you'd like to connect is correctly selected, then hit **Connect**.
# Confluence required permissions
Source: https://docs.incident.io/integrations/confluence-permissions
Grant incident.io just the Confluence access it needs to publish your post-mortems automatically.
To utilize our [Confluence integration](/integrations/confluence) to export Post-mortems you need to allow the following permissions for incident.io to create new pages
**View**
* **confluence-content.summary, confluence-space.summary**
* Read a summary of the content, which is the content without expansions. Note, APIs using this scope may also return data allowed by read:confluence-space.summary. However, this scope is not a substitute for read:confluence-space.summary.
* Read a summary of space information without expansions.
**Search**
* **confluence**
* Search Confluence. Note, APIs using this scope may also return data allowed by read:confluence-space.summary and read:confluence-content.summary. However, this scope is not a substitute for read:confluence-space.summary or read:confluence-content.summary.
**Update**
* **confluence-content, confluence-file, confluence-space**
* Permits the creation of pages, blogs, comments and questions.
* Upload attachments.
* Create, update and delete space information.
# Datadog
Source: https://docs.incident.io/integrations/datadog
See the Datadog monitor behind an incident without leaving Slack.
Looking for Datadog SIEM and how to stream audit logs? Please look at our [audit log help article here.](/admin/audit-logs)
## Alerts
If you'd like to automatically create incidents from Datadog monitors, we'd recommend using our Alerts product. To do that, head into the dashboard and choose Alerts in the left hand bar (or open the [Alerts page](https://app.incident.io/~/alerts/sources) directly).
Here, you can create a new alert source using Datadog, which will walk you through a series of steps to create a webhook in Datadog that triggers alerts. Once you've created your alert source and connected it to a route, you should be set to automatically create incidents.
## Legacy Triggers
If you'd like to create incidents directly from Datadog, we'd recommend using the instructions detailed in **Alerts** above.
If you'd rather route Datadog through PagerDuty or OpsGenie to notify someone before creating an incident, you can do that and incident.io automatically pulls through information about any Datadog monitors that triggered the escalation.
This means that when you join an incident channel, everything you need is right there:
* The name of the triggering monitor, with a link to see more
* Up to 500 characters of the body of the trigger monitor. This means you can link things like runbooks in your monitors and have access to them in your incident channel.
* The Alert Priority and Priority of your Datadog monitor
* Any tags on your Datadog monitor
Additionally, we'll record the monitor as an incident.io attachment, so you if you go to the incident homepage on the web, you'll have a link to the monitor there under both the **Attachments** tab, and listed in your **Timeline**.
## How do I set it up?
To get started, you need to first send your Datadog monitors to either PagerDuty or OpsGenie - if you've not done that, you can find instructions on Datadog's site ( [PagerDuty](https://www.pagerduty.com/docs/guides/datadog-integration-guide/), [OpsGenie](https://docs.datadoghq.com/integrations/opsgenie/) ).
Once you've installed those integrations, you can tag whichever service you want inside a Datadog monitor using something like `@pagerduty-growth-team`. This will mean that when your monitor triggers, you'll page the service you've tagged.
The final piece to set up is to configure incident.io to trigger incidents when a PagerDuty/OpsGenie alert occurs - details on how to do this can be found in our guide on [auto-creating incidents](/incidents/auto-create).
Once you've completed the above steps, that's you! incident.io will now automatically pull through the originating Datadog monitor when an incident is created.
## Pinning messages
In addition to incident.io automatically pulling through Datadog Monitors, you can also pin Slack messages and incident.io will put them on your incident timeline in the dashboard and post-mortems.
This is useful for links to Datadog logs, traces, and dashboards that might have helped you track down the cause of an incident.
Additionally, if you paste in the link to any Datadog snapshots, Slack will unfurl the image, and if you pin that message, incident.io will add the linked image to your timeline.
For more info on pinning items, check out our article on [incident timelines](/post-incident/timeline).
## Screenshots
Finally, incident.io automatically tracks any images that are shared in incident channels. So, if you screenshot a useful graph or trace, and then paste it into your incident channel, that image will automatically be tracked on the incident timeline and will be included in generated post-mortems.
# Scheduling debriefs in a specific calendar
Source: https://docs.incident.io/integrations/debrief-calendar
Keep debriefs landing in the same shared calendar every time, instead of whoever's happens to be scheduling it.
## Why would you use this feature?
It's possible for us to pre-fill the debrief event so that it will be created in a specific Google Calendar.
This means that if you always expect debriefs to be scheduled in a shared calendar such as `Incident debriefs`, we'll default to creating the event in that calendar rather than the calendar of the user who's scheduling the event.
## How do I set it up?
In order for this to work successfully, your responders need to have:
1. Permission to create events in this calendar
2. Subscribed to this calendar within Google Calendar
## 1. Permissions
To ensure that everyone has the correct permission, you'll need to click the three dots next to your calendar and choose `Settings and sharing`.
Under the `Share with specific people or groups` section, hit `Add people or groups`. Then you can choose a user group (such as `engineering@incident.io`), and you'll need to select the `Make changes to event` permission from the dropdown.
## 2. Subscriptions
Unfortunately every user needs to subscribe to this calendar manually. We prompt users to do this when they click `Schedule debrief` from within our app. We'll point them to [instructions for subscribing and checking permissions](/integrations/calendar-events) to get set up.
# Customising your debrief invitees
Source: https://docs.incident.io/integrations/debrief-invitees
Automatically invite the right people to every debrief, without hunting down email addresses each time.
[Running an incident debrief](/post-incident/debriefs) is often a helpful way to make sure that everyone is on the same page. You might go over your post-mortem, ensure that you've recorded all follow-up tasks, or distilled and shared any important learnings.
But how do you know who to invite?
This might vary based on the size and impact of your incident but it could include people directly involved in the incident, members from the teams of services that were affected, and any senior execs that express an interest.
You can set up custom rules to automatically invite the right people to your debrief based on incident fields, custom fields, and even data you keep in your catalog.
This helps avoid having to remember who to invite, what teams were affected, and manually typing in their emails each time to the calendar invite.
## Adding an invitee
To set up automated lists of invitees for your debriefs, [navigate to the debrief settings page](https://app.incident.io/~/settings/debriefs).
By default, we'll add the active responders from the incident to your debrief. You can edit this or add additional invitees using the `Add invitee` button.
When adding an invitee you can choose for them to be invited only under certain conditions. For example, you might only want to invite the team leads for a critical incident:
The invitees can be the active participants in the incident, observers, particular roles or even custom expressions and fields that return a list of users.
If you cannot find the user within our system, you can alternatively type a raw email address by clicking `Enter email(s) instead`. This is handy for group / team emails which may not appear in the users list:
If you use [the catalog](https://incident.io/catalog) (and you're missing out if you aren't!) this can become very powerful. You could invite all the team leads of components or features that were affected - like in the above example - all powered by your own custom catalog entries.
To add your own expression just click `Use variable`.
In the below you can see how (with a few catalog entries configured) you might want to select the team leads of any service affected by the incident:
Once created you will see your new entry in the list of invitees and any conditions that apply to that list:
## Creating a debrief with invitees
Once you're set up - you can create a debrief by clicking **Schedule a debrief** from the incident homepage. This will take you to a pre-filled event in Google Calendar.
Here we have 2 guests added who were active participants in the incident and our custom group email - all automatically added for us, neat!
If you install our [Google Calendar integration](/integrations/google-calendar), we'll automatically attach this event for you when you hit `Save`, so everyone will know when it is.
# Debrief placeholders
Source: https://docs.incident.io/integrations/debrief-placeholders
Save responders the hassle of hunting for a free slot by pre-booking regular debrief time on everyone's calendar.
By default, we help responders schedule a debrief by pushing them to a pre-filled Google Calendar event with the [right people on the invite list](/integrations/debrief-invitees). This means that a responder is responsible for finding a time that works for everyone, using the Google Calendar interface.
If your attendees are on different timezones, or have very busy schedules, this can be tricky to do. You might want to pre-emptively invite everyone to regular placeholder events to keep time available for debriefs. If you don't have any incidents that require a debrief, then great, everyone gets the time back!
## How does it work?
Let's say you've followed the instructions below to get set up. When a responder clicks the `Schedule debrief` button from the incident homepage, they'll be presented with upcoming placeholders that are available:
If a debrief is already scheduled during a particular placeholder, you won't see it in this list.
Once the responder chooses the best option, we'll schedule the event for you, using your default title and description etc. The event will get attached to the incident immediately, so everyone knows when it is. Neat!
If you ever need to schedule a debrief outside one of these placeholders, you can still do that by hitting the `Schedule manually` option.
## How do I get set up?
Debrief placeholders are an **Enterprise** feature.
Here, we've provided instructions for getting set up if either: A. You have an existing placeholder you want to use
B. You want to create a new placeholder
## A. How do I use my existing placeholder event?
#### 1. Step 1: Subscribe to the calendar which holds the placeholder
Note the calendar which holds your placeholder event:
Then add this as a subscribed calendar within our app following the instructions in [Google Calendar](/integrations/google-calendar).
#### 2. Step 2: Make sure your event meets the requirements
For us to recognize that the event is a placeholder, it must:
* Be a recurring event (e.g. it repeats weekly / monthly / etc)
* Contain `#incident-io-debrief-placeholder` in the event description
Once you've made these changes, you should notice the event appear in the `Placeholders` section on the [Settings → Debriefs page](https://app.incident.io/~/settings/debriefs).
Then you're good to go! You'll now see the time-slot options for this placeholder when scheduling a debrief.
## B. How do I create a new placeholder?
#### 1. Step 1: Subscribe to the calendar you want to create the placeholder in
If you know what calendar you'd like your repeating event to exist in, you'll need to add it as a subscribed calendar within our app, by following the instructions in [Google Calendar](/integrations/google-calendar).
#### 2. Step 2: Create the placeholder
We can help you create a placeholder event. Just choose `Add placeholder ` from the [Settings → Debriefs page](https://app.incident.io/~/settings/debriefs) and click **Create with Google Calendar**.
We'll take you to a Google Calendar event which has been pre-filled with some information:
You'll need to:
* Pick the calendar you want the placeholder to be created in, using the dropdown
* Ensure that the event repeats on a frequency that suits you (e.g. weekly / monthly)
* Fill in any other details, like the time, guests, location and description
* Ensure that `#incident-io-debrief-placeholder` stays in the description
Once you've created the placeholder event, you should notice it appear on the [Settings → Debriefs page](https://app.incident.io/~/settings/debriefs).
Then you're good to go! You'll now see the timeslot options for this placeholder when scheduling a debrief.
# GitHub
Source: https://docs.incident.io/integrations/github
Link pull requests to incidents and keep follow-ups moving, without leaving GitHub.
Are you using GitHub for version control, or to track your team's tasks?
You should consider installing our integration
***
## What our GitHub integration can do
Our integration lets you:
### 1. Export your incident to-dos to GitHub
You can export your follow-ups to GitHub. We'll sync the status of your tasks, so you can work in GitHub without worrying about updating statuses manually in incident.io!
You'll see the option to export your follow-ups from the incident homepage:
You can also create export templates and [automatically export follow-ups](/integrations/auto-export-follow-ups). In your templates, you can use expressions to set GitHub labels dynamically, for example tagging follow-ups by team or priority.
#### 2. Attach GitHub pull requests to incidents
When you drop a link to a GitHub PR in your incident channel, we'll ask if you want to add it as an [attachment](/incidents/attachments). Once it's attached, we'll notify the channel about changes to that PR, for example if it gets merged.
***
## Setting Up
Adding GitHub to incident.io is simple.
1. **Go to Settings** → [Integrations](https://app.incident.io/~/settings/integrations)
Hit `Connect` next to GitHub.
2. **Install incident.io**
*Your GitHub account* **must be an Organization** *(not a personal account). Enterprise customers can connect multiple organizations. [Get in touch](mailto:support@incident.io) to set this up.*
That's it!
**GitHub Enterprise Server** and **multiple GitHub organization** support are available for enterprise customers. [Get in touch](mailto:support@incident.io) to get set up.
If you run into any issues, [get in touch](http://incident.io/community)
# GitLab
Source: https://docs.incident.io/integrations/gitlab
Keep follow-ups, merge requests, and incident updates in sync with GitLab.
## What our GitLab integration can do
1. **Export** [your incident follow-ups](/post-incident/follow-ups) **to GitLab**
You can export your follow-ups to GitLab. We'll sync the status of your tasks, so you can work in GitLab without worrying about updating statuses manually in incident.io!
Use [auto-export follow-ups](/integrations/auto-export-follow-ups) to make sure all your follow-up tasks are tracked in GitLab
You'll see the option to export your follow-ups from the incident homepage:
2. **Link GitLab issues to your follow-ups.**
You can copy the reference of issues you already have and link them back to your incident.io follow-ups.
3. **Attach GitLab Merge Requests to incidents from Slack**
You can attach GitLab MRs to your incident directly from the incident channel.
4. **Attach GitLab MRs to incidents from GitLab**
You can also attach an MR by mentioning the incident number in the MR title or source branch.
5. **Post comments on GitLab issues via workflows**
Use [workflows](/workflows/getting-started) to automatically post internal comments on GitLab issues as incidents progress, keeping your team informed directly in GitLab.
## Setting Up
Adding GitLab to incident.io is simple.
You'll need a GitLab top-level group owner to perform some of these steps.
#### 1. Create a Service Account user in GitLab
Follow [GitLab's guide to creating a service account](https://docs.gitlab.com/ee/user/profile/service_accounts.html#create-a-service-account).
We recommend using 'incident.io' for the `name`, since this will show up in the UI on issues and comments created by the integration.
Make sure the bot user has access to create and edit issues, and view and comment on merge requests in all relevant projects.
We recommend assigning the `Reporter` role to your incident.io service account user.
If connecting the GitLab integration for Investigations you should instead assign the `Developer` role. This allows Investigations to open Merge Requests when users request it.
See GitLab.com: [Permissions and roles](https://docs.gitlab.com/ee/user/permissions.html)
#### 2. Create a Personal Access Token
Follow [GitLab's guide here](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-service-account-personal-access-token-with-no-expiry-date).
For **scopes** the integration requires the `api` scope.
After generating the token, make sure to copy the token value for the next step!
#### 3. Connect the integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), click on GitLab, then Connect.
Paste in the access token created in step 2. and click **Connect**. That's it
For GitLab users to connect with their incident.io accounts, their GitLab public email must:
1. Match their incident.io user email
2. Be visible on their GitLab profile
If you're using self-managed GitLab, how you connect depends on where your instance runs:
* **Reachable from the internet**: make sure traffic from [our IPs](/integrations/ip-allowlist) can reach your instance.
* **Private network**: route our requests through a [proxy](/integrations/proxy) instead of exposing the instance.
#### Next up
We recommend adding a Group Hook in GitLab, which allows us to sync changes in GitLab back to incident.io. Read our [setup guide here](/integrations/gitlab-group-hook).
If you run into any issues, [get in touch](https://incident.io/community)
# Setting up a GitLab Group Hook
Source: https://docs.incident.io/integrations/gitlab-group-hook
Keep GitLab and incident.io in sync in real time, not just once a day.
We rely on a GitLab Group Hook to enable:
1. **Syncing changes to follow-ups in GitLab back to incident.io**
2. **Linking merge requests to incidents automatically** when you mention the incident reference (e.g. `INC-123`) in a merge request.
3. **Posting updates to merge requests in the incident channel**, for example when a linked MR is merged.
## Setting up
You'll need a GitLab Group Owner to do this setup.
#### 1. Find your secret token
Under [Settings → Integrations → GitLab](https://app.incident.io/~/settings/integrations/gitlab), you'll find a unique secret token. Copy this down - you'll need it to successfully configure the hook.
#### 2. Create the hook
Within your top-level group, click **Settings** then **Webhooks** :
Then **Add new webhook**.
For the **URL** use `https://app.incident.io/webhooks/gitlab`.
For the **Secret token**, paste in the secret token from the incident.io dashboard.
Under **Trigger**, select:
**Work item events** (or **Issues events** on older GitLab versions; the screenshot below shows the older label)
**Merge request events**
Everything else can be left as the default. Click **Add webhook**.
#### 3. Verify the connection
In [Settings → Integrations → GitLab](https://app.incident.io/~/settings/integrations/gitlab), you can see when the last webhook was received. Make a small change to an issue to trigger a webhook:
**You're all set**
# Google Calendar
Source: https://docs.incident.io/integrations/google-calendar
Keep meetings connected to the right incident automatically, without anyone pasting in a link.
Looking to see holidays from Google Calendar in your on-call schedules? You can set that up using [calendar feed subscriptions](/on-call/holidays)
Sometimes, you need to schedule meetings related to your incident. Perhaps a war room for everyone to sync their findings whilst an incident is ongoing, or a debrief about what happened once the incident is resolved.
Our Google Calendar integration lets you attach events to an incident, and pulls through relevant information about when it is and who is attending.
***
## Installation
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Google Workspace connections like this, which use OAuth, belong to a specific user. For this reason, you must [set up a dedicated service or "bot" account](/integrations/google-service-account). We use the same user account connection for all our Google integrations. Therefore, the account you use to connect this integration will need to be the same for Google Meet (which we will connect automatically for you after you connect Calendar) and Google Docs (which requires a separate installation).
## 1. Installing the integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Google Calendar** and click **Install**.
Click **Install** and you'll be redirected to the installation flow within Google Workspace. Review the permissions we're requesting and click **Next**.
Once you've completed the Google authentication flow, you'll be redirected back to incident.io.
## 2. Adding a subscribed calendar (optional)
Our integration works by listening for events that invite the connected user OR are created within a specific Google calendar, and attaching them if they're related to an incident.
Therefore, you can declare which calendars you'd like us to additionally look for events in (even if they don't invite the connected user), for example: `Engineering Shared Calendar`.
**Important** : you will need to make sure that the account used to set up your integration in **Step 1** also has access to this shared calendar. See [Share your calendar with someone](https://support.google.com/calendar/answer/37082) for more details about sharing permissions.
To find the Calendar ID ( [why this?](#faqs) ) of your chosen calendar(s):
1. Head to [Google Calendar](https://calendar.google.com/)
2. Under **My calendars** or **Other calendars** in the left sidebar, find your chosen calendar, click the three dots and select **Settings and Sharing**.
3. Copy the **Calendar ID** from the **Integrate Calendar** section.
4. Paste it into the "Add calendar" section of the [Google Calendar configuration page](https://app.incident.io/~/settings/integrations/google_calendar).
Note that if you want us to always create debrief events in one of your subscribed calendars, you can set this up from the [debrief settings](https://app.incident.io/~/settings/debriefs) page. Read more about this in [scheduling debriefs in a specific calendar](/integrations/debrief-calendar).
***
## What happens next?
Now that you're all set up, you just need to create an event in Google Calendar which:
1. Has the **incident identifier** (e.g. INC-123) in the title or description
2. Invites the **connected user** or is created within one of your **subscribed calendars**
When this happens, we'll automatically attach the event to your incident and message the relevant incident Slack channel:
If you identify the incident as a [debrief meeting](/post-incident/debriefs) (i.e. a catch-up after the incident has been resolved), we'll additionally let the channel know when it's happening and who's invited:
Note that if you include the word "debrief" in the event (or whatever your preferred name for this term is, according to your [debrief settings](https://app.incident.io/~/settings/debriefs) ), we'll automatically attach the event as a debrief without prompting you first.
***
## Can I undo this?
If we automatically attach an event which should not be linked to your incident, you can unlink it by heading to the attachments tab on the incident homepage, and clicking the unlink button:
If we identify a meeting as a debrief when it isn't, you can undo this from the overflow on the `Debrief scheduled` message from Slack or from the sidebar on the incident homepage:
***
## One last thing
Did you know that we can help with creating your debrief meeting? We can build a Google Calendar event which has been pre-filled with the incident participants and other useful information - you just need to fill in the rest.
Once your incident has been resolved, you'll notice a new option to `Schedule a debrief` from the sidebar:
This will take you to a pre-populated Google Calendar event. You just need to choose a time and hit save:
## FAQs
Our Google Calendar integration listens for relevant meetings created within Google calendars we're subscribed to. Simply referencing an incident ID (e.g. `INC-108`) in a meeting title or description attaches the meeting to that incident.
To set this up, we need the ID of the Google calendar so we can create the subscription and listen for new events. We deliberately took this path to protect your privacy and limit the permissions we request from your Google account: the only permission we need is `https://www.googleapis.com/auth/calendar.events`, which lets us read event details in a specific calendar and create new events (e.g. generating a Google Meet call when an incident is created).
This keeps it in your control which calendars we look at for incident-related events, rather than us checking every calendar the connected user is subscribed to.
# Debriefs: Google Calendar Permissions
Source: https://docs.incident.io/integrations/google-calendar-debrief-permissions
Fix calendar permission errors that stop incident.io detecting or scheduling your debriefs.
As part of our Google Calendar integration, you can subscribe to calendars. This allows incident.io to detect relevant debrief meetings for your incidents, and schedule an incident's debrief meeting using a placeholder timeslot.
Both of these pieces of functionality require the connected user, the account which was used to add the Google Calendar integration, to have the correct level of access to the subscribed calendar.
A **No read access** badge is shown on the [Settings → Integrations → Google Calendar → Subscribed calendars](https://app.incident.io/~/settings/integrations/google_calendar) section if an incorrect access level is currently configured.
This help article walks you through configuring the correct level of access for your subscribed calendar.
## Permissions
Google Calendar allows calendars to be shared with specific people or groups, using one of the four following **access levels** :
1. See only free/busy (lowest access level)
2. See all event details
3. Make changes to events
4. Make changes and manage sharing (highest access level)
You can make changes to a calendar's permissions by going to **Google Calendar**, selecting the calendar in the left-hand sidebar, selecting **Settings and sharing**, then navigating to the **Share with specific people or groups** section. You'll need to add the connected user to this list.
## Requirements
### Debriefs
For incident.io to be able to detect debriefs that relate to an incident, the connected user must have at least the **See all event details** access level or higher; this is shown within the dashboard as **Read access**.
### Placeholders
For incident.io to be able to schedule a debrief for an incident within a placeholder timeslot, the connected user must have at least the **Make changes to events** access level or higher; this is shown within the dashboard as **Read & write access**.
# Google Docs
Source: https://docs.incident.io/integrations/google-docs
Export post-mortems to Google Docs, keeping write-ups where the rest of your team already works.
After your incident is over, it can be useful to dig into what happened in an incident, why, and how it can be prevented in future.
Our Google Docs Integration allows you to export post-mortems into Google Docs. Which you can then use to collaborate with your team.
***
## Installation
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Google Workspace connections like this, which use OAuth, belong to a specific user. For this reason, you may wish to set up a dedicated service or "bot" account. We use the same user account connection for all our Google integrations. Therefore, the account you use to connect this integration will need to be the same for Google Meet and Calendar.
## 1. Installing the Integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Google Docs** and click **Install**.
Click **Install** and you'll be redirected to the install flow within Google Workspace. Review the permissions we're requesting and click **Next**.
Once you've completed the Google flow, you'll be redirected back to incident.io:
## 2. Setting up a post-mortem destination
incident.io has now been connected to Google Docs. Next, we need to specify where in your Google Drive you'd like to export post-mortems to.
Go to [Settings → Post-mortems](https://app.incident.io/~/settings/post-mortem), then click **Add destination**
Within your web browser, navigate to the folder in Google Drive where you'd like to export post-mortems to. This should look like:
```plaintext theme={null}
https://drive.google.com/drive/folders/1OLTvX7Ak7Z03...
```
Paste the link in, give it a sensible name, and click **Create**.
You should now be good to go!
# Google Meet
Source: https://docs.incident.io/integrations/google-meet
Give responders an instant call to join the moment an incident is declared, with no manual setup.
We can automatically create an individual Google Meet call whenever an incident is declared, and attach it to the incident.
This helps speed up your incident response, and reduces the burden of manual tasks on responders.
## Installation
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Google Workspace connections like this, which use OAuth, belong to a specific user. For this reason, you may wish to set up a dedicated service or "bot" account. We use the same user account connection for all our Google integrations. Therefore, the account you use to connect this integration will need to be the same for Google Calendar (which we will connect automatically for you after you connect Meet) and Google Docs (which requires a separate installation). Make sure the user has the following privileges in [admin.google.com](https://admin.google.com/) :
* Read and write calendar events
* Read users
Additionally Google requires the user to be an admin user. However, you should be able to restrict what the service account is able to do just like any custom role in Google Workspace. This can all be done via [admin.google.com](https://admin.google.com/).
## 1. Installing the Integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Google Meet** and click **Install**.
Click **Install** and you'll be redirected to the install flow within Google Workspace. Review the permissions we're requesting and click **Next**.
We request Google Calendar scopes, in order to create a Google Calendar meeting that has a Google Meet video call attached.
## 2. Turn on auto-create call
Click **Configure** next to Google Meet on the integrations page, and enable auto creating an incident call
You should now be good to go!
# Using a service account to integrate with Google
Source: https://docs.incident.io/integrations/google-service-account
Keep calendar invites, meetings, and documents from being tied to any one person's Google account.
You may have noticed when setting up an integration with Google that we strongly recommend using a dedicated service account rather than your own user account - but what is a service account, why do you need one, and how do you set one up?
## What are service accounts?
Service accounts, also known as robot accounts, are accounts specifically created to act within a limited capacity and often for a single purpose. They usually have an obvious name that highlights them as a non-human account. Something like `incidentio-robot@yourdomain.com` is usually good!
They are not tied to a single real user and are often created with limited permissions compared to what you would normally allow a user to do.
In the context of incident.io, the service account is the account you will give us permissions to use or act through for things like [creating calendar events](/integrations/google-calendar), [meetings and calls](/integrations/google-meet), and post-mortem documents.
We don't currently support private key authentication for service accounts, you'll therefore need to ensure that you're able to sign in with Google using OAuth 2.0 as the service account user.
## Why do I need one?
You might be tempted to just sign in using your own account or another user's when you click to set up the integration, but there are some very good reasons why you would want to avoid doing so.
When the connection is made and the integration installed, it will **belong to the user that installed it**. If the installing user leaves the organization or changes their settings, this can lead to the integration breaking and needing to be re-installed (and preventing us from doing anything in the meantime!).
In the case of calendars, we use the connected user's calendar to monitor and create calendar events. If you signed in as yourself, we will potentially create calendar events for debriefs in your calendar, along with inviting your user to every meeting! You can see why this might start to be inconvenient.
## What will the service account have access to?
A single account will be used for Google Meet, Google Calendar, and Google Docs. *Note: You cannot use separate accounts for each integration.*
**Scope**
* For Google Docs: we need access to `drive.file`
* For Meet + Calendar: we need access to `calendar.events`
## How do I make a service account?
There are a few ways to create new accounts within Google, and it might depend a little on what setup you have.
[This article covers most of the basics, though](https://support.google.com/a/answer/179832?hl=en), and is a good starting point for learning more about how to do it.
At a basic level, you will need to:
* create a new account within your organization
* name it something obvious and simple that highlights it as a robot account
* store the details (such as the password / 2fa key) somewhere secure that can be shared with others, such as a password manager
## FAQs
* **Google Meet**: to read the details of call participants so we can display them in incident channels and the dashboard, we require `https://www.googleapis.com/auth/meetings.space.readonly`
* **Google Calendar**: to create debrief events and invite people to them, we require `https://www.googleapis.com/auth/calendar.events`
* **Google Drive**: to export post-mortems to Google Drive, we require `https://www.googleapis.com/auth/drive.file`
* **Listing users**: to join Google users back to incident.io users (for example, inviting the right "Jane Smith" to a debrief event, or resolving them as a participant on an incident call), we require `https://www.googleapis.com/auth/admin.directory.user.readonly`. This also means your service account needs to be an Admin who can read the directory for these features to work.
* **Transcribing calls**: no additional scopes are required for our Google Meet transcription feature.
# Using the Grafana Integration
Source: https://docs.incident.io/integrations/grafana
Turn Grafana alerts into incidents automatically, with dashboard context on hand when you need it.
## Overview
The Grafana integration allows you to connect your Grafana instance to incident.io to automatically create incidents from Grafana alerts, enrich alerts with organizational context, and attach dashboard screenshots to incidents for faster debugging.
## What you can do with Grafana
Once connected, you can:
* Create incidents automatically from Grafana alerts by setting up alert sources
* Attach dashboard screenshots to incidents to provide visual context during response
* Enrich alerts with attributes using labels on your Grafana alert rules to map to services, teams, and other catalog types
* Sync telemetry dashboards to your incident.io catalog for easy reference
***
## Connecting Grafana to incident.io
**Prerequisites**
Before connecting, you'll need:
1. Grafana API URL - The hostname of your Grafana instance (e.g., [acme.grafana.net](http://acme.grafana.net/) )
2. API Key - A Grafana API key with the following permissions:
3. Read permissions for dashboards and folders
4. For older Grafana versions: Dashboard modification permissions
**To create an API key in Grafana:**
1. Navigate to Configuration > API Keys in Grafana
2. Click Add API Key
3. Give it a descriptive name like "incident.io Integration"
4. Set it to Admin role (or at minimum, read access to dashboards)
5. We recommend creating a non-expiring key to avoid connection issues
**Connection steps**
1. In incident.io, go to Settings > Integrations
2. Find Grafana and click Connect
3. Enter your Grafana API URL and API Key
4. Click Connect to Grafana
Once connected, incident.io will validate the connection by attempting to access your Grafana instance.
***
## Setting up Grafana alert sources
Alert sources allow you to automatically create incidents from Grafana alerts.
**Creating an alert source**
1. Go to Settings > Alert Sources in incident.io
2. Click Create Alert Source
3. Select Grafana as the source type
4. Configure your alert source settings (name, routing rules, etc.)
5. Copy the webhook URL provided (it will look like `https://api.incident.io/v2/alert_events/grafana/{alertSourceId}`)
**Configuring Grafana to send alerts**
1. In Grafana, navigate to Alerting > Contact points
2. Click Add contact point (or edit an existing one)
3. Select Webhook as the type
4. Paste the incident.io webhook URL
5. Under Authentication, select Bearer Token and paste the token provided by incident.io *Note: For older Grafana versions, you may need to use HTTP Basic Auth instead*
6. Save the contact point
**Alert grouping options**
When configuring your alert source, you can choose how Grafana alert groups map to incident.io alerts:
* One alert per group (recommended) - Creates a single incident.io alert for each Grafana alert group, keeping related alerts together
* Individual alerts - Creates separate incident.io alerts for each alert within a Grafana alert group
***
## Enriching alerts with tags
You can tag your Grafana alert rules with labels that map to incident.io catalog types (like services, teams, or custom catalog types). This automatically enriches your incidents with the right context.
**Adding tags to Grafana alerts**
1. In Grafana, edit your alert rule
2. Add labels in the format `{catalog-type-name}` with the value being the catalog entry name
*Example: Add a label service with value payment-api*
1. When this alert fires, incident.io will automatically:
2. Look up the service catalog type
3. Find the entry named payment-api
4. Attach it to the incident
**Common catalog types to use:**
* service - Link alerts to specific services
* team - Route to the right team
* Any custom catalog types you've created in incident.io
***
Still got questions? Reach out to [support@incident.io](mailto:support@incident.io) or message us in your Slack Channel!
# Intercom app for status pages
Source: https://docs.incident.io/integrations/intercom
Let customers check your service status from inside Intercom, cutting down repetitive support questions.
## Overview
If you’re an Intercom customer that’s using our status pages, you can now keep your customers informed by showing real-time status updates from your status page directly in the Intercom Messenger.
Customers can also directly subscribe to updates inside of Intercom Messenger, so they always know your service status without needing to ask. This reduces the number of questions about your system's status, allowing your support team to focus on more complex issues.
Your support staff can also check system health directly from your internal Intercom Support Inbox, making it easy for your team to stay updated with what’s happening on your status page and improve customer satisfaction.
## Getting started
To get started, head over to [Settings > Integrations](https://app.incident.io/~/settings/integrations) to connect your Intercom account.
Next, on the Intercom side, go to Settings > Channels > Messenger > Web, hit **Customize Home with apps** and add incident.io.
# Requesting Additional GitHub Permissions
Source: https://docs.incident.io/integrations/investigations-github-permissions
Give Investigations the GitHub access it needs to help pinpoint the code change behind an incident.
[Investigations](https://incident.io/investigations) requests an additional permission on your GitHub app: **Contents: Read**.
This powers Investigations' ability to find problematic code changes that might've caused an incident, and suggest them in the incident channel as a possible root cause. To do that well, it needs to see the contents of pull requests.
**You don't have to accept the new permissions**
If you don't want to accept this new permission, it's completely fine to deny the request.
Your GitHub integration will not be affected in any way - it will work just like it does now!
If you have any questions at all, please drop us a line at [support@incident.io](mailto:support@incident.io).
# Allowlisting IP addresses for VCS/on-premise integrations
Source: https://docs.incident.io/integrations/ip-allowlist
Give incident.io access to on-premise or IP-restricted systems without opening them up to the wider internet.
When communicating with on-premise services e.g. Jira Server, or other services which may enforce IP-allowlisting (e.g. Gitlab or GitHub), we use specific IP addresses.
Some services, when run in an on-premise or enterprise SaaS configuration, encourage you to use IP addresses to filter traffic from unknown sources, however we strongly recommend that you use additional strategies to secure your instance, including SSL/TLS.
## IP addresses
The following IP addresses are currently used:
```plaintext theme={null}
34.91.219.113
34.32.171.26
146.148.114.148
104.155.67.8
```
If using our **Investigations** product, access must be allowed from **additional** IP addresses:
```plaintext theme={null}
34.52.216.178
34.140.142.231
35.204.31.148
35.204.114.23
```
## Further information
All IP addresses stated above are reserved solely for incident.io application usage only, and not shared with other organizations or infrastructure.
We will send **notice 2 weeks in advance** of any changes to this list, to all customers using an integration dependent on these addresses.
All requests from incident.io to on-premise integrations are made using secure cryptography to protect data in transit.
To ensure changes to follow-ups in **Jira Server** specifically sync back to incident.io, you'll need to register a webhook. Learn how to [register a Jira Server webhook](/integrations/jira-server-webhook).
# Jira
Source: https://docs.incident.io/integrations/jira
Keep incident tickets and follow-ups in step with your planned work in Jira.
incident.io integrates with Jira so you can colocate follow-ups of incidents with your teams’ planned work.
***
## What we can do with Jira
There are 2 main features incident.io supports with Jira:
## Exporting follow-ups as Jira tickets
With Jira connected to incident.io you can export follow-ups via the web dashboard and our Slack/MS Teams apps. Information on the ticket such as its title, assignee, and completion is synced back to incident.io, updating the corresponding follow-up.
You can also configure this to have them **automatically exported** based on attributes of an incident. This ensures that tickets are created in the right Jira projects without incident responders having to think about it.
## Syncing incidents to Jira
When enabled, a Jira ticket will be created to represent each incident in Jira. We automatically sync the incident ticket when the incident is changed in incident.io.
Just like auto-exporting follow-ups, you are also able to configure exactly which Jira projects to create tickets in based on an incident’s attributes.
If an incident has a Jira ticket associated with it, we will mark it as related to any exported follow-ups.
***
## Setting up
We connect to Jira as a specific user. That means that actions taken by incident.io in Jira will show up as by the connecting user.
We therefore recommend you create a Jira user called something like "incident.io", and sign in to Jira with that account before you begin (you can remain signed in to incident.io as your usual account!)
1. Head to [Settings → Integrations → Jira](https://app.incident.io/~/settings/integrations/jira)
2. Click on **Connect**: you'll be redirected in to Jira to approve our access
If you run into any issues, [get in touch](http://incident.io/community)
We also support Jira on Atlassian GovCloud. The setup process is the same as for standard Jira Cloud instances.
## Enabling multiple Jira sites
Depending on your billing plan, you may be able to enable multiple Jira sites to be used in incident.io , allowing incident.io to create tickets in multiple Jira sites.
You can do this by clicking on the edit button next to the site name in the Jira integration settings page, where you will be able to enable more sites.
If you don’t see the desired sites, click **Connect another site** to authorize access to additional sites.
Note that if you've previously used Atlassian Connect, you'll need to disconnect all sites and reconnect via OAuth, due to [Atlassian ending support for Connect at the end of 2026](https://www.atlassian.com/blog/developer/announcing-connect-end-of-support-timeline-and-next-steps).
## FAQs
Yes, Components are treated as optional fields within your template.
# How to export follow-ups to Jira Cloud
Source: https://docs.incident.io/integrations/jira-follow-ups
Turn incident follow-ups into Jira tickets your team can track through to completion.
Follow-ups are a really important part of any incident management process, and with incident.io, you can export any remaining follow-ups to issue trackers, such as Jira Cloud.
After you've [integrated your incident.io account with your Jira Cloud account](/integrations/jira), navigate to [follow-ups within the dashboard](https://app.incident.io/~/follow-ups), here you'll be able to see any outstanding and completed follow-ups from incidents you've had. You'll also be able to see if anyone has been assigned the follow-up to complete.
Even better, if someone marks a follow-up as completed in Jira, the follow-ups dashboard in incident.io will reflect this, and vice versa.
## Exporting single follow-ups
With your follow-ups dashboard, you can export single follow-ups as new tickets or connect them to existing tickets and choose which project they are exported to.
If you're creating a new ticket, you can assign it to yourself, or someone else, as well as giving them a description.
## Connecting follow-ups to existing Jira tickets
Instead of creating a new ticket, you can connect a follow-up to an existing ticket, helping folks close the loop.
This can also be done by simply pasting a link to the Jira ticket in the incident's slack channel.
*Note: You can only link existing Jira issues that don't have a status of Done*
## Setting "paragraph" custom fields in Jira when exporting follow-ups
* If you're manually exporting follow-ups, you'll be prompted to enter a value for the "paragraph" field during the export process.
* For automatic follow-up exports, you can configure the field to populate based on incident properties when you set up your export template.
***
# Jira required permissions
Source: https://docs.incident.io/integrations/jira-permissions
Know exactly what access Jira needs before you connect it to incident.io.
Permissions required to utilize our [Jira Integration](/integrations/jira) to create Jira issues, keep them synced, and read custom field values to utilize in Jira Export templates.
* **Manage**
* **jira-webhook**
* Register and manage Jira webhooks.
* **View**
* **jira-user, jira-work**
* View user information in Jira that the user has access to, including usernames, email addresses, and avatars.
* Read Jira project and issue data, search for issues, and objects associated with issues like attachments and worklogs.
* **Update**
* **jira-work**
* Create and edit issues in Jira, post comments as the user, create worklogs, and delete issues.
# Jira Server and Data Center
Source: https://docs.incident.io/integrations/jira-server
Keep incident tickets and follow-ups in step with your planned work in self-hosted Jira.
The Jira Server integration works with self-hosted Jira, covering both Jira Server and Jira Data Center. It's separate from the [Jira](/integrations/jira) integration, which connects to Jira Cloud.
Connect using [basic authentication](#basic-authentication) or an [application link](#application-link) from **Settings → Integrations → Jira Server**. Once connected, export follow-ups as Jira issues, create tickets to represent incidents, and use Jira projects, users, and priorities in your catalog.
***
## Prerequisites
Before you start, make sure you have:
* **Jira administrator access**, to create the application link or the service account.
* **A route from incident.io to your Jira instance**. See [Network access](#network-access) for the options.
## Choose an authentication method
| Method | What it needs | Choose it when |
| ---------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Basic authentication | A Jira service account, and its username and password | You want the quickest setup, and you're happy for us to store the account's credentials |
| Application link (OAuth 1.0) | An incoming application link in Jira, created by an administrator | You'd rather we didn't store credentials, or your Jira has password authentication turned off |
### Basic authentication
incident.io acts as the service account in Jira, so anything it does shows up as that user. Give the account permission to browse projects, and to create, edit, assign, and link issues in the projects you plan to use.
1. Select **HTTP Basic Authentication**
2. Enter your Jira base URL, then the service account's username and password
### Application link
An application link authenticates with OAuth 1.0 and avoids storing a set of credentials in incident.io. The connect dialog generates a consumer key and public key for your account, which you paste into Jira when you create the link.
1. Select **Application Link (OAuth 1)** and follow the steps shown, which include the values to paste into Jira
2. Enter your Jira base URL and select **Connect** to authorize the link in Jira
## Sync changes back from Jira
Register a webhook in Jira so updates to exported issues reach incident.io quickly. See [Setting up a webhook in Jira Server](/integrations/jira-server-webhook).
## Network access
How you connect depends on where your Jira runs:
* **Reachable from the internet**: allow inbound traffic from [our IP addresses](/integrations/ip-allowlist).
* **Private network**: route our requests through a [proxy](/integrations/proxy) instead of exposing the instance.
* **Internal certificate authority**: paste your CA certificate into the connect dialog so we trust the certificate Jira presents.
# Setting up a webhook in Jira Server
Source: https://docs.incident.io/integrations/jira-server-webhook
Get status changes in Jira Server back into incident.io in real time, not on a delay.
Registering a webhook in Jira Server means that changes to follow-ups that have been exported to Jira will sync back quickly.
You'll need to be a Global Administrator in Jira to register a webhook.
## 1. Navigate to System → WebHooks
In Jira, use the cog menu in the top-right to enter System settings.
You may need to enter your password to enter 'administrator mode'.
Near the bottom of the left-hand menu, select **WebHooks** under **Advanced**:
Near the top-right, click **Create a WebHook**:
## 2. Configure the destination
**Name** : 'incident.io'
**Status** : Enabled
**URL** : Check [Settings → Integrations → Jira Server](https://app.incident.io/~/settings/integrations/jira_server) to find your webhook URL
**Description** : Leave blank
## 3. Add events
Under **Issue related events**, check **issue created**, **issue updated**, **issue deleted**, **issue link created** and **issue link deleted**.
All other events can be left disabled.
If you configure a JQL filter here, incident.io will only be able to sync updates to issues matching that filter.
## 4. Create the webhook
At the bottom of the page, ensure **Exclude body** is **not** checked, and click **Create**.
## You're all set up!
If your Jira Server is behind a firewall, you'll need to ensure that the firewall allows outbound traffic to `app.incident.io`. Please contact your customer success manager if we can help with this.
# Syncing incidents with Jira
Source: https://docs.incident.io/integrations/jira-sync
Give every incident a single Jira ticket that stays up to date automatically.
You might be aware that you can [export follow-ups to Jira](/integrations/jira-follow-ups) but did you know that you can automatically create tickets representing an incident too?
Often it can be hard to keep track of which tickets or follow-ups relate to which incident, or have a central place in your project tracking where you can add comments and extra information.
By having a single incident ticket created automatically you can attach, link, and refer back easily back to this one ticket. We will also keep fields and variables in sync and update the ticket with the latest information.
You can also use templates and conditions to create different tickets in different projects depending on custom fields, and incident types within incident.io.
## Getting started
To get this set up, follow the [setup process](/integrations/jira) and once connected head to [Settings → Incident tickets](https://app.incident.io/~/settings/incident-tickets).
You may not have a default template - before you can save, you will need to add a template and potentially any conditions you wish to match against.
## Creating and editing templates
When we sync information about an incident with Jira we will need to know what project, issue type, and any required fields to use when we create it.
By filling out the template you can specify any required and optional fields along with the ticket description itself using either static text or fields powered by our variables.
This gives you the flexibility to show more or less in the description for certain incidents. For example you might want a completely different set of information for a maintenance event vs a critical incident.
You can create multiple templates (depending on your billing plan) and use conditions to select which one to use in certain circumstances. This will allow you to route your tickets to different Jira projects based on incident conditions.
## Using conditions
You're now ready to enable **Create tickets**:
If there are no conditions specified we will use the first template in the list and create a ticket for all incidents.
If you only wish to create a ticket for certain incidents, or create tickets in different projects then you'll need to set up some conditions.
For example, if we wanted to use a security template for security type issues we can create the following condition:
And once saved see how it will affect the creation of tickets:
By default if you have created at least one condition we will **not** create a ticket if there is no match.
You can edit this no match fallback behavior to enable always creating a ticket, for example here we fallback to our default template:
## Reusing a Jira ticket from an alert
If you use Jira as an [alert source](/alerts/alert-sources) *and* have incident tickets configured for Jira, an incident created from a Jira alert will **reuse that alert's Jira issue as its incident ticket**, rather than creating a second, duplicate ticket. We then keep that existing issue in sync with the incident just like any other incident ticket.
This happens automatically when all of the following are true:
* The incident was created from a **single** Jira alert. If several Jira alerts are grouped into one incident we can't tell which issue to use, so we create a new ticket instead.
* The alert's issue is in the **same project** that your incident ticket template targets.
* The alert's issue is the **same issue type** that your template targets.
* The issue isn't already linked to another incident or follow-up, and still exists in Jira.
If any of these aren't true, we fall back to creating a new incident ticket from your template as usual.
## Private incidents
If you do wish to create tickets for private incidents you can enable this with the checkbox.
However be aware that anyone with access to the chosen Jira project will be able to see them, so take care.
## FAQs
Direct status synchronization isn't available between incident.io and Jira, but you can work around it using string custom fields and Jira automations:
1. Create a string custom field in Jira to store the incident status.
2. In incident.io's Jira export template, configure the incident status to sync to this string field.
3. Set up Jira automations to update the actual Jira ticket status based on the value in the string field.
Only string, date, and user fields can be synced from incident.io to Jira. Single or multi-select fields in Jira can only be set as hard-coded values in the export template, and other custom fields from Jira can't be dynamically synced from incident.io.
# Linear
Source: https://docs.incident.io/integrations/linear
Route follow-ups and on-call triage straight into Linear, assigned to the right person automatically.
Using Linear to track your team's tasks? Using Linear to *triage* your team's tasks?
This is how you can export [your incident to-dos](/incidents/task-tracking) to Linear to keep everything centralized, *and* automatically assign tasks according to your [incident schedules](/on-call/building-schedules).
***
## What we can do with Linear
### Assign triage tickets automatically
If you use [On-call](https://incident.io/on-call) with incident.io, you can combine this with [Linear's Triage functionality](https://linear.app/docs/triage) to automatically action triage tasks to who is currently on call on your incident.io schedules.
### → Exporting follow-ups
1. **Export** [your incident follow-ups](/post-incident/follow-ups) to Linear;
2. **Sync the status of your tasks between Linear and incident.io**, so you can work in Linear without worrying about updating statuses manually in incident.io!
3. **Bulk Exports through the Follow-ups tab.**
4. **Export templates,** this enables you to pre-set values to fields that can be used when exporting follow-ups.
5. **Auto-exports to Linear,** you can automate the export process of follow-ups based on certain incident criteria, such as severity, and specific custom fields such as responsible teams
... [get in touch](http://incident.io/community) to give us your wishlist!
Follow-ups can be Linear **projects** as well as issues. Set **Create as** to **Project** on an export template, or paste a project URL to connect an existing one.
### Create incident tickets in Linear
You can create incident tickets in Linear, keeping a record of your incidents alongside your team's other work. Incident status can be synced to the Linear ticket using expressions in your template configuration.
An incident ticket can be a project too. When it is, that incident's follow-ups are moved into the project as they're linked, so all of an incident's work lands in one place. A follow-up whose template already sets a project keeps that project.
***
## Setting Up
Adding Linear to incident.io is simple.
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
Hit `Connect` next to Linear.
2. **Log into Linear**
*We currently only support one single Linear workspace*.
3. **Enable a Triage action for your team on Linear**
In `linear.app/settings/teams/your-team/triage`, select `Notify` or `Assign` as a Triage action and click **Use schedule** to pick which incident.io schedule you want to automatically use.
That's it!
## FAQs
* Status, Title, Description, and Assignee will all go from Linear to incident.
* The Title and Description fields will go from incident to Linear.
* Schedule name and times for the next 5 weeks will go from incident to Linear.
* Linear will assign the person which comes from the first rota that is active
* Example: If you have a rota 9am-5pm and a rota 5pm-12am, then we'll return whoever is on shift for each of those. But if you have a first rota that's 24/7, the person on that will always be assigned to the Linear triage tickets.
# Using a service account to integrate with Microsoft Outlook, Teams and SharePoint
Source: https://docs.incident.io/integrations/microsoft-service-account
Keep Outlook, Teams, and SharePoint integrations working even after the person who connected them moves on.
You may have noticed when setting up Outlook, Microsoft Teams for online meetings, or SharePoint, that we strongly recommend using a dedicated **service account** rather than your own user account - but what is a service account, why do you need one, and how do you set one up?
## What are service accounts?
Service accounts, also known as robot accounts, are accounts specifically created to act within a limited capacity and often for a single purpose. They usually have an obvious name that highlights them as a non-human account. Something like `incidentio-robot@yourdomain.com` is usually good!
They are not tied to a single real user and are often created with limited permissions compared to what you would normally allow a user to do.
In the context of incident.io, the service account is the account you will give us permissions to use or act through for things like creating calendar events ([Google Calendar](/integrations/google-calendar) or [Outlook](/integrations/outlook-calendar)), and meetings and calls ([Google Meet](/integrations/google-meet) or [Microsoft Teams](/integrations/teams-meetings)).
## Why do I need one?
You might be tempted to just sign in using your own account or another user's when you click to set up the integration, but there are some very good reasons why you would want to avoid doing so.
When the connection is made and the integration installed, it will **belong to the user that installed it**. If the installing user leaves the organization or changes their settings, this can lead to the integration breaking and needing to be re-installed (and preventing us from doing anything in the meantime!).
In the case of calendars, we use the connected user's calendar to monitor and create calendar events. If you signed in as yourself, we will potentially create calendar events for debriefs in your calendar, along with inviting your user to every meeting! You can see why this might start to be inconvenient.
## What will the service account have access to?
A single account will be used for Outlook Calendar, Microsoft Teams online meetings and SharePoint. *Note: You cannot use separate accounts for each integration.*
**Scopes**
* For Outlook Calendar: we need access to `Calendars.ReadWrite`, `Calendars.ReadWrite.Shared` & `offline_access`
* For Microsoft Teams online meetings: we need access to `OnlineMeetings.ReadWrite` & `OnlineMeetingArtifact.Read.All`
* For SharePoint: we need access to `Sites.ReadWrite.All` & `offline_access`
## How do I make a service account?
At a basic level, you will need to:
* create a new account within your organization
* name it something obvious and simple that highlights it as a robot account
* store the details (such as the password / 2fa key) somewhere secure that can be shared with others, such as a password manager
# Notion
Source: https://docs.incident.io/integrations/notion
Export post-mortems to Notion, and optionally use a Notion database as your follow-up issue tracker.
After your incident is over, it can be useful to dig into what happened in an incident, why, and how it can be prevented in the future.
Our Notion integration lets you export post-mortems into Notion so you can collaborate with your team. You can also turn on Notion as a [follow-up issue tracker](/integrations/notion-follow-ups) and export follow-ups into a Notion database.
***
## Installation
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Notion** and click **Install**.
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user who installed it**. Notion connections like this, which use OAuth, belong to a specific user. For this reason, you may wish to set up a dedicated service or "bot" account.
Click **Install in Notion**, and you'll be redirected to the install flow within Notion. Review the permissions we're requesting, and click **Next**
We also need to install a template for the pages we create. Click **Use a template provided by the developer**, and then **Allow access**
## You're done
Congratulations, it's been installed
You'll find the page in your private Notion space – move it to somewhere that suits you, and that can be accessed by everyone.
***
## Exporting your first post-mortem
1. Go to the incident timeline of an incident
2. On the right-hand side, in the **Post-mortem** section, click **Create a post-mortem**
3. The **Create post-mortem** modal will appear
* Select **Notion** from the destinations
* Select your template
* Select which timezone should be used
* Click **Create** and wait a few seconds
* Your post-mortem document has been created, and it'll be linked to the incident page
***
## Grant access to specific pages
You can also connect Notion pages and databases as [document sources for investigations](/nexus/documentation). When you add a page there and see this error, the URL is usually fine:
> We couldn't find this Notion page or database. Check the URL, or share it with the incident.io integration in Notion.
The integration can only read the pages and teamspaces you select in Notion, so a newly created page or teamspace stays invisible to us until you grant access to it.
To grant access, open Notion and go to **Settings → Connections**, select **incident.io**, and under **Page access** add the pages or teamspaces you want to sync, including the one that failed. There's no need to reconnect from incident.io.
### Grant access via reconnect
If the above doesn't work, reconnect the integration and select the pages you need on Notion's consent screen:
1. Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations) and open **Notion**.
2. Click **Reconnect**.
3. On Notion's consent screen, under **View pages you select**, choose every page or teamspace you want to sync, including the one that failed.
4. Click **Allow access**.
If Notion asks you to install the post-mortem template again, choose **Skip**. Your existing post-mortem database
stays connected as long as its teamspace is still selected.
# Export follow-ups to Notion
Source: https://docs.incident.io/integrations/notion-follow-ups
Turn incident follow-ups into Notion database pages, with status, assignee, and priority sync back to incident.io.
If your team tracks work in a Notion database, you can export [follow-ups](/post-incident/follow-ups) there the same way you would to Jira or Linear. Choose a database (like choosing a Jira project), map the fields you care about, and keep working in Notion while status, assignees, and priorities stay in sync.
This is separate from [exporting post-mortems to Notion](/integrations/notion). You can use both: post-mortems for write-ups, and a tasks database for follow-up work.
## What can you do?
* **Export** follow-ups into a Notion database as new pages
* **Connect** an existing Notion page by pasting its URL
* **Sync** title, description, status, assignee, and priority back from Notion
* **Export templates** and [auto-export](/integrations/auto-export-follow-ups) rules, with the database as the project equivalent
Notion does not offer page-change webhooks, so sync runs when someone opens the follow-ups view (about once a minute while you're looking) and once a day for open exports as a safety net.
## Set up
1. [Install the Notion integration](/integrations/notion) if you have not already.
2. Open [Settings → Integrations → Notion](https://app.incident.io/~/settings/integrations) and turn on **Use as issue tracker**.
3. In Notion, share the task database (and its teamspace if needed) with the incident.io connection. See [Grant access to specific pages](/integrations/notion#grant-access-to-specific-pages).
4. Confirm the database has a **Status** property. Databases without one cannot be used for follow-up export.
## Database conventions
As a Notion database is completely free-form, we have a few built-in conventions to enable follow-ups to sync back into incident.io from Notion.
### Required: Status
The database must include a **Status** property. We use the first Status column from left to right, and rely on that to drive the status in incident.io.
Follow-up status comes from the Notion **status group** the option sits in, not from the option's display name:
| Notion status group | Follow-up status in incident.io |
| ------------------- | ------------------------------- |
| To-do | Open |
| In progress | Open |
| Complete | Completed |
Exception: Complete options named `cancelled`, `declined`, or `not doing` (case-insensitive) sync as **not doing**.
### Optional: Assignee or Owner
A **People** property named **Assignee** or **Owner** (case-insensitive) syncs the follow-up owner.
If the database has no such column, we leave the follow-up assignee unchanged.
### Optional: Priority or Urgency
A **Select** column named **Priority** or **Urgency** (case-insensitive; Priority wins if both exist) can be filled on export from the follow-up's priority. We write the priority **option name** into Notion.
Priority changes in Notion sync back to incident.io, as long as the option names match your [follow-up priorities](/post-incident/follow-up-priorities).
### Title and description
* **Title** is required when creating a page.
* A **Description** rich-text property exports and syncs both ways when present.
### Other properties
Once you pick a database, the export form and templates list the writable properties in database order. You can map strings, numbers, checkboxes, URLs, emails, phones, dates, selects, multi-selects, status options, and people. Unwritable property types are skipped.
## Export a follow-up
1. Open the [follow-ups](https://app.incident.io/~/follow-ups) page, or an incident's follow-ups.
2. Choose **Export** (or create a new ticket) and select **Notion**.
3. Pick the database, then fill any fields your template or form requires.
4. Confirm. We create a page in that database and link it to the follow-up.
You can also set up [export templates and auto-export](/integrations/auto-export-follow-ups) under [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups). On a Notion template, choose the database first; the rest of the fields come from that database's schema.
## Connect an existing Notion page
Paste a Notion page URL into the incident channel, or use **Connect to existing** on the follow-up. Deep links with query strings or `#fragments` work. The page must be one the integration can access.
## What syncs
| Direction | Fields |
| -------------------------------- | ----------------------------------------------------------------- |
| Notion → incident.io | Title, description, status (via groups above), assignee, priority |
| incident.io → Notion (on export) | Title, description, mapped template fields (including priority) |
## FAQs
It needs a Status property, and the incident.io connection must have access to that database (and its teamspace). Share it under Notion **Settings → Connections**, or reconnect the integration and select the right pages.
Notion has no page webhooks. Open the [follow-ups](https://app.incident.io/~/follow-ups) page to trigger a sync, or wait for the daily catch-up. Confirm the page's status sits in the Complete group if you expect the follow-up to complete.
Yes. Post-mortem export and follow-up export share the Notion connection. Turn on **Use as issue tracker** only when you want follow-up export offered in the product.
# Opsgenie
Source: https://docs.incident.io/integrations/opsgenie
Page the right people through Opsgenie without ever leaving Slack.
In an incident, at the boundaries of your knowledge and need help to figure something out? We've all been there.
With incident.io, you can use `/incident escalate` **to directly page users in Slack** — no need to log into Opsgenie, search around and find the right place!
You can also automatically trigger incidents when an alert fires in Opsgenie by [setting up Opsgenie as an alert source](https://app.incident.io/~/alerts/sources/create?source_type=opsgenie). You'll need to have connected Opsgenie as an integration first.
***
## Setting Up
You can connect Opsgenie to incident.io in just a few clicks.
*For this integration to work, your Opsgenie account will need to be on the **Standard** or **Enterprise** plan. This is a* [limitation of Opsgenie](https://docs.opsgenie.com/docs/essentials-plan-restrictions#serviceincident-operations-through-api) *, where they restrict access to the Incidents API to these tiers.*
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
2. **Press Install next to Opsgenie**
3. **Fetch your API key from Opsgenie**
You'll need to create an API key by heading to the settings page of [your Opsgenie account](https://app.opsgenie.com/auth/login).
You can find this by heading to **Settings** and then scrolling down to **API key management**. The page will look something like this:
Click *Add new API key*
* Call it "incident.io"
* Set access rights:
* We require Read, Create, Delete, Update and Configuration access
* We require a **Global integration** API Key
* We don't delete resources that aren't managed by incident.io
* We will create 2 integrations one of type `API` and another of type `Webhook`: we need the deletion permission so that we can clean up any resources we create if you were to uninstall the Opsgenie integration
Copy the key to your clipboard.
4. **Paste the API key** from your clipboard into the incident.io modal
Hit Save, and you're all set up with Opsgenie!
***
## Escalating an incident
Just head over to the incident's Slack channel and hit `/incident escalate`.
**Who can I page?**
* *A team* : we'll use the settings you've defined for the team to page whoever's on-call.
* *Any user on Opsgenie* : sometimes, you know that special someone that can help you out when you get stuck. Escalate to them directly, and bring them in to help.
* *Both the above at once!* In the middle of a particularly gnarly incident? You can page multiple teams and individuals all at once
# Outlook Calendar
Source: https://docs.incident.io/integrations/outlook-calendar
Attach Outlook meetings to incidents automatically, and schedule debriefs in a single click.
Sometimes, you need to schedule meetings related to your incident. Perhaps a war room for everyone to sync their findings whilst an incident is ongoing, or a debrief about what happened once the incident is resolved.
Our Outlook integration lets you attach events to an incident, and pulls through relevant information about when it is and who is attending.
## Installation
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Outlook connections like this, which use OAuth, belong to a specific user. For this reason, you must set up a dedicated service or "bot" account.
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Outlook Calendar** and click **Install**.
Click **Install** and you'll be redirected to the Microsoft installation flow. Review the permissions we're requesting and click **Accept**:
Once you've completed the Microsoft authentication flow, you'll be redirected back to incident.io:
## Scheduling a debrief
In one-click, we can build an Outlook event which has been pre-filled with the incident participants and other useful information - you just need to fill in the rest.
Once your incident has been resolved, you'll notice a new option to **Schedule a debrief** from the sidebar:
This will take you to a pre-populated Outlook event. You just need to choose a time and hit save:
## Linking an event from Outlook to an incident
In addition to scheduling a debrief for you, we can also link events created in Outlook to your incidents. You just need to create an event in Outlook which:
1. Has the **incident identifier** (e.g. `INC-123`) in the title or description
2. Invites the **connected user**
When this happens, we'll automatically attach the event to your incident and message the relevant incident channel:
If you identify the incident as a [debrief meeting](/post-incident/debriefs) (i.e. a catch-up after the incident has been resolved), we'll additionally let the channel know when it's happening and who's invited:
Note that if you include the word "debrief" in the event (or whatever your preferred name for this term is, according to your [debrief settings](https://app.incident.io/~/settings/debriefs) ), we'll automatically attach the event as a debrief without prompting you first.
## Removing a linked event
If we automatically attach a debrief which should not be linked to your incident, you can unlink it by heading to the sidebar on the incident details page, clicking the debrief, and then clicking **...** > **Unlink debrief**:
# PagerDuty
Source: https://docs.incident.io/integrations/pagerduty
Page the right people through PagerDuty without ever leaving Slack.
In an incident, at the boundaries of your knowledge and need help to figure something out? We've all been there.
With incident.io, you can use `/incident escalate` **to directly page users in Slack** — no need to log in to PagerDuty, search around and find the right place!
You can also use the PagerDuty integration to attach related PagerDuty incidents, pull information onto your timeline, and even auto-create incidents from PagerDuty!
***
## Setting Up
You can connect PagerDuty to incident.io in just a few clicks.
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
2. **Press Connect next to PagerDuty.**
3. **Fetch your API key from PagerDuty**
You'll need to create an API key by heading to your PagerDuty account, and navigating to **Integrations > API Access Keys**
**If you can't see the API Access Keys menu item**, you probably don't have access to create API keys in PagerDuty.
Click **Create an API Key**
* Call it "incident.io"
We **do** need write access, so leave the **read-only key** box unchecked!
Copy the key to your clipboard.
4. **Paste the API key** from your clipboard into the incident.io modal
5. **Choose your bot account**
All escalations will originate from the email of the chosen account. This is unfortunately a **limitation of the PagerDuty API**. When you create an incident, it must always be associated with the email of a valid PagerDuty user, as bots (i.e., us) are not allowed to create incidents on their own.
If you'd rather not have incidents attached to a user's email, you could create a dedicated account in PagerDuty and connect that to incident.io. However, be aware PagerDuty will charge you for the extra seat.
Alright, you're all set up with PagerDuty!
***
## Escalating an incident
Just head over to the incident's Slack channel and hit `/incident escalate`.
**Who can I page?**
* *An escalation policy* : a way to notify on-call users about an incident that relates to a service or system, and have the right people notified at the right time.
* *Any user on PagerDuty* : sometimes, you know that special someone that can help you out when you get stuck. Escalate to them directly, and bring them in to help.
* *Both the above at once!* In the middle of a particularly gnarly incident? You can page multiple teams and individuals all at once
## Things to know
All escalations will originate from the email of the user that you selected when connecting PagerDuty to your incident.io account. This is unfortunately a **limitation of the PagerDuty API**. When you create an incident, it must always be associated with the email of a valid PagerDuty user, as bots (i.e., us) are not allowed to create incidents on their own.
If you'd rather not have incidents attached to a user's email, you could create a dedicated account in PagerDuty and connect that to incident.io. However, be aware PagerDuty will charge you for the extra seat.
To automatically create incidents from PagerDuty, [set up PagerDuty as an alert source](https://app.incident.io/~/alerts/sources/create?source_type=pager_duty). You'll need to connect PagerDuty as an integration first.
## Catalog
When you install the PagerDuty integration, we also sync data from PagerDuty in to the catalog so that you can set up Workflows and other automations that use it. Installing the integration will create the following types and attributes in the catalog:
**PagerDuty User**
* Name
* Email
* Role
* Job title
* Timezone
* incident.io User (we match based on the email)
**PagerDuty Team**
* Name
* Description
* Members (this links to the PagerDuty User type)
**PagerDuty Service**
* Name
* Description
* Status
* Escalation policy (this links to the PagerDuty Escalation Policy type)
* Teams (this links to the PagerDuty Team type)
**PagerDuty Priority**
* Name
* Description
**PagerDuty Escalation Policy**
* Name
* Description
* Teams (this links to the PagerDuty Team type)
The PagerDuty Priority type is synced daily, the other types are synced hourly.
## FAQs
We auto-acknowledge incidents when:
* Someone manually goes "Yes, that PD incident *is* related to this incident"
* When a triage incident is accepted
Once triggered, we check:
* If the PagerDuty incident has already been acknowledged, do nothing
* If the actor doing the trigger action is not a human (e.g. a workflow), we do nothing
* If the human was not paged by this escalation (or we can't match them to a PD user), we do nothing. In this case, we post a message with a button saying "want to acknowledge this?"
If all those conditions pass, we acknowledge the incident and add a note saying "Automatically acknowledged via incident.io", and link to the incident. We then best-effort send a message to the user, saying "We've acknowledged PagerDuty incident ... for you".
Yes! For any given service, you can add `incident-io-ignore` anywhere within the description and we'll no longer pull this into our platform.
Similarly for an escalation policy you can add `incident-io-ignore` as a tag.
No - see [Things to know](#things-to-know) above for why all escalations originate from the connecting user's email.
# Pagerduty sample incident import script
Source: https://docs.incident.io/integrations/pagerduty-import
Bring your historical PagerDuty incidents into incident.io with a sample import script.
This script provides a basic structure that can be utilized to import historical incident data from Pagerduty to incident.io.
For best results, we recommend doing further mapping to ensure all fields are being mapped to your requirements.
You can use the PagerDuty API to fetch incidents and the incident.io API to add retrospective incidents.
## Prerequisites
Ensure you have the necessary API keys and permissions for both services.
Also, make sure you have the required libraries installed by running:
```bash theme={null}
pip install requests
```
## Sample script
Here's a simple Python script that demonstrates how you might export incidents from PagerDuty and add them as retrospective incidents to incident.io:
```python theme={null}
import math
import requests
import json
# PagerDuty API credentials
pagerduty_token = 'your_pagerduty_token'
pagerduty_api_url = 'https://api.pagerduty.com/incidents'
# Incident.io API credentials
incidentio_token = 'your_incidentio_token'
incidentio_api_url = 'https://api.incident.io/v2/incidents'
# Function to fetch incidents from PagerDuty
def fetch_pagerduty_incidents(params):
headers = {
'Authorization': f'Token token={pagerduty_token}',
'Content-Type': 'application/json',
}
response = requests.get(pagerduty_api_url, headers=headers, params=params)
return response.json()
def import_incidents_to_incident_io(incident, retrospective_data):
headers = {
'Authorization': f'Bearer {incidentio_token}',
'Content-Type': 'application/json',
}
response = requests.post(incidentio_api_url, headers=headers, data=json.dumps(retrospective_data))
if response.status_code == 201:
print(f"Retrospective incident added for PagerDuty incident ID: {incident['id']}")
else:
print(f"Failed to add retrospective incident for PagerDuty incident ID: {incident['id']}")
# Function to add retrospective incidents to Incident.io
def add_retrospective_incidents(incident_total):
max_pages = math.ceil(incident_total/10) # calculate how many pages we need
for page in range(1, max_pages + 1):
offset = (page - 1) * 10
params = {
"limit": 10,
"offset": offset
}
pagerduty_incidents = fetch_pagerduty_incidents(params)["incidents"]
if pagerduty_incidents:
for incident in pagerduty_incidents:
# Customize the data you want to send to Incident.io
retrospective_data = {
'name': f"Retrospective - {incident['summary']}",
'idempotency_key': f"pagerduty-import-{incident['id']}",
'mode': 'retrospective',
'severity_id': 'your_default_severity_id', # Replace with a real severity ID
'visibility': 'public',
# Add any other relevant fields, This is where you get to customize any fields on incident.io side
# with data from PagerDuty
}
import_incidents_to_incident_io(incident, retrospective_data)
def main():
# Fetch the total number of incidents from PagerDuty to handle pagination
total_number_of_incidents = fetch_pagerduty_incidents({"limit": 10, "offset": 0, "total": True})["total"]
print(total_number_of_incidents)
# Extract relevant information from PagerDuty incidents and add to Incident.io
if total_number_of_incidents:
add_retrospective_incidents(total_number_of_incidents)
else:
print("No incidents found in PagerDuty.")
if __name__ == "__main__":
main()
```
**Note:** Make sure to replace placeholders like `'your_pagerduty_token'`, `'your_incidentio_token'`, and `'your_default_severity_id'` (find severity IDs via the [List Severities API](https://docs.incident.io/api-reference/severities-v1/list)), and customize the data fields according to your needs.
# Proxy
Source: https://docs.incident.io/integrations/proxy
Securely reach the tools running inside your private networks.
A proxy lets incident.io reach services that aren't exposed to the public internet, for example self-hosted infrastructure, such as Grafana or GitLab, or internal resources like Kubernetes clusters and SQL databases. You run a small proxy in your network that establishes an outbound, encrypted tunnel to incident.io. When we need to query one of those private services, the request travels through that tunnel.
The settings screen, API, and audit log still call a proxy a **Connector**. They're the same thing.
## How it works
The proxy is a lightweight service you deploy inside your network. When it starts up, it:
1. Opens an outbound SSH connection over port `443` to `relay.incident.io`.
2. Authenticates using a token you generate when you create the proxy.
3. Establishes a reverse tunnel that lets incident.io reach the destinations you've allowed.
You stay in control of what incident.io can reach: only the data sources and integrations you explicitly attach to a proxy are routed through it, and you can restrict outbound destinations further with an allowlist.
## Prerequisites
Before you set up a proxy, make sure you can:
* **Run a container or binary** somewhere inside the network that hosts the data sources you want to expose. Most teams run the proxy in Kubernetes, ECS, or as a systemd service.
* **Make outbound connections** to `relay.incident.io:443` from that environment. No inbound ports are required.
If you're running the binary directly (rather than the Docker image), you'll also need **OpenSSH 9.2 or newer** on the host. The proxy uses the system's `ssh` command, and versions before 9.2 have a bug that breaks reverse forwarding. The published Docker image already includes a compatible version.
## Setting up a proxy
Go to **Settings → [Connectors](https://app.incident.io/~/settings/connectors)** and click **Add connector**.
Give the proxy a name that reflects which network it runs in and what it can reach. The description is a good place to record the specific services it has access to.
On the next screen, copy the **Connector ID**, then click **Generate token**.
The token is shown only once. Store it somewhere safe. You can regenerate it at any time, but the previous token stops working as soon as you do.
The proxy is published as a Docker image at [`incidentio/connector-proxy`](https://hub.docker.com/r/incidentio/connector-proxy).
Pass the **Connector ID** and **token** you copied above as environment variables or flags:
```bash theme={null}
docker run --rm \
-e INCIDENT_CONNECTOR_ID= \
-e INCIDENT_CONNECTOR_API_TOKEN= \
incidentio/connector-proxy
```
Store the token in a `Secret` and reference it from a `Deployment` so the token never appears in your manifests or pod spec. Three replicas gives you redundancy across nodes. The proxy reconnects on its own if a pod is rescheduled. The liveness probe checks the proxy's metrics endpoint on port 9090, so Kubernetes restarts a pod whose process becomes unresponsive.
```yaml connector.yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
name: incident-connector
type: Opaque
stringData:
api-token:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: incident-connector
labels:
app.kubernetes.io/name: incident-connector
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: incident-connector
template:
metadata:
labels:
app.kubernetes.io/name: incident-connector
spec:
containers:
- name: connector-proxy
image: incidentio/connector-proxy:latest
env:
- name: INCIDENT_CONNECTOR_ID
value:
- name: INCIDENT_CONNECTOR_API_TOKEN
valueFrom:
secretKeyRef:
name: incident-connector
key: api-token
ports:
- containerPort: 9090
name: metrics
livenessProbe:
httpGet:
path: /metrics
port: metrics
resources:
requests:
cpu: 500m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 65532
capabilities:
drop: [ALL]
```
Apply it with `kubectl apply -f connector.yaml`. To restrict outbound destinations, add an `INCIDENT_CONNECTOR_FORWARD_DEST_ALLOWLIST` env var to the container (see [below](#restricting-which-services-the-proxy-can-reach)).
```bash theme={null}
./connector-proxy \
--connector-id= \
--api-token=
```
When the proxy connects successfully, you'll see a log line like:
```plaintext theme={null}
Allocated port 53990 for remote forward to socks
```
Back in **Settings → Connectors**, the proxy should now appear as online.
## Connecting telemetry data sources through a proxy
Go to **Investigations → Telemetry → [Add data source](https://app.incident.io/~/investigations/telemetry/add)** and pick the type of data source you want to connect.
Under **Network access**, select **Private network** and choose the proxy you created.
Finish configuring the data source and click **Test connection**. If everything is wired up correctly, the test should pass and you're ready to go.
You can switch which proxy a data source uses at any time from the data source's **Settings** tab in [Investigations
telemetry](https://app.incident.io/~/investigations/telemetry).
## Connecting integrations through a proxy
Connect any of these through a proxy when they run inside a private network:
* **Self-managed GitLab**, for both the [GitLab integration](/integrations/gitlab) and [code analysis in Investigations](/nexus/code/overview)
* **GitHub Enterprise Server**, for [code analysis in Investigations](/nexus/code/overview)
* **Jira Server or Data Center**, for the [Jira Server integration](/integrations/jira-server)
In each case you select the proxy in the integration's connect dialog, the same way you do for a data source.
## Restricting which services the proxy can reach
By default, the proxy will forward requests to any destination an investigation asks for, as long as it's reachable from the network the proxy is running in. To narrow that down, set `--forward-dest-allowlist` (or `INCIDENT_CONNECTOR_FORWARD_DEST_ALLOWLIST`) to a space-separated list of `host:port` entries:
```bash theme={null}
./connector-proxy \
--connector-id= \
--api-token= \
--forward-dest-allowlist="grafana.internal:3000 prometheus.internal:9090"
```
Any destination not on the list is rejected. You can layer network policies on top of this for defense in depth.
## Troubleshooting
If your proxy shows as **offline** in incident.io, it either isn't running or can't reach our relay. Check the proxy logs and confirm it can make outbound connections to `relay.incident.io:443`.
If a data source's **Test connection** fails:
* **Proxy unreachable** means incident.io can't talk to your proxy. Check that the proxy is running and online.
* **Credentials incorrect** means the proxy reached the data source, but the credentials you supplied are wrong.
## FAQs
The proxy opens a single SSH connection to `relay.incident.io` on port `443`. No inbound ports are required.
The proxy exposes Prometheus metrics at `/metrics` on port `9090`. Point your scraper at that endpoint to ingest
proxy-level metrics.
Use the `--forward-dest-allowlist` flag (or `INCIDENT_CONNECTOR_FORWARD_DEST_ALLOWLIST` environment variable) to specify a space-separated list of `host:port` destinations. Any request to a destination outside the list is rejected.
Examples:
* Single host: `--forward-dest-allowlist="localhost:5432"`
* Multiple destinations: `--forward-dest-allowlist="db.internal:5432 api.internal:8080 redis.internal:6379"`
You can also apply network policies in your infrastructure for an additional layer of control.
Yes. Most teams run a separate proxy per network they want to reach (for example, one per VPC or per environment).
Each data source picks the proxy it should route through.
Reach out to us in our shared Slack channel. We're happy to help.
# Using Pylon with incident.io for incident management
Source: https://docs.incident.io/integrations/pylon
Route urgent customer escalations straight to your on-call engineer, and keep support tickets linked to the incidents they caused.
Internally, we have two main use cases for using Pylon along with incident.io
* Linking Pylon issues with incidents
* Sending customer escalations to the on-call Support Engineer for urgent support
## Linking issues with incidents
Pylon offers an [incident.io app](https://docs.usepylon.com/pylon-docs/integrations/incident-management/incident.io) that can be added to Pylon, which will let you:
* Create a view of tickets, filtered by a specific incident
* Run reporting & analytics on how many tickets are associated with incidents
* Create differentiated automated workflows for tickets that are tied to an incident
## Escalating issues to Support Engineers
We want to give our users the power to escalate issues to us that they consider urgent. This is important for issues that may come up outside working hours or during bank holidays, so that our customers can page someone and get support within minutes.
### How is this configured?
* We do this by using Pylon's [Forms](https://docs.usepylon.com/pylon-docs/support-workflows/ticket-forms)
* Form is triggered whenever a user reacts with a ‼ emoji on a message, which sends a form within the thread, asking the customer two questions:
* Escalating Reason
* Details of escalation
* Once the two fields are submitted, we trigger a webhook call to our HTTP alert source to create a new alert in incident.io
* This allows us to pass in all sorts of metadata to the alert.
* Once we receive the alert, we trigger an escalation and create an incident using our alert [routes](/alerts/escalations-from-alerts)
# Salesforce integration
Source: https://docs.incident.io/integrations/salesforce
Bring customer and account context from Salesforce into every incident.
Using our Salesforce integration, you can attach your customer accounts to incidents in only a few clicks, enabling smarter workflows and making data analysis easier and more impactful. You can also do powerful things like:
* Send an email to senior managers when a high-revenue customer is impacted by an incident
* Add the relevant Customer Success Manager to an incident when one of their customers is impacted
* Remind an incident channel when there's an open opportunity for a prospect that might be impacted by an incident
Before configuring the integration, make sure that you have an [Account List](https://trailhead.salesforce.com/content/learn/projects/prepare-your-salesforce-org-for-users/create-a-unique-account-list-view) configured in Salesforce so that you can easily identify it when you go through our install process.
***
## Setting Up
1. **Go to Settings → Integrations →** [Salesforce](https://app.incident.io/~/settings/integrations/salesforce)
Click **Connect** and you'll be redirected to Salesforce, where you can login as the user you'd like to connect with — or, if you're already logged in, you'll see a modal prompting you to authorize incident.io to access a variety of scopes within Salesforce.
Click Allow, and you'll be redirected back to your integration settings page to complete configuration. From here, choose an Account List to integrate with the Catalog.
Note: Your integration will be considered **incomplete** until you do this.
Once this is done, you'll be able to see the list of your customers' accounts as entries under the new **Salesforce Account** Catalog type.
By default, we'll synchronize:
* Name
* Owner
* Description
* Employees
* Industry
The incident.io Catalog can be configured to also sync dynamic attributes. To do this, navigate to the desired type in Catalog, e.g. **Salesforce Account**, click **Edit type** and then click **Import from Salesforce**.
Note that in order for incident.io to successfully sync these dynamic attributes the attached service account must also have permission to read them.
The integration is read-only, so only read permissions are required for all attributes.
Also note that you can only sync one Account List, with a limit of 50,000 accounts that can be synced from this list.
***
## Adding more Salesforce objects and fields
Once you've set up the basic Salesforce integration, you can choose to add Salesforce custom fields, as well as more Salesforce objects like **Contact** or **Opportunity**.
Head to [Catalog](https://app.incident.io/~/catalog), scroll to Salesforce and hit **Import another type**:
After a few minutes, the new Salesforce object will load with the relevant entries. To add more Salesforce fields, hit **Edit type** and then **Add attribute**:
***
## Salesforce Service Cloud
We're launching an app for Salesforce Service Cloud that lets support agents view active incidents and link cases to
incidents directly inside Salesforce. Reach out to your account team to get started.
# Building a Salesforce Integration to view and create incidents
Source: https://docs.incident.io/integrations/salesforce-integration
Build a custom Salesforce integration for declaring and tracking incidents your way.
We're launching a native Salesforce Service Cloud integration for viewing incidents and linking cases directly inside
Salesforce. Reach out to your account team to learn more. The guide below is still useful if you want to declare
incidents from Salesforce, which the native app doesn't yet support.
The below guide should help provide a blueprint of how to build a custom Salesforce integration yourself without too big of a lift, taking advantage of our existing [Salesforce — Catalog integration](/integrations/salesforce).
## Declaring Incidents
The simplest way to declare incidents within Salesforce is to add a button within any given page layout that links to [inc.new](http://inc.new/). This will take the user to your default incident declaration form where they'll be able to then declare an incident.
### Pre-filling the declaration form
You might want to default to a certain incident type or automatically tag a customer that's affected by an incident e.g. I could have a declare incident for customer button within the Account page layout
You can do this by passing various values within the querystring of the URL in the button e.g. [inc.new?name=hello-world](http://inc.new/?name=hello-world) would launch an incident declare form with the name of the incident already set to "hello-world".
You can find a more extensive article on exactly what you can pass within the querystring in [Pre-filling 'declare incident' fields using URL parameters](/incidents/url-parameters)
### Declaring an Incident for a specific customer
It's fairly common to expose an *Affected Customer(s)* field when declaring an incident. This not only helps with tracking who to provide updates to but can also provide additional context to responders and trigger automations using our [Catalog](/catalog/what-data). Our existing [Salesforce integration](/integrations/salesforce) pulls a list of Accounts from your Salesforce instance. This catalog type can then be used as the type of a [custom field](/catalog/catalog-setup#populating-custom-fields-with-catalog-data) e.g. *Affected Customer(s)* and exposed within your incident declaration form. You can then pre-fill this when declaring an incident from a specific salesforce account.
When pre-setting a custom field value that has a catalog type, you'll need to send the `external_id` or an `alias` of a catalog entry for that type. You can find those values by heading into any given catalog entry within the UI. The accounts created from the Salesforce — Catalog integration will all have an `external_id` equivalent to that account's Account Id in Salesforce. An example formula you could therefore have within a Button on an Account page might look like this:
```plaintext theme={null}
https://app.incident.io/~/incidents?createIncident=true&name=Incident%20declared%20from%20Salesforce%20for%20{!Account.Name}&custom_field_[id-of-your-custom-field]={!Account.Id}
```
## Viewing Incidents
You may also wish to provide greater visibility for live incidents within Salesforce and potentially report on incident data within Salesforce. This requires a little more effort than that needed to add the declare incident button but can be done in a couple of ways:
### Representing incidents in Salesforce
We'd recommend first creating a new custom object to represent an incident.io Incident. At a minimum you'll probably want the following fields:
| **Field Name** | **Field Type** |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Name | Text() |
| Status | Picklist() - Options should align with your incident statuses that can be configured within your [incident lifecycle](/incidents/lifecycle) |
| Summary | Text Area (Long) |
| Affected Account | Lookup(Account) |
### Pushing incident data into Salesforce
To get start populating the data in your new customer object in Salesforce, you could implement either a Pull-based or Push-based method depending on how realtime you need your incident data to be in Salesforce.
For the Pull-based method, you'd need to periodically call incident.io's [list incidents](https://docs.incident.io/api-reference/incidents-v2/list) API endpoint to retrieve incident data and then use the Salesforce API to create or update incidents in Salesforce. The staleness of data here will be dependent on how frequently you're retrieving information from the API and updating / creating your incidents in Salesforce.
For the Push-based method, you'd handle real-time updates sent by incident.io via [webhooks](https://docs.incident.io/api-reference/webhooks) and use the information we send within these to create / update the Salesforce incidents via the API. This is the preferred method if you want your data to be as close to realtime as possible.
# Sentry
Source: https://docs.incident.io/integrations/sentry
Keep error tracking and incident response in sync by linking Sentry issues directly to incidents.
Use [Sentry](https://sentry.io/) for error tracking, or performance monitoring? To keep everything organized, you can now link issues and incidents.
You can read [Sentry’s documentation on our integration](https://docs.sentry.io/product/integrations/issue-tracking/incidentio/).
## What we can do with Sentry
1. **Link Sentry issues to incidents** From a Sentry issue, just as you can link to Issue Trackers such as Jira, Linear and GitHub, you can also link to incident.io
2. **Attach Sentry Issues to incidents** When a Sentry link is posted in an incident Slack channel, it’ll offer to attach it
3. **Keeping you up-to-date** Activity on the Sentry Issue will be propagated to the incident Slack channel:
4. **Page from Sentry alerts** Sentry alerts are available as an [alert source](https://app.incident.io/~/alerts/sources/create?source_type=sentry)
## Installation
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
2. **Press Connect next to Sentry**
3. **Login to Sentry**
4. **Install**
Review the permissions, then click **Accept & Install**
That's it!
If you run into any issues, [get in touch](http://incident.io/community)
# ServiceNow
Source: https://docs.incident.io/integrations/servicenow
Bridge fast incident response with the structured record-keeping your ServiceNow processes rely on.
We have a ServiceNow integration to keep your incidents in sync with incident.io.
For teams running their operations in ServiceNow, we know how important it is to preserve the structured record-keeping you rely on. This integration closes the loop between fast-moving incident response in Slack or Microsoft Teams and the structured processes in ServiceNow, so you get the best of both worlds without duplicate effort.
This document will explain how to connect ServiceNow to incident.io.
## Connecting ServiceNow
incident.io connects to ServiceNow using an **OAuth app** and **Web Service user account**. Sync is bi-directional: updates made in ServiceNow flow back to incident.io, not just the other way. Installing our ServiceNow app makes that back-sync real-time, so we recommend it. If you'd rather not, grant the service account the `admin` role instead.
You will need a ServiceNow Admin to complete these steps.
## 1. Install the ServiceNow app
Install the **incident.io** [app from the ServiceNow Store](https://store.servicenow.com/store/app/2ee3e7b697a9cbd8fe857a121153af21).
To skip the ServiceNow app installation, grant the `admin` role in [step 3](#3-create-a-web-service-account) instead.
## 2. Create an OAuth App
Log in to ServiceNow and search for **OAuth** in the filter navigation:
Select **Application Registry**, and click **New**.
Select **New Inbound Integration Experience**.
Click **New Integration.**
Click **OAuth - Resource owner password credential grant.**
Enter 'incident.io' for the name, and add 'useraccount' to the Auth Scopes section. Leave other options as the defaults:
Find the app you've just created in the list. Copy the **Client ID** and **Client Secret** values: we'll need them later!
## 3. Create a Web Service Account
Any ServiceNow user account can be used so long as it has the relevant roles assigned. However, any actions taken by incident.io in ServiceNow will appear as being taken by this user account, so we strongly recommend creating a user for this purpose only.
In ServiceNow, search for **User Administration** in the filter navigation:
Select **Users**, then click **New** in the top-right.
Select a **username** and **email**, for example 'incident.io' and '[incidentio-service@my-domain.com](mailto:incidentio-service@my-domain.com)':
Make sure **Password needs reset** and **Locked out** are not selected, and **Active** is selected.
Change the identity type to **Machine.**
Click **Submit**, then navigate to the newly-created user.
At the bottom, select the **Roles** tab, then **Edit...** Add the roles for the path you're following.
If you installed the app in step 1, add:
* `x_incident_io.api_user`: shipped by the app. Grants incident.io the API access it needs for sync configuration and incident writes.
* `cmdb_read`: allows us to read data from your Configuration Management Database.
* `sn_cmdb_user`: allows us to read information about users and groups in your ServiceNow account.
* `incident_manager`: allows us to sync incident data into ServiceNow incident records.
If you're not installing the app, add the `admin` role instead, which gives incident.io full access to your ServiceNow instance.
Click **Save** to apply these changes and return to the user page.
Click **Set Password**, then **Generate**, then **Save Password**.
Copy the newly-generated password, we'll need it shortly! Make sure to update the record before going back to the [dashboard](https://app.incident.io/).
## 4. Create ACLs
If you granted the `admin` role in step 3, you can skip this step, as admin already covers it.
incident.io creates, reads, and updates follow-ups on the `task` table, so the service account needs **create**, **read**, and **write** access (the app doesn't grant access to `task` itself).
To add ACLs, you first need to elevate your user to Security Admin. Click your profile icon and select **Elevate role**.
Click **security\_admin** and then **Update**.
Search for **Access Control** and select **Access Control (ACL)** under **System Security**.
Select **New**.
Create an Access Control record with the following properties:
* **Type**: `record`
* **Operation**: `read`
* **Application**: `Global`
* **Active**: checked
* **Decision Type**: `Allow If`
* **Admin overrides**: checked
* **Name**: select `task` in the first dropdown, and leave the second as `-- None --`.
Click **Submit**. When prompted to select a role, choose `x_incident_io.api_user`.
Click **OK** and then **Update** to save the ACL.
Repeat for the **create** and **write** operations, so that you have three `task` ACLs assigned to `x_incident_io.api_user`.
## 5. Installing the integration
We're now ready to install the ServiceNow integration in incident.io.
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations/servicenow), and click on **ServiceNow**, then **Connect**.
Use the following details:
* Your **subdomain** is the part of the URL where you log in to ServiceNow. For example, if your ServiceNow instance is accessed at `hyper-payments.service-now.com`, your subdomain is `hyper-payments`.
* Your **OAuth Client ID** and **OAuth Client Secret** are the credentials you created in [step 2](#2-create-an-oauth-app).
* Your **Username** and **Password** are the credentials for the service account you created in [step 3](#3-create-a-web-service-account).
* Click **Connect** to verify your credentials and complete the connection
Next, you'll want to set up your incident ticket to sync incidents to ServiceNow. See [Syncing incidents and follow-ups to ServiceNow](/integrations/servicenow-sync) for the steps.
# Syncing incidents and follow-ups to ServiceNow
Source: https://docs.incident.io/integrations/servicenow-sync
Keep ServiceNow incident records current automatically, for audit and compliance needs.
Once you've [set up your integration](/integrations/servicenow) with ServiceNow, you can start to automatically create incidents in ServiceNow from incident.io. That way, you can ensure that all relevant information happening in our platform is also tracked in ServiceNow for any auditing, regulatory or internal process requirements you may have. We will also sync any work notes/comments and image attachments added to your ServiceNow incident back to incident.io.
## Creating (and editing) incident tickets
Once incident.io is connected to ServiceNow, you'll want to head over to [Settings → Incident tickets](https://app.incident.io/~/settings/incident-tickets).
You'll first need to create an incident ticket template. When we sync information about an incident back to ServiceNow, we will need to know how to populate your required fields (i.e. description, caller), as well as any optional ones.
You can create multiple templates (depending on your billing plan) and use conditions to select which one to use in certain circumstances. For example:
* You could route any engineering-related incidents to Jira
* Then, route any security-related incidents to ServiceNow
Once you have a ServiceNow incident ticket template, you can enable '**Create tickets**.' This is a toggle under the template(s) you just created.
If there are no conditions specified we will use the first template in the list and create a ticket for all incidents. If you only wish to create a ticket for certain incidents (ie. only Security incidents or only those with 'Critical' severity) then you'll need to set up some conditions.
By default if you have created at least one condition we will **not** create a ticket if there is no match.
You can edit this 'no match' fallback behavior to enable always creating a ticket. For example:
* You could export any engineering-related incidents to Jira
* Then, export any security-related incidents to ServiceNow
* If no match, default export to the ServiceNow incident ticket template
## Reusing a ServiceNow ticket from an alert
If you use ServiceNow as an [alert source](/alerts/alert-sources) *and* have incident tickets configured for ServiceNow, an incident created from a ServiceNow alert will **reuse the ServiceNow incident behind that alert as its incident ticket**, rather than opening a second, duplicate one. We then keep that existing ServiceNow incident in sync just like any other incident ticket.
This happens automatically when all of the following are true:
* The incident was created from a **single** ServiceNow alert. If several ServiceNow alerts are grouped into one incident we can't tell which ServiceNow incident to use, so we create a new ticket instead.
* The ServiceNow incident isn't already linked to another incident or follow-up, and still exists.
If any of these aren't true, we fall back to creating a new incident ticket from your template as usual.
## Private incidents
If you do wish to create incidents for private incidents created in incident.io you can enable this with the checkbox.
## Field mappings between incident.io and ServiceNow
For some additional context when building your incident ticket templates, please view our mappings for fields in incident.io to ServiceNow.
## Incidents
* Incident name: `short_description`
* Description is as set in your template
* `Incident state`: fixed value 1 (New)
* `urgency`: fixed value 2 (Medium)
* `impact`: fixed value 2 (Medium)
* `opened_by`: fixed value integration\_user
## Follow-ups
* Follow-up title: `short_description`
* Follow-up description: `description`
* Linked incident's `external_issue_reference`: `parent`
* `state`: fixed value 1 (Open)
## State mappings
* 1 (New), 2 (InProgress), 3 (OnHold), 4 (Pending), 5 (AwaitingProblem), all become "Open" in incident.io.
* 6 (Resolved), 7 (Closed) become "Completed"
# SharePoint
Source: https://docs.incident.io/integrations/sharepoint
Export post-mortems to SharePoint, keeping write-ups inside your Microsoft 365 environment.
After your incident is over, it can be useful to dig into what happened in an incident, why, and how it can be prevented in future.
Our SharePoint Integration allows you to export post-mortems into SharePoint. Which you can then use to collaborate with your team.
***
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user
that installed it**. SharePoint connections like this, which use OAuth, belong to a specific user. For this reason,
you may wish to set up a dedicated service or "bot" account. We use the same user account connection for all our
Microsoft integrations. Therefore, the account you use to connect this integration will need to be the same for
Microsoft Teams and Outlook.
## 1. Installing the Integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **SharePoint**.
Click **Install** and you'll be redirected to the Microsoft installation flow. Review the permissions we're requesting and click **Accept**:
Once you've completed the Microsoft authentication flow, you'll be redirected back to incident.io:
## 2. Setting up a post-mortem destination
incident.io has now been connected to SharePoint. Next, we need to specify where in your SharePoint you'd like to export post-mortems to.
Go to [Settings → Post-mortems](https://app.incident.io/~/settings/post-mortem), then click **Add destination**
Within your web browser, navigate to the folder in SharePoint where you'd like to export post-mortems to.
Click the share button
Click **Copy link**.
Paste the link in, give it a sensible name, and click **Create**.
You should now be good to go!
## Permissions
* `Sites.ReadWrite.All` - Enables us to read the site/document library/folder structure so users can pick a target location for exports, and to write post-mortem documents to the selected SharePoint location.
# Shortcut (formerly Clubhouse)
Source: https://docs.incident.io/integrations/shortcut
Keep task tracking in Shortcut without manually copying incident follow-ups back and forth.
Using Shortcut to track your team's tasks? Want to export [your incident to-dos](/incidents/task-tracking) to Shortcut to keep everything centralized?
This is how.
***
## What we can do with Shortcut
Our current integration is a fairly simple setup for now. In its present state, the integration lets you:
1. **Export** [your incident to-dos](/incidents/task-tracking) to Shortcut; and
2. **Sync the status of your tasks between Shortcut and incident.io**, so you can work in Shortcut without worrying about updating statuses manually in incident.io!
You can also [bulk-export follow-ups and use export templates](/integrations/auto-export-follow-ups) to automatically route them to Shortcut based on conditions like incident type or severity.
***
## Setting Up
Adding Shortcut to incident.io is simple.
1. **Go to Settings >** [Integrations](https://app.incident.io/~/settings/integrations)
Hit `Connect` next to Shortcut.
2. **Get your API token**
Log into your Shortcut account and head to Settings.
Go to **API Tokens**.
Give your API key an explicit name (e.g. incidentio), and click **Generate Token**.
3. **Copy-Paste the generated API key into the incident.io pop-up**
That's it!
If you run into any issues, [get in touch](http://incident.io/community)
# Exporting your data using a Singer tap
Source: https://docs.incident.io/integrations/singer-tap
Get your incident data into your data warehouse without building and maintaining your own export pipeline.
Incident data can be incredibly powerful and while we provide [our own insights](https://app.incident.io/~/insights) within the dashboard we understand that joining this data with your own can help to improve your understanding even more.
One method for extracting your incident data is to [query our API](https://docs.incident.io/api-reference/). We provide endpoints for things like incidents, roles, severities, and much more.
Often though you will want to regularly take that data and store it in a data warehouse such as BigQuery, Redshift, or Snowflake. This can take time to build, test and maintain. To save you that effort we have now released a Singer tap which you can easily install and run on your own infrastructure.
## What is Singer?
[Singer is an open-source specification](https://www.singer.io/) for building processes to extract and load data. You can run "taps" that extract from different sources and "targets" that import data from those taps into your data warehouse. The great part about Singer is that a lot of people have already built taps and targets for you - allowing you to simply put the parts together that you need.
## Getting Started
To get started using our Singer tap see the project documentation here:
[https://github.com/incident-io/singer-tap/](https://github.com/incident-io/singer-tap/)
As a quick start you can try using the [BigQuery Target](https://github.com/z3z1ma/target-bigquery) to load data into some BigQuery tables.
You install our tap, the target, add some config json files, and then all that's left to extract data from our incident.io account and store it in BigQuery is one simple command!
```plaintext theme={null}
tap-incident --config tmp/config.json --catalog tmp/catalog.json | target-bigquery --config tmp/bigquery-config.json
```
Once it finishes, we will get the following tables and schema within BigQuery allowing you to join this against other data in your warehouse. Great!
BigQuery is not the only data warehouse available - as mentioned before there are a lot of targets that people have built already. You can even build your own if you really need something bespoke.
If you use [Stitch](https://www.stitchdata.com/) to run your data sync processes, please use the **Suggest Integration** button on the Integrations page within your account to request that they add the incident.io tap to their platform.
# Splunk Integrations
Source: https://docs.incident.io/integrations/splunk
Connect Splunk for on-call escalations or to stream audit logs, however your team works.
There are currently 2 ways of integrating with Splunk from incident.io:
* For using **Splunk On-Call** and escalating incidents or paging policies, see our [Splunk On-Call integration guide](/integrations/splunk-on-call).
* For using **Splunk SIEM** to stream your audit logs, see our [audit log documentation](/admin/audit-logs).
# Splunk On-Call (VictorOps)
Source: https://docs.incident.io/integrations/splunk-on-call
Escalate incidents and page on-call teams through Splunk On-Call.
## You can use Splunk On-Call to escalate incidents and page policies or people.
***
## Setting up the integration with your incident.io account
Navigate to the [integration settings](https://app.incident.io/~/settings/integrations) within your incident.io account and search for 'Splunk On-Call' and hit Install.
You'll then be prompted to provide your API ID and API Key.
# Statuspage
Source: https://docs.incident.io/integrations/statuspage
Update customers automatically, without relying on one person to remember to log into Statuspage.
Did you set up a Statuspage to give [real-time status updates to your customers](/incidents/customer-updates), only to realize no one remembers to update it in the heat of an incident? Or only you really know how to because everyone else spends so little time in the tool?
Fear no more! To solve this, we've brought Statuspage right into Slack.
***
## Setting Up
You can add Statuspage to incident.io in just a few clicks.
## 1. Go to Settings > Integrations
Then hit Install next to Statuspage.
2. **Fetch your API key from Statuspage**
*We'll outline the steps below, but if you run into any trouble there's a lovely guide from Statuspage about how to* [create and manage API keys](https://support.atlassian.com/statuspage/docs/create-and-manage-api-keys/) *,*
First, head to [your Statuspage account](https://manage.statuspage.io/) and hover over the avatar icon in the bottom left.
Press API info > Create key.
Call it something nice and descriptive so it's clear to others what you're using this key for. Then hit Confirm.
3. **Paste the API key** into incident.io
Copy the token that was generated, and paste it in the incident.io Statuspage modal below.
4. **Select the Statuspage pages** you'd like to use
Not all plans are able to select multiple Statuspage pages. If you select more than one page, then we'll ask you which page you'd like to edit when you start an update.
5. Hit **Save**, and you're all set up with Statuspage!
***
## Creating & Updating Statuspage
Just head over to the incident's Slack channel and hit `/incident statuspage` !
This integration doesn't automatically update Statuspage for you. On top of our built-in [rule-based suggestions](/incidents/rule-based-suggestions) (see video), you could also set up a [Workflow](https://app.incident.io/~/workflows) like the one below to remind your team to update Statuspage:
***
## Notes
To avoid conflicts, we recommend against making manual changes to any Statuspages that are created by incident.io. There's some technical reasons for this which we'd happily nerd-out on if you're interested.
If you'd like some help setting up those workflows, get in touch!
## FAQs
Yes. Statuspage has a built-in feature that lets you pre-fill the impact, update text, and affected components, which makes it faster to write updates. All of the template configuration happens within Statuspage itself: use the `/incident statuspage` command in Slack and the modal will let you select which template you'd like to use.
# Microsoft Teams Online Meetings
Source: https://docs.incident.io/integrations/teams-meetings
Give every incident a dedicated Microsoft Teams call, created automatically the moment it's declared.
We offer a Microsoft Teams integration for **Slack** organizations. We'll **automatically generate and surface an individual call URL when an incident is declared**, so you have a dedicated 'war room' for every incident.
You can also manually create calls from the incident details page, or paste a link to the call in your incident slack channel, and we'll pick it up.
This helps speed up your incident response, and reduces the burden of manual tasks on responders.
## Installation
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Microsoft connections like this, which use OAuth, belong to a specific user. For this reason, you may wish to set up a dedicated service or "bot" account. We use the same user account connection for all our Microsoft integrations. Therefore, the account you use to connect this integration will need to be the same for Outlook Calendar.
[Read more about service accounts and the permissions we require](/integrations/microsoft-service-account).
## 1. Installing the Integration
Go to [Settings → Integrations](https://app.incident.io/~/settings/integrations), find **Microsoft Teams** and click **Connect**.
Click **Sign in with Microsoft** and you'll be redirected to the install flow within Microsoft. Review the permissions we're requesting and click **Next**.
## 2. Turn on auto-create call
If you wish to have calls auto-created when new incidents are declared, toggle on **Automatically create incident call**.
## Use
As well as auto-creation of calls, you can also manually create them from the dashboard and Slack.
## Creating call from the dashboard
Choose to start a call from the incident details page in the dashboard. If you've only got Microsoft Teams configured, we'll automatically create the call. If you have other providers, you'll be able to choose.
Responders will then see a link to the call in the dashboard and Slack.
## Creating call from Slack
From within your incident channel, use `/inc call` to create a new Microsoft Teams meeting.
If you already have a meeting created, you can paste a link to it, and we'll offer to attach it to the incident for you.
# Vanta
Source: https://docs.incident.io/integrations/vanta
Give your Vanta auditor automatic evidence of access reviews and incident follow-ups.
You can integrate Vanta with your incident.io account!
Using Vanta's Connectors API you can connect your Vanta account to track any follow-ups matching the conditions you define as Security Tasks in Vanta.
***
## What can I do with this integration?
1. Auditing of users with access to your incident.io account, and of those with elevated privileges. This lets your Vanta auditor quickly and painlessly check that you're being careful with giving out admin/owner privileges, and provides evidence that leavers are locked out quickly.
2. Track follow-ups as 'security tasks' inside Vanta: this lets security teams have their incident follow-ups tracked in Vanta, so they can provide evidence that they're meeting any SLAs on them (e.g. 'we complete all security tasks within 2 weeks, in compliance with SOC 2').
***
## How do I set this up?
1. Navigate to the [integrations settings](https://app.incident.io/~/settings/integrations) within incident.io and click **Install** next to the Vanta option. We'll bounce you straight to Vanta's app and ask you to accept the security policies.
2. Add conditions to incidents that should have their follow-ups tracked in Vanta.
It's as easy as that!
# Webex
Source: https://docs.incident.io/integrations/webex
Automatically create Webex meetings for incidents and enable Scribe transcription
## Webex
We can automatically create a Webex meeting whenever an incident is declared and attach it to the incident.
This helps speed up your incident response and reduces the burden of manual tasks on responders.
## Installation
### 1. Go to Settings → Integrations, find **Webex**
### 2. Click **Connect** on the Webex integration
### 3. Log in using a Webex organizational admin service account
The connecting user must be an organization administrator and have host privileges in your Webex organization.
It's important to know that when the integration is installed, the connection to incident.io will belong to **the user that installed it**. Webex connections like this, which use OAuth, belong to a specific user, for this reason, you may wish to set up a dedicated service or "bot" account.
Clicking **Connect** will redirect you to a Webex login page.
Once you've logged in and authorized the connection, you'll be redirected back to the dashboard.
### 4. Enable auto creation of incident calls
With Webex installed, you can now configure it to automatically create Webex meetings for your incidents. Toggle on **Automatically create incident calls**
### 5. Enable Scribe
To enable scribe for Webex meetings, your Webex administrator must authorize our Service App:
1. Sign in to the [Webex Admin Hub](https://admin.webex.com/apps/service-apps)
2. Navigate to Management > Apps > Service apps
3. Scroll down and select **incident.io Scribe**. If you are unable to find it, you can also search by app ID: `Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL0NjZmRiOTU2ZTE3NzUzNDhkMTg0MmRjYWYxZTZkZjg0MjQ1M2YzZjA1NTQyOWJiNTBiMWY1OTM4YmE0MzgyZjJl`
4. Click Authorize and then click **Save** to grant the required permissions
Once authorized, we will automatically detect this and enable Scribe for your Webex meetings.
## Permissions
* `spark-admin:people_read` - Enables us to add Webex users as a catalog type, so that we can link Webex users to incident.io users.
* `meeting:admin_schedule_write` - Enables us to schedule meetings on behalf of others. This is used to create meetings for the incident lead.
* `meeting:admin_schedule_read` - Enables us to add an existing meeting to an incident. For example, if you have an ongoing meeting and want to use that as the incident call instead of the automatically created one.
* `meeting:admin_participants_read` - Enables us to track which users are taking part in the incident call, allowing this to be shown in the incident timeline.
# Webhooks
Source: https://docs.incident.io/integrations/webhooks
Get notified the moment something changes in incident.io, so your other tools never fall out of sync.
Webhooks can be used to receive notifications when certain events occur in incident.io. This might be useful for annotating graphs in a monitoring tool with incidents, keeping track of follow-ups, or syncing on-call data like alerts, escalations, and schedule changes to external tools. Our webhooks are powered by [Svix](https://svix.com/).
## Getting started
To start using webhooks, you’ll need to create a webhook endpoint. You can do this in the same way that you’d create any other endpoint in your application.
If you’d like to play around with our webhooks, we’d recommend using [Svix Play](https://www.svix.com/play/) which allows you to set up an endpoint and inspect the payloads via their web interface. There are also other services (e.g. [ngrok](https://ngrok.com/) ) that have great debugging tools to help get started with webhooks.
## Status codes, errors, and retries
When processing webhooks, please return a 2xx status code (e.g. `200 OK` or `204 No Content`). If the endpoint returns a non-2xx status code, we’ll try to resend the event with a backoff over the next 24 hours.
If attempts to a specific endpoint repeatedly fail for over 5 days, we’ll mark the endpoint as disabled and notify you via email.
If you do miss some messages (e.g. due to unexpected downtime), Svix offers several options for [replaying messages](https://docs.svix.com/receiving/using-app-portal/replaying-messages) which you can access via [Settings > Webhooks](https://app.incident.io/~/settings/webhooks).
## Verifying webhooks
It’s important to know whether a webhook has come from incident.io, or a third party that might be trying to exploit a vulnerability. To avoid this, we send a `signature` in the header of our webhooks, which you can verify using a `Signing secret`.
The webhooks we send will have three headers that you’ll want to look at:
```plaintext theme={null}
{ "webhook-id": "123", "webhook-timestamp": 1676033031, "webhook-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=" }
```
You can verify the signature either using the [Svix client libraries](https://docs.svix.com/receiving/verifying-payloads/how), or manually by following [these instructions](https://docs.svix.com/receiving/verifying-payloads/how-manual).
## Keeping another system in line with incident.io
A common use case for webhooks is to keep another system up-to-date with everything that’s happening in incident.io. As we deliver webhooks individually over HTTPS, we cannot guarantee that they’ll be delivered in the correct order. That means that to keep the other system up-to-date, we’d recommend that you build an application that:
* Receives a webhook about a resource (e.g., an incident, alert, or escalation)
* Makes a request to our public API to get the latest state
* Save that state to your system
This means you aren’t relying on the order in which you receive webhooks to make sure your system remains up-to-date.
## Webhooks on private resources
In general, we try to send webhooks with all the relevant information in the payload (e.g. the name, summary, status, etc.). However, private resources are the exception.
For private incidents, alerts, and escalations, we only send the ID of the resource that's been changed. If your integration needs to access the full data, you'll need to [create an API Key](/integrations/api-overview) with private access. You can then use that key to get the details about the specific resource. This is to make sure we don't leak information about private resources to a system that shouldn't have access to them.
For more information, check out our [API docs](https://docs.incident.io/api-reference/webhooks).
Our webhooks are not currently HIPAA compliant, and are therefore excluded from our BAA.
# Using Zapier
Source: https://docs.incident.io/integrations/zapier
Trigger incidents automatically from any app you connect through Zapier.
Connect your Zapier account with incident.io to declare incidents when something happens in another system.
1. First, install the incident.io Zapier app, by clicking **Accept Invite & Build a Zap** on this [invite page](https://zapier.com/developer/public-invite/162447/c60b514649e6aeb2a3d29594e7943a9d/).
2. Click **Create Zap** and choose a trigger from one of your other systems. For this example we're using the **incoming email** trigger:
3. In the **Action** section, search for "incident.io":
4. Select the **Create Incident** action:
5. Click **sign in** to add an API key:
This will open a new window where you can paste in an API Key. Generate one from the [**API Keys** section of our dashboard](https://app.incident.io/~/settings/api-keys). You'll need to give it permission to create incidents, view data (like public incidents and organization settings), and view catalog types and entries.
6. Paste the key into Zapier, and click **Yes, Continue**
7. Now configure the incident information: the minimum required fields are:
* **idempotency key**: we'll only ever create one incident for each unique value here, so this should be something that uniquely identifies the trigger. In this example, each email is assigned a **Message ID**, so using that as the idempotency key means we'll only open one incident for each email.
* Severity: select this from the dropdown
* Visibility: whether this incident should be public or private
You can also pre-fill custom fields, and assign roles by either email address or Slack user ID.
# Zendesk
Source: https://docs.incident.io/integrations/zendesk
Keep support agents and responders in sync, without anyone switching between tools.
During an incident, communication with your customers is key!
With incident.io we can help. We'll enable your incident response team to communicate better with your support team, providing updates on both sides.
This integration allows you to link Zendesk tickets directly with your incident, relaying comms between the two places and ensuring everything is well connected. Engineers will have visibility on communications coming from your customers and support agents will be kept up to date on ongoing issues.
Read on to find out how to get started!
***
## Setting up
You can add Zendesk to incident.io and configure the settings in just a few clicks.
1. Go to Settings → [Integrations](https://app.incident.io/~/settings/integrations)
Scroll down to **collaborate** and click **Connect** next to Zendesk
2. Type in your subdomain
Click `Go to Zendesk` and approve authorization of incident.io
3. Copy the token provided
Click the `Install the Zendesk app` button
4. Paste in the token into the Zendesk UI
Press `Install` to complete
Once your account is connected you can start powering up your teams!
***
## Attaching tickets
Now that your account is connected you can start to attach tickets to your incidents.
When your support agents are viewing a new ticket they will have a snapshot into any ongoing incidents you and your responders are managing.
They’ll be able to search for incidents with certain keywords, to check if the ticket in front of them is related to an existing incident.
When the agent finds the relevant incident, they’ll be able to attach it from within Zendesk and have visibility on any updates.
Additionally, if a Zendesk ticket link is pasted into an incident channel this will attach the ticket to the incident.
Top tip! If you would like incident.io to appear at the top of your app list in Zendesk, learn how to [reorder your apps](https://support.zendesk.com/hc/en-us/articles/4409155972378-Managing-your-installed-apps#topic_tc5_qn4_ym).
***
## Ticket updates
Once a Zendesk Ticket is attached, we'll keep it in sync with an incident.
Any updates on the incident - such as a change in severity, or a status update from your incident lead - are added as internal notes on the ticket.
Similarly, any comments on the ticket are relayed into the incident channel.
***
## Updating your incident channel
With this integration we'll make it easy for everyone involved in an incident to get updates.
* Attaching tickets pushes a notification to your incident channel *This gives responders a quick insight into customer communications and start to get an understanding of the potential impact of the issue.*
* Responses and internal notes in Zendesk are pushed to your incident channel. *This gives your responders real time updates directly from customers with information that could help them to debug the issue.*
***
## Tagging tickets
Any Zendesk user will know the power of the tag and when it comes to incident.io it's no different!
Every time an incident is attached to a ticket a tag will be added (`incident/[id]`). If you decide that the ticket isn't related to the incident, you can simply remove it.
Tagging incidents will also allow you to perform bulk actions.
* Attach multiple tickets to ongoing incidents
* Remove tickets from ongoing incidents
Tags will allow you to get a snapshot into the scale of an incident and provide important data for your post incident process.
***
## Catalog types
Once you connect Zendesk, you can configure incident.io to pull through organizations from Zendesk into Catalog. This will then allow you to create a custom field based on that Catalog type. This is useful as a way to tag which customers are affected by an incident without having to manually upload a customer list to incident.io via a separate sync process.
To enable this sync, switch the toggle in Settings > Integrations > Zendesk and click **Save**.
***
We hope you love the Zendesk integration as much as we do! If you have any questions or feedback please don't hesitate to [get in touch](mailto:support@incident.io).
# Zoom
Source: https://docs.incident.io/integrations/zoom
Save responders the extra step of creating a Zoom call by hand for every incident.
Having responders create a Zoom meeting whenever they start an incident is best practice, but it's also easily forgotten and not very scalable...
We can take on that work for you! We'll **automatically generate and surface an individual call URL when an incident is declared**, so you have a dedicated 'war room' for every incident.
***
## Installation
You can add Zoom to incident.io and configure auto create in just a few clicks.
### 1. Go to Settings → Integrations
### 2. Click **Connect** on the Zoom Integration
### 3. Log in using a service account
Clicking **Connect** will take you to the Zoom Marketplace, where you'll be asked to sign in and install the app by accepting the permissions.
To access our full range of incident calls features, you'll need to install with an account that has role permissions to view users, and check the box **Allow this app to use my shared access permissions**.
Make sure to create/sign in with a [service account](#faqs)!
On the following screen you will be able to see which permissions our app requests.
Be sure to tick the option to allow shared access permissions at the bottom.
Without this, features such as Scribe will not work correctly and we will not be able to call participant information to display which users are currently on the call.
After authorizing the app, you'll be redirected back to the integrations page where Zoom should show as connected.
### 4. Enable auto create
With Zoom installed, you can now configure it to automatically create video calls for your incidents.
### 5. All set!
You're good to go.
## Automatically creating calls
With this configuration applied, incident.io will create a Zoom meeting whenever an incident is declared.
* The meeting link will be set to the incident's Call URL, display in the dashboard and anywhere the incident is mentioned.
* We'll also message about the Zoom meeting in the incident channel, with an easy **Join Call** button.
If you need help with this, [get in touch](http://incident.io/community) !
## Permissions
Installing Zoom will authorize incident.io to:
* **View and manage meetings** : so we can create meetings in this users name
* **View and manage recordings** : so we can automatically record these meetings (should it be requested)
* **View user information** : to help us identify the Zoom user and link them to their Slack identity for debugging of the integration
* **View user settings** : to read password requirement settings
Additionally, ensure that your settings in the Zoom workspace allows users to request local recordings, this will allow Scribe to start transcribing the call.
## Connecting multiple accounts
Zoom allows only a single access token per app, per user. This means that once you connect incident.io to Zoom, any previously issued access token for that app and user is invalidated. This means that if (for example) you have a production account connected to Zoom, and you then connect the same Zoom user to your sandbox account, that the production account will be disconnected from Zoom.
This behavior from Zoom aligns with OAuth 2.0 best practices to ensure secure access control and prevent simultaneous sessions with multiple tokens.
## FAQs
We recommend using a **service account** rather than a real team member's account. Whoever incident.io authorizes against gets assigned as the Zoom meeting host, so using a real person's account means:
* It might be confusing to imply a human created the meeting rather than a dedicated bot account
* It's always the same person, which adds to the confusion
* That person's calendar fills up with every incident call
* You lose access to the Zoom integration if that person leaves
Yes. Visit [https://app.incident.io/api/zoom\_uninstall](https://app.incident.io/api/zoom_uninstall) to revoke the existing credentials and clear any Zoom data from incident.io's systems.
# Getting started
Source: https://docs.incident.io/investigations/getting-started
Connect your sources and run your first investigation.
Investigations get better the more context they can draw on. Connecting your sources takes a few minutes each, and you can start with whichever you have to hand. Every source you add makes investigations more grounded.
Everything below is configured from the [Investigations settings](https://app.incident.io/~/investigations) in your dashboard.
## 1. Connect your sources
Let investigations find similar incidents from your history and the fixes that worked before. See [Past
incidents](/nexus/past-incidents).
If you use Slack, add the channels where your team shares deploys, config changes, and incident context. See [Slack
channels](/nexus/slack). Connecting channels as a source is available for Slack only. Investigations in Microsoft
Teams still read their own incident channel, but can't draw on other channels.
Sync your runbooks and reference docs from Confluence, Notion, GitHub, or GitLab. See
[Documentation](/nexus/documentation).
Connect GitHub or GitLab so investigations can link relevant pull requests and read your code. See [Code
setup](/nexus/code/overview#setup).
Connect the observability tools your team uses during incidents. See [Telemetry](/nexus/telemetry/overview).
Connect the dashboards and data sources your team actually reaches for during an incident. The closer they reflect
your real workflow, the more useful investigations will be.
## 2. Choose when investigations run
Decide whether investigations run for every incident, only when conditions are met, when a workflow triggers them, or only on demand. See [Triggering investigations](/investigations/triggering) for the options.
## 3. Run your first investigation
Create a test incident and trigger an investigation to see it in action. In Slack, use `/inc investigate` in the incident channel. Otherwise, set investigations to run automatically or trigger one from a [workflow](/investigations/triggering).
## What's next
* **See what an investigation can read**: the conversation, the call, shared files, and your incident's own details. See [What we can see](/investigations/what-we-can-see).
* **Understand how we measure it**: how we grade investigations for accuracy and use it to keep improving them. See [Measuring accuracy](/investigations/measuring-accuracy).
* **Try the agent**: ask about logs, code changes, past incidents, or recent deploys. In Slack, tag `@incident` in the incident channel; in Microsoft Teams, use the incident tab; or chat from the dashboard on either platform. See the [agent docs](/ai/at-incident).
* **Share feedback**: use the thumbs up/down buttons on investigation messages, and tell us what's working and what isn't.
# How investigations work
Source: https://docs.incident.io/investigations/how-investigations-work
From the first alert to a root cause backed by evidence.
An investigation isn't a single prompt to a model. It's a structured process that gathers evidence, forms a hypothesis, then tests that hypothesis against your code and telemetry, refining its conclusion as new evidence arrives. This page explains how that process works, so you know what to expect from the results and why connecting more sources makes investigations better.
## The shape of an investigation
Every investigation moves through three phases.
The investigation starts from what it already knows: the alert that fired (including any error and stack trace) and
the message that declared the incident. This gives it an initial read on what happened and where, in seconds.
While that initial picture forms, the investigation fans out across every source you've connected, all at once:
searching Slack for relevant discussion, finding similar past incidents and what resolved them, surfacing the
runbooks and reference docs that apply, lining up recent deploys, feature flags, and config changes from your change
events, pulling in the code changes that could be responsible, and querying your telemetry for anomalies around the
time of the incident. It also checks whether any third-party providers you depend on were having an outage at the
same moment. All of this runs in parallel, so the slow searches never hold up the rest.
The investigation pulls the gathered evidence into an initial hypothesis, then looks for what's missing. It asks
targeted follow-up questions (often by reading your code or running further telemetry queries) and feeds the answers
back in. Each pass makes the hypothesis more specific and better grounded.
The first two phases run the same way for every incident; they're the foundational legwork. The third phase is where each investigation becomes specific to your incident, shaped entirely by what the evidence reveals.
## Investigations run throughout the incident
An investigation doesn't stop after its first report. It keeps running for as long as the incident is live, re-assessing as the situation changes. New activity in the channel, fresh alerts, a third-party provider changing state, or a responder steering it: any of these prompt the investigation to gather new evidence and reconsider its hypothesis.
This means the investigation stays current with the incident rather than going stale the moment it posts. If the cause shifts, or new information rules out the original theory, the investigation follows along.
Investigations keep going until the incident is resolved or declined. You can also pause one if you'd rather it
stopped, and pick it back up later.
## From evidence to findings
The investigation reasons in terms of **findings**: concrete hypotheses about what happened, each backed by **evidence**.
* A finding is a claim, like "a recent deploy introduced a query that locks the orders table under load."
* Evidence is what supports or contradicts it: a specific Slack message, a pull request diff, a metric spike, a line of code.
* Each finding carries a **confidence** level, so you can see how sure the investigation is.
Findings evolve as the investigation progresses. A hypothesis that looks promising early on can be **discounted** when later evidence contradicts it, and the investigation keeps that audit trail rather than quietly dropping it. The final report surfaces only the findings still standing, each linked back to the evidence behind it.
This is why investigations improve as you connect more sources. A finding grounded in a real code diff and a matching
metric spike is far stronger than one inferred from an error message alone.
## Building conviction
An investigation doesn't just look for evidence that fits its theory. It spends as much effort trying to break it. Roughly half of an investigation's work goes not into forming a hypothesis but into challenging and proving it: looking for the evidence that would *disconfirm* the leading theory, ruling out the alternatives, and, when it confirms a trigger like a deploy, checking what else that trigger might have affected. A theory that has only ever been supported, and never tested, isn't one it trusts.
This is why an investigation won't claim more certainty than it has earned. Before it presents a hypothesis, it grades its own **conviction** in it, based on how strongly the evidence backs it, and that grade drives the confidence you see in the channel.
| Conviction level | What it means |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **Speculation** | Too little to anchor on. |
| **Pattern match** | Fits the alert data and resembles past incidents or general knowledge, but nothing specific to this incident confirms it. |
| **Supported by context** | Incident-specific context (your code, the discussion, a stack trace) backs the mechanism, but no live system state has verified it yet. |
| **Validated by system state** | Independent system state, like logs, metrics, traces, or a database read, verifies it, though other explanations remain plausible. |
| **Validated, alternatives ruled out** | System state verifies it *and* the alternatives have been ruled out or are implausible. |
Two outcomes override that ladder: a hypothesis is marked **contradicted** when newer evidence disproves it, and flagged when an **alternative is just as likely**, meaning two theories with equal support that the evidence can't yet separate.
An investigation only reaches the top of the ladder, and only tells you it's highly confident, when it has found compelling, verifiable evidence against the data sources it trusts, like your logs, metrics, and traces. When it can't find that proof, it says so: it lowers its confidence and is explicit about what it couldn't confirm, rather than dressing a guess up as a conclusion.
This conviction is the investigation's own assessment of a live theory. Separately, we grade investigations against
what really caused past incidents to measure and improve them over time. See [Measuring
accuracy](/investigations/measuring-accuracy).
## Reading your code
When an investigation needs to understand the code itself, it does more than search for keywords. It works out which repositories are relevant from the incident's context, plans the specific questions worth answering ("where is this value set?", "what changed here recently?"), and then reads the code to answer them.
All code analysis runs inside isolated, sandboxed containers. Repositories are cloned into ephemeral workspaces and deleted after use. See [Code setup](/nexus/code/overview#setup) for how access and security work.
## Querying your telemetry
Investigations query the same logs, metrics, traces, and dashboards your responders reach for. Rather than blindly running queries, the investigation learns the shape of each connected data source (its labels, common query patterns, and the dashboards your team actually uses) so its queries are relevant to your systems. See [Telemetry](/nexus/telemetry/overview) for the providers you can connect.
## Checking your dependencies
Not every incident is your fault. Alongside everything else, an investigation checks whether the third-party providers you depend on (AWS, GitHub, Stripe, and the like) were having an outage around the time of your incident, and surfaces any that could explain it. This needs no setup. See [Third-party dependencies](/investigations/third-party-dependencies).
## What you get
The investigation posts a summary into the incident channel and keeps it up to date as it runs, with the same detail available on the incident in the dashboard. It surfaces:
* **A summary**: the headline conclusion in plain language.
* **Findings**: the hypotheses that survived, each with its confidence and supporting evidence.
* **Evidence**: links straight back to the source: the Slack message, the pull request, the dashboard, the log line.
As it learns more, it threads progress onto the summary and posts a heads-up when it discovers something important, and you can ask it questions or steer it at any point by tagging `@incident`. See [Incident channel experience](/investigations/incident-channel-experience) for what this looks like and how to interact with it.
## Investigate alongside the agent
The investigation runs centrally, but you don't have to work apart from it. With the incident.io desktop app, you can pull a live investigation into a local coding agent such as Claude Code, Codex, or Cursor and investigate side by side, each of you informing the other.
It works as a loop:
* **Pull the investigation in**: your local agent downloads the full investigation: its findings, the checks it ran, the incident context, and the conversation so far. It can read all of this alongside your actual codebase.
* **Get live updates**: as the central investigation learns more, your local agent keeps in sync, so you're always working from its latest thinking.
* **Send what you find back**: when you spot something the investigation hasn't (the real cause, a misleading metric, a wrong turn it's taking) you can steer it. Your local agent feeds that back, with evidence, and the central investigation re-assesses its hypothesis within a few minutes. Your input is attributed in the incident channel, so everyone sees where a change in direction came from.
The two work as a pair: the central agent does the broad, continuous legwork across all your sources, while you and your local agent go deep on the code in front of you, and neither of you loses what the other finds.
The desktop app connects incident.io to your local agent over the [incident.io MCP](/ai/remote-mcp). Mention an
incident by reference (like `INC-123`) and a capable agent can pull it in and start working.
## Tuning how deep investigations go
Investigations run more than one pass of analysis by default, refining the hypothesis each time. More passes mean a more thorough investigation but a slower one. If you'd like to adjust how deep investigations go for your organization, reach out to us.
## FAQs
Rather than guessing from too vague a brief, an investigation holds off and waits until there's enough to go on
before it starts digging, so it doesn't chase a cause unrelated to the actual problem. You can give it what it needs
by tagging `@incident` in the channel. See [Ask and steer with
@incident](/investigations/incident-channel-experience#ask-and-steer-with-incident).
No. There's nothing to train. Investigations index your repositories and incident history automatically and keep
that understanding fresh over time, so you get value by [connecting your sources](/nexus/overview), not by teaching
the system.
Yes. Investigations continually re-explore your connected sources and revalidate what they've learned. If your team
changes something, like a log format, the system discovers that and adjusts on its own, without you needing to tell
it. See [Learning your stack](/nexus/telemetry/overview#learning-your-stack).
Yes. Investigations are deliberately general, not overfit to "the website is broken." Teams run them on all kinds of
incident, from security issues to operational and real-world ones, not just software failures.
## Where to go next
The sources an investigation draws on, and how to set each one up.
How investigations stay under your control, auditable, and honest about what they know.
Decide when investigations run.
# Incident channel experience
Source: https://docs.incident.io/investigations/incident-channel-experience
What an investigation looks like in your incident channel, and how to talk to it.
Most of an investigation happens in your incident channel, in Slack or Microsoft Teams. This page covers what you'll see there (the summary message, the progress updates, and the heads-ups) and how to ask questions or steer the investigation as it runs.
The walkthrough below describes the experience in Slack. Investigations work in Microsoft Teams too, with a few
differences. See [In Microsoft Teams](#in-microsoft-teams).
## The summary message
When an investigation starts, it posts a single **summary message** to the channel and keeps it up to date in place. It's kept short and scannable, with headers for the things a responder most wants to know:
* **What's going on?**: the situation in plain language.
* **What caused it?**: the current best hypothesis.
* **What can I do next?**: concrete next steps, linked to the evidence behind them.
While the investigation is still working, the message shows its progress and what it's still checking. As it learns more, the same message updates, so the channel always shows current thinking, never a stale first guess.
> **What's going on?**
> The Redis instance in production is sustaining CPU above 50% (measured at 55.3%), which triggered an operational alert.
>
> **What caused it?**
> The elevated Redis CPU is plausibly linked to increased worker queue load, particularly from the `statuspage-worker` process, a pattern seen in past incidents.
>
> **What can I do next?**
>
> * Correlate the Redis CPU spike with `statuspage-worker` queue metrics in Grafana for the incident window
> * If they line up, temporarily gate the event subscriptions driving Redis load
> * Keep watching Redis CPU and workload metrics over the next 30 minutes
## Progress in the thread
As the investigation works, it posts updates into the thread beneath the summary, so you can watch what it's doing as it does it. You don't need to read these to follow along (the summary always reflects the latest) but they're there when you want the detail.
You'll see things like:
* **Hypothesis updates** when its thinking changes, labeled so you can see the shift at a glance, such as "New hypothesis", "Hypothesis strengthened", or "Hypothesis weakened".
* **Check results** as each piece of work completes: a short summary of what it found, with links to the source.
> **New hypothesis**
>
> * I'm now looking at upstream rate limiting from the payments API, with sustained 429s and flat database metrics
> * Shifted away from the earlier database contention theory
> * Next: checking whether the payments API quota was changed recently
> **Querying telemetry**
>
> * A core deploy shipped 11 minutes before the first error (PR #54586), and the build SHA matches
> * 107 successful responses vs 4 server errors over 4 hours, with no latency spike
>
> Links: Grafana dashboard, PR #54586
This thread is read-only, it's where the investigation shows its work. To ask a question or steer the investigation,
tag `@incident` in the main channel instead.
## Heads-up messages
The summary and thread are there whenever you choose to look. But sometimes the investigation works out something important that you probably don't know yet, and waiting for you to check back isn't good enough. In that case it posts a **heads-up message** to the channel, with the detail in a thread.
> **Heads up:** I think this could be database connection pool exhaustion.
>
> The auth-gateway connection pool hit saturation (50/50) at 14:23 UTC, exactly when errors started spiking.
Heads-ups are deliberately quiet. The investigation only posts one when there's a genuine shift worth your attention (a code change that explains the error, a past incident with the same fingerprint, a third-party outage) so they read as progress, not noise. The thread carries the supporting evidence and links, including any similar past incidents.
## Ask and steer with @incident
The investigation isn't a one-way broadcast. At any point you can talk to it in the channel by tagging `@incident`.
### Ask about the investigation
Ask questions about what it's found or why it thinks what it thinks, and it answers from everything the investigation knows.
> @incident why do you think this is a Redis problem and not Postgres?
> @incident has anything like this happened before?
### Steer it
If you know something the investigation doesn't, whether the real cause, a misleading signal, or a wrong turn it's taking, tell it what to focus on instead. It feeds that in and re-assesses its hypothesis within a few minutes, and your input is attributed in the channel so everyone can see where the change in direction came from.
> @incident the investigation is wrong. It's Redis, not Postgres. Connections have been at 100% since 14:32.
> @incident focus on the 14:30 deploy of payment-service v2.3.1. The errors started right after it. The integration warnings are unrelated noise.
You can also steer from the investigation message directly using **Add context**, or from the incident in the
dashboard. Engineers working in a local coding agent can steer it too. See [Investigate alongside the
agent](/investigations/how-investigations-work#investigate-alongside-the-agent).
## In Microsoft Teams
Investigations work in Microsoft Teams too. The same summary and heads-up messages post to your incident channel, and the investigation reads the channel just as it does in Slack. A few things work differently.
* **The full investigation lives in an embedded tab.** The messages posted to the channel are kept light; the complete investigation (every finding, the evidence behind it, and the checks it ran) opens in a Teams tab from **View full investigation** on the summary message.
* **Ask and steer from the tab, not with `@incident`.** Tagging `@incident` in the channel isn't supported in Teams. Instead, use **Chat to incident about this** on the investigation message: it opens the investigation in the embedded tab with an agent chat alongside it, where you can ask questions and steer just as you would in Slack. You can also **Add context** from the investigation message, or steer from the incident in the dashboard.
* **Progress updates depend on your channel layout.** In channels that use the threads layout, progress is posted as replies beneath the summary, as in Slack. In channels that use the posts layout, the summary can't be threaded, so it updates in place instead.
We recommend the **threads** layout for your incident channels. It keeps each investigation's progress in a thread
beneath its summary, closest to the Slack experience, rather than updating the summary in place.
## Related
The process behind what you see in the channel.
The context an investigation reads from inside your incident, including the channel and call transcripts.
Everything else you can ask the agent during an incident.
# Measuring accuracy
Source: https://docs.incident.io/investigations/measuring-accuracy
How we grade investigations against what really caused your incidents, and use those scores to make them better.
We hold investigations to the same standard you would: would acting on this have actually fixed the incident? To answer that at scale, we grade past investigations against the cause your responders established, score them for accuracy and a handful of supporting metrics, and use the results to find where investigations in your account can improve.
This is different from the confidence an investigation shows in the channel while an incident is live. That's its own
real-time read on how well-evidenced its current theory is, covered in [Building
conviction](/investigations/how-investigations-work#building-conviction). Accuracy is measured *afterwards*, against
what turned out to be true.
## Which investigations we measure
Every investigation on a closed incident appears in the table on your [Investigations page](https://app.incident.io/~/investigations), but not all of them carry a score. Measuring one needs two things:
* **A known cause.** Your responders established what actually caused the incident. That's the ground truth we grade against, so an incident that closed without one has nothing to compare the investigation to and shows as **Not scored**.
* **A diagnosis we can attribute.** We can locate the moment the cause was understood and trace the steps that got there. See [Measuring autonomy](/investigations/measuring-diagnosis) for how attribution works.
Trends and aggregate statistics build on those measurements, so they appear once enough incidents qualify.
## How we grade accuracy
Once an incident is closed and its real cause is known, we compare what the investigation concluded against the **ground truth**: the cause and the key findings your responders established. We grade by simulation: if a responder mid-incident had taken the investigation's headline diagnosis and acted on it, where would they have ended up, compared with what actually needed fixing?
That gives a score on a four-point scale:
| Score | Grade | What it means |
| -------- | ------------ | ----------------------------------------------------------------------------------- |
| **100%** | Bullseye | Correct diagnosis. Acting on it would directly fix the incident. |
| **65%** | On target | Correct, but incomplete. Responders would need to dig further to fix the incident. |
| **35%** | Miss | Names the right area, but acting on the diagnosis wouldn't have fixed the incident. |
| **0%** | Nowhere near | Points responders at a different part of the system entirely. |
### Why these thresholds
The scale measures how useful the diagnosis would have been to a responder who acted on it. Each grade answers a question, and the grades build on each other from the bottom up.
If the diagnosis sends responders somewhere unrelated to the actual fault, nothing else about it can help. A wrong
location, whatever its reasoning, scores **0%**.
Naming the right area isn't enough on its own. A diagnosis can identify the right component but explain it in a way
that sets responders to work that wouldn't have resolved the incident, like reverting the wrong change or
remediating the wrong layer. The right area with the wrong course of action scores **35%**.
A diagnosis can lead to the fix while leaving responders one step to find themselves: a trigger it didn't identify,
a final hop in the chain. They reach the fix, just not immediately. Right place but one piece missing scores
**65%**.
The right component, the right mechanism, and nothing in the diagnosis that the ground truth rules out mean acting
on it leads straight to the fix. That's a bullseye, **100%**.
What makes an investigation *good* is the jump from 35% to 65%. Both look close to the answer, but only a 65% actually leads responders to the fix. They still have to spend time finding the final piece, but it gets them there. A 35% on the other hand leads them to work that wouldn't have resolved the incident. It's a small gap in score, but marks a large gap in usefulness: the difference between a delay and a wrong turn.
Grading is also deliberately **fair to the investigation**. A claim only counts against it if the ground truth actually rules it out; where the ground truth is silent, the investigation gets the benefit of the doubt. And a wrong file name or an imperfect fix suggestion never lowers the score when the diagnosed cause itself is right: we grade the diagnosis, not the prescription.
## Why accuracy comes first
Accuracy matters because it's the precondition for everything else, though it isn't the whole of the value, and the difference is worth being precise about.
An AI SRE product provides value through **engagement**: responders reading what it surfaces, checking what it suggests, steering it, and acting on it. None of that happens if the information can't be trusted; nobody engages with a system that's usually wrong. Accuracy is what makes engaging with an investigation worth a responder's time. In our experience, **65% is the inflection point**: below it, responders treat an investigation as a maybe and re-check everything themselves; above it, they find it's almost always telling them something useful (if not the exact answer, then a genuine head start) and engagement takes hold.
From there, a lot of the value comes from the moments an investigation creates, rather than from being right end-to-end. A [heads-up](/investigations/incident-channel-experience#heads-up-messages) that turns out not to be the cause can still be the thing that reminds a responder to check something they hadn't, and advances the incident. So we pay as much attention to how teams actually engage with investigations as we do to the accuracy score itself, because that engagement is where the return ultimately shows up.
So when you evaluate an investigation or AI SRE system, whether ours or anyone else's, treat accuracy as the entry bar rather than the finish line. Ask how it's measured, on which incidents, and whether it clears the threshold that makes it worth engaging with. Any system that doesn't meet that bar won't see the engagement that drives value; one that clears it should be judged on the value it goes on to create.
## Beyond accuracy
Accuracy is the headline, but not the whole picture. We track a few supporting metrics so we can see *why* an investigation scored the way it did.
### Reach
Whether the investigation actually got to the evidence it needed. Reach separates a reasoning problem from an access problem: a low accuracy score paired with low reach usually means the answer was somewhere the investigation couldn't get to, not that it thought poorly.
For example, if the real cause was connection-pool exhaustion visible only in a database the investigation wasn't connected to, it can reason perfectly and still miss, purely due to lack of reach. That tells us connecting that database would do more for your account than any change to the model.
### Findings quality
How well the investigation's individual findings match the ones your responders established, measured as precision and recall:
* **Precision**: of the findings it surfaced, how many were real. If it raised four findings and three held up while one was a red herring, that's 75% precision.
* **Recall**: of the findings that mattered, how many it found. If five findings were key to the incident and it surfaced three of them, that's 60% recall.
The two pull against each other: an investigation that lists every possible factor scores high on recall but low on precision as it buries real findings in noise. Conversely, one that only commits to its single surest finding scores high on precision but low on recall, because it misses things. We combine them into an **F1 score**, which only rewards doing both well: finding what matters, without padding it with noise.
### Overall signal
A single measure that combines accuracy and findings quality, so we can track the trend for an account in one number: whether investigations are getting better or worse month to month, and whether a backtested change moved things in the right direction overall.
## How we use accuracy scores
Once an incident closes and its cause is established, we grade the investigation automatically. That gives us, and you, a continuous picture of how investigations perform in your account, rather than a one-off sample.
Those scores aren't just a report card; they're how we find and fix weak spots:
* **Spotting opportunities.** Patterns in the scores tell us where investigations in your account underperform: a telemetry source it isn't querying well, a kind of incident it consistently struggles with, evidence it keeps missing.
* **Driving improvements.** Those opportunities feed changes to the things that drive accuracy: the prompts, the [telemetry guidance and memory](/nexus/telemetry/memory) that teach investigations your stack, the models, and internal tuning.
* **Specific to your systems.** Because grading uses your incidents and your ground truth, the opportunities we find are specific to your environment rather than a generic average.
## Backtesting
Continual scoring tells us how investigations are doing today. **Backtesting** lets us ask "what if?". We re-run investigations across a set of your past incidents where the real cause is already known, and score the results the same way. We use it for two things.
### Catching regressions
We don't ship a change to investigations and hope. As we evolve the system through new models, new prompts, and internal tuning, we backtest against historical incidents. We compare the scores against the previous run, with each incident investigated several times so run-to-run variation doesn't skew the result. A change that would lower accuracy shows up here, in a backtest, rather than in your live incidents. Run regularly, this is how we keep pushing accuracy up while making sure investigation performance never quietly degrades as the system evolves.
### Testing a change before you make it
Backtesting works just as well for changes on your side. If you're weighing whether to connect a new telemetry source, or to improve the runbooks you've already connected, we can re-run investigations over your past incidents, with and without the change, and show you the difference in accuracy. You see how we'd have performed on real incidents you've already handled, before committing to anything.
Backtests aren't self-serve, so [get in touch](mailto:support@incident.io) and we'll run one for you. Backtest investigations run entirely in the background, and never post anything into your incident channels.
## FAQs
The real cause and the key findings your responders established for an incident. Because humans sometimes stop
digging once an incident is mitigated, the ground truth can be incomplete; where it's silent, we don't penalise the
investigation for committing to a plausible explanation.
Not on its own. A low accuracy score with low reach usually means the investigation couldn't get to the evidence it
needed (often a missing or under-connected data source) rather than that it reasoned badly. Low scores often
highlight such opportunities.
No. Grading and backtesting use your incidents and your ground truth, scoped to your account.
The confidence you see in the channel is the investigation's real-time assessment of how well its current theory is
evidenced. See [Building conviction](/investigations/how-investigations-work#building-conviction). Accuracy is
measured after the fact, against the cause that was eventually established.
## Related
The process behind a result, and how an investigation builds conviction in real time.
How we measure the way responders actually use an investigation, from reading it to acting on it.
How investigations stay under your control, auditable, and honest about what they know.
How investigations learn to query your stack better over time.
# Measuring autonomy
Source: https://docs.incident.io/investigations/measuring-diagnosis
How much of each incident's diagnosis Investigations drove on its own, and how much faster incidents reach a diagnosis when it leads.
[Accuracy](/investigations/measuring-accuracy) tells you whether an investigation's diagnosis was right. **Autonomy** answers a different question: **who surfaced the relevant clues to get to the answer?** For each incident we work out how much of the diagnosis Investigations drove on its own, and how much came from your responders. Alongside that we measure **time to diagnosis**, so you can see how much faster incidents reach an answer when Investigations leads.
Both appear on the [Investigations page](https://app.incident.io/~/investigations) in your dashboard, under **Autonomy**.
## How we work out who diagnosed it
Once responders establish an incident's cause, we look back over everything that happened before the cause was understood (channel messages, incident calls, and the investigation's own findings) and reconstruct the **diagnostic chain**: the small number of steps that were genuinely key to reaching the answer. Exploration that didn't pan out doesn't count, and neither does anything after the diagnosis. Confirmation and remediation are important work, but they aren't diagnosis.
Each step is attributed to whoever **first surfaced** it. Attribution comes from the evidence behind the step: the message, call moment, or investigation finding that delivered the result. If a step's results arrived in an investigation finding, the step is the investigation's; if they arrived in a responder's message, it's the responders'; a genuine collaboration counts toward both.
The balance of steps places each incident in one of four bands:
| Band | What it means |
| --------------------- | ------------------------------------------------------------------------------------------------------- |
| **Autonomous** | Investigations reached the correct diagnosis independent of responder input. |
| **Mostly autonomous** | The incident was diagnosed mainly by Investigations, with a small amount of assistance from responders. |
| **Mostly manual** | The incident was diagnosed mainly by responders, with a small amount of assistance from Investigations. |
| **Manual** | Responders reached the correct diagnosis independent of Investigations input. |
Between the two extremes, the band goes to whichever side drove the majority of the steps. On a dead-even split, it goes to whoever surfaced the first load-bearing clue.
### An example
Here's how an example incident breaks down:
Checkout starts returning 500s. Within a minute, the investigation traces the errors to a single downstream (the
payments service) and posts a heads-up. First diagnostic step, attributed to Investigations.
It pulls the payments service's logs and surfaces a spike of database connection-pool timeouts that lines up with
the error rate. Second step, again the investigation's: it recovered the evidence that mattered.
A responder recognizes that the timeouts began right after a deploy that cut the connection-pool size, and names
that as the cause. This is the moment the cause is understood, so it ends the diagnostic chain and stops the
time-to-diagnose clock. As the step that named the cause, it's the responder's step.
Responders restore the pool size. The fix comes after the diagnosis, so it doesn't affect which band the incident
lands in, or its time to diagnose.
Three steps in all, two of them the investigation's, so this incident lands in **Mostly autonomous**: the band
follows who did the majority of the diagnostic work, not who spoke the final diagnosis.
Note that credit goes to whoever surfaced each piece of the answer first, regardless of what happened next. If an investigation names the root cause in its hypothesis but responders investigate independently and arrive at the same answer themselves, the credit is still the investigation's: it found the answer first, even though its version wasn't the one responders acted on. That's why we frame this around who *diagnosed* the incident rather than who *fixed* it: it measures who found the answer, not whose work resolved the incident.
Because this breakdown credits whoever surfaced each finding first, it deliberately doesn't tell you how much of an
investigation's content responders actually used. That's what [engagement](/investigations/measuring-engagement)
measures: whether responders read, steered, and acted on what an investigation surfaced. Read the two together: an
investigation can drive the diagnosis and still see little engagement, or see heavy engagement without leading the
diagnosis.
## Time to diagnose
For each incident that reached a diagnosis, we measure the time from the **start of the investigation** to the **moment the cause was first understood**: the specific message or call moment where the answer landed, located after the fact from the incident's own record. The dashboard shows the **median** time to diagnose for each band, so you can compare how quickly incidents reach a diagnosis depending on who drove them there.
We also calculate how much faster incidents are diagnosed when Investigations drove the diagnosis: the median time to diagnose for incidents in the **Autonomous** and **Mostly autonomous** bands, compared against the median for the rest (**Mostly manual** and **Manual**).
### Not enough data
A median is only trustworthy with enough incidents behind it. Any band with **fewer than five incidents** doesn't get one: the time card shows **Not enough data** for that band instead of a number, rather than reading too much into a handful of incidents.
## Where you see it
The Autonomy section appears on the Investigations page in your dashboard, once around ten investigations in the selected period have reached a diagnosis we can attribute. The percentages are shares of those diagnosed, attributable incidents. An incident whose cause was never established, or whose diagnostic steps couldn't be attributed to either side, isn't part of the split.
## FAQs
The breakdown needs a diagnosis to work back from. If an incident's cause was never established, or we couldn't
locate the moment it was understood, there's no diagnostic chain to attribute and the incident sits out of it.
Credit stays with whoever surfaced it first. It measures who found the answer, not whose version of the answer
responders acted on, so an investigation that named the cause early keeps the credit even if responders
independently re-derived it later.
It means the diagnostic steps all came from Investigations independently of the responders. Responders were still
there confirming the diagnosis, fixing the incident, but the work of finding the answer didn't depend on them.
No. Investigations still ran. Manual just means none of its work fed the diagnosis: every key step came from
responders, so even where the investigation surfaced findings, none of them turned out to be part of the chain that
reached the cause.
A step whose result was genuinely a collaboration counts toward both sides. And when an incident splits exactly
evenly, the band goes to whoever surfaced the first load-bearing clue.
No. It's a comparison across different incidents, not the same incident with and without an investigation. And the
incidents Investigations can lead tend to be the more tractable ones. Treat the gap as a useful signal, not a
controlled experiment.
## Related
How we grade investigations against what really caused your incidents.
The process behind a result, and how an investigation builds conviction in real time.
How investigations show up for responders while an incident is live.
How investigations stay under your control, auditable, and honest about what they know.
# Measuring engagement
Source: https://docs.incident.io/investigations/measuring-engagement
How we measure the way responders use an investigation: reading it, steering it, and acting on what it finds.
[Accuracy](/investigations/measuring-accuracy) is the entry bar: an investigation has to be right often enough to be worth a responder's time. But accuracy and engagement answer different questions. Accuracy asks *was the investigation right?* Engagement asks *did responders use it?* A perfectly accurate investigation that nobody read created no value; a partly-right one that prompted a responder to check the right thing created a lot. We track both, because the return only shows up when accuracy and engagement are both there. See [Why accuracy comes first](/investigations/measuring-accuracy#why-accuracy-comes-first).
## How we measure engagement
We give every investigation a single engagement score, computed once its incident closes. It's **deterministic**: there's no separate AI judgment involved. We tally the interactions we already record between responders and the investigation, weight them by how much they signal real use, and normalize for the number of responders.
## What we count
Not every interaction says the same thing. Skimming a link is weaker evidence than merging the code change an investigation proposed. So we group signals into three strengths, from strongest to weakest:
* **Acted** — a responder *acted* on it: acted on a [heads-up](/investigations/incident-channel-experience#heads-up-messages), merged a [code change](/nexus/code/making-code-changes), merged a duplicate incident it flagged, [steered](/investigations/incident-channel-experience#ask-and-steer-with-@incident) the investigation, or held a sustained conversation with `@incident`.
* **Responded** — a responder *worked* with it: responded to a heads-up, rated a message useful, or asked `@incident` a question.
* **Noticed** — a responder *took it in*: clicked through to something it surfaced, or rated a message somewhat useful.
These are the individual signals we count. On the [homepage](#seeing-engagement-in-your-dashboard) they're aggregated into a single score and shown as one of three engagement bands.
A few details shape the tally:
* **Acted signals count for the most.** These are the moments where an investigation changed what a responder did: the clearest evidence it earned its place. A conversation with `@incident` counts for more the longer it runs: a sustained exchange weighs more than a single question.
* **We only count real engagement.** A heads-up that was ignored, or a message nobody reacted to, contributes nothing.
## Normalizing for incident size
A raw tally would make every large incident look more engaged than every small one, simply because more people were in the channel. That's not what we want to measure.
So we scale the score by the number of responders on the incident, but gently, so it grows slower than headcount. A small, tightly-focused incident where two responders both acted on the investigation can score as high as a large one where a handful of a much bigger crowd did. This keeps engagement comparable across incidents of very different sizes, so a trend in the score reflects how responders are using investigations rather than how big their incidents happened to be.
## Engaging responders
Alongside the score, we track **how many** of an incident's responders engaged: the distinct people behind an attributable signal, as a share of everyone who responded.
This separates two very different situations that can produce the same score: one responder leaning on the investigation heavily, versus the whole team each using it a little. Broad engagement across a team is a stronger sign that investigations have become part of how people respond, rather than something one person relies on.
## Seeing engagement in your dashboard
You can view engagement metrics for your account on the [Investigations homepage](https://app.incident.io/~/investigations) in your dashboard, alongside accuracy. Each investigation's score is shown as one of three bands:
| Band | What it means |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **None** | Responders made no use of the investigation. We couldn't attribute any interaction: no reactions, feedback, questions, or actions. |
| **Light** | Responders made light use of the investigation. Some engagement, usually weaker signals like reading what it surfaced or asking a single question. |
| **Strong** | Responders made heavy use of the investigation. At least one **Acted** signal, such as acting on a heads-up, merging a code change it proposed, or steering it. A consistent run of lighter signals can also reach this band. |
The band comes from the same score described above, so it already accounts for both how strong each signal was and how many responders were on the incident.
To dig into specific incidents, use the investigations list there to find investigations with particularly high or low engagement, a quick way to see what's landing with your responders and what isn't.
## How we use engagement scores
Every closed incident's investigation is scored this way, so we have a continuous picture of how investigations are being used across your account rather than a one-off sample. We use these scores in a few ways:
* **Spotting where value is or isn't landing.** [Accuracy](/investigations/measuring-accuracy) tells us whether investigations are right; engagement tells us whether that's translating into use. High accuracy with low engagement points at a delivery problem (the right answer surfaced in a way that didn't land) rather than a reasoning one.
* **Driving improvements.** Engagement points at how investigations show up for responders: the timing and clarity of [heads-up messages](/investigations/incident-channel-experience#heads-up-messages), how findings are surfaced in the channel, and how actionable their suggestions are.
* **Specific to your teams.** Because it's built from your responders' real interactions, engagement reflects how *your* teams work with investigations, not a generic average.
## FAQs
Accuracy measures whether an investigation was right, graded against the cause your responders established.
Engagement measures whether responders used it. An investigation can be accurate but ignored, or partly right but
genuinely useful. The two are measured separately and both matter. See [Measuring
accuracy](/investigations/measuring-accuracy).
No. The engagement score is deterministic: it's a weighted tally of interactions we already record (heads-up
reactions, feedback, steers, agent threads, link clicks, merged code changes), normalized for incident size. There's
no separate model judgment involved.
Without it, big incidents would always look more engaged than small ones, purely because more people were present.
Scaling by responder count (gently, so it grows slower than headcount) keeps a small, high-engagement incident
comparable to a large one, so the score reflects how investigations are used rather than how big the incident was.
Not on its own. A low score can mean the investigation wasn't useful, but paired with high accuracy, it more often
points at how findings were surfaced, or an incident that resolved before responders needed to lean on it. It's a
signal to look at, not a verdict.
## Related
How we grade investigations against what really caused your incidents, and why accuracy comes first.
Where responders meet investigations, from heads-up messages to asking questions and steering.
The process behind a result, and how an investigation builds conviction in real time.
# Investigations
Source: https://docs.incident.io/investigations/overview
Find the root cause of incidents faster, with evidence you can trust.
Investigations automatically work out what's going on during an incident, doing the legwork a responder normally would, faster and across every source at once.
The moment an incident is declared, an investigation gathers context from across your stack: the alert and its stack trace, similar past incidents, incident channel discussion and change events, your runbooks, recent code changes, and your telemetry. It forms a hypothesis and then tests it, reading your code and querying your dashboards to confirm or rule it out, then posts a root cause, the evidence behind it, and clear next steps into the incident channel within the first few minutes. Responders open the channel to a head start, not a blank page.
## What an investigation looks at
Investigations draw on context from across your stack, combining these sources into a single picture. The more you connect, the more grounded each investigation becomes.
Surface similar incidents from your history and the fixes that worked before.
Search your runbooks and reference docs from Confluence, Notion, GitHub, and GitLab.
Query the logs, metrics, traces, and dashboards your team already relies on.
Identify the pull request that caused an issue and trace errors through your code.
Correlate deploys, feature flags, and config changes against when the incident started.
If you're on Slack, point us at the channels where deploys, config changes, and team discussion happen.
And one source needs no setup: every investigation automatically checks whether [third-party dependencies](/investigations/third-party-dependencies) you rely on (AWS, GitHub, Stripe, and the like) were having an outage at the time.
## Where to go next
Connect your sources and run your first investigation.
Understand the phases an investigation moves through and how it builds findings.
The context an investigation reads from inside your incident, from the conversation to call transcripts.
How we grade investigations against what really caused your incidents, and use it to improve them.
How investigations stay under your control, auditable, and honest about what they know.
Choose when investigations run: automatically, by condition, or on demand.
Set up each source, from telemetry providers to code repositories.
For details on how incident.io handles your data during AI processing, see our [AI privacy
guidance](https://trust.incident.io/) in the Trust Center.
# Third-party dependencies
Source: https://docs.incident.io/investigations/third-party-dependencies
Investigations automatically check whether a provider outage explains your incident.
Plenty of incidents aren't your fault. They start with a problem at a provider you depend on. Every investigation automatically checks whether the providers you rely on, like AWS, GitHub, Stripe, Slack, or Datadog, were having an outage around the time of your incident. When one was, that's a concrete starting point for triage, rather than searching your own systems for a fault that was never there.
## How it works
During an investigation, the system:
1. Works out which third-party dependencies are relevant, from the incident's context: the alert, the error, the discussion.
2. Matches them against the third-party services it monitors.
3. Builds an outage timeline for each match within your incident's window.
4. Surfaces any outage that could plausibly explain the incident as a finding, with timing, like "AWS us-east-1 went down 3 minutes before this incident started."
You can also ask the agent directly during an incident ("is GitHub down?", "is Stripe having issues?") and get the current status, recent changes, and which components are affected. If a service's status changes while your incident is still open, the investigation can pick up the new information.
## What's covered
We continuously monitor the health of around 150 widely-used providers in the background: cloud platforms (AWS, Google Cloud, Azure), source control (GitHub, GitLab), observability tools (Datadog, Grafana, Sentry), communication and SaaS platforms (Slack, Zoom), payment and messaging providers (Stripe, Twilio), and AI providers, among others. Because that history is already being tracked, the moment your incident starts an investigation can look back over exactly what each provider was doing, with no lag and nothing to wire up.
## Setup
There's nothing to set up. This works automatically for every investigation, with no configuration.
The list of monitored providers is maintained by incident.io and shared across all customers. These are services many
teams depend on, so we monitor them centrally. You can't currently add your own services to the list. If there's a
provider you'd like covered, let us know.
## Related
How a provider outage becomes a finding.
# Triggering investigations
Source: https://docs.incident.io/investigations/triggering
Decide when investigations run, automatically, by condition, or on demand.
You control when investigations run. Run them for everything while you build trust, narrow them to the incidents that matter, or keep them entirely on demand.
Configure this from [Investigation settings](https://app.incident.io/~/investigations?drawer=investigation-settings) in your dashboard.
## When investigations run
Every incident gets an investigation automatically. A good default while you're getting a feel for the results.
Define conditions that decide when an investigation runs. For example, only for incidents above a certain severity, or
with a particular custom field set.
Start an investigation when something about an incident changes, such as severity being raised or a field being
updated. See the [workflows guide](/workflows/getting-started) for the full set of triggers and conditions.
Investigations only run when a responder asks. You can still start one any time (see below).
## Running an investigation on demand
In **Slack**, anyone can start an investigation from the incident channel:
* Use `/inc investigate` in the channel.
* Add **Run an investigation** as a [quick action](/incidents/quick-actions) on your incident welcome message.
Outside of Slack, have investigations run automatically for the incidents that matter (see [When investigations run](#when-investigations-run) above), or trigger one from a [workflow](/workflows/getting-started).
## FAQs
Yes. Use [conditions](#when-investigations-run) to target whichever incidents you want, including by status,
severity, or a custom field, so you can run investigations on triage incidents or any other subset that matters to
you.
Yes, once your organization has opted in under [Settings → AI
governance](https://app.incident.io/~/settings/ai-governance#ai-incident-access). Anything shared in a private
incident stays within that incident and is never pulled into another conversation. See [What investigations can
see](/investigations/what-we-can-see).
Yes. Investigations work the same whether your incidents run in Slack or Microsoft Teams. The one exception is
connecting *other* Slack channels as a source (and the change events built from them), which is Slack-only. See
[Nexus](/nexus/overview).
Investigations run on incidents rather than on alerts directly. To get an investigation from an alert, turn it into
an incident (for example automatically with a [workflow](/workflows/getting-started)); your triggering rules then
decide whether an investigation runs.
## Related
What happens once an investigation starts.
The sources investigations draw on.
# Trust and safety
Source: https://docs.incident.io/investigations/trust-and-safety
How investigations stay under your control, keep a full record of their work, and stay honest about what they know.
Letting an AI agent work on a live production incident only pays off if you can trust it: to stay within the bounds you set, to show its working, and to be honest about what it does and doesn't know. Investigations are built for exactly that. This page covers the controls you have, the record an investigation keeps, and the safeguards behind its conclusions.
## You stay in control
An investigation's job is to do the legwork and recommend, not to change your systems behind your back. It reads, reasons, and surfaces findings and next steps; acting on them is your call.
The one place an investigation can touch your systems is your code, and only ever as a pull request you review and merge yourself; it never merges or deploys anything. By default, it opens one only when you [ask it to](/nexus/code/making-code-changes) in the channel. It can also propose a fix unprompted once it reaches high confidence, but that's off by default and opt-in, and still arrives as a draft pull request for you to review.
You also decide [when investigations run at all](/investigations/triggering), whether for every incident, only those that meet your conditions, or never automatically, and you can [steer, correct, or pause](/investigations/incident-channel-experience#ask-and-steer-with-incident) one at any point.
Investigations don't take action on your behalf without your request or approval. Where one updates an incident
automatically (a suggested summary, for instance) you can always change it back. Code only ever changes through a pull
request a human merges.
## A full record of what it did
Every investigation keeps a complete, inspectable account of its work, so nothing it concludes is a black box.
* **Its reasoning**: the findings it formed, the evidence behind each, and how its hypothesis changed as it learned. It keeps the theories it considered and [discounted](/investigations/how-investigations-work#from-evidence-to-findings) too, rather than quietly dropping them.
* **Its sources**: every finding links back to where it came from: the Slack message, the pull request, the dashboard, the log line. You can follow any conclusion to the evidence behind it.
* **Who did what**: when a responder steers an investigation or asks it to make a change, that's attributed in the channel; when the investigation opens a pull request, it's tracked and linked to the incident like any other action.
Account-level actions are also captured in your [audit log](/admin/audit-logs), recording who did what and when.
## Honest about what it knows
An investigation is only useful if it's clear about how sure it is; an over-confident agent is worse than none. So an investigation grades its own [conviction](/investigations/how-investigations-work#building-conviction) in every hypothesis and shows that confidence alongside it, surfaces the alternatives it's weighing, and only claims high confidence when it has verifiable evidence against sources it trusts. When it can't find that proof, it says what it couldn't confirm rather than presenting a guess as a conclusion.
That's also how false positives are kept in check. In the moment, a thinly-evidenced theory is shown as exactly that: low confidence, with its gaps spelled out, so responders can weigh it before acting. Over time, we grade every investigation against what really caused past incidents and [backtest](/investigations/measuring-accuracy#backtesting) changes before they ship, so accuracy keeps climbing and regressions are caught before they ever reach a live incident.
## Your data
Investigations run on the same AI providers as the rest of incident.io, OpenAI, Anthropic, and Google Vertex, under Zero Data Retention agreements, so your data is never stored by them and never used to train models. Code analysis runs in [isolated, sandboxed containers](/nexus/code/overview#security) that are torn down after use, and you can [redact sensitive data](/admin/managing-sensitive-data#ai-data-redaction) before it ever reaches a model.
For the full picture of how incident.io handles your data, see [AI data handling](/admin/ai-usage) and our [Trust Center](https://trust.incident.io/).
## FAQs
No. Investigations are recommendation-first: they surface findings and next steps, and acting on them is your call.
The only change they can make to your systems is opening a pull request, which a human always reviews and merges;
nothing is auto-merged or deployed. Proposing a fix unprompted is off by default and opt-in, and still produces a
draft pull request for review.
Yes. Each investigation keeps a full record of its findings, the evidence behind them, how its thinking changed, and
the actions it took, and any steering or change request is attributed in the channel. Account-level actions are also
recorded in your [audit log](/admin/audit-logs).
An investigation grades its own [conviction](/investigations/how-investigations-work#building-conviction) and only
claims high confidence with verifiable evidence; weakly-supported theories are shown as low confidence with their
gaps stated. We also grade every investigation against real causes and
[backtest](/investigations/measuring-accuracy) changes before they ship.
No. We have Zero Data Retention agreements with OpenAI, Anthropic, and Google Vertex, so your data isn't stored by
them or used for training. See [AI data handling](/admin/ai-usage).
Yes. The AI providers behind investigations, OpenAI, Anthropic, and Google Vertex, operate under Zero Data Retention
agreements, so your data isn't retained by them and is never used to train their models. All the same data
governance as the rest of incident.io applies. See [AI data handling](/admin/ai-usage).
Not currently. Investigations use a combination of models across providers, chosen for accuracy, so there's no
bring-your-own-model or bring-your-own-key option today.
An investigation and its record are retained as part of your incident data for as long as you're a customer. You can
erase specific data or have all your data deleted on request (see [Managing sensitive
data](/admin/managing-sensitive-data)) and our [Trust Center](https://trust.incident.io/) covers data handling in
full.
## Related
How we grade investigations and keep improving them.
How an investigation builds conviction and tests its own theories.
How a fix becomes a pull request you review.
How incident.io uses AI and handles your data.
# What investigations can see
Source: https://docs.incident.io/investigations/what-we-can-see
The context an investigation reads from inside your incident: the conversation, the call, shared files, and the incident's own details.
An investigation reads your incident the way a responder joining late would: it catches up on the conversation, the call, the files people have shared, and the incident's own details, then reasons over all of it at once. This page covers what's visible to an investigation from inside an incident, separate from the [external sources you connect](/nexus/overview), which add even more.
## The channel conversation
Every message in the incident channel is part of what an investigation reads, both what people say and what your bots post. It follows threads, not just top-level messages, so a detail buried in a reply isn't lost.
Human discussion gives it the context telemetry can't: a suspected cause, a migration someone mentions in passing, a decision to roll back. Automated messages (deploy bots, CI, alert notifications) are read too, and the ones that describe a change are also turned into [change events](/nexus/change-events) so they can be lined up against the incident timeline.
This is the incident's **own** channel, which an investigation always reads. Connecting *other* Slack channels (your
`#deploys` channel, an infrastructure channel) is a separate source. See [Slack channels](/nexus/slack).
Anything you tell the investigation by tagging `@incident` becomes context too. If you know something it doesn't, say
so. See [Ask and steer with @incident](/investigations/incident-channel-experience#ask-and-steer-with-incident).
## Call transcripts
If you use [Scribe](/ai/scribe), our AI note-taker that joins your incident calls, the call transcript is available to the investigation as evidence, alongside the channel conversation. That means an investigation can pick up things only said out loud on the call: a hypothesis someone floated, a config change being made live, the moment a fix went out, and who said what.
So when someone asks "do you use the Scribe transcript?", the answer is yes. While Scribe is transcribing an incident call, what's discussed there feeds into the investigation just like the messages in the channel do.
Scribe stores only the call transcript, never the audio or video, and is available on Pro and Enterprise plans once a
call provider is set up. See [Scribe](/ai/scribe) for how it works and how to enable it.
## Attachments
People drop a lot into incident channels: a forwarded alert email, a pasted stack trace, a chunk of config. Investigations read these too, pulling in the full content when it's relevant rather than just the filename.
The subject, sender, recipients, and full body of an email shared into the channel, so a forwarded alert or vendor
notification is read in full, not just noted.
Pasted snippets and uploaded text files: logs, stack traces, configs, and structured formats like JSON, YAML, and XML.
The full content is read on demand, up to around 500,000 characters; very large files (over 5 MB) keep a preview
instead.
Code and snippets pasted inline in a message are read as part of that message.
Deleted files are skipped: once a file is removed there's nothing left to read.
Attachment content is tied to the incident and the channels a file was shared into. Content shared in a private
incident is only ever read within that incident, never pulled into another conversation.
## The incident's own details
Beyond the conversation, an investigation reads the structured incident record, which tells it what kind of incident this is and how it has evolved:
| Source | What it adds |
| -------------------------- | ---------------------------------------------------------------------------- |
| **Status and severity** | How serious the incident is and where it is in its lifecycle. |
| **Custom fields** | Your own metadata: affected service, region, team, and the like. |
| **Roles and participants** | Who's involved and in what capacity. |
| **Updates and timeline** | What's been communicated and the sequence of events so far. |
| **Alerts** | The alerts that triggered the incident, including any error and stack trace. |
| **Actions and follow-ups** | What's been done and what's still outstanding. |
| **Postmortem** | The postmortem document, if one exists. |
## Everything you connect
What's visible inside the incident is only part of the picture. Investigations also draw on the [sources you connect](/nexus/overview), like past incidents, telemetry, code repositories, documentation, and other Slack channels, plus an automatic check of whether your [third-party dependencies](/investigations/third-party-dependencies) were having an outage. The more you connect, the more grounded each investigation becomes.
## FAQs
Yes. While Scribe is transcribing an incident call, that transcript is available to the investigation as evidence,
so it can use what was said on the call alongside the messages in the channel. See [Scribe](/ai/scribe).
The incident's own channel, always, plus any other Slack channels you explicitly [connect as a
source](/nexus/slack). It doesn't read direct messages or channels you haven't connected.
Forwarded emails, pasted text snippets, and uploaded text files such as logs, stack traces, configs, and JSON, YAML,
or XML. It reads text-based content; the full body is loaded when it's relevant, capped at around 500,000
characters, with very large files (over 5 MB) keeping a preview.
Attachment content carries the incident and channels it was shared into, and content from a private incident is only
served back within that incident. For how incident.io handles your data during AI processing, see our [Trust
Center](https://trust.incident.io/).
## Related
How this context becomes findings backed by evidence.
What an investigation looks like in your channel, and how to talk to it.
The external sources investigations draw on, and how to set each one up.
AI transcription and summaries for your incident calls.
# Catalog
Source: https://docs.incident.io/nexus/catalog
Your catalog gives Nexus the map of your systems, services, and ownership.
The [catalog](/catalog/catalog-setup) is where incident.io holds the structure of your organization: your services, the teams that own them, and how everything depends on everything else. It's one of the richest things Nexus knows about you, and it works across the whole platform, not just Investigations.
For Nexus, the catalog is the map. It's what turns a pile of incidents into a picture of your organization: which services keep failing, which customers keep getting hit, which teams keep absorbing the work, and which dependencies show up behind unrelated-looking problems. Without it, incidents are a list. With it, they're connected to the things they happened to. It's also what the [agent](/ai/at-incident) reads when you ask who owns a service or what sits downstream of it.
Set up the catalog and understand how it's structured.
Populate the catalog from Backstage, Cortex, OpsLevel, and other sources.
Model your teams and connect them to the services they own.
Decide what belongs in your catalog and how to shape it.
# Change events
Source: https://docs.incident.io/nexus/change-events
Turn your deploy and change notifications into evidence Nexus can use.
Most incidents are caused by a change: a deploy, a feature flag flip, a config push. Change events capture those changes as they happen, so an investigation can line them up against when your incident started and point at the one that likely caused it.
You don't connect anything separately for this. Change events are built automatically from the bot and automated messages already flowing through the [Slack channels you connect](/nexus/slack): the deploy bot in your `#deploys` channel, the feature-flag notifications, the infrastructure alerts.
Change events are built from connected Slack channels, so they're available for Slack only. They aren't extracted from
Microsoft Teams channels today.
## How it works
When an automated message arrives in a channel you've connected, incident.io reads it and, if it describes a change, extracts a structured change event from it, pulling out what changed, when, who triggered it, and a link back to the source. A deploy notification becomes a deploy event with its service, environment, and commit; a feature-flag message becomes a flag event with the flag name.
During an investigation, these change events are correlated with the incident's timeline. A deploy that landed three minutes before the first error is exactly the kind of thing the investigation will surface, and because deploy events tie back to the underlying commit, it can connect that change to the specific code that shipped.
Only automated messages are turned into change events: the deploy bots, CI notifications, and flag-change alerts.
Ordinary human discussion in the same channels is still used as [Slack context](/nexus/slack), just not as change
events.
## What gets captured
Change events are sorted into categories so Investigations can reason about them:
| Category | Examples |
| ------------------ | -------------------------------------------------------- |
| **Deploy** | A service or application being released |
| **Feature flag** | A flag being turned on, off, or rolled out |
| **Config** | A configuration or settings change |
| **Infrastructure** | Changes to infrastructure, such as scaling or networking |
| **Database** | Migrations and other database changes |
| **Alert** | Automated alert notifications |
| **Other** | Changes that don't fit the categories above |
Each event also captures whatever detail the message contains: environment, service, commit, flag name, and a link back to the original notification.
## Setup
There's nothing extra to set up. Once you've connected the [Slack channels](/nexus/slack) where your automated change notifications land, change events are extracted from them automatically.
Connect the channels where your deploy, release, feature-flag, and infrastructure bots post. The more of your real
change stream Investigations can see, the more reliably they can trace an incident back to the change that caused it.
## Related
Connect the channels change events are built from.
Connect repositories so deploy events tie back to the code that shipped.
# Delegating agents
Source: https://docs.incident.io/nexus/code/delegating-agents
Hand code changes to your team's own coding agent instead of incident.io's built-in one.
By default, incident.io writes code changes with its own built-in agent. If your team already runs a coding agent, you can delegate the work to it instead. incident.io still owns everything around the change: the investigation, the conversation in the channel, the progress updates, and linking the finished pull request back to the incident. It hands off only the step of writing the code.
The point of delegating is that the change is made with all the setup you've already built in that tool: your rules and conventions, the MCP servers you've connected (including incident.io's own, so the agent can pull live incident context), and your development environment. The fix comes from the agent your team has already tuned to your codebase, rather than a generic one.
## Choosing which agent runs
Which agent writes the change is an explicit choice. In **Settings → Investigations → Code changes** you pick one of four options: incident.io's built-in agent, Cursor, GitLab Duo, or your own custom platform. The one you select runs for every code change, so connecting more than one is fine. Your selection is always what's used.
## Cursor
Connect Cursor with an API key, and code change requests are handed to a Cursor cloud agent that makes the change and opens the pull request. It runs with your Cursor configuration, including any MCP servers you've set up for your repositories, and the resulting pull request is linked back to the incident exactly as the built-in flow would.
## GitLab Duo
Connect GitLab Duo and code change requests trigger a [Duo Agent Platform](https://docs.gitlab.com/user/duo_agent_platform/) developer workflow on your own GitLab instance. Duo makes the change and opens the merge request there, using its own access rather than ours, so it works only with GitLab repositories.
To connect, go to **Settings → Investigations → Code changes**, choose GitLab Duo, and provide two things:
* **GitLab host**: the base URL of your GitLab instance, for example `https://gitlab.com`.
* **Personal access token**: a token with the `api` scope. `read_api` isn't enough, since it's read-only and can't trigger workflows. The token must belong to a regular user rather than a service account — service accounts can't start Duo workflows, so we reject their tokens when you connect. Every workflow runs as that user. This token is separate from your GitLab code connection, so a Duo-scoped token never has to share credentials with anything else.
The "Test connection" button verifies the token against your instance, shows you which scopes it carries, and confirms it belongs to a real user, so you can check the setup before the first real run.
On the GitLab side, you'll need:
* GitLab 18.8 or later, on a Premium or Ultimate plan.
* GitLab Duo and the developer flow enabled for the project.
If you'd like us to support another hosted agent out of the box, such as Devin, [get in
touch](mailto:support@incident.io) and we'll work with you.
## Your own platform
If you run an internal coding agent platform, you can connect it directly by implementing the small HTTP interface specified below. **We call you** to launch and steer agent runs, and **you call us back** (or let us poll) with status. Your agent opens the pull request with its own credentials in your own infrastructure. We only ever need read access to the repository to attach the finished PR to the incident.
Connect your platform from **Settings → Investigations → Code changes → Custom agent** in the dashboard. You'll need your
platform's endpoint URL (which must start with `https://`) and a bearer token it issued for us. Everything else, including the webhook signing secret,
is handled automatically. You can also give the connection a display name, which Slack uses when narrating the agent's progress.
Each organization can connect one custom agent platform today. If your agents are split across several internal systems, put a thin router in front of them and connect that. The `repository` field on each launch tells you where to route. [Get in touch](mailto:support@incident.io) if you'd like first-class support for multiple connections.
### How a delegated task flows
1. A responder asks for a code change (for example from the incident channel), and we render a self-contained markdown **brief**: the incident title and reference, the repository, the user's instructions, our expectations for the PR, and a snapshot of the investigation so far.
2. We call `POST /agents` on your platform with the brief and structured identifiers, plus a per-launch webhook URL and signing secret.
3. Your platform starts a run and responds with a run ID and a link to its own UI, which we surface in Slack.
4. While the run is in flight, you send signed status callbacks to the webhook, or we poll `GET /agents/{id}` every 2 minutes. Both work.
5. Your agent opens a **draft PR** with its own GitHub credentials and reports `finished` with the PR URL. We attach the PR to the incident and move the task into review.
6. If a responder asks for changes, we call `POST /agents/{id}/followup` with the new instructions, and the same run updates the same PR.
### The interface you implement
All endpoints are served from the base URL you configure, authenticated with the bearer token you issue us (`Authorization: Bearer `). Every request we send carries an `X-Incident-Interface-Version` header (currently `2026-06-12`) so you can tell which revision of this contract you're being called with. Breaking changes ship under a new version value, announced ahead of time.
| Endpoint | Required? | Purpose |
| ---------------------------- | -------------------- | ------------------------------------------------ |
| `POST /agents` | Required | Launch a run |
| `GET /agents/{id}` | Required | Report run status |
| `POST /agents/{id}/followup` | Strongly recommended | Send follow-up instructions to a run |
| `POST /agents/{id}/stop` | Optional | Cancel a run (best effort) |
| `GET /ping` | Optional | Used by the dashboard's "Test connection" button |
| Webhook (you call us) | Recommended | Push status instead of waiting for our poll |
#### `POST /agents`: launch
```json theme={null}
{
"task_id": "01JXAMPLE7AXZ2C93K61WBPYEH",
"prompt": "",
"incident_id": "01JXAMPLE0INCIDENT0ID0000",
"reference": "INC-123",
"investigation_id": "01JXAMPLE0INVESTIGATION00",
"repository": "acme/payments-service",
"webhook": {
"url": "https://app.incident.io/webhooks/code-agent/custom/",
"secret": ""
}
}
```
* `task_id` is our identifier for the request. Treat it as an **idempotency key**: if you receive a second launch with a `task_id` you've already started, return the existing run rather than starting another.
* `prompt` is the rendered brief. It's self-contained, so an agent with no other context can act on it.
* `incident_id`, `reference` and `investigation_id` are also embedded in the prompt, but exposed as structured fields so your harness can fetch live data through our [MCP server](/ai/remote-mcp) without parsing markdown. They're omitted when the task has no incident or investigation.
* `webhook` is where to send status callbacks for **this run**, and the secret to sign them with. You may ignore it and rely on polling, but webhook-driven updates feel noticeably faster in Slack.
Respond within **10 seconds**:
```json theme={null}
{ "id": "run_8f2k1", "url": "https://agents.example.com/runs/run_8f2k1" }
```
* `id` is your opaque run identifier. We include it in every subsequent call.
* `url` (optional) links to your platform's UI for the run and is shown to responders in Slack.
If launching takes longer than that, accept the request, return the run ID immediately, and do the heavy lifting asynchronously.
#### `GET /agents/{id}`: status
```json theme={null}
{
"id": "run_8f2k1",
"status": "running",
"summary": "Reproduced the bug, writing a regression test",
"pr_url": "",
"branch": ""
}
```
* `status` is one of `running`, `finished` or `error`.
* `summary` is a short progress message. We show the latest one in Slack, so keep it human-readable and current.
* `pr_url` is **required when reporting `finished`**. A `finished` status without a PR URL is treated as a failure, not as "almost done", so report `running` until the PR exists.
* `branch` (optional) is the feature branch the agent pushed to.
#### `POST /agents/{id}/followup`: iteration
```json theme={null}
{ "instructions": "Also handle the retry case in the worker" }
```
The run picks up the new instructions and finishes by updating the **same PR**. Implementing this is strongly recommended: it's what powers "request changes" from the incident channel. Respond `running` to status calls while the follow-up is in progress, then `finished` with the same `pr_url` once the PR is updated.
#### `POST /agents/{id}/stop`: cancel
Best effort, no body. We call it when a responder abandons or retries a task. Returning `404` for a run you've already cleaned up is fine.
#### `GET /ping`: connection test
Return `200` to confirm the endpoint is reachable and the bearer token is valid. The dashboard's "Test connection" button calls this; platforms that don't implement it still work, but admins lose the ability to verify the connection before the first real launch.
### The webhook you send us
POST the **same JSON body as the status response** to the per-launch webhook URL, signed with the per-launch secret:
```
X-Webhook-Signature: sha256=
```
* Send one whenever the run meaningfully progresses: on completion at minimum, and ideally on summary changes too.
* Our handling is **idempotent**, and the webhook and our poller converge on the same logic, so duplicate or out-of-order deliveries are harmless.
* You don't need a retry pipeline: if a delivery fails, our 2-minute poll picks the status up. (Retries are welcome all the same.)
* We respond `200` even for runs we no longer track, so you can fire-and-forget.
### Timing expectations
| What | Expectation |
| ---------------------------- | --------------------------------------------------- |
| Response to any of our calls | Within 10 seconds |
| Our polling cadence | Every 2 minutes per active run |
| Maximum run length | **2 hours**, after which we mark the task as failed |
| Webhook deliveries | Any time during a run; completion at minimum |
### What this interface doesn't do
Instructions flow one way. There is no way for your agent to ask the responder a question mid-run (no elicitation step). If the brief is ambiguous, the agent should make a reasonable choice and explain it in the PR description. Responders iterate after the fact through follow-ups, which is the intended loop.
### Giving your agent live incident data
The brief embeds an investigation snapshot capped at 30,000 characters. For full, current context, configure your agent harness with access to our [MCP server](/ai/remote-mcp) using an incident.io API key:
* `investigation_sync` downloads the complete investigation (findings, hypotheses, check outputs) as an archive via a short-lived signed URL.
* `incident_show` and `alert_show` fetch the live incident and related alerts.
The brief tells the agent to prefer these tools when they're available and to fall back to the embedded snapshot otherwise, so MCP access is an upgrade, not a requirement.
### Security model
There are three credentials in play, each scoped to one direction:
1. **Us → your API**: the bearer token you issue and paste into our dashboard. We store it encrypted and send it on every call. Rotate it by reconnecting with a new token.
2. **You → our webhook**: the HMAC secret we generate when you connect, delivered to you inside each launch request. You never need to store it long-term. Sign each run's callbacks with the secret that run was launched with.
3. **Your agent → our MCP**: an incident.io API key you create and configure into your agent environment, governed by the same scopes as any other API key.
Your platform must be reachable from the public internet over HTTPS. If it isn't, [talk to us](mailto:support@incident.io).
## Related
How responders ask for a fix from the incident channel.
Give your agent live incident and investigation data.
# Making code changes
Source: https://docs.incident.io/nexus/code/making-code-changes
Ask @incident to fix what an investigation found, as a pull request grounded in the investigation.
When an investigation has worked out what's wrong, the next step is usually to fix it. You can ask `@incident` to make the change, and it opens a pull request for you to review, built on everything the investigation already knows.
## Asking for a change
In the incident channel, tag `@incident` and describe the change you want: fix a bug it identified, revert a risky change, add a guard. It opens a pull request against the right repository and posts its progress back into the channel as it works; when the PR is up, it's linked to the incident like any other resource.
Because the request runs with the full investigation behind it, you don't have to re-explain the problem. The agent making the change starts from the investigation's root-cause finding, the evidence behind it, and the code the investigation already read, so the change targets the actual cause rather than guessing from a one-line instruction. That means you can be brief:
> @incident open a pull request to fix this.
Or point it at something specific when you already know the fix:
> @incident this is the missing timeout on the payments client: add a sensible one and open a PR.
You can keep iterating in the channel: ask for adjustments and the same pull request is updated.
> @incident can you also add a test that covers the timeout?
Making code changes needs a connected code repository with write access. See [Code setup](/nexus/code/overview#setup).
## Who makes the change
By default, incident.io makes the change itself. A coding agent runs in an isolated, sandboxed container, makes the edit, and opens the pull request, with no setup beyond [connecting your repositories](/nexus/code/overview).
If your team already uses its own coding agent, you can delegate the work to it instead, so the fix comes from the tooling you've already tuned to your codebase. Which agent runs is an explicit setting, so you stay in control even when more than one is connected. See [Delegating agents](/nexus/code/delegating-agents) for what's supported and how to choose.
## Automatic code changes
Investigations can go one step further and propose a fix without being asked. When an investigation reaches high confidence in a root cause that's addressable in code, it can open a pull request itself and announce it in the channel, turning a diagnosis straight into a proposed fix for you to review.
This is off by default. If you'd like Investigations to propose code changes automatically, [get in touch](mailto:support@incident.io) and we'll enable it for your organization.
## Related
Hand code changes to Cursor or your own coding agent platform.
Everything else you can ask `@incident` during an incident.
How code changes stay under your control: review, approval, and a full audit trail.
# Code
Source: https://docs.incident.io/nexus/code/overview
Give Nexus your repositories, so it can find the change that caused an issue, read your code, and draft the fix.
Access to the codebase is often the difference between a quick resolution and hours of guesswork. Connecting your repositories gives Investigations the same advantage: they can identify recently merged pull requests that may have caused an issue, trace error paths through the code, and understand how services fit together. With write access, responders can also ask an investigation to draft a fix and open a pull request.
## How Investigations use this
Investigations work with your code in two complementary ways: they keep a continually-updated picture of every change you ship, and, when a hypothesis calls for it, they read the code itself.
### Finding the change that caused it
incident.io tracks every pull request and merge request as it moves through your workflow. When one merges, we process it in the background and enrich it with an AI summary of what it does, category tags, the files it touched, and its commits and full diff, building a searchable index of your changes rather than a flat list of titles.
During an investigation, that index is searched for the changes most likely to be responsible (the recent merges, plus any whose summaries line up with the alert and the symptoms) and each one is weighed for whether it could actually have caused what you're seeing. A change whose summary matches the failure is exactly what gets surfaced, with a link to the diff.
This is where [change events](/nexus/change-events) come in. A merged pull request tells you a change exists; a deploy change event tells you it actually shipped, and when. By tying deploys back to the specific commits they carried, an investigation can rule a change in or out on timing: a pull request that merged last week but only reached production two minutes before the first error is far more interesting than one that's been live for days.
### Reading the code
Linking changes only goes so far. When a hypothesis needs confirming in the code itself, the investigation clones the relevant repositories and runs a full coding agent against them.
Across organizations with thousands of repositories, the investigation narrows to the handful worth cloning by matching the incident against repository names, recent merge activity, and an AI-built understanding of what each repository is for and how it's structured.
Once a repository is cloned, the agent does what an engineer would: it plans the specific questions worth answering, then reads the code to answer them: tracing a call path across files, following an error back to where it's thrown, checking what a recent commit actually changed. It's the difference between guessing from an error message and reading the line that produced it. See [How investigations work](/investigations/how-investigations-work#reading-your-code).
With write access, that same capability can go a step further and draft a fix as a pull request for you to review.
Connected repositories aren't only for Investigations: ask the [agent](/ai/at-incident) a question about your code and it reads them the same way.
## Security
Code access is built to touch as little as possible, for as short a time as possible.
**We clone repositories only when we need them.** An investigation doesn't mirror or hold a copy of your codebase. It clones a repository only at the moment it needs to read code to test a hypothesis, and only the specific repositories relevant to the incident, never your whole estate. Each clone lands in its own ephemeral workspace that's deleted as soon as the analysis finishes.
**The code agent runs in a locked-down sandbox.** Analysis happens inside an isolated container that exists only for that work. It has no inbound network access and tightly restricted outbound access, and it can see only the code we've cloned and the investigation's own context, nothing else on your systems or ours.
**We only use the access you grant.** Everything stays within the permissions you've configured. If you've connected read-only, an investigation can read and analyze your code but can never write to your repositories. See [the access levels below](#setup) for exactly what each permission allows.
This whole setup (cloning, isolation, and execution) has been audited by external penetration testers. For more on how we handle your data during AI processing, see our [Trust Center](https://trust.incident.io/).
## Setup
Connect your code provider from the [integrations settings](https://app.incident.io/~/settings/integrations) in your dashboard. We only ever use the access you grant for the work described above: reading the changes and code behind an incident, and, if you allow it, drafting a fix.
Both providers support two access levels:
* **Read only**: Investigations can read your code, clone repositories to analyze them, and link the pull requests behind an incident.
* **Read and write** (recommended): adds a single capability on top, opening a pull request with a drafted fix for you to review.
**Read-only access is fully supported.** Every part of an investigation (linking the changes behind an incident,
reading and analyzing your code, tracing a root cause) works without any write access. The only thing write access
adds is having an investigation draft a fix as a pull request; on read-only, you simply apply the fix yourself. If
your policy only permits read access, you lose none of the diagnostic capability.
### GitHub
incident.io connects to GitHub as a **GitHub App** installed into your organization, authenticating with short-lived installation tokens rather than anyone's personal account. Access is scoped to the app and isn't tied to an individual, so it survives people joining or leaving the team. Both **GitHub.com** and **GitHub Enterprise Server** (self-hosted) are supported. On Enterprise Server you install a dedicated app against your own instance.
The access level you choose maps to these permissions:
| Permission | Read only | Read and write | Why we need it |
| ----------------- | --------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Metadata** | Read | Read | Basic repository information such as names and branches. GitHub includes this on every app. |
| **Contents** | Read | Write | Read source files and clone repositories so Investigations can analyze your code. Write lets an investigation commit a fix to a branch. |
| **Pull requests** | Read | Write | Read the pull requests and diffs behind an incident to identify a likely cause. Write lets an investigation open a fix as a pull request. |
| **Members** | Read | Read | Resolve organization membership, so changes can be attributed to their authors and reviewers. |
We request nothing beyond these, and the read-only configuration carries no write permission of any kind.
### GitLab
incident.io connects to GitLab with a **personal access token** created for a dedicated **service account** user, so the integration isn't tied to a real person's account. Both **GitLab.com** and **self-managed** instances are supported.
Two things decide what Investigations can do: the service account's **project role** and the token's **scopes**.
| Access level | Service account role | Token scopes | What it allows |
| ------------------ | -------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| **Read only** | Reporter | `read_api` + `read_repository` | `read_api` reads merge requests and their diffs; `read_repository` clones repositories so Investigations can analyze your code. |
| **Read and write** | Developer | `api` | Everything above, plus opening merge requests with a drafted fix. The `api` scope is what grants write access. |
A few details worth knowing:
* The same token is used both to read merge request data and to clone repositories, so its scopes need to cover both.
* `api` is a superset of `read_api` + `read_repository`, so a single `api`-scoped token works for either access level. For a read-only setup, the narrower pair keeps the grant as small as possible.
* **Self-managed GitLab:** if your instance restricts access by IP address, allow [incident.io's IP ranges](/integrations/ip-allowlist) so we can reach it.
For step-by-step setup, see the [GitLab integration guide](/integrations/gitlab).
### Private and self-hosted instances
If your GitHub Enterprise Server or self-managed GitLab instance runs inside a private network and isn't reachable from the public internet, connect it through a [proxy](/integrations/proxy), a lightweight service you run inside your own network that opens a secure, outbound-only tunnel to incident.io. We reach your instance over that tunnel, so there's no need to open inbound firewall ports or expose it publicly.
## Making code changes
Reading your code is only half of what a connected repository unlocks. With write access, you can ask an investigation to fix what it found and open a pull request, grounded in everything it already knows about the incident. By default incident.io's own agent makes the change, or you can hand the work to a coding agent your team already runs.
See [Making code changes](/nexus/code/making-code-changes) for how responders request a fix from the incident channel, and [Delegating agents](/nexus/code/delegating-agents) for handing the work to Cursor or your own platform.
## FAQs
An investigation clones a repository only when it needs to read code, and only the repositories relevant to that
incident, into an isolated, locked-down sandbox that's torn down as soon as the analysis finishes. It uses only the
access you grant, and the whole setup has been audited by external penetration testers. See [Security](#security).
Yes. Both GitHub Enterprise Server and self-managed GitLab are supported. If the instance runs inside a private
network, connect it through a [proxy](/integrations/proxy) so we can reach it over an outbound-only tunnel. See
[Private and self-hosted instances](#private-and-self-hosted-instances).
With read and write access, an investigation can open a pull request with a drafted fix for you to review; it never
merges or deploys anything itself. You can also hand the change to a coding agent your team already runs. See
[Making code changes](/nexus/code/making-code-changes).
## Related
How code analysis fits into the investigation loop.
Full details on the GitHub integration.
# Documentation
Source: https://docs.incident.io/nexus/documentation
Give Nexus your runbooks and reference docs, so your team can search them from the agent.
Your team's documentation holds knowledge that lives nowhere else: the runbook for this exact failure, how a service is meant to behave, the decision behind an architecture. Connect your documentation and Nexus can pull in the right runbook or reference at the right moment, and your team can search it directly from the agent.
## How Investigations use this
Connected documentation is synced and indexed for both keyword and semantic search. From there it's available in two places:
* **In Investigations**: relevant runbooks and reference docs surface as evidence, helping ground a finding in how your systems are actually meant to work and what to do about a known failure.
* **In the agent**: ask a question, in an incident or not, and the answer can cite the specific docs it drew on, with links back to the source.
Documentation is most valuable when it captures operational knowledge: runbooks, architecture overviews, and
references. The more your docs describe how to operate and debug your systems, the more Nexus can lean on them.
## Providers you can connect
| Provider | What gets synced |
| ---------- | ----------------------------------------------- |
| Confluence | Pages from the spaces you choose |
| Notion | Pages and databases you choose |
| GitHub | Markdown and docs in repositories, by file path |
| GitLab | Markdown and docs in repositories, by file path |
## Setup
Configure document sources from the [Nexus documents settings](https://app.incident.io/~/nexus/documents) in your dashboard.
Connect the relevant integration (Confluence, Notion, GitHub, or GitLab) if you haven't already.
Scope each source to the docs that matter:
* **Confluence**: select the spaces to sync.
* **Notion**: select the pages or databases to sync.
* **GitHub and GitLab**: choose repositories and the file paths to include (for example `docs/**` or `*.md`).
Documents are fetched, summarized, and indexed for search. Sources refresh automatically each day, and you can
trigger a resync at any time.
When a document is removed at the source, it's dropped from search on the next sync. Only the documents you scope are
synced: Investigations never read beyond the spaces, pages, or paths you choose.
## Related
How a runbook becomes evidence in a finding.
Ask questions during an incident and get cited answers.
# Nexus
Source: https://docs.incident.io/nexus/overview
Built from your catalog, your incidents, your code, and your telemetry, and sharper with every incident.
Nexus is incident.io's living model of your organization: how your systems are built, how your team operates, and how things break. It combines everything it can see with an understanding of how that fits together. It's unique to your organization, included with the platform, and powers the products you use across it.
## Explore your incidents
You don't need Investigations to get value from Nexus. From your [catalog](/nexus/catalog) and your past incidents alone, it builds a clustered map of your incident history: related incidents grouped into themes, so you can see your data in a way a list never shows you.
Exploring your incidents in Nexus is available on Pro and Enterprise plans.
Use it to spot the failures that keep recurring, the themes eating the most time, and the responders who show up across related incidents.
## What Nexus knows
Each source you connect gives Nexus another angle on your organization. Catalog and past incidents come from incident.io itself. Connecting the other sources, like telemetry and code, currently requires [Investigations](/investigations/overview).
Once a source is connected, everything draws on it: Investigations use it when an incident is live, and so does [the agent](/ai/at-incident) whenever you ask it a question. With telemetry connected, you can ask the agent what your systems were doing and it'll go and query them for you. Connect whatever you have; you don't need everything to get value.
Your services, teams, and who owns what.
Everything that's happened before, and how it was fixed.
Deploys, feature flags, and config changes, correlated with incidents.
Runbooks and reference docs from Confluence, Notion, GitHub, and GitLab.
Your pull requests and the code behind them, safely sandboxed.
Logs, metrics, traces, and dashboards from your observability tools.
Real-time context: deploys, config changes, and team discussion.
Sources are configured from the [Nexus homepage](https://app.incident.io/~/nexus) in your dashboard.
## FAQs
No. Nexus is the intelligence underneath the platform, not a separate purchase. Every product you use adds to what
it knows, and it's unique to your organization: your data never trains shared models. Connecting sources like code
and telemetry does require [Investigations](/investigations/overview), but your catalog and your past incidents feed
Nexus without it.
# Past incidents
Source: https://docs.incident.io/nexus/past-incidents
Find similar incidents and reuse the fixes that worked before.
Incidents rarely happen in isolation. The same failure modes recur, and the fastest way through an incident is often to remember how you got through the last one like it. Connecting your incident history lets Nexus do exactly that: recognizing that a similar latency spike happened three months ago and was resolved by rolling back a specific deploy, and surfacing those proven steps instead of starting from scratch.
## How Investigations use this
An investigation matches the incident you're responding to against your entire history, not by keyword, but by what actually happened. It looks at the symptoms, the systems involved, and the shape of the failure to find genuinely similar incidents, then draws out what mattered from each: the root cause that was eventually found, and the steps that resolved it.
Those learnings feed directly into the investigation's hypothesis and its recommended next steps, so a finding can be grounded in something your team has already lived through. The knowledge is already there, captured in incidents you've run and resolved, and an investigation can recall all of it at once.
It's the same history the [agent](/ai/at-incident) searches when you ask it whether you've seen something before, so you can draw on it outside an incident too.
A resemblance to a past incident is a strong starting point, but on its own it's a pattern to test, not a conclusion.
An investigation builds [conviction](/investigations/how-investigations-work#building-conviction) in the match as your
code, telemetry, and the incident's own context corroborate it.
## Setup
Enable past incidents from the [Nexus homepage](https://app.incident.io/~/nexus) in your dashboard. Nexus uses the incidents already in your incident.io account, so there's nothing external to connect.
## Related
How similar incidents become evidence in a finding.
# Slack channels
Source: https://docs.incident.io/nexus/slack
Give Nexus the real-time context that lives in your Slack.
Slack messages often hold context that telemetry alone can't provide: an engineer mentioning a database migration, an automated deploy notification, a feature flag flip. Connecting the right channels lets Investigations pick up these signals and link them to what's happening in the incident.
Connecting channels as a source is available for Slack only. Investigations in Microsoft Teams still read their own
incident channel, but can't draw on other channels you'd connect here.
## How Investigations use this
During an investigation, the channels you've connected are searched for recent messages that could be relevant: discussion that explains a cause, or change events like deploys and config pushes that line up with when the incident started. Relevant messages are connected to the incident, with links back to the original.
Add the channels where people share context that could explain an incident, such as:
* Team discussion
* Deploy and release notifications
* Infrastructure and config changes
Automated messages in these channels (deploy bots, CI notifications, feature-flag alerts) are also turned into [change
events](/nexus/change-events): structured records of changes that Investigations correlate against the incident
timeline to find a likely cause.
## Setup
From the [Nexus messages settings](https://app.incident.io/~/nexus/messages) in your dashboard, choose the public Slack channels Investigations can read. They only ever read the channels you explicitly connect, so pick the ones with the highest-signal context. You don't need to connect everything.
## Related
How a Slack message becomes evidence in a finding.
What an investigation reads from inside the incident, including its own channel, always.
# AWS
Source: https://docs.incident.io/nexus/telemetry/aws
Connect AWS once to give Nexus CloudWatch, EKS, OpenSearch, and your RDS databases.
AWS is a provider: connect it once and Nexus reaches the accounts and regions behind your credentials. From there it discovers the services you enable: CloudWatch metrics and logs, Kubernetes workloads on EKS, OpenSearch domains, and PostgreSQL or MySQL databases on RDS and Aurora.
## What it provides
Connecting AWS lets Nexus discover and query the data sources behind it:
| Data source | Capability |
| --------------------------------------------------- | ---------------- |
| [CloudWatch](/nexus/telemetry/cloudwatch) | Metrics and logs |
| [Kubernetes](/nexus/telemetry/kubernetes) (via EKS) | Cluster state |
| [OpenSearch](/nexus/telemetry/opensearch) | Logs |
| [PostgreSQL](/nexus/telemetry/postgresql) (via RDS) | SQL |
| [MySQL](/nexus/telemetry/mysql) (via RDS) | SQL |
Each has its own page covering what it supports and how it's queried. Note that:
* **CloudWatch is region-scoped**, so Nexus sees one CloudWatch data source per region you enable.
* **RDS covers Aurora too**: selecting RDS also discovers Aurora clusters. Both are surfaced as PostgreSQL or MySQL sources.
## Setup
Setting up AWS has two parts: give incident.io credentials that can read your telemetry, then choose the accounts and regions Nexus may query.
### Credentials
Choose one of two ways for incident.io to authenticate to your account.
* **OIDC IAM role (recommended).** Create a [role for web identity federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html) that incident.io assumes with `sts:AssumeRoleWithWebIdentity`.
* You provide the role ARN, and the trust policy federates `accounts.google.com`, pinning two conditions: `accounts.google.com:sub` (the numeric unique ID of incident.io's Google service account, shown in the setup form) and `accounts.google.com:oaud` (`incident-io-telemetry`). Do not pin `accounts.google.com:aud`.
* Sessions are short-lived, so there are no long-lived keys to store or rotate.
* **Static access keys.** Create an IAM user with the same permissions and paste in its access key ID and secret access key. This works for a single account, but the keys are long-lived and you own rotating them, so we recommend using the role.
We recommend read-only access either way. Nexus only reads telemetry from AWS. The connect wizard shows CLI, Terraform, and CloudFormation tabs with the exact trust and permissions policy JSON for the services you selected.
### Permissions per service
Grant only the actions for the services you want Nexus to use. The in-product setup emits an IAM policy with one block per service, so you can keep a block to allow that service or drop it to hold it back:
* **CloudWatch**: `cloudwatch:ListMetrics`, `cloudwatch:GetMetricData`, and the CloudWatch Logs Insights actions `logs:DescribeLogGroups`, `logs:StartQuery`, `logs:GetQueryResults`, and `logs:StopQuery`. `logs:StopQuery` lets a running query be canceled rather than left to finish.
* **EKS**: `eks:ListClusters` and `eks:DescribeCluster` to discover clusters. Access to workloads inside each cluster is granted separately: create an EKS access entry for the role or user, and associate the managed `AmazonEKSViewPolicy` on each cluster.
* **OpenSearch**: `es:ListDomainNames`, `es:DescribeDomains`, `es:ListTags`, and the data-plane calls `es:ESHttpGet`, `es:ESHttpPost`, and `es:ESHttpHead`. Domains also need a domain access policy that allows those `es:ESHttp*` calls. If fine-grained access control (FGAC) is enabled, map the principal to an OpenSearch backend role with read privileges.
* **RDS**: `rds:DescribeDBInstances`, `rds:DescribeDBClusters`, and `rds:DescribeBlueGreenDeployments` for discovery. The IAM policy covers discovery of your RDS and Aurora databases. After you connect, choose how each database authenticates: RDS IAM (`rds-db:connect` on the database user, with no stored password) or a username and password. Add a [proxy](/integrations/proxy) if the database isn't reachable from the public internet.
The blocks in the IAM policy match the service toggles in the connect form. Whatever you choose during connection, the
permissions you grant and the services Nexus uses stay in step.
### Connecting
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **AWS**.
2. Choose OIDC or access keys, select the services to enable, and follow the in-product instructions to create the role or user. Provide the role ARN, or the access keys, along with a default region.
3. Optionally set a region allowlist, the regions Nexus may query. Leave it empty to use the default region only.
4. Test the connection. Before connecting, incident.io makes read-only calls to each service you selected and reports back exactly which permissions are missing, per service, so you can fix the policy before finishing.
Once connected, Nexus discovers the account behind your credentials and a child data source for each service and region you enabled.
Discovered data sources start in a disabled state. Review what's found and enable the ones your team relies on during
incidents.
### Pre-existing Google OIDC provider
If the AWS account already has an IAM Identity Provider for `accounts.google.com`, AWS validates the incoming token against that provider's **Client IDs** before it evaluates the role trust policy.
When that list doesn't include incident.io's identity, the connection fails with `InvalidIdentityToken`, even if the trust policy's `sub` and `oaud` conditions are correct.
Fix it by adding our service account's **numeric unique ID** (the same value as `accounts.google.com:sub` in the setup form) to the provider's Client IDs. Adding only `incident-io-telemetry` is not enough when the token carries an `azp` claim, because AWS compares Client IDs against `azp` in that case.
Check whether a provider already exists in the console under IAM → Identity providers, or with `aws iam list-open-id-connect-providers`.
## Related
Metrics and logs behind AWS.
Workloads on your EKS clusters.
Logs on your OpenSearch domains.
SQL against RDS and Aurora Postgres.
How providers and data sources fit together.
Routing, query planning, guidance, and memory.
# CloudWatch
Source: https://docs.incident.io/nexus/telemetry/cloudwatch
Query your CloudWatch metrics and logs to see how your AWS services behaved during an incident.
Amazon CloudWatch holds the metrics and logs your AWS services emit. Nexus queries it to see how a service behaved around the time of an incident: the error rate that climbed, the function that started timing out, the log line that appeared right after a deploy.
CloudWatch is reached through a provider, not connected on its own. Connect it via [AWS](/nexus/telemetry/aws) or via
[Grafana](/nexus/telemetry/grafana). Either route gives Nexus the same access, so pick whichever matches how you
already reach CloudWatch.
## What we support
CloudWatch is one data source with two surfaces, and Nexus queries both:
* **Metrics**: CloudWatch Metric Math over AWS service metrics (EC2, RDS, Lambda, ELB, etc.) and any custom metrics your application publishes. Nexus graphs a counter climbing, a latency percentile spiking, or a queue backing up across the incident window.
* **Logs**: CloudWatch Logs Insights (CWLI) over your AWS and application log groups. Nexus pulls the actual log lines a service wrote, or aggregates them to count error patterns and break latency down by route.
### Searching logs across services
A CWLI query runs against named log groups, and Nexus can scan several at once (the Lambdas behind one service, or a service and its load balancer) in a single query, surfacing which group each line came from. That turns "where did this request fail" into one search across the path it took, rather than one query per service.
CWLI also reads structure straight out of your logs. JSON log lines expose their top-level keys as queryable fields, and AWS-managed formats (Lambda runtime logs, CloudTrail, VPC Flow Logs) are parsed automatically, so Nexus filters on a status code, request ID, or level without you indexing anything. For plain-text logs, fields are carved out by pattern at query time.
### Metric namespaces and dimensions
CloudWatch metrics live under namespaces (`AWS/Lambda`, `AWS/RDS`, or a custom namespace like `MyApp/Checkout`), each with its own dimensions for grouping by function, instance, database, and so on. Nexus prefers your custom namespaces first, since those encode what your team chose to measure, before falling back to the AWS-managed ones.
Nexus learns this structure automatically: your log groups and their field shapes, your populated namespaces, their metrics and dimensions, and which regions each appears in. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting CloudWatch
CloudWatch is discovered when you connect a provider. There are two routes, and both give Nexus the same access.
### Via AWS
Connect [AWS](/nexus/telemetry/aws) with an OIDC IAM role or static access keys, and CloudWatch is discovered automatically for the accounts and regions you enable. Nexus queries it directly through the AWS APIs using those credentials, with nothing CloudWatch-specific to configure.
### Via Grafana
If your CloudWatch already sits behind Grafana, connect [Grafana](/nexus/telemetry/grafana) and CloudWatch is discovered as one of the data sources behind it, queried through Grafana's own credentials.
Either way, CloudWatch is disabled by default. Log queries can be broad, so you opt in deliberately: enable the CloudWatch data sources your team uses once they're connected.
## Best practice
* Enable only the accounts and regions your responders actually reach for during incidents. CloudWatch is region-scoped, so the same service can appear in several regions independently.
* Scope the credentials to read-only access. Nexus only ever reads from CloudWatch, never changes anything.
* If you reach CloudWatch through Grafana, connect the dashboards that query it. Nexus learns your real query patterns from them, which makes CloudWatch queries more accurate.
## Related
Connect CloudWatch through your AWS accounts and regions.
Connect CloudWatch through Grafana instead.
How Nexus queries your metrics and logs.
# Coralogix
Source: https://docs.incident.io/nexus/telemetry/coralogix
Query your Coralogix logs, metrics, and traces to see what your systems were doing during an incident.
Coralogix is one connection that covers logs, dimensional metrics, and traces, queried with Coralogix's DataPrime query language (and PromQL for metrics) over your Coralogix account. Nexus queries it to see what your services were doing around the time of an incident: the log lines, the metric that moved, and the slow or failing span behind a bad request.
You connect Coralogix directly, with an API key and your region. A single connection brings logs, metrics, and traces,
and you choose which ones Nexus can use.
## What we support
Connecting Coralogix gives Nexus three capabilities, each of which you can enable independently, plus your dashboards:
| Capability | What it queries |
| ---------- | ---------------------------------------------------------------------- |
| Logs | Log lines from your services, and trends derived from those logs |
| Metrics | Dimensional metrics, graphed for the incident window |
| Traces | Traces and spans across your services to find slow or failing requests |
| Dashboards | The queries built into your own dashboards |
### Logs
Nexus searches your Coralogix logs with DataPrime to read what a service was logging at the time of an incident, scoped by the application and subsystem the logs belong to. The same query language turns logs into time-series, so an error rate climbing or a request volume dropping away shows up as a graph even where you never set up a dedicated metric for it.
### Metrics
Nexus queries your dimensional metrics with PromQL and graphs them for the incident's time window, so a resource spike, a latency change, or a growing error count shows up against the period that matters.
### Traces
Nexus uses your traces and spans in three ways: searching for the spans behind a problem (a slow endpoint, a failing dependency, a particular service), pulling a specific trace by ID to see the full span tree and where it broke, and aggregating spans into throughput, latency, and error-rate signals for a service.
### Dashboards
Your Coralogix dashboards are discovered automatically once you connect, and read for the DataPrime and PromQL behind their widgets, so Nexus learns the applications, fields, and filters your team already queries.
Nexus learns the structure of your Coralogix data automatically: your applications and subsystems, the fields on your logs, your metric names, and the services your spans belong to. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Coralogix
You connect Coralogix directly. There's no provider in front of it.
**What you'll need:**
* A Coralogix **API key** with permission to run queries, created under **API keys** in your Coralogix account. We recommend a key scoped to read-only access, so Nexus can only read.
* Your Coralogix **region**, matching the domain you log in to (for example, `eu2` for `eu2.coralogix.com`). Coralogix is region-pinned, so a key used against the wrong region is rejected.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Coralogix**.
2. Enter your API key and region, then test the connection. We check the key authenticates against that region.
3. Choose which capabilities (logs, metrics, traces) Nexus can use. The ones you select are enabled once you connect.
Your dashboards are discovered automatically once Coralogix is connected — there's nothing extra to set up.
## Best practices
* Use a dedicated API key scoped to read-only access, so Nexus can't do anything Coralogix itself wouldn't allow a viewer to do.
* Check the region matches the account you want to query. A key from a different region won't authenticate.
* Enable logs, metrics, and traces together where your team uses them. With more than one connected, an investigation can move from a log line to the trace behind it, or from a metric to the logs explaining it.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Datadog
Source: https://docs.incident.io/nexus/telemetry/datadog
Query your Datadog logs, metrics, traces, and error tracking to see what your systems were doing during an incident.
Datadog is one connection that covers four kinds of telemetry: logs, metrics, traces, and error tracking. Nexus queries it to see what your services were doing around the time of an incident: the log lines, the metric that moved, the slow span, and the errors that were firing.
You connect Datadog directly, with a Datadog API key, application key, and your Datadog site. A single connection
brings all four capabilities, and you choose which ones Nexus can use.
## What we support
Connecting Datadog gives Nexus four capabilities, each of which you enable independently:
| Capability | What it queries |
| -------------- | ------------------------------------------------------------------ |
| Logs | Log lines from your services, and trends derived from those logs |
| Metrics | Time-series metrics, graphed for the incident window |
| Traces | Spans across your services to find slow or failing requests |
| Error tracking | Errors grouped into issues, with counts, services, and error types |
### Logs
Nexus searches your Datadog logs to read what a service was logging at the time of an incident: the errors, the warnings, the request that failed. It can also turn those logs into time-series, so you get a graph of an error rate climbing or request volume dropping away even where you never set up a dedicated metric.
### Metrics
Nexus queries your metrics and graphs them for the incident's time window, so a CPU saturation, a latency change, or a queue backing up shows up against the period that matters.
### Traces
Nexus searches your spans to find the requests behind a problem: which service was slow, where a request failed, how an error propagated across services. Where you've connected the Datadog Service Catalog, services are described with their team, tier, and runbook links, so an investigation can tell which team owns a failing service.
### Error tracking
Datadog groups individual error events into issues, so the same exception that fired ten thousand times is one issue rather than ten thousand log lines. Nexus queries error tracking to see which issues are active and at what volume, then drills from an issue into the underlying logs or traces for the full stack traces and individual events. This is the difference between "errors appeared" and "this specific issue, on this service, started after the deploy and is firing at this rate", which is usually what you want during an incident.
Nexus learns the structure of your Datadog data automatically: your log fields, metric names and tags, services, and the error issues that show up. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Datadog
You connect Datadog directly. There's no provider in front of it: one connection covers all four capabilities.
**What you'll need:**
* A Datadog **API key**.
* A Datadog **application key**.
* Your **Datadog URL**, exactly as it appears in your browser, for example `https://app.datadoghq.com` (US1), `https://app.datadoghq.eu` (EU), or `https://us3.datadoghq.com`. The URL tells us which Datadog region your account lives in, and (if you have one) the custom subdomain that identifies your organisation.
We recommend keys scoped to read-only access: Nexus only ever reads from Datadog. Each capability reads a different part of Datadog, so grant the application key the read scopes for the capabilities you plan to use: for example log data for logs, and error tracking for error tracking. Some optional scopes enrich what Nexus can do, such as reading your monitors and notebooks to learn the queries your team already relies on, and the Service Catalog to attach team and tier detail to your services.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Datadog**.
2. Enter your API key, application key, and Datadog URL, then test the connection.
3. Choose which of the four capabilities (logs, metrics, traces, error tracking) Nexus can use.
All four capabilities are enabled by default once you connect. Turn off any you don't want Nexus to query.
### Connecting more than one Datadog organisation
Several Datadog organisations can share a region. `app.datadoghq.com`, for instance, is the same URL for every US1 account. To connect more than one, each organisation needs its own **custom subdomain** so we can tell them apart and route queries to the right place: a URL like `https://your-org.datadoghq.com` rather than the shared `https://app.datadoghq.com`.
Custom subdomains aren't enabled by default. If your organisations don't have one yet, contact Datadog support to request it. See [Datadog's custom sub-domains guide](https://docs.datadoghq.com/account_management/multi_organization/#custom-sub-domains). Once an organisation has its own subdomain, connect it using that full URL.
If you connect a second organisation on the same region without a distinguishing subdomain, the connection test flags the clash so you don't end up with two connections we can't tell apart.
## Best practice
* Grant the read scopes for every capability you intend to use, and the optional scopes for monitors, notebooks, and the Service Catalog. Nexus learns your real query patterns and service ownership from them, which makes queries more accurate.
* Keep error tracking enabled alongside logs and traces. On its own it tells you which issues are firing; with logs and traces enabled, an investigation can follow an issue through to the stack traces and individual events behind it.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Elasticsearch
Source: https://docs.incident.io/nexus/telemetry/elasticsearch
Search your Elasticsearch log indices to see what your services recorded during an incident.
Elasticsearch stores and searches your logs. Nexus queries the index patterns you point it at to read what your services recorded around the time of an incident: the errors, the warnings, the request that failed.
You connect Elasticsearch directly, with your cluster's endpoint and credentials. It works the same whether you run
Elastic Cloud or manage your own cluster.
## What we support
Nexus queries Elasticsearch with its Query DSL against the log index patterns you configure, in two ways:
* **Log searches**: pull back the actual documents, whether that's what a service logged at the time, whether errors appeared on an endpoint, or whether a message started showing up right after a deploy.
* **Aggregations over logs**: turn matching documents into a time series, so Nexus can graph trends straight from your logs, such as an error count climbing, request volume dropping away, or the frequency of a particular message across the incident window. You get a chart of what your logs were doing even where you never set up a dedicated metric for it.
### Querying your index patterns
Elasticsearch doesn't expose one set of logs. It holds whatever indices and data streams you ship to it, and the useful ones differ by team. So you tell Nexus which index patterns to query, for example `logs-*` for application logs or a security audit stream, and each pattern becomes its own queryable source you can enable or disable independently.
Until you configure at least one index pattern, an Elasticsearch connection has nothing to query. Add your patterns during setup, then enable the ones your responders reach for.
### Learning your fields and mappings
A log document in Elasticsearch can carry hundreds of fields, and a query is only as good as knowing which ones exist and what they hold. For each index pattern, Nexus reads its mapping to learn the fields and their types, then samples recent documents to learn which fields are actually populated, how many distinct values each holds, and the common values for the ones worth filtering on, such as a status code, a service name, or a customer. It also learns the timestamp field your index uses and how long it retains data, so queries scope to the incident window and don't reach past what's still there.
This means Nexus can filter on the fields that matter in your logs without you describing your schema by hand. How that learning works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Elasticsearch
Connect Elasticsearch from the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry) by adding a telemetry data source and choosing **Elasticsearch**.
**What you'll need:**
* **Your cluster's endpoint.** For Elastic Cloud, this is your deployment's Cloud ID. For a self-managed cluster, this is one or more node addresses.
* **Credentials.** Either an API key or a username and password.
* **A CA certificate** (self-managed only, optional). Provide one if your cluster uses a self-signed or internal certificate authority. Elastic Cloud uses public certificates, so this isn't needed there.
To connect:
1. Choose **Elastic Cloud** or **self-managed**, then enter your Cloud ID or node addresses.
2. Add your API key or username and password, and a CA certificate if your self-managed cluster needs one.
3. Add the index patterns you want Nexus to query, then test the connection.
The credentials only need read access. Grant the `monitor` cluster privilege, and `read`, `view_index_metadata`, and `monitor` on the index patterns you connect:
```json theme={null}
{
"incident_io_role": {
"cluster": ["monitor"],
"indices": [
{
"names": ["logs-*"],
"privileges": ["read", "view_index_metadata", "monitor"]
}
]
}
}
```
Each index pattern you add becomes its own data source. Enable the patterns your responders use during incidents.
## Best practice
* Connect the index patterns your team actually searches during incidents, rather than every index in the cluster. Each one is enabled independently, so keep the noisy or rarely-used ones off.
* Scope `names` in your role to the patterns you're connecting, so the credentials only read the indices you intend.
* Use a dedicated read-only API key or user. Nexus only ever reads from Elasticsearch.
## Related
How providers and data sources fit together.
How Nexus queries your logs.
# Google Cloud
Source: https://docs.incident.io/nexus/telemetry/google-cloud
Connect Google Cloud once to give Nexus your logs, metrics, traces, and the workloads behind them.
Google Cloud is a provider: connect it once with a service account, and Nexus can reach the projects behind it. From there it queries your logs, metrics, and traces, and inspects the Kubernetes clusters running on GKE, all through a single set of credentials.
## What it provides
Connecting Google Cloud lets Nexus discover and query the data sources behind your projects:
| Data source | Capability |
| ------------------------------------------------------------------- | ------------- |
| [Google Cloud Logging](/nexus/telemetry/google-cloud-logging) | Logs |
| [Google Cloud Monitoring](/nexus/telemetry/google-cloud-monitoring) | Metrics |
| [Google Cloud Trace](/nexus/telemetry/google-cloud-trace) | Traces |
| [Kubernetes](/nexus/telemetry/kubernetes) | Cluster state |
Each has its own page covering what it supports and how it's enabled.
## Setup
**What you'll need:**
* A Google Cloud service account key in JSON.
* The IAM permissions below, granted to that service account.
We recommend a read-only service account: Nexus only ever reads from Google Cloud, never writes. Grant the permissions through read-only roles rather than broad editor or owner roles.
### Permissions
Grant the service account this permission on each project you want Nexus to reach:
* `logging.logEntries.list`: read Cloud Logging entries.
To let the service account discover your projects automatically, also grant:
* `cloudresourcemanager.projects.list`: list the projects the account can reach.
These permissions help Nexus find and identify the workloads in a project, so it knows what's worth querying:
* `container.clusters.list`: discover GKE clusters.
* `logging.buckets.list`: read each log bucket's retention window.
Without project discovery, you can still connect a single project by supplying its ID directly (see below).
### Connect Google Cloud
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Google Cloud**.
2. Paste your service account JSON key. If the account can't list projects across your organization, enter a single project ID instead and we'll connect just that project.
3. Test the connection. We check the key is valid and confirm the account holds the permissions it needs.
### Enabling projects
Once connected, Nexus discovers every project the service account can reach. Each project arrives **disabled by default**, so you opt in deliberately rather than exposing every project at once. Review the list and enable the ones your team runs production workloads in.
Enabling a project turns on its Cloud Logging access and surfaces the GKE clusters running inside it, which you then enable individually.
## Related
Querying your project logs during an incident.
Routing, query planning, guidance, and memory.
# Google Cloud Logging
Source: https://docs.incident.io/nexus/telemetry/google-cloud-logging
Read what your Google Cloud services logged around the time of an incident.
Google Cloud Logging is where your Google Cloud projects collect their logs. Nexus queries it to read what your services logged around the time of an incident: the errors, the failed requests, the message that started appearing after a deploy.
Cloud Logging is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud once, then
enable the projects you want Nexus to read. There's nothing to set up for Cloud Logging on its own.
## What we support
Nexus queries Cloud Logging with the Logging query language, the same filter expressions you'd write in the Logs Explorer. It uses this to:
* **Read log lines**: pull back what a service logged in the incident window, scoped to a project.
* **Narrow by resource**: filter to a resource type and its labels, so a query reaches one GKE namespace, one Cloud SQL instance, or one Cloud Run service rather than everything in the project.
* **Filter on severity**: Cloud Logging orders severity numerically, so Nexus can ask for everything at `ERROR` and above and let warnings and info fall away.
### Querying structured and unstructured logs
Cloud Logging holds both plain text logs and structured JSON, and the useful detail often lives inside the payload. Nexus queries both: a free-text search across `textPayload` and `jsonPayload.message`, or a precise filter on a nested field such as a status code, a request method, or an HTTP latency. It reaches into the request metadata too, so a query can find every 5xx from a load balancer or every request slower than a threshold.
A query can answer questions like:
> Did the checkout service log any errors in the ten minutes after the deploy?
> Which namespace was throwing connection-refused errors during the outage?
> Were the load balancer's 5xx responses concentrated on one backend?
### Knowing what's in each project
A project can hold many kinds of workload, and a query only works if it names the right resource type and labels. Nexus learns what each enabled project actually runs (its GKE clusters, Cloud SQL instances, Cloud Run services, and the resource types generating logs) so it queries the resources that matter instead of guessing. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Cloud Logging
Cloud Logging is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud with a service account that can read logs, then enable the projects your team runs production workloads in. Each project is disabled by default, so you opt in deliberately; enabling one turns on its Cloud Logging access.
## Best practice
* Enable the projects your responders actually investigate, rather than every project the service account can reach.
* Grant the service account read-only logging access. Nexus only ever reads from Cloud Logging.
## Related
The provider Cloud Logging is connected through.
How Nexus queries your logs.
# Google Cloud Monitoring
Source: https://docs.incident.io/nexus/telemetry/google-cloud-monitoring
Graph what your Google Cloud infrastructure was doing around the time of an incident.
Google Cloud Monitoring collects metrics from your Google Cloud projects: your GKE clusters, Cloud SQL instances, load balancers, Pub/Sub subscriptions, and more. Nexus queries it to see what your infrastructure was doing around the time of an incident: CPU climbing, a connection pool filling up, a request rate falling away.
Cloud Monitoring is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud once, then
enable the projects you want Nexus to read. There's nothing to set up for Cloud Monitoring on its own.
## What we support
Nexus queries Cloud Monitoring with PromQL, through Google Cloud's Prometheus-compatible API. It uses this to:
* **Graph a metric over the incident window**: CPU utilization on a Cloud SQL instance, memory on a container, the backlog on a Pub/Sub subscription, scoped to a project.
* **Narrow by resource**: filter on resource labels so a query reaches one GKE namespace, one database, or one backend service rather than everything in the project.
* **Aggregate and rank**: sum across the containers in a namespace, average across instances, or pull the top few pods by memory to find the one that's misbehaving.
This covers both Google's built-in metrics and any custom metrics you send through Managed Service for Prometheus, so a single query can move between infrastructure and your own application metrics.
A query can answer questions like:
> Did the database's CPU spike when the checkout errors started?
> Which pods in the payments namespace were using the most memory during the outage?
> Was the Pub/Sub backlog growing while messages went unprocessed?
### Checking a metric before trusting it
A metric that isn't emitting tells you nothing, and a filter on a label that doesn't exist returns an empty graph that looks like a problem when it isn't. Before building a query, Nexus checks whether a metric is actually producing data in the incident window and learns which labels it carries, so it doesn't graph a silent metric or filter on a label that was never there, and it knows which resource labels are available to narrow on.
### Knowing what's in each project
A project can run many kinds of workload, and a PromQL query only works if it names the right metric and labels. Cloud Monitoring's naming differs from plain Prometheus, and resource labels vary by service. Nexus learns what each enabled project actually runs (its GKE clusters, Cloud SQL instances, load balancers, and the metric types they emit) so it queries the resources that matter instead of guessing. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Cloud Monitoring
Cloud Monitoring is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud with a service account that can read metrics, then enable the projects your team runs production workloads in. Each project is disabled by default, so you opt in deliberately; enabling one turns on its Cloud Monitoring access.
## Best practice
* Enable the projects your responders actually investigate, rather than every project the service account can reach.
* Grant the service account read-only monitoring access. Nexus only ever reads from Cloud Monitoring.
## Related
The provider Cloud Monitoring is connected through.
How Nexus queries your metrics.
# Google Cloud Trace
Source: https://docs.incident.io/nexus/telemetry/google-cloud-trace
Follow a request across your Google Cloud services to see where it broke.
Google Cloud Trace collects distributed traces from your Google Cloud projects: the spans a single request leaves as it moves through your services. Nexus retrieves a trace to follow one request end to end and see where it slowed down or failed.
Cloud Trace is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud once, then enable
the projects you want Nexus to read. There's nothing to set up for Cloud Trace on its own.
## What we support
Nexus retrieves a trace by its ID, scoped to a project. A trace ID usually comes from elsewhere in the investigation: a log line, an error, or an earlier metric query points at a specific request, and the trace shows what happened to it.
Once a trace is retrieved, Nexus reconstructs it into the full picture of the request:
* **The span tree**: every span linked to its parent, so you can see which call led to which, where time was spent, and which service handed off to the next.
* **The services involved**: the set of services the request touched, drawn together from the trace so you can see its full path.
* **Where it failed**: spans flagged as errors, whether from a failing HTTP status, an explicit error label, or a recorded exception, so the broken step stands out rather than being buried in the tree.
A trace can answer questions like:
> Where did this request spend its time before it timed out?
> Which downstream service returned the error the user saw?
> How many services did this request pass through before it failed?
### Making sense of varied span data
Google Cloud services label their spans inconsistently. A Cloud Run service, a GKE container, an App Engine module, and an OpenTelemetry-instrumented service each name themselves differently, and errors show up under several different conventions. Nexus recognizes these patterns, so a span gets attributed to the right service and an error is caught however it was recorded, instead of a trace reading as a wall of anonymous spans.
## Connecting Cloud Trace
Cloud Trace is connected through [Google Cloud](/nexus/telemetry/google-cloud). Connect Google Cloud with a service account that can read traces, then enable the projects your team runs production workloads in. Each project is disabled by default, so you opt in deliberately; enabling one turns on its Cloud Trace access.
## Best practice
* Enable the projects your responders actually investigate, rather than every project the service account can reach.
* Grant the service account read-only trace access. Nexus only ever reads from Cloud Trace.
## Related
The provider Cloud Trace is connected through.
How Nexus queries your traces.
# Grafana
Source: https://docs.incident.io/nexus/telemetry/grafana
Connect Grafana to give Nexus your dashboards and the data sources behind it.
Grafana is a provider: connect it once and Nexus can reach the data sources behind it and query the dashboards your team has built. All of it comes through a single connection.
## What it provides
Connecting Grafana lets Nexus discover and query the data sources it fronts:
| Data source | Capability |
| ----------------------------------------- | ---------------- |
| [Loki](/nexus/telemetry/loki) | Logs and metrics |
| [Prometheus](/nexus/telemetry/prometheus) | Metrics |
| [Tempo](/nexus/telemetry/tempo) | Traces |
| [Pyroscope](/nexus/telemetry/pyroscope) | Profiles |
| [CloudWatch](/nexus/telemetry/cloudwatch) | Logs and metrics |
Each has its own page covering what it supports and how it's set up. When Nexus cites a result from one of these data sources, the citation links into Grafana Explore with the same query and time range. You can rerun and refine it yourself.
These are the data source types Nexus discovers from Grafana today. If Grafana fronts a tool that isn't listed here,
connect that tool directly instead; most have their own page in this section.
## Dashboards
Alongside the data sources it fronts, Grafana brings your dashboards, and Nexus uses them in two ways:
* **Read as images.** Nexus renders a dashboard for the incident's time window and reads the resulting image. It interprets the charts the way a responder glancing at the dashboard would: the spike, the dip, the line that breaks trend. It isn't limited to the numbers behind a panel; it sees the panel.
* **Learned from.** The queries built into your dashboards are a record of how your team investigates: which signals matter, how they're filtered and grouped. Nexus learns from them, which sharpens how it queries the data sources behind Grafana, dashboard or not. See [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
Reading dashboards depends on Grafana's image renderer. Grafana Cloud includes it; on self-hosted Grafana, install the [grafana-image-renderer](https://grafana.com/grafana/plugins/grafana-image-renderer/) plugin. Where it's missing, Nexus sets your dashboards aside rather than trying to read them, though it still learns from their queries.
Connect the dashboards your team reaches for during incidents, up to 100. Nexus queries the dashboards you selected, and your selection isn't a hard boundary for learning: Nexus can also learn from other dashboards it can see.
## Setup
**What you'll need:**
* The URL of your Grafana instance. It must use HTTPS and a publicly resolvable hostname; if your Grafana runs on a private network, run a [proxy](/integrations/proxy) and connect through it instead.
* A Grafana service account token. It must be non-expiring: Grafana suggests an expiry when you create a token, so choose no expiration. Otherwise the connection stops working when the token lapses.
Nexus only ever reads from Grafana, so grant the service account read access in whichever of these ways fits how you manage Grafana permissions:
* **Viewer basic role**: assign the [Viewer](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/) basic role to the service account. It grants read and query access to all data sources, and it's the fastest to set up.
* **Fixed roles**: assign the three [fixed roles](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/) **Dashboards Reader**, **Folders Reader**, and **Data sources Reader**. The middle ground: scoped to just what Nexus reads, without maintaining a custom role.
* **Custom role**: create a [custom role](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/create-custom-roles/) with exactly the actions Nexus needs, then assign it to the service account:
```json theme={null}
{
"version": 1,
"name": "custom:incidentio:telemetry",
"displayName": "incident.io telemetry",
"global": true,
"permissions": [
{ "action": "datasources:read", "scope": "datasources:*" },
{ "action": "datasources:query", "scope": "datasources:*" },
{ "action": "dashboards:read", "scope": "dashboards:*" },
{ "action": "folders:read", "scope": "folders:*" }
]
}
```
**To connect Grafana:**
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Grafana**.
2. Enter your Grafana URL and service account token, then test the connection. If you're connecting through a proxy, choose it here; you can also set a public URL so that links back into Grafana open somewhere your browser can reach.
3. Once connected, Nexus discovers the data sources behind Grafana and lists your dashboards. Enable the data sources your team uses and select their most-used dashboards.
Requests to Grafana come from a fixed set of IP addresses, so if your instance sits behind an IP allowlist you can [allowlist ours](/integrations/ip-allowlist).
Every data source discovered from Grafana starts disabled, so you opt in deliberately. Turn on the ones your
responders rely on.
## Related
Log queries, and metrics derived from logs.
Metrics for how your services behaved.
Traces that follow a request across services.
Profiles showing where CPU and memory went.
AWS logs and metrics, through your Grafana connection.
How providers and data sources fit together.
Routing, query planning, guidance, and memory.
# Honeycomb
Source: https://docs.incident.io/nexus/telemetry/honeycomb
Query your Honeycomb traces and events to see how requests moved through your services during an incident.
Honeycomb stores your distributed traces and the events behind them. Nexus queries it to follow a request through your services around the time of an incident: where it slowed down, where it errored, and which service was responsible.
You connect Honeycomb directly, with a Honeycomb API key and the API endpoint for your region. It isn't fronted by
another provider.
## What we support
Nexus queries Honeycomb's event data in three ways:
* **Traces**: pull back a full trace by its ID and reconstruct the span tree, so an investigation can see the path a request took across services, the timing of each span, and where errors appeared.
* **Span search**: find spans matching a set of conditions, for example every errored span on a service, or the slow requests above a latency threshold, without already knowing a trace ID.
* **Metrics**: for environments that send metrics to Honeycomb, query a metric over the incident window (a request rate, an error count, a latency aggregation) grouped by attributes such as the service that emitted it.
### Filtering on any column, including high-cardinality ones
Honeycomb stores wide events, and the value of that breadth shows up at query time. Nexus filters on any column you send, not a fixed set of indexed dimensions: resource attributes, span attributes, and the intrinsic fields Honeycomb adds to every event. That includes high-cardinality fields like a request ID, a status code, a customer or tenant, or an endpoint, so an investigation can narrow to the exact slice of traffic that failed rather than approximating it from coarse labels.
When a search comes back empty, an investigation can check the columns it filtered on to see which condition excluded everything, then adjust and try again rather than reporting nothing found.
Nexus learns this structure automatically: your environment's datasets, services, and the columns that actually carry data. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Honeycomb
Connect Honeycomb directly with its API key and region endpoint.
**What you'll need:**
* A Honeycomb API key with permission to run queries and read columns. We recommend a key scoped to read-only query access, since Nexus only ever reads from Honeycomb.
* The API endpoint for your region: `https://api.honeycomb.io` for US, or `https://api.eu1.honeycomb.io` for EU.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Honeycomb**.
2. Enter your API key and select your region's API endpoint, then test the connection.
3. Once connected, Nexus reads the team and environment the key belongs to, so traces and searches run against the right data.
Once connected, Honeycomb is available to Nexus straight away. You can disable it at any time if you'd prefer Nexus
didn't query it.
A Honeycomb key needs both query and column permissions to look up traces. If a key has one but not the other, the
connection test can still pass while queries fail, so grant both.
## Best practice
* Use a read-only key scoped to the environment you want Nexus to query, rather than a broad key with write access.
* Pick the API endpoint that matches your Honeycomb region. The US and EU instances are separate, and a key from one won't work against the other.
## Related
How providers and data sources fit together.
How Nexus queries your traces.
# How telemetry works
Source: https://docs.incident.io/nexus/telemetry/how-it-works
How Nexus queries your observability stack like an engineer who knows it.
Querying an unfamiliar observability stack well is hard, even for experienced engineers. You have to know which system holds the answer, the query language it speaks, and the labels and conventions specific to your setup. Telemetry is the part of Nexus that does all of this for you. This page explains how it works: how the right data source gets picked, how a correct query is written against it, and how it gets better at your stack over time. It's the same machinery whether an investigation is testing a hypothesis or you're asking the agent a question directly.
## Choosing where to look
A connected data source advertises what it can do through its **capabilities**: logs, metrics, traces, SQL, dashboards. A question about error rates routes to the data sources that can answer it with metrics; a question about what a service logged routes to the ones that hold logs. Nexus never has to query a system that couldn't possibly answer.
To choose between data sources that share a capability, Nexus uses a short, learned **summary** of what each one is actually good for in your environment. That's how "payment errors" goes to the data source that holds payment logs, not just any log source. For [providers](/nexus/telemetry/overview#how-telemetry-is-modeled) like Grafana, the same routing picks the right child behind it: the relevant Loki source for logs, Prometheus for metrics, and so on.
When several lines of enquiry are independent, Nexus runs them in parallel, pulling logs and metrics at the same time rather than one after another.
## Writing the query
Once it knows where to look, Nexus translates your question into a real query in that data source's own language: LogQL for Loki, PromQL for Prometheus, SQL for a database, the right trace query for your tracing backend.
Nexus doesn't write queries from generic knowledge of a query language. For the data source it's targeting, it works from:
* **A query language reference**: how to write correct, efficient queries in that language, including how to recover from timeouts and expensive queries.
* **That data source's guidance**: the real labels, fields, and conventions discovered in your instance, so it filters on attributes that actually exist (see [below](#learning-your-stack)).
* **Proven patterns**: example queries that have worked before for similar questions, used as a starting point rather than guessed from scratch (see [memory](#getting-better-over-time)).
Before a query runs, Nexus checks it, including parsing it with the data source's own query parser to catch invalid syntax. A query can still fail when it runs: a syntax error, a timeout, a cardinality limit. Nexus reads the error and rewrites the query to address it, rather than giving up or repeating the same mistake.
## Learning your stack
The reason Nexus can query your systems well is that it learns the shape of each one. For every connected data source, we continually build **guidance**: a living description of how to query that specific data source in your environment. It comes from three sources:
* **The data source itself**: Nexus inspects the data source directly for the ground truth: which labels and fields exist, their cardinality, the kinds of events or metrics it holds.
* **Your dashboards**: the dashboards your team has built are a record of the questions you ask most and the queries that answer them, so we learn your real query patterns from them.
* **Proven queries**: patterns from past queries that successfully answered a question feed back in (see [below](#getting-better-over-time)).
We build guidance automatically when you connect a data source, and keep it fresh as your systems change. It's what lets Nexus filter on the labels you actually use and reach for the right defaults when a question is vague. It's the difference between a query written by someone seeing your stack for the first time and one written by someone who already knows it.
## Getting better over time
Beyond guidance, Nexus keeps a **memory** of what works: a learned library of proven question-to-query patterns for each data source, built from the queries that successfully answered questions during real investigations. When Nexus writes a new query, it draws on the memories most similar to the question as worked examples, so it reaches a correct query faster and more reliably. Those patterns also enrich the guidance above.
Memory grows from your own investigations, so Nexus gets better at your stack the more it's used. See [Memory](/nexus/telemetry/memory) for how it's built and how it compounds.
## Making sense of the results
Raw telemetry output is huge and repetitive: thousands of near-identical log lines, walls of timestamped numbers, traces with hundreds of spans. The few lines that matter are easy to lose in everything around them.
So Nexus reworks results into compact, readable forms before reasoning over them, one for each kind of telemetry. It cuts the repetition: shared fields appear once, and runs of similar log lines collapse to just what changed between them. It describes time-series by their shape rather than every point in them. It renders traces as readable timelines. What's left is enough to spot the pattern, the anomaly, or the change, without burying it in everything else.
## Related
What you can connect, and how providers and capabilities fit together.
Where telemetry fits in the wider investigation.
# Kubernetes
Source: https://docs.incident.io/nexus/telemetry/kubernetes
See the state of your cluster during an incident: what was running, what was failing, and why.
Kubernetes runs your workloads, and when an incident starts the first question is often "what is the cluster doing right now?". Nexus reads your cluster's live state (the deployments, pods, services, and events) to answer that without anyone reaching for `kubectl`.
Kubernetes clusters are discovered through your cloud provider. Connect [AWS](/nexus/telemetry/aws) to surface your
EKS clusters, or [Google Cloud](/nexus/telemetry/google-cloud) to surface your GKE clusters. Either route gives Nexus
the same read-only access to the cluster.
## What we support
Nexus reads your cluster the way a responder would with `kubectl get` and `kubectl describe`: listing resources and describing a single object in detail. It never writes to the cluster; access is read-only.
* **List resources**: get a `kubectl get`-shaped view of any kind: pods, deployments, statefulsets, daemonsets, jobs, services, ingresses, nodes, events, and the custom resources your operators add. Scope a list to a namespace or a label selector to stay fast on busy clusters.
* **Describe a resource**: get the `kubectl describe`-shaped detail for a single object: its spec and status, labels and annotations, the recent events attached to it, and the ownership chain that links a pod back to its replica set and deployment.
### Seeing what's failing
The useful detail in an incident is rarely the healthy workload; it's the one that isn't. When Nexus lists pods it sees the same signals you would: the ready container count, the pod phase, and the restart count. When it describes a failing pod it gets its container statuses and the events behind them, so a crash shows up as what it actually is (`CrashLoopBackOff`, `ImagePullBackOff`, `OOMKilled`) rather than a pod that's simply "not ready".
That lets an investigation walk a symptom to its cause: start at the deployment a responder named, check its rollout conditions, list the pods behind it, and describe the one that's failing to read the events that explain why. The ownership chain ties it together, so a single failing pod can be traced back to the deployment that owns it.
### Logs and metrics live elsewhere
Kubernetes tells Nexus the *state* of your workloads, not what they logged or how much CPU they burned. For the log lines a service emitted, connect a logging data source such as [Loki](/nexus/telemetry/loki); for resource usage over time, connect a metrics data source such as Prometheus. Nexus combines them: the cluster shows a pod restarting, and your logs and metrics show what led up to it.
Nexus learns the shape of each cluster automatically: its namespaces, the workloads that run in them, the label conventions your team uses, and the operators you've installed. That structure makes queries land on the right resource the first time. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Kubernetes
Connect the cloud provider that hosts your clusters, and Nexus discovers them using that provider's credentials. If your clusters aren't discoverable that way, you can also connect one directly with a kubeconfig.
### Through AWS
Connect [AWS](/nexus/telemetry/aws) with **EKS** among the selected services, and your clusters are discovered automatically across the regions you enable.
Discovery and cluster access are granted in two different places, so EKS requires an additional step per cluster:
* **Discovery** comes from the IAM policy on the role or user incident.io authenticates as: `eks:ListClusters` and `eks:DescribeCluster`.
* **Reading workloads inside a cluster** is granted on the cluster itself. Create an [EKS access entry](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html) for that same principal, and associate the AWS-managed `AmazonEKSViewPolicy` with it. That policy is read-only by design.
The AWS setup instructions generate this for you, with CLI, Terraform, and CloudFormation versions of both the access entry and the policy association.
If a cluster's API endpoint is private, attach a [proxy](/integrations/proxy) to the AWS connection so cluster calls travel through your network rather than the public internet.
We filter two kinds of cluster out of discovery, because we can't be granted access to them:
* **Clusters whose authentication mode is `CONFIG_MAP` only.** Access there is controlled solely by the in-cluster `aws-auth` ConfigMap, which we never modify, so the access entry above can't grant anything. Switch the cluster to `API` or `API_AND_CONFIG_MAP` and it'll be picked up on the next discovery. Switching is additive, so your existing `aws-auth` mappings keep working, though AWS makes it a one-way change. If you'd rather not switch, connect the cluster [directly with a kubeconfig](#directly-with-a-kubeconfig) instead, which doesn't depend on the authentication mode at all.
* **Public clusters restricted to a CIDR allowlist.** If the endpoint is public but locked to specific ranges, our egress isn't in them. Use a private endpoint with a proxy instead.
### Through Google Cloud
Connect [Google Cloud](/nexus/telemetry/google-cloud) and your GKE clusters are discovered automatically. The service account you grant Google Cloud is exchanged for cluster access, so each discovered cluster inherits those credentials.
### Enabling discovered clusters
One provider connection can surface many clusters, so discovered Kubernetes clusters are left disabled by default. Review the clusters that appear and enable the ones your team runs incidents against.
### Directly, with a kubeconfig
When a cluster can't be reached through a provider, connect it on its own with a kubeconfig. This is the route for a self-managed cluster, a cluster on a provider we don't discover yet, or an EKS cluster whose authentication mode is `CONFIG_MAP` only.
Add a telemetry data source, choose **Kubernetes**, and paste the kubeconfig for the cluster. We read the API server endpoint, the cluster CA certificate, and the bearer token from it.
The token only needs read access. Nexus issues `get` and `list` against namespaces, nodes, pods, services, events, endpoints, persistent volumes and claims, the `apps` workloads (deployments, replicasets, statefulsets, daemonsets), `batch` jobs and cronjobs, and ingresses and network policies. Bind a service account to a read-only ClusterRole covering those, and use its token.
A few resources are treated as optional, so a connection still works without them: ConfigMaps and ServiceAccounts (withhold these if they may hold sensitive data), pod logs, and the ArgoCD and metrics-server resources that only matter if you run those add-ons. The connect form lists every scope with what it's used for and tells you which are missing when you test.
If the cluster sits behind a proxy that authenticates the connection itself and injects the identity (e.g. Tailscale's
Kubernetes API server proxy), connect it with no client credentials and pair it with a [proxy](/integrations/proxy) so
requests arrive from inside your network.
A directly-connected cluster stands on its own: it isn't rediscovered or kept in sync by a provider, and you own rotating the token. We recommend connecting a provider where one is available.
## Best practice
* Grant the cloud provider read-only access. Nexus only ever reads cluster state, so a read-only role keeps the blast radius small.
* Enable the clusters your responders actually investigate (your production clusters) rather than every cluster the provider can see.
* Connect a logging and a metrics data source alongside Kubernetes. Cluster state shows you *what* failed; logs and metrics show you *why*.
## Related
Connect AWS to discover your EKS clusters.
Connect Google Cloud to discover your GKE clusters.
How Nexus learns and queries your cluster.
# CrowdStrike Falcon LogScale
Source: https://docs.incident.io/nexus/telemetry/logscale
Query your LogScale logs to see what your systems were doing during an incident.
CrowdStrike Falcon LogScale (formerly known as Humio) holds your log events, queried with LogScale's query language, LQL.
Nexus queries it to read what a service was logging around the time of an incident, and to graph how those logs changed.
You connect LogScale directly, with your deployment URL and an API token. One connection covers every repository and
view that token can read, and you choose which ones Nexus can query.
## What we support
LogScale is a log store, so connecting it gives Nexus one capability, plus your dashboards:
| Capability | What it queries |
| ---------- | ----------------------------------------------------------------------------------- |
| Logs | Log events from the repositories and views you enable, and trends over those events |
| Dashboards | The queries built into your own dashboards |
### Logs
Nexus queries your log events with LQL, scoped to one repository or view at a time, in two ways:
* **Log queries**: read the events themselves. What a service was logging when an incident started, whether the same errors were appearing elsewhere, whether a message started right after a deploy.
* **Trends over those logs**: LQL buckets events into a time series, so Nexus graphs an error rate climbing, latency moving, or one endpoint's volume falling away. You get a chart of what your logs were doing across the incident window even where you never set up a metric for it.
LogScale defines no schema beyond its own `@` fields and `#` tags, so every other field name is whatever your shipper chose to write. One view can carry several shippers that spell the same thing three ways (`severity`, `level`, and `log.level`), and a filter on the wrong one comes back empty rather than failing. Nexus learns which names each slice of your data actually uses, and the values those fields really hold, so an error search filters on a spelling and a value that exist.
### Dashboards
Your LogScale dashboards are discovered automatically once you connect, and read for the LQL behind their widgets. That's the only place your team's own queries exist in writing, so it teaches Nexus the fields, tags, and filters you really query on, and which slices of the data matter.
### Repositories and views
LogScale calls a repository or a view a search domain. Every one your token can read arrives as its own data source that you enable individually, so a token that reaches more than you want investigated doesn't put all of it in scope. A view is queried like any repository, including one that federates several.
## Connecting CrowdStrike Falcon LogScale
You connect LogScale directly. There's no provider in front of it.
**What you'll need:**
* Your **deployment**: LogScale Cloud in the EU (`https://cloud.humio.com`) or the US (`https://cloud.us.humio.com`), or the base URL of your self-hosted deployment, without a path.
* An **API token**, created in LogScale under **Settings → API tokens**, whose role has read access to the repositories and views you want searched. A Repository & View token reaches the single repository or view it was issued for; a broader token reaches every one its role can read, and we connect each of them. LogScale covers this in its [API token documentation](https://library.humio.com/data-analysis/api-tokens.html).
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **CrowdStrike Falcon LogScale**.
2. Choose your deployment, either a LogScale Cloud region or your own base URL, then enter the token and test the connection. We check that LogScale accepts the token and can read at least one repository or view.
3. Enable the repositories and views you want Nexus to query. Each one arrives switched off, so you opt in to each deliberately.
If your team issues a token per repository or view rather than one that covers them all, you can add those tokens after connecting, and each brings in everything it can read.
Your dashboards are discovered automatically once LogScale is connected — there's nothing extra to set up.
## Best practice
* Use a token whose role grants read access and nothing more, so Nexus can only do what a reader in LogScale could.
* Give that role read access to the repositories behind a view, not only to the view itself. Retention is configured on repositories, so a token that can't read every repository behind a view leaves Nexus without your retention window, and without knowing how far back it's worth searching. If you'd rather not widen the token, set the retention window yourself on the data source instead.
* Enable the repositories and views your responders actually open during an incident, rather than everything the token reaches. Each domain enabled is more data in scope, and more of it read on every query.
* Select the LogScale dashboards your responders reach for during incidents. Nexus learns your real query patterns from them, which makes the queries it writes more like the ones you'd write.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Logz.io
Source: https://docs.incident.io/nexus/telemetry/logzio
Search your Logz.io logs and query your metrics to see what your services were doing during an incident.
Logz.io stores and searches your logs on a hosted ELK stack, and stores your metrics on a Prometheus-compatible backend. Investigations query them to read what your services were doing around the time of an incident: the errors and warnings your services logged, and the metric that moved.
You connect Logz.io directly with your main account's API token and region — it isn't fronted by another provider.
That token searches your logs automatically; metrics accounts (and any logs account that isn't searchable from the
main account) are then connected with their own tokens.
## What we support
Connecting Logz.io gives investigations two capabilities, which you can enable independently:
| Capability | What it queries |
| ---------- | ---------------------------------------------------------------- |
| Logs | Log lines from your services, and trends derived from those logs |
| Metrics | Your metrics, graphed for the incident window |
### Logs
Investigations query Logz.io with Elasticsearch Query DSL against your logs, in two ways:
* **Log searches**: pull back the actual log documents, whether that's what a service logged at the time, whether errors appeared on an endpoint, or whether a message started showing up right after a deploy.
* **Aggregations over logs**: turn matching logs into a time series, so investigations can graph trends straight from your logs, such as an error count climbing, request volume dropping away, or how often a particular message appears across the incident window. You get a chart of what your logs were doing even where you never set up a dedicated metric.
Your main account's logs — and any sub-account that's searchable from it — are covered by the token you connect, with no extra tokens needed. A logs account that isn't searchable from the main account can still be included by giving it its own token, the same way metrics accounts are connected.
### Metrics
Investigations query your Logz.io metrics with PromQL and graph them for the incident's time window, so a resource spike, a latency change, or a growing error count shows up against the period that matters.
Logz.io keeps metrics in separate accounts, each with its own API token (distinct from your logs token), so metrics are opt-in: after connecting, you choose which metrics accounts to include and give each its own token. Connect as many as you use, and add, remove, or rotate them later from the data source's settings.
### Learning your data
Logz.io logs arrive as flattened fields, such as a service name, a log level, a trace ID, and whatever structured fields your applications emit, alongside the raw message. A query is only as good as knowing which of those fields exist and what they hold, so investigations sample your logs to learn the fields that are actually populated and the common values for the ones worth filtering on, like a status code, a service, or a level. They learn this across the full spread of your logs rather than only the most recent burst, so a field that shows up occasionally still gets picked up. Your metric names are learned the same way, so investigations know what's there to query.
This means investigations filter on the fields that matter in your logs, and reach for the metrics you actually have, without you describing your schema by hand. How that learning works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
### When a search comes back empty
An empty result is ambiguous: it can mean nothing happened, or that a filter used a field or value that doesn't exist in your logs. When a search returns nothing, an investigation re-checks the structural part of the query on its own to tell those apart, a genuine absence versus a filter that excluded everything, then adjusts and tries again rather than reporting nothing found.
## Connecting Logz.io
Connect Logz.io directly with your main account's API token and region, then choose any extra accounts to include.
**What you'll need:**
* Your **main (owner) account's API token**, from Settings → Manage tokens → API tokens. It has to be an owner-account token — that's what lists your accounts and searches your logs. We recommend one scoped to read-only search, since investigations only ever read from Logz.io.
* Your account region: one of US, EU, UK, AU, or CA. This is the region your Logz.io account lives in, shown in the URL you use to log in, for example `app-eu.logz.io` for EU.
* A token for each **metrics account** you want to include, and for any **logs account that isn't searchable from the main account** — each Logz.io account has its own token.
To connect:
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Logz.io**.
2. Enter your main account's API token and region, then test the connection.
3. Choose which accounts to connect: paste a token for each metrics account — and each non-searchable logs account — you want investigations to use. Your main account's logs and its searchable sub-accounts are already covered, so you can skip this if you only need logs.
4. Turn on the search over your main account's logs when you want investigations to use it. It's created switched off, so it stays unqueried until you enable it. Every account you connected in step 3 is enabled straight away — naming one means you've supplied its token and want it used.
You can add, remove, or re-token accounts anytime from the data source's settings.
We check each token as you connect it, so a wrong one is caught here rather than turning up as an empty result mid-incident. The accounts whose tokens work are connected even if another fails, and each one we couldn't connect is flagged with the reason, so a single mistyped token won't fail the rest.
We also catch tokens that are correct but pasted against the wrong account, rather than quietly returning another account's data, which is easy to do when you have several. An account that's already connected keeps its existing token if a replacement is refused, so trying a new one can't cost you access you already have.
## Best practice
* Connect with your main account's owner token, scoped to read-only search — it's what lists your accounts and searches your logs, and investigations only ever read from Logz.io.
* Pick the region that matches your account. Logz.io's regions are separate, and a token from one won't work against another.
* Add a metrics account (or a non-searchable logs account) only when you want investigations to use it — connecting one enables it, and you can remove it later.
* Leave your main account's log search switched off until you want investigations reading your logs — it's the one source that doesn't turn itself on.
## Related
How providers and data sources fit together.
How investigations query your logs and metrics.
# Loki
Source: https://docs.incident.io/nexus/telemetry/loki
Query your Loki logs to see what your services were saying during an incident.
Loki is Grafana's log store. Nexus queries it to read what your services logged around the time of an incident: the errors, the warnings, the request that failed.
Loki is connected through [Grafana](/nexus/telemetry/grafana): connect Grafana, and Nexus discovers every Loki data
source behind it automatically, with nothing separate to configure.
## What we support
A Loki data source gives Nexus two capabilities, both queried with LogQL:
| Capability | What it queries |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Logs | The actual log lines: what a service was logging at the time, or whether a message started showing up right after a deploy |
| Metrics | Trends graphed straight from your logs (an error rate climbing, request volume dropping away), with no dedicated metric needed |
### Filtering beyond your label index
Loki only indexes the stream labels you choose, but plenty of useful detail lives outside that index: in structured metadata attached to each entry, and in fields parsed out of the log body (for example with `| json`). Nexus uses all three, so it can filter on attributes you never indexed, not just your labels: a request ID, a status code, a customer.
### Fast queries on high-volume logs
The cost of a Loki query comes down to its stream selector: too broad and it's slow or rejected, too narrow and it misses data. Nexus scopes the selector to the streams that matter, using what it's learned about your labels and their cardinality. Queries stay fast even on noisy, high-volume logs. If a query does time out, Nexus narrows it and tries again rather than giving up.
Nexus learns this structure automatically: your labels, structured metadata, parsed fields, and which labels are high-cardinality. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Loki
Connect [Grafana](/nexus/telemetry/grafana), and Nexus discovers every Loki data source behind it automatically, using Grafana's own credentials, with nothing separate to configure.
Discovered Loki data sources start disabled. Log queries can be broad, so you opt in deliberately: enable the Loki data sources your team uses from your [telemetry settings](https://app.incident.io/~/nexus/telemetry).
If an enabled Loki data source holds no log data yet, Nexus sets it aside rather than run queries that can't return anything. It starts using the source once logs arrive.
## Best practice
* Connect the Grafana dashboards that query Loki. Nexus learns your real log query patterns from them, which makes Loki queries more accurate.
* Enable the Loki data sources your responders reach for during incidents, rather than every source available.
## Related
The provider Loki is connected through.
How Nexus queries your logs.
# Memory
Source: https://docs.incident.io/nexus/telemetry/memory
Nexus gets better at querying your telemetry the more it's used.
Nexus doesn't just query your telemetry well on day one; it gets better at it over time. Memory is how: a learned library of the queries that have actually worked for your data sources, built from your own investigations and fed back into every new query.
## What memory is
When an investigation writes a query against one of your data sources and it successfully answers a question, that pairing is worth remembering: "to find out X, this kind of query works against this data source". Memory is the store of those proven patterns, built up specifically for your systems.
It's related to, but distinct from, the [guidance](/nexus/telemetry/how-it-works#learning-your-stack) Nexus learns for each data source. Guidance is the broad description of a data source: its labels, fields, and conventions. Memory is the narrower set of queries that have actually worked. Guidance tells Nexus what exists; memory shows it what has worked before.
## How it's built
Memory grows from real investigations, on its own:
* When a query answers a question (and is used in the investigation's reasoning, rather than discarded as noise) it becomes a candidate to remember.
* Queries that came back empty or unhelpful aren't remembered, so memory reflects what works against your systems, not just what happened to run.
* We curate it as it grows, consolidating overlapping patterns and retiring ones that no longer hold, so it stays sharp rather than sprawling.
There's nothing to set up and nothing for you to maintain. Memory accrues as investigations run.
## How it makes investigations better
When an investigation plans a new query, it draws on the remembered patterns most similar to the question and uses them as worked examples. Starting from a query shape that's already succeeded, rather than from scratch, it reaches a correct query faster and with fewer wrong turns. Those same patterns also feed back into guidance, sharpening the broader picture Nexus works from.
The effect compounds: the more investigations run against your stack, the better Nexus gets at querying it.
## Scoped to your systems
Memory is specific to your organization, to each data source, and to each kind of query. The patterns that work for your logs are learned from your logs, and your metric names and labels are your own. Nothing in memory is shared across organizations.
## Related
Routing, query planning, and the guidance memory feeds into.
What you can connect, and how it fits together.
How we measure investigations improving over time, and backtest changes before they ship.
# MySQL
Source: https://docs.incident.io/nexus/telemetry/mysql
Query your MySQL database during an investigation to confirm what the data actually shows.
Connect a MySQL database and Nexus can run read-only SQL against it, checking the rows directly when that's the fastest way to confirm a hypothesis. Is a record in the state the symptoms suggest? When did a value last change?
You can connect a MySQL database directly with its own host and credentials, or connect [AWS](/nexus/telemetry/aws)
and have your RDS and Aurora MySQL databases discovered for you. Both give the same read-only SQL access, so use AWS
for databases on RDS or Aurora, and connect directly for anything else.
## What we support
Nexus queries MySQL with read-only SQL. It writes the query, runs it for the window that matters, and reads back the results: joining across tables, filtering and aggregating, and reading from tables and views.
### Exploring your schema
Nexus doesn't need you to describe your database. It learns the shape on its own: the tables you have, their columns and types, primary and foreign keys, and how tables relate. From there it explores progressively, starting with an overview of the database, then pulling fuller detail on the specific tables a question turns out to need, rather than loading everything up front. That keeps queries accurate against large schemas and grounded in tables that actually exist.
How Nexus learns and uses this structure is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
Nexus only ever reads from your database; it never writes. Connect with a **read-only** database user so that
guarantee is enforced on your side, not just trusted.
## Security
Nexus queries your database to read from it, never to change it, and that guarantee is enforced in several independent layers rather than left to trust.
**Every query runs on a read-only connection.** Each query runs on its own fresh connection opened in read-only transaction mode, so there's no long-lived session that could be left in a writable state. We recommend connecting a read-only database user too, so the guarantee holds on your side as well.
**Every query is parsed and checked before it runs.** Each query is parsed with a real MySQL parser and must be a single `SELECT`. Anything that writes or changes structure, bundles multiple statements into one request, or reaches a write path another way (such as a write hidden in a subquery) is rejected.
**Queries can't overload your database.** Every query runs under a timeout and returns a capped number of rows, so a broad or expensive query stays bounded rather than running away. Each query gets its own short-lived connection that we open, use once, and close, so we never hold idle connections open to your database. And we give up quickly on a database we can't reach.
For more on how we handle your data during AI processing, see our [Trust Center](https://trust.incident.io/).
## Connecting MySQL
You can either connect a database directly with its connection details, or connect AWS and let it discover your RDS and Aurora databases.
### Directly
**What you'll need:**
* The **host** and **port** of your database (port defaults to 3306).
* The **database name** to connect to.
* A **username** and **password**.
* The **TLS mode** to use, and any **client certificate**, **client key**, or **CA certificate** your database requires. Mutual TLS is supported for environments that need it, and a client certificate can stand in for the password.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **MySQL**.
2. If the database isn't reachable from the public internet, which is the common case, set **Network access** to **Private network** and route through a [proxy](/integrations/proxy) you run in your network.
3. Enter the connection details and credentials, or paste a full connection string to fill the fields in one go, then test the connection. The test passes only when the user can log in and read at least one table.
4. Once connected, the database is enabled for Nexus. You can disable it at any time.
### Through AWS (RDS and Aurora)
Connect [AWS](/nexus/telemetry/aws) with **RDS** among the selected services, and your databases are discovered for you. Discovery covers the MySQL and Aurora MySQL engines: one selection covers both, and an `aurora-mysql` cluster appears as a MySQL data source alongside plain RDS instances rather than as a separate Aurora type.
Discovery finds the databases and their endpoints, but not a way to log into them. So each discovered database needs a login, which you choose per database once it appears:
* **RDS IAM.** Give the role or user incident.io authenticates as `rds-db:connect` on the database user you want it to log in as. Each connection mints a short-lived token, so there's no password stored with us. Connections verify the server against the AWS RDS trust bundle, which we ship, so you don't need to supply a CA. You'll need IAM authentication enabled on the database and a database user set up for it. See AWS's guide to [IAM database authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).
* **Username and password.** Provide credentials for a database user as you would for a direct connection.
If a database isn't reachable from the public internet, attach a [proxy](/integrations/proxy) to the AWS connection.
Discovered databases are disabled by default, so review what's found and enable the ones worth querying during an incident.
## Best practice
* Connect a **read-only** user. Nexus only ever reads, and a read-only user makes that enforceable on your side.
* On a direct connection, point it at a **replica** rather than your primary, so investigation queries never compete with production traffic. Databases discovered through AWS currently always connect to the primary.
* Grant access to the tables Nexus should see and no more. It explores only what the user can read.
* On RDS and Aurora, prefer **RDS IAM** over a stored password, so there's no long-lived credential to rotate.
## Related
Discover your RDS and Aurora databases.
How providers and data sources fit together.
How Nexus explores your schema and queries your data.
# New Relic
Source: https://docs.incident.io/nexus/telemetry/new-relic
Query your New Relic logs, metrics, and APM traces to see what your systems were doing during an incident.
New Relic is one connection that covers logs, dimensional metrics, and APM (traces and spans), all queried with NRQL over New Relic's data store. Nexus queries it to see what your services were doing around the time of an incident: the log lines, the metric that moved, and the slow or failing span behind a bad request.
You connect New Relic directly, with a User key, region, and account ID. Nexus discovers New Relic logs, metrics, and
APM automatically, and you choose which of them to enable.
## What we support
Connecting New Relic gives Nexus three capabilities, each of which you can enable independently, plus your dashboards:
| Capability | What it queries |
| ---------- | ---------------------------------------------------------------------- |
| Logs | Log lines from your services, and trends derived from those logs |
| Metrics | Dimensional metrics, graphed for the incident window |
| APM | Traces and spans across your services to find slow or failing requests |
| Dashboards | The NRQL queries built into your own dashboards |
### Logs
Nexus searches your New Relic logs with NRQL to read what a service was logging at the time of an incident. The same query language turns logs into time-series, so an error rate climbing or a request volume dropping away shows up as a graph even where you never set up a dedicated metric for it.
### Metrics
Nexus queries your dimensional metrics and graphs them for the incident's time window, so a resource spike, a latency change, or a growing error count shows up against the period that matters.
### APM
Nexus uses your traces and spans in three ways: searching for the spans behind a problem (a slow endpoint, a failing dependency, a particular service), pulling a specific trace by ID to see the full span tree and where it broke, and aggregating spans into throughput, latency, and error-rate signals for a service.
### Dashboards
Your dashboards are read for the NRQL behind their widgets, so Nexus learns the event types, attributes, and filters your team already queries.
Nexus learns the structure of your New Relic data automatically: your log attributes, metric names, and the services your spans belong to. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting New Relic
You connect New Relic directly. There's no provider in front of it.
**What you'll need:**
* A New Relic **User key** (starts `NRAK-`). We recommend creating one for a dedicated integration user with a read-only role, under **API keys** in New Relic.
* Your account's **region**: US or EU, matching whichever New Relic domain you log in to (`one.newrelic.com` or `one.eu.newrelic.com`). New Relic rejects a key used against the wrong region.
* Your **account ID**, the numeric ID of the account you want Nexus to query.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **New Relic**.
2. Enter your User key, region, and account ID, then test the connection. We check the key authenticates and that it can reach the account you specified.
3. Once connected, Nexus discovers New Relic logs, metrics, and APM. Each arrives disabled by default, so review them and enable the ones your team uses.
Your dashboards are available to connect as soon as New Relic is connected.
## Best practices
* Use a dedicated integration user for the User key, with a read-only role, so Nexus can't do anything New Relic itself wouldn't allow a viewer to do.
* Connect the dashboards your team relies on. Nexus learns your real query patterns from them, which makes New Relic queries more accurate. We'll do best-effort dashboard discovery ourselves, but you can specify which ones your team uses the most.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# OpenSearch
Source: https://docs.incident.io/nexus/telemetry/opensearch
Search your OpenSearch log indices to see what your services recorded during an incident.
OpenSearch stores and searches your logs. Nexus queries the index patterns you point it at to read what your services recorded around the time of an incident: the errors, the warnings, the request that failed.
You can connect OpenSearch directly with your cluster's endpoint and credentials, or connect
[AWS](/nexus/telemetry/aws) and have your Amazon OpenSearch Service domains discovered for you. Both query the same
way, so use AWS for managed domains, and connect directly for a self-managed cluster.
## What we support
Nexus queries OpenSearch with its Query DSL against the log index patterns you configure, in two ways:
* **Log searches**: pull back the actual documents, whether that's what a service logged at the time, whether errors appeared on an endpoint, or whether a message started showing up right after a deploy.
* **Aggregations over logs**: turn matching documents into a time series, so Nexus can graph trends straight from your logs, such as an error count climbing, request volume dropping away, or the frequency of a particular message across the incident window. You get a chart of what your logs were doing even where you never set up a dedicated metric for it.
### Querying your index patterns
OpenSearch doesn't expose one set of logs. It holds whatever indices and data streams you ship to it, and the useful ones differ by team. So you tell Nexus which index patterns to query, for example `logs-*` for application logs or a security audit stream, and each pattern becomes its own queryable source you can enable or disable independently.
Until you configure at least one index pattern, an OpenSearch connection has nothing to query. Add your patterns during setup, then enable the ones your responders reach for.
### Learning your fields and mappings
A log document in OpenSearch can carry hundreds of fields, and a query is only as good as knowing which ones exist and what they hold. For each index pattern, Nexus reads its mapping to learn the fields and their types, then samples recent documents to learn which fields are actually populated, how many distinct values each holds, and the common values for the ones worth filtering on, such as a status code, a service name, or a customer. It also learns the timestamp field your index uses and how long it retains data, so queries scope to the incident window and don't reach past what's still there.
This means Nexus can filter on the fields that matter in your logs without you describing your schema by hand. How that learning works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting OpenSearch
You can either connect a cluster directly with its endpoint and credentials, or connect AWS and let it discover your Amazon OpenSearch Service domains. Use AWS for managed domains, and connect directly for a self-managed cluster.
### Directly
Connect OpenSearch from the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry) by adding a telemetry data source and choosing **OpenSearch**.
**What you'll need:**
* **Your cluster's endpoint.** One or more node addresses as full URLs, for example `https://your-host:9200`.
* **Credentials.** A username and password.
* **A CA certificate** (optional). Provide one if your cluster uses a self-signed or internal certificate authority.
To connect:
1. Enter one or more node addresses for your cluster.
2. Add your username and password, and a CA certificate if your cluster needs one.
3. Add the index patterns you want Nexus to query, then test the connection.
Choose the **OpenSearch** connection type for an OpenSearch cluster. If you point it at an Elasticsearch cluster, the
connection test tells you to use the [Elasticsearch](/nexus/telemetry/elasticsearch) type instead.
The credentials only need read access. Grant the `cluster_monitor` cluster permission, and `read` plus `indices:admin/validate/query` on the index patterns you connect:
```json theme={null}
{
"incident_io_role": {
"cluster_permissions": ["cluster_monitor"],
"index_permissions": [
{
"index_patterns": ["logs-*"],
"allowed_actions": ["read", "indices:admin/validate/query"]
}
]
}
}
```
Each index pattern you add becomes its own data source. Enable the patterns your responders use during incidents.
### Through AWS
Connect [AWS](/nexus/telemetry/aws) with **OpenSearch** among the selected services, and your domains are discovered across the regions you enable. No OpenSearch credentials are stored: queries are signed with the AWS credentials from the parent connection (SigV4), so there's no separate username and password to manage or rotate.
Two things are configured on the AWS side:
* **The domain access policy** on each domain has to allow the `es:ESHttp*` calls for the role or user incident.io authenticates as. IAM permissions alone aren't enough.
* **Fine-grained access control (FGAC)**, if the domain has it enabled, needs the same principal mapped to an OpenSearch backend role with read privileges on the indices you want queried. See AWS's [fine-grained access control](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html) guide.
Discovery finds the domain, but not which indices to search. Add your index patterns to each discovered domain, then enable it, the same as a direct connection.
A VPC-only domain publishes an endpoint that only resolves inside your VPC, so a [proxy](/integrations/proxy) is the
only route to it. It will be discovered, and will inherit the proxy set for the AWS connection by default. You can
point an individual domain to a different proxy, or choose to connect it over public internet instead.
## Best practice
* Connect the index patterns your team actually searches during incidents, rather than every index in the cluster. Each one is enabled independently, so keep the noisy or rarely-used ones off.
* Scope `index_patterns` in your role to the patterns you're connecting, so the credentials only read the indices you intend.
* Use a dedicated read-only user. Nexus only ever reads from OpenSearch.
## Related
Discover your Amazon OpenSearch Service domains.
How providers and data sources fit together.
How Nexus queries your logs.
# Telemetry
Source: https://docs.incident.io/nexus/telemetry/overview
Give Nexus the logs, metrics, traces, and dashboards your team relies on.
Telemetry is the hard signal that explains what your system was actually doing: error spikes, latency changes, log lines, and the dashboards your team already trusts. Connect the observability tools your responders reach for during an incident, and Nexus can query them directly. It learns the shape of each source, including the queries in your own dashboards. So it queries them the way an engineer who knows your systems would, not with generic guesses.
Once you're connected, Nexus uses your telemetry in two places:
* **During an investigation**: Nexus queries your sources to confirm or rule out a hypothesis. It's the evidence that carries the most weight, and verifying against live system state is what gives an investigation the most [conviction](/investigations/how-investigations-work#building-conviction) in a finding.
* **In the agent**: ask [the agent](/ai/at-incident) what your systems are doing, from Slack, the dashboard, or the mobile app. It queries the same sources to answer, whether or not there's an incident open.
## What you can connect
Connect a provider to bring several data sources at once, or connect a data source directly.
**Providers**
CloudWatch, EKS, OpenSearch, and RDS.
Cloud Logging, Cloud Monitoring, Cloud Trace, and GKE clusters.
Loki, Prometheus, Tempo, Pyroscope, and CloudWatch.
**Connect directly**
Logs, metrics, traces, and dashboards.
Logs and dashboards from your repositories and views.
Logs, metrics, traces, error tracking, events, and dashboards.
Logs from your index patterns.
Traces and spans from your environments.
Live cluster state: what was running, what was failing, and why.
Read-only SQL queries.
Logs, metrics, APM traces, and dashboards.
Logs from your index patterns.
Read-only SQL queries.
Logs, metrics, and dashboards.
Metrics and dashboards.
Logs and metrics.
Connecting an HTTP API or an MCP server works differently: those are [connectors](/investigations/extensions/connectors), which give an investigation tools beyond telemetry.
## How telemetry is modeled
Some tools host others. Connect **Grafana** once, and Nexus can discover the data sources behind it: Loki for logs, Prometheus for metrics, Tempo for traces, and more. **AWS** works the same way: it exposes accounts and regions, then CloudWatch, EKS clusters, OpenSearch domains, and RDS databases. So does **Google Cloud**, which exposes projects, and the GKE clusters running in them. You connect the provider once, then choose which of the discovered data sources to enable.
The Grafana stack is connected this way only: there's no separate Loki, Prometheus, Tempo, or Pyroscope entry in the connect flow. Connect Grafana, and they come with it, using Grafana's own credentials.
Other tools are connected directly and stand on their own. Some data sources work either way: a PostgreSQL database or a Kubernetes cluster can be connected directly or discovered behind a provider.
### Capabilities
Each data source provides one or more capabilities, which is what Nexus uses it for:
| Capability | What it answers |
| ---------- | -------------------------------------------------------------------------------------------- |
| Logs | What was the system logging around the time of the incident? |
| Metrics | Did error rates, latency, or saturation change? |
| Traces | Where did a slow or failing request spend its time, and which requests hit the same problem? |
| Profiles | Where did CPU and memory actually go? |
| Kubernetes | What was running, and what was failing, in the cluster? |
| SQL | What does the data in this database actually show? |
| Dashboards | What do the views my team already built reveal? |
## Enabling data sources
Each data source can be enabled or disabled, which controls whether Nexus can use it. Which state it starts in depends on how the data source arrived:
* Data sources discovered through a provider start disabled, so you opt in deliberately.
* Data sources you connect directly start enabled.
Either way, you can turn each one on or off from your [telemetry settings](https://app.incident.io/~/nexus/telemetry). Review the list after connecting a provider and enable the sources your team uses.
## Learning your stack
Nexus doesn't query blindly. For each connected data source we continually learn how to query it well in your environment. We discover its real labels and fields, learn the query patterns in your own dashboards, and remember what worked in past investigations. That's what lets a query filter on the attributes you actually use and reach for sensible defaults, instead of guessing against an unfamiliar stack.
Routing a question to the right data source, translating it into the right query language, and the guidance and memory the system builds over time all sit behind this. See [How telemetry works](/nexus/telemetry/how-it-works) for the full picture.
Connect the data sources and dashboards your team reaches for during real incidents. The more your setup reflects your
real workflow, the better Nexus learns to query it.
## FAQs
No. We connect to the observability tools you already run and query them on demand; there's no need to ship
telemetry to us or keep a copy. The goal is to become an expert user of your existing stack, not to replace it.
Yes. For a data source that isn't exposed to the public internet, such as a Loki, Prometheus, or VictoriaMetrics
instance inside your VPC, run a [proxy](/integrations/proxy) in your network and attach the data source to it.
Queries travel over an outbound-only, encrypted tunnel, so you never open inbound ports.
No. Nexus learns each source by exploring it and making test queries, so connecting the source is enough to get
started. A well-built Catalog can improve results, but it isn't required.
## Related
Routing, query planning, guidance, and memory.
How telemetry queries become evidence in a finding.
Why a data source's queries fail, and what to do about it.
# PostgreSQL
Source: https://docs.incident.io/nexus/telemetry/postgresql
Query your PostgreSQL database during an investigation to confirm what the data actually shows.
Connect a PostgreSQL database and Nexus can run read-only SQL against it, checking the rows directly when that's the fastest way to confirm a hypothesis. Is a record in the state the symptoms suggest? When did a value last change?
You can connect a PostgreSQL database directly with its own host and credentials, or connect
[AWS](/nexus/telemetry/aws) and have your RDS and Aurora PostgreSQL databases discovered for you. Both give the same
read-only SQL access, so use AWS for databases on RDS or Aurora, and connect directly for anything else.
## What we support
Nexus queries PostgreSQL with read-only SQL. It writes the query, runs it for the window that matters, and reads back the results: joining across tables, filtering and aggregating, and reading from tables, views, and materialized views.
### Exploring your schema
Nexus doesn't need you to describe your database. It learns the shape on its own: the tables you have, their columns and types, primary and foreign keys, and how tables relate. From there it explores progressively, starting with an overview of the database, then pulling fuller detail on the specific tables a question turns out to need, rather than loading everything up front. That keeps queries accurate against large schemas and grounded in tables that actually exist.
Partitioned tables are handled too: a table split by month or by customer reads the same as an ordinary one.
How Nexus learns and uses this structure is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
Nexus only ever reads from your database; it never writes. Connect with a **read-only** database user so that
guarantee is enforced on your side, not just trusted.
## Security
Nexus queries your database to read from it, never to change it, and that guarantee is enforced in several independent layers rather than left to trust.
**Every connection is read-only, and stays that way.** Connections open in read-only transaction mode and re-assert it before each query, so a session can't be flipped into a writable state mid-flight. We recommend connecting a read-only database user too, so the guarantee holds on your side as well.
**Every query is parsed and checked before it runs.** Each query is parsed with PostgreSQL's own parser and must be a single `SELECT`. Anything that writes or changes structure, bundles multiple statements into one request, or reaches a write path another way is rejected. The functions a query may call are allowlisted to safe, read-only ones, so anything unrecognized is blocked rather than allowed by default.
**Sensitive system tables are off limits.** Queries can't read PostgreSQL's internal tables for credentials, roles, other sessions' activity, or server configuration, regardless of what the connected user could otherwise see.
**Queries can't overload your database.** Every query runs under a timeout and returns a capped number of rows, so a broad or expensive query stays bounded rather than running away. We hold only a small number of connections to your database, close idle ones quickly, and recycle them regularly. And we give up quickly on a database we can't reach.
For more on how we handle your data during AI processing, see our [Trust Center](https://trust.incident.io/).
## Connecting PostgreSQL
You can either connect a database directly with its connection details, or connect AWS and let it discover your RDS and Aurora databases.
### Directly
**What you'll need:**
* The **host** and **port** of your database (port defaults to 5432).
* The **database name** to connect to.
* A **username** and **password**.
* The **SSL mode** to use, and any **client certificate**, **client key**, or **CA certificate** your database requires. Mutual TLS is supported for environments that need it, and a client certificate can stand in for the password.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Postgres**.
2. If the database isn't reachable from the public internet, which is the common case, set **Network access** to **Private network** and route through a [proxy](/integrations/proxy) you run in your network.
3. Enter the connection details and credentials, or paste a full connection string to fill the fields in one go, then test the connection. The test passes only when the user can log in and read at least one table.
4. Once connected, the database is enabled for Nexus. You can disable it at any time.
### Through AWS (RDS and Aurora)
Connect [AWS](/nexus/telemetry/aws) with **RDS** among the selected services, and your databases are discovered for you. One selection covers both RDS and Aurora: an `aurora-postgresql` cluster is discovered alongside plain RDS PostgreSQL instances, and both appear as PostgreSQL data sources rather than a separate Aurora type.
Discovery finds the databases and their endpoints, but not a way to log into them. So each discovered database needs a login, which you choose per database once it appears:
* **RDS IAM.** Give the role or user incident.io authenticates as `rds-db:connect` on the database user you want it to log in as. Each connection mints a short-lived token, so there's no password stored with us. Connections verify the server against the AWS RDS trust bundle, which we ship, so you don't need to supply a CA. You'll need IAM authentication enabled on the database and a database user set up for it. See AWS's guide to [IAM database authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).
* **Username and password.** Provide credentials for a database user as you would for a direct connection.
If a database isn't reachable from the public internet, attach a [proxy](/integrations/proxy) to the AWS connection.
Discovered databases are disabled by default, so review what's found and enable the ones worth querying during an incident.
## Best practice
* Connect a **read-only** user. Nexus only ever reads, and a read-only user makes that enforceable on your side.
* On a direct connection, point it at a **replica** rather than your primary, so investigation queries never compete with production traffic. Databases discovered through AWS currently always connect to the primary.
* Grant access to the tables Nexus should see and no more. It explores only what the user can read.
* On RDS and Aurora, prefer **RDS IAM** over a stored password, so there's no long-lived credential to rotate.
## Related
Discover your RDS and Aurora databases.
How providers and data sources fit together.
How Nexus explores your schema and queries your data.
# Prometheus
Source: https://docs.incident.io/nexus/telemetry/prometheus
Query your Prometheus metrics to see how your services behaved during an incident.
Prometheus is a time-series metric store. Nexus queries it to see how your services behaved around the time of an incident: the error rates that climbed, the latency that crept up, the saturation that tipped a service over.
Prometheus is connected through [Grafana](/nexus/telemetry/grafana): connect Grafana, and Nexus discovers every
Prometheus data source behind it automatically, with nothing separate to configure.
## What we support
Nexus queries Prometheus with PromQL, its query language. It goes beyond reading a metric's raw value: PromQL turns counters and histograms into the rates and percentiles you actually reason about during an incident.
* **Rates from counters.** Counters only ever climb, so the raw number means little on its own. Nexus wraps them in `rate()` to ask the real question: how fast are requests failing right now, and was that different before the incident started.
* **Percentiles from histograms.** Latency lives in histogram buckets, not a single number. Nexus uses `histogram_quantile()` to pull out the p95 or p99 your responders care about, rather than an average that hides the tail.
* **Aggregations across dimensions.** With `sum by`, `avg by`, and `max by`, Nexus rolls a metric up to the dimension that matters: per service, per route, per namespace. That shows which slice of your fleet is misbehaving.
### Discovering your metrics and labels
Prometheus exposes thousands of metrics and labels, and a query that names the wrong one returns nothing. Rather than guess, Nexus reads what your Prometheus actually holds, focusing on what's been recently active: your metric names, their types, and the help text you've attached. It also reads your labels, with a sense of how many distinct values each one takes.
Types and help text depend on your backend serving metric metadata. Many Prometheus-compatible backends, such as VictoriaMetrics, Mimir, and Thanos, don't populate it. There Nexus works from the metric names alone.
Cardinality shapes how Nexus builds queries. Grouping by a low-cardinality label like `service` or `namespace` gives a readable breakdown; grouping by a high-cardinality one like `pod` or `instance` produces noise. Nexus learns which labels are which, so it groups on the ones that clarify and filters on the ones that would overwhelm.
Nexus learns this structure automatically: your metrics, their types, and your labels and their cardinality. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Prometheus
Connect [Grafana](/nexus/telemetry/grafana), and Nexus discovers every Prometheus data source behind it automatically, using Grafana's own credentials, with nothing separate to configure. That covers any backend Grafana fronts as a Prometheus data source: Amazon Managed Service for Prometheus, Thanos, Cortex, Mimir, and VictoriaMetrics all work the same way.
Discovered Prometheus data sources start disabled, so you opt in deliberately: enable the ones your team uses from your [telemetry settings](https://app.incident.io/~/nexus/telemetry).
If you run several Prometheus servers (per cluster, per region, or HA replicas), you can group their data sources into one logical view: add a **Prometheus aggregate** from the connect wizard and pick its members. A query against the aggregate reaches every member and merges the results, so a sum or a rate is one correct global answer rather than a per-server fragment.
## Best practice
* Connect the Grafana dashboards that query Prometheus. Nexus learns your real query patterns from them (which metrics matter, how they're filtered and grouped), which makes Prometheus queries more accurate.
* Enable the Prometheus data sources your responders reach for during incidents, rather than every source available.
## Related
Connect Prometheus through Grafana.
How Nexus queries your metrics.
# Pyroscope
Source: https://docs.incident.io/nexus/telemetry/pyroscope
See which code paths burned CPU or allocated memory when an incident hit.
Pyroscope is Grafana's continuous profiling backend. Nexus queries it to see where your services were spending CPU and allocating memory around the time of an incident, broken down by the functions and call paths responsible.
Connect Pyroscope by connecting [Grafana](/nexus/telemetry/grafana). Nexus discovers it automatically as one of the
data sources behind Grafana, using Grafana's own credentials.
## What we support
Profiling answers a question logs, metrics, and traces can't. A metric tells you CPU hit 90%, a trace tells you which request was slow, but neither tells you which function inside the process was burning the cycles. Pyroscope does: it samples your running services continuously, so Nexus can look back at the incident window and see exactly which code paths were responsible.
Nexus queries Pyroscope by profile type and a label selector, for example the CPU profile for `{service_name="api"}` over the incident window. Profile types depend on what your services emit, and commonly include:
* **CPU**: where processes spent their time on the CPU.
* **Memory**: allocations and in-use memory, by where they were allocated.
* **Goroutines and other types**: concurrency and other resource profiles, where your services produce them.
### Reading a flame graph as findings
A raw profile is a flame graph: thousands of stack frames that are hard to read without clicking around. Nexus turns one into two things you can act on:
* **Top functions**: the functions that consumed the most CPU or memory in their own right, ranked, with each one's share of the total.
* **The hottest path**: the single heaviest call chain from entry point down to the leaf, so you can see not just which function was expensive but how the code reached it.
Alongside those summaries, Nexus reads the flame graph itself as a rendered image, the way an engineer scanning it would.
Nexus learns the profile types, labels, and service names in your Pyroscope instance automatically, so it queries for profile types you actually emit and filters on labels that exist. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Pyroscope
Connect [Grafana](/nexus/telemetry/grafana), and Nexus discovers Pyroscope automatically as one of the data sources behind it, using Grafana's credentials, with nothing separate to configure. Pyroscope appears in your data source list once the Grafana connection finishes syncing.
Discovered Pyroscope data sources start disabled, so you opt in deliberately: enable the ones your team uses from your [telemetry settings](https://app.incident.io/~/nexus/telemetry).
## Best practice
* Enable the Pyroscope data sources whose CPU and memory behavior you investigate, rather than every source available.
* Connect the Grafana dashboards your team uses for profiling. Nexus learns your real query patterns from them.
## Related
The provider Pyroscope is connected through.
How Nexus queries your profiles.
# Splunk (Enterprise and Cloud Platform)
Source: https://docs.incident.io/nexus/telemetry/splunk
Query your Splunk logs and metrics to see what your systems were doing during an incident.
Splunk Enterprise and Splunk Cloud Platform keep your logs and metrics in indexes you query with SPL. Nexus searches those indexes to read what a service was logging when an incident started, and to graph the metric that moved.
Splunk Observability Cloud is a separate Splunk product with [its own page](/nexus/telemetry/splunk-observability-cloud), and you can connect both.
You connect Splunk directly, with your management API endpoint and an authentication token. One connection covers
logs, metrics, and your dashboards. You choose which of them Nexus can use.
## What we support
Connecting Splunk gives Nexus two capabilities, each of which you can enable independently, plus your dashboards:
| Capability | What it queries |
| ---------- | ------------------------------------------------------------------- |
| Logs | Events from the indexes your token can read, and trends across them |
| Metrics | Measurements from your metric indexes, graphed for the incident |
| Dashboards | The searches behind the panels your team already built |
### Logs
Nexus searches your indexes with SPL to read what a service was logging at the time of an incident.
### Trends from your logs
SPL turns events into time series, and Nexus uses this to graph trends straight from your logs: an error rate climbing, request volume dropping away, a message appearing right after a deploy. You get a chart of what your logs were doing even where you never sent a metric for it.
### Metrics
Nexus queries your metric indexes with SPL and graphs a measurement across the incident's time window, so a CPU saturation, a latency change, or a queue backing up shows against the period that matters.
### Dashboards
Nexus reads the searches behind your dashboard panels to learn how your team queries Splunk. The panels themselves aren't run during an investigation.
Nexus learns this structure automatically. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
Every finding cites the search behind it, and links back to that search in Splunk with the same time bounds, so you can pick up where the investigation left off.
## Connecting Splunk
You connect Splunk directly.
**What you'll need:**
* **Your deployment type**, Splunk Enterprise or Splunk Cloud Platform.
* **Your management API endpoint**, for example `https://acme.splunkcloud.com:8089`. This is the management API, not the web interface you browse. Port `8089` is the default on both deployment types.
* **A public HTTPS hostname for that endpoint.** Bare IP addresses and internal hostnames aren't accepted. If your Splunk Enterprise deployment sits inside a private network, connect it through a [proxy](/integrations/proxy).
* **REST API access, on Splunk Cloud Platform.** The management API is closed by default. Ask Splunk Support to enable it for your stack, and add [our IP ranges](/integrations/ip-allowlist) to your stack's REST API allow list.
* **An authentication token**, created in Splunk under **Settings → Tokens**. Token authentication has to be enabled on the deployment first, which is done from the same page. Splunk covers this in its documentation for [Splunk Cloud Platform](https://docs.splunk.com/Documentation/SplunkCloud/latest/Security/CreateAuthTokens) and for [Splunk Enterprise](https://docs.splunk.com/Documentation/Splunk/latest/Security/CreateAuthTokens).
* **A role for that token with the `search` capability**, which every Splunk query needs. The built-in `user` role is enough.
* **The indexes in that role's allowed list.** This, not the role's capabilities, decides what Nexus can read. An index outside the list returns nothing rather than an error.
* **A CA certificate** (Splunk Enterprise only, optional). Provide one if your deployment uses a self-signed or internal certificate authority. We always verify TLS.
To connect:
1. [Get in touch](mailto:support@incident.io) or ask in our shared Slack channel, and we'll enable Splunk for your account.
2. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Splunk**.
3. Choose which capabilities (logs, metrics, or both) Nexus can use.
4. Enter your deployment type, endpoint, and token, then test the connection. We check that Splunk accepts the token and that its role can run searches.
5. Choose the dashboards you want Nexus to learn from.
## Best practice
* Create a dedicated token on a role that has the `search` capability and an allowed index list covering the indexes you want queried. That role defines everything Nexus can reach.
* Give the token a long expiry, or plan to rotate it. Splunk expires tokens, and the connection stops working the day it does.
* Connect logs and metrics together where you have both. With both available, an investigation can move from a metric that moved to the log lines explaining it.
* Select the dashboards your responders actually open during an incident. Nexus learns your team's search conventions from them, so a dashboard that reflects how you really debug a service makes for better queries than one nobody looks at.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Splunk Observability Cloud
Source: https://docs.incident.io/nexus/telemetry/splunk-observability-cloud
Query your Splunk Observability Cloud metrics and dashboards to see what your systems were doing during an incident.
Splunk Observability Cloud (formerly SignalFx) keeps your infrastructure, application, and APM metrics in a single store. Nexus queries it to find the metric that moved around the time of an incident, and reads your dashboards to learn what your team watches.
You connect Splunk Observability Cloud directly, with an access token and your realm. One connection covers both
metrics and dashboards.
## What we support
Connecting Splunk Observability Cloud gives Nexus two capabilities:
| Capability | What it queries |
| ---------- | ----------------------------------------------------------------------------- |
| Metrics | Time-series metrics from across your account, graphed for the incident window |
| Dashboards | The dashboards and charts your team has already built |
### Metrics
Infrastructure, custom, and APM metrics all live in one place in Splunk Observability Cloud, and Nexus queries all of it. It graphs a metric for the incident's time window, so a CPU saturation, a latency change, or a queue backing up shows up against the period that matters.
Queries are grounded in the metrics your account actually reports. Nexus learns the metric names and dimensions that carry live data, rather than every name your account has ever registered, so it filters and groups by dimensions you really have instead of guessing. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
If you send traces to Splunk APM, Splunk derives request, error, and duration metrics per service from them. Nexus reads those to see which service's error rate climbed or which one slowed down, broken down by service and environment, and takes percentiles from the underlying distribution rather than an average that hides the slow tail.
### Dashboards
Nexus reads the dashboards in your account and the queries behind their charts. That tells it which metrics your team relies on, and how you filter and group them, so the metrics an investigation reaches for are the ones your team would reach for.
## Logs
Splunk Observability Cloud has no log store of its own. Your logs live in Splunk Cloud Platform or Splunk Enterprise, and Log Observer Connect gives you a view onto them from the Observability Cloud interface: it queries your platform indexes in place, and doesn't store or index anything itself.
To search those logs, connect [Splunk](/nexus/telemetry/splunk) as well. It's a separate connection to the platform your logs actually sit in, and the two work alongside each other.
## Connecting Splunk Observability Cloud
You connect Splunk Observability Cloud directly. There's no provider in front of it.
**What you'll need:**
* An **access token** with the **API** authorization scope, created under **Settings → Access Tokens → New Token**. Choose **API token** as the scope: that's the one that can read data back. The ingest tokens your OpenTelemetry Collector or Smart Agent uses to send data in can't read it, and a connection made with one fails the connection test. You need to be an organization administrator to create a token. Splunk covers this in its [access token documentation](https://help.splunk.com/en/splunk-observability-cloud/administer/authentication-and-security/authentication-tokens/org-access-tokens).
* An **expiry** you've set deliberately on that token. Splunk expires access tokens by default, and the connection stops working the day it does.
* Your **realm**: the deployment your organization is hosted on, such as `us0`, `eu0`, or `au0`. Find it under **Settings → your name → Organizations**. The realm has to match your organization, because Splunk doesn't carry credentials across realms.
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Splunk Observability Cloud**.
2. Enter your access token and realm, then test the connection.
Connecting adds a metrics data source, which you can turn off if you don't want Nexus to query it. Dashboards are read through the connection itself.
## Best practice
* Create a dedicated access token for the connection rather than reusing one, and give it a long expiry. An access token belongs to your organization rather than to a person, so the connection keeps working when people move teams.
* Leave the token's **SignalFlow job start limit** unset, which is Splunk's default. Nexus queries in bursts, so a low cap rejects queries and leaves an investigation without the metrics half of its picture. If your policy requires a limit, you can find it under **Settings → Access Tokens → the token's actions menu → Manage limits**.
* Select the dashboards that your responders use in your configuration. Nexus learns from the charts your team built, so a dashboard that reflects how you actually debug a service makes for better queries than one nobody looks at.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Sumo Logic
Source: https://docs.incident.io/nexus/telemetry/sumo-logic
Query your Sumo Logic logs and metrics to see what your systems were doing during an incident.
Sumo Logic is one connection that covers two kinds of telemetry: logs and metrics. Nexus queries it to see what your services were doing around the time of an incident: the log lines a service was emitting, and the metric that moved.
You connect Sumo Logic directly, with an Access ID, Access Key, and your deployment region. A single connection brings
both capabilities, and you choose which ones Nexus can use.
## What we support
Connecting Sumo Logic gives Nexus two capabilities, each of which you enable independently:
| Capability | What it queries |
| ---------- | ---------------------------------------------------------------- |
| Logs | Log lines from your services, and trends derived from those logs |
| Metrics | Time-series metrics, graphed for the incident window |
### Logs
Nexus searches your logs with the Sumo Logic search query language to read what a service was logging at the time of an incident: the errors, the warnings, the request that failed. It scopes each search to the source categories that matter and filters on Sumo Logic's built-in `_loglevel` field, which is the reliable way to find error-level logs: a bare `error` keyword also matches lines carrying fields like `error_count=0`, so it isn't a dependable level filter.
It can also turn those logs into time-series, so you get a graph of an error rate climbing or request volume dropping away even where you never set up a dedicated metric. This is the same log data, aggregated over time rather than read line by line.
### Metrics
Nexus queries your Sumo Logic metrics and graphs them for the incident's time window, so a CPU saturation, a latency change, or a queue backing up shows up against the period that matters. Queries are grounded in the metric names and dimensions that actually exist in your account, so Nexus filters and groups by the dimensions you really have rather than guessing at labels.
Nexus learns the structure of your Sumo Logic data automatically: your source categories and fields, and your metric names and dimensions. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
Traces aren't supported yet. If your team relies on Sumo Logic tracing, [get in touch](mailto:support@incident.io):
it's on our roadmap.
## Connecting Sumo Logic
You connect Sumo Logic directly. There's no provider in front of it: one connection covers both capabilities.
**What you'll need:**
* A Sumo Logic **Access ID** and **Access Key**, created under **Administration → Security → [Access Keys](https://help.sumologic.com/docs/manage/security/access-keys/)**. An access key isn't scoped on its own; it inherits the [role capabilities](https://help.sumologic.com/docs/manage/users-roles/roles/role-capabilities/) of the user that owns it. So you control what we can do through that user's role, and we recommend creating a dedicated **service account** for the connection rather than tying it to a person.
* A role for that user that grants the capabilities each enabled capability needs. Nexus only ever reads from Sumo Logic, so these are all view/read capabilities: no management or write access is required.
* **For logs**: **Download Search Results** (this is the capability that lets us run searches and read the results) and **View Collectors** (the connection test lists a collector to confirm the credentials and region, so this is needed even before any search runs). We also read your partitions and fields to learn how your data is structured, which needs view access to your account's data.
* **For metrics**: the **Metrics** capability.
* Your **deployment region**: the API endpoint for the pod your account lives on. This is `https://api.sumologic.com` for US1, and `https://api..sumologic.com` for the others (for example `https://api.eu.sumologic.com` or `https://api.us2.sumologic.com`). The region must match your account, because Sumo Logic doesn't carry credentials across regions; connecting against the wrong one fails the connection test. Sumo Logic lists every pod in its [API endpoint reference](https://help.sumologic.com/docs/api/getting-started/#sumo-logic-endpoints-by-deployment-and-firewall-security).
1. From the [Nexus telemetry settings](https://app.incident.io/~/nexus/telemetry), add a telemetry data source and choose **Sumo Logic**.
2. Enter your Access ID, Access Key, and deployment region, then test the connection.
3. Choose whether Nexus can use logs, metrics, or both.
Connecting Sumo Logic adds two data sources, one for logs and one for metrics, that mirror Sumo Logic's two query surfaces. Both are enabled by default once you connect, and you can toggle each independently. Turn off either one you don't want Nexus to query.
## Best practice
* Connect with a dedicated service account rather than a personal access key, so the connection keeps working when people move teams. Give its role only the capabilities the connection needs (**Download Search Results** and **View Collectors** for logs, and **Metrics** for metrics) so the credentials stay scoped to reading the data Nexus queries.
* Scope your searches with source categories. Sumo Logic caps a single raw log search at 100,000 messages, so a narrow `_sourceCategory` filter returns complete results where an unscoped search over a wide window can be truncated. Nexus does this for you, and it works best when your source categories are meaningful.
* Enable both logs and metrics. With both connected, an investigation can move from a metric that moved to the log lines behind it, rather than seeing only one half of the picture.
## Related
How data sources and capabilities fit together.
Routing, query planning, guidance, and memory.
# Tempo
Source: https://docs.incident.io/nexus/telemetry/tempo
Query your Tempo traces to see how a request moved through your services during an incident.
Tempo is Grafana's distributed tracing backend. Nexus queries it to follow a request across your services: which service handled it, where it slowed down, and where it errored.
Tempo is connected through [Grafana](/nexus/telemetry/grafana): connect Grafana, and Nexus discovers every Tempo data
source behind it automatically, with nothing separate to configure.
## What we support
A Tempo data source gives Nexus three capabilities, all queried with TraceQL:
| Capability | What it queries |
| ------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Span search | Spans matching a shape, such as slow or erroring spans by service, endpoint, attribute, or duration |
| Traces | A complete trace by its ID, whether that came from a span search, a log line, or an error report |
| Trace metrics | Spans turned into time-series: request rates, counts, and latency quantiles grouped by service, status, or any attribute |
When Nexus retrieves a trace, you get it as a timeline: each span with its service, operation, duration, and status, nested under the span that called it. You can see where the request spent its time and where the failure started.
### Aggregating over span attributes
Span attributes are rarely exposed as labeled metrics elsewhere: a customer ID, an endpoint, a SQL fingerprint, a status. TraceQL metrics let Nexus chart rates and latency quantiles grouped by those attributes directly. A question like "p95 latency on `POST /v1/incidents` in production" can be answered from traces even when no metric was set up to track it. Trace-derived metrics depend on Tempo's metrics-generator; where it isn't running, Nexus falls back to span search over the same period.
Nexus learns the structure of your traces automatically: your services, the resource and span attributes you emit, and which of them are high-cardinality. That way, queries target attributes that actually exist. How that works is covered in [How telemetry works](/nexus/telemetry/how-it-works#learning-your-stack).
## Connecting Tempo
Connect [Grafana](/nexus/telemetry/grafana), and Nexus discovers every Tempo data source behind it automatically, using Grafana's own credentials, with nothing separate to configure.
Discovered Tempo data sources start disabled, so you opt in deliberately: enable the ones your team uses from your [telemetry settings](https://app.incident.io/~/nexus/telemetry).
If an enabled Tempo data source holds no spans yet, Nexus sets it aside rather than run queries that can't return anything. It starts using the source once spans arrive.
## Best practice
* Enable the Tempo data sources your responders reach for during incidents, rather than every source available.
* If you want trace-derived metrics, run Tempo's metrics-generator. Without it, Nexus can still search spans and retrieve traces, but can't chart rates or latency quantiles.
* Connect the Grafana dashboards that query Tempo. Nexus learns your real trace query patterns from them, which makes Tempo queries more accurate.
## Related
The provider Tempo is connected through.
How Nexus queries your traces.
# Troubleshooting
Source: https://docs.incident.io/nexus/telemetry/troubleshooting
Diagnose a data source that's failing, returning nothing, or asking to be reconnected.
Every data source has a detail page in your [telemetry settings](https://app.incident.io/~/nexus/telemetry) that shows how it's doing: its connection health, its query results, and why queries failed. This page covers what you'll see there and how to fix each problem.
## Connection health
Each data source carries a connection status from its most recent check:
* **Connected**: the last check passed. Nothing to do.
* **Degraded**: the source is usable and Nexus keeps querying it, but something non-blocking is off, most commonly that the source holds no recent data. Check the detail on the data source's page to see what.
* **Connection failed**: the last check found a blocking problem, so the source can't currently be reached or used. Run the connection test to see which requirement failed.
## When a data source needs reconnecting
When a data source stops being usable, its page shows a banner and Nexus pauses queries against it until you act. This happens for three reasons:
* **Authentication failures**: the provider repeatedly rejected the credentials, so Nexus stopped querying the source and flagged it. Reconnect with fresh credentials to restore access.
* **Missing permissions**: the credentials still authenticate, but a permission Nexus needs has been revoked. Grant the missing permission to the existing credential; reconnecting with the same key changes nothing.
* **Configuration required**: the source is missing something it was never given, such as a database discovered through a provider that has no credentials yet, or a private resource Nexus can't reach without a [proxy](/integrations/proxy). Finish the setup from the data source's page.
## Testing the connection
Select **Test connection** on a data source's page to run a fresh check. It works through each requirement in turn: reaching the endpoint, authenticating, permissions, access to the data. When one fails, it names exactly what's missing and how to fix it, down to the specific permission to grant.
## Failed queries
The detail page also breaks failed queries down by category, so when a source has a low query success rate you can see *why*. Most categories are about the data source itself; a couple are things you can fix directly.
| Category | What it means | What to do |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **Rate limited** | The provider rate-limited our queries. | Usually eases on its own. If it persists, raise the provider's API rate limits or quota where possible. |
| **Timeout** | The query ran longer than our time limit and was cut off. | Eases as Nexus learns to write faster queries. Scaling and improving performance of the data source can also help where possible. |
| **Provider error** | The provider's own backend returned an error (a 5xx). The query itself was valid. | Usually transient. Check the provider's status if it keeps happening. |
| **Unauthorized** | The provider rejected our credentials. | Reconnect the data source to refresh its credentials. |
| **Invalid query** | The query we built wasn't valid for this source, such as an unknown field, a filter that matched nothing, or a time range outside the source's retention. | Improves automatically as Nexus learns your stack. Contact support if it stays high. |
| **Unknown** | A failure we couldn't categorize. | Contact support if you see a sustained run of these. |
A healthy source occasionally errors, that's normal. It's a sustained shift in one category that's worth acting on,
like a jump in **Unauthorized** (reconnect) or **Rate limited** (provider limits).
## Queries succeed but return nothing
The detail page separates queries that returned data from ones that came back empty, so a source that always returns nothing stands out even when every query succeeds. The common causes:
* **The connection is scoped to the wrong place**: an index pattern, dataset, or project that doesn't hold the data your team asks about. Check the data source's configuration.
* **The data has aged out**: queries target a window the source no longer holds. Check the retention settings below.
* **The source genuinely doesn't hold that data**: enable the sources your responders reach for during incidents instead.
## Retention windows
Nexus queries within a data source's retention window, and a query whose time range falls outside it fails as an invalid query. Nexus learns retention where the data source reports it, and you can set it yourself under **Data source retention** in the data source's settings. If a source's retention has changed (say you shortened it to cut costs), update it there so Nexus stops reaching for data that's gone.
## Related
What you can connect, and how providers and capabilities fit together.
Routing, query planning, guidance, and memory.
# Acting on time off
Source: https://docs.incident.io/on-call/acting-on-holidays
Arrange cover for a holiday with an override, or flag upcoming overlaps with a vacation policy
Once you've set up some [public holiday](/on-call/public-holidays), [calendar feed](/on-call/calendar-feeds), or [HRIS](/on-call/direct-hris-integrations) subscriptions, we'll automatically surface relevant holidays alongside your On-call schedule shifts. From there, you can arrange cover yourself, or set up a policy to automatically flag any upcoming overlaps.
## Create an override
To arrange cover for a holiday, hover over it in the timeline and click **Create override**.
## Detect on-call and vacation overlaps with a policy
Nobody wants to get paged on the beach. A vacation policy checks upcoming vacations against your On-call schedules and notifies you of any overlaps, so they're spotted well before someone's already off.
Here's how it works:
* **We spot overlaps automatically.** We check upcoming vacations against who's scheduled to be on-call and surface any conflicts.
* **We look 60 days ahead.** We scan for overlaps in the next 60 days, so there's time to arrange cover.
* **We notify the person on vacation.** When we spot an overlap, we let them know so they can sort cover before they're off.
Vacation overlaps are configured as a policy. To turn this on, see [Policies](/admin/policies).
# Setting up notifications on Android
Source: https://docs.incident.io/on-call/android-notifications
**Download our mobile app**
If you'd like the best possible experience as a responder, download our mobile app [here](https://play.google.com/store/apps/details?id=com.incidentio.incidentio).
For responders in Mainland China, see [Mobile app in China](/on-call/china-mobile-app) — there's a separate
事件incidentio app distributed through Chinese app stores, and the incident.io app won't reliably deliver
notifications inside the country.
When you are paged, we'll try and contact you according to your [notification rules](https://app.incident.io/~/user-preferences/on-call-notifications).
By default, assuming you've enabled them, this will include:
* Push notification
* Phone call
* SMS
* Email
* Slack direct message
* WhatsApp message
For push notifications, phone calls, and SMS messages, there are steps you can take to ensure you get notified, regardless of what your phone's silent mode and do-not-disturb settings are set up like.
***
## Phone calls + SMS
1. Save [the incident.io contact card](https://app.incident.io/api/mobile/responder_vcard) to your contacts.
2. Open the Contacts app and find the contact you've just saved.
3. Favorite the contact by tapping on the star icon
4. Open the Settings app and search for Do Not Disturb
5. If you have Do Not Disturb enabled, make sure you go under Exceptions > Calls and/or Messages and ensure you allow DND exceptions for **Favorite contacts only** (this should have been done in step 3)
Depending on your Android version, you may need to Tap on People and then for both Message and Calls, ensure that Starred contacts can interrupt your Do Not Disturb.
Please note that Android's "interrupting Do Not Disturb" setting for a contact only refers to whether calls and SMS are displayed while in Do Not Disturb. It does not bypass your mute switch or volume settings.
**If your phone is on silent (not Do Not Disturb)**
The Favorite / starred contact and Do Not Disturb exception steps above only control whether calls and SMS come through while your phone is in **Do Not Disturb** mode. They do **not** make calls ring when your phone is on **silent** (ringer off / muted).
To have incident.io's calls ring while your phone is on silent, set a per-contact override so the incident.io contact is allowed to ring through the mute switch. On most **Samsung** devices:
1. Open the **Contacts** app and find the incident.io contact you saved.
2. Tap the **⋮ (three dots)** menu, then tap **Change ringtone**.
3. Enable the **"Ring when on mute"** toggle.
The exact wording and location of this option varies by manufacturer and Android version — look for a per-contact ringtone setting that lets that specific contact ring while the phone is silenced. It's separate from the Do Not Disturb and Favorites settings above, so if you use both silent and Do Not Disturb, configure both.
## Push notifications
When you receive a critical push notification on Android, incident.io plays the sound through your phone's **alarm audio stream** and shows a full-screen alert when your screen is off or locked — similar to how an alarm app behaves. This makes pages audible regardless of whether your phone is on silent or in Do Not Disturb.
**How it behaves**
* We play the sound through the alarm stream, using a notification channel called "High priority notifications (Alarm style)".
* When your phone screen is off, or your phone is locked, we display the notification using a "Full screen intent" — similar to how an alarm appears.
* When your phone screen is on, we show a heads-up notification through the same alarm channel.
* The sound plays at your alarm stream volume.
**Make sure pages are always audible**
* Set your alarm stream volume to a high value.
* Make sure alarms are allowed through Do Not Disturb. This is usually on by default, but if you have custom Do Not Disturb modes (e.g. Work, Sleep) you may need to allow alarms in each one.
**Permissions**
For full-screen alerts to display, the app needs the **Display over other apps** / Full-screen intent permission. This is typically granted automatically when you install the app. If you've revoked it, pages will still ring but won't show the full-screen alert — open the app to re-grant it.
Pages ring through the alarm audio stream, which bypasses Do Not Disturb modes by default — no app permissions required for that.
We do still recommend granting **Do Not Disturb access** (called **Modes access** on Android 14 and newer). When granted, we use it to make pages louder and harder to miss:
* Boosting your alarm stream volume to the level you've configured in the app, if needed.
* If you have Do Not Disturb set to a mode that explicitly blocks alarms (e.g. Total silence), temporarily disabling it so the page can ring.
* If your phone is on silent or vibrate, temporarily switching it to normal ringer mode so the page is audible.
All of these are temporary. We run a background task to restore your previous state around 60 seconds later. This is best-effort — the system may occasionally end the task early.
We also strongly recommend checking these settings:
1. Disable **Pause app activity if unused**. By default, Android typically will allow the incident.io app to be paused if the app is unused - which may be typical if you're not on call very often. You can find this by opening the Settings app, tapping on Applications, incident.io and then scrolling down to find the toggle at the bottom.
2. Enabling **Unrestricted battery usage**. By default, Android will enable "Optimized" battery usage for the incident.io app. We don't perform any background work that should drain your battery, other than receiving push notifications. You can find this by opening the Settings app, tapping on Applications, incident.io, App battery usage, and then enabling **Unrestricted**.
**Work profiles**
The full-screen intent permission works inside work profiles, so push notifications behave the same way as on a personal profile.
Work profiles can't be granted Do Not Disturb / Modes access. If this matters to you, there's a workaround: install incident.io in a personal profile too and grant Do Not Disturb access in that profile (you don't need to sign in). The work profile inherits the permission.
**Device limitations**
* If using a **OnePlus** device which has a physical mute switch, we cannot guarantee that push notifications will play a sound, whether that's in do not disturb or not. This is due to OnePlus limitations. We recommend leaving your OnePlus in "Ring" for notifications to work both in Do Not Disturb and normal mode.
* Some **Samsung** devices have a feature called Focus modes which can add additional rules to your do-not-disturb settings. If you're not receiving notifications whilst in a Focus mode (such as "Work") then you need to edit the Do Not Disturb settings for the Focus mode specifically and whitelist **incident.io** in the Allowed Apps section.
**Smartwatches and connected devices**
If you have a smartwatch (such as a Pixel Watch or Galaxy Watch) paired with your phone, it may interfere with notification sounds on your phone. By default, many smartwatches mute notification sounds on your phone when the watch is connected, so that you only hear them on your wrist.
For **Pixel Watch**: Open the Pixel Watch app on your phone, go to **Notifications** > **Mute notifications**, and toggle off "Mute notifications" in the **Phone** section. This will allow notification sounds to play on your phone even while your watch is connected.
For **other Wear OS watches**: Open the Wear OS app on your phone, go to **Settings** > **Notifications**, and disable **Silence phone while wearing watch**.
Connected **headphones or earbuds** (such as Pixel Buds or other Bluetooth audio devices) can also affect where notification sounds are routed. If you're not hearing notifications, check that your audio isn't being routed to a connected Bluetooth device.
**Custom notification sounds**
You can customize sounds for each notification channel through your device settings from ringtones installed on your phone. To do this, head to the mobile app. In your personal preferences, under "Notifications" you can click on each notification channel to customize the sound through your device settings.
**Repeat notification sound**
In your notification preferences, you can enable repeating notification sounds so that pages continue to ring until you interact with them.
**Acknowledging from a notification**
If you're using an Android device with a VPN, such as Google VPN, and you're seeing errors trying to quick-ack from a notification, it might be due to your VPN settings. You can add an opt-out of our app in your VPN in order for this to work.
## WhatsApp
You can receive escalations as WhatsApp messages, and acknowledge or mark yourself as not available straight from the buttons in the message. We support WhatsApp messages only, not calls.
To make sure your pages come through, allow the WhatsApp app to override Do Not Disturb. On most **Samsung** devices, head to **Settings → Do Not Disturb → Apps** and add **WhatsApp** to allow it to override your Do Not Disturb settings.
# Setting up the mobile app in a work profile in Android
Source: https://docs.incident.io/on-call/android-work-profile
Android supports [work profiles](https://support.google.com/work/android/answer/6191949?hl=en), which allow users to separate work applications from personal applications.
When setting up our mobile app in a work profile, it is best to follow these steps:
1. Sign into work slack in the browser, outside of our app (i.e: log in at [https://app.slack.com](https://app.slack.com))
2. Sign in using our app, which will use the session already in the browser, from step 1.
# Building schedules
Source: https://docs.incident.io/on-call/building-schedules
Leverage schedules to tell us who should be on-call and when. We'll walk you through all the steps to create schedules that will work for your organization's needs.
## Getting Started
1. First, head to [On-call](https://app.incident.io/~/on-call/escalations) within the incident.io dashboard
2. Go to Schedules and create a new schedule
3. Name your new schedule, set up rotation, and choose the people who should be in that specific schedule. If you select a team, we'll add everyone in the team by default.
4. Preview your schedule and save
Read how to get started with On-call and how to connect your schedules to Alert routes [here](/on-call/getting-started).
## Rotation
Rotations are a great way to have a rolling schedule for your team to be on-call. Set up the times and people you want to work on specific times. There's an option for Daily, Weekly, or Monthly rotations.
### Asymmetric schedule
If you are splitting your shifts to be more asymmetric, you can create time intervals within hours days and weeks. By adding a new interval, you can create a rule to have your shifts to work example in 3 and 4 day shifts.
If you create shifts that are asymmetric and the amount of shifts is the same as the people in the schedule, we rotate the people to have a balanced amount of time on-call.
## Advanced rotas
Schedules offer a lot of additional customisations that can help with your organization's specific setup. Advanced rotas allow you to bring multiple rotas to your schedule.
For example, in global companies, we often see rotas that support follow-the-sun. Different locations could be on-call during different times during the day which will allow for all day coverage.
We've mapped out an example below where we have created two rotas: One for the US and one for the UK. The UK team is on-call between 9 am to 8 pm daily and the US team is between 8 pm to 9 am GMT.
### Add a person multiple times to a rota
You can add multiple people to a rota by just choosing the same person multiple times, we'll let you know if the person appears more than once!
## Intervals
Intervals are a great tool to use when you have different shifts throughout your week. For example, if some of the teams are only on-call during office hours you can choose specific times for your office hours.
## Shadow schedules
When you have new joiners in the team, a great way to get them into the product and schedules is to have a shadow schedule. This way the new joiners can follow alerts and incidents to build more context around your product and get used to being on call.
Just add a new rota and name it 'Shadow Schedule' and add people and times you want them to shadow alerts and incidents.
## Planning changes to a schedule
If you are looking to make changes like...
* Onboarding or removing responders from a certain date / time
* Changing the working hours of your schedule
* Changing the rotation's interval
* Any combination of the above
and you want your changes to come into effect from a future date (e.g. from the next shift), you can specify this while editing your schedule. Make all the edits you need, then choose when they take effect:
If you want to change who is on your schedule rotation, we suggest changing the handover time to match the effective time for your rotation to start from scratch. This is because we rotate through shifts based on the handover date, not the effective time.
You can use the preview to make sure your changes look right!
## Restoring a previous schedule version
If you make a change to a schedule, and then find you need to restore to a previous version, then you can easily do so from the schedule's drop down menu. You'll be able to see a preview of the schedule with the version you're restoring to.
Restoring to a previous version will use the previous version's config to determine what your schedule shifts look like going forward, but it won't change historical shifts.
## Overrides
Sometimes your team member is heading on a holiday or might need to head to a doctor's appointment. In Schedule overrides you don't need to change your current schedule or rotations, but can create one time changes to suit any miscellaneous events that happen during the week.
1. To create an override, click 'Add override' and add details
2. After you have created the override, you can see and review it on the Schedule's page and edit it if needed.
You can also [create overrides via the API](/api-reference/schedule-overrides-v2/create), for example to sync time off from an HR system. To mark that no one should be on call for a period, pass `"NOBODY"` as the user ID.
## Cover me
Cover me allows your team to ask for an override instead of just adding someone in.
1. Go to your #incidents channel in Slack and type `/inc cover me`
2. Choose your shift and choose the times you need cover for
3. Add more information and Submit!
Then your team members in the same schedule will receive the request both in the mobile app and Slack
And receive a confirmation if you accept
## Viewing multiple schedules
From the Schedules page, select **View multiple** to view up to 10 schedules at once. Your selection is saved in the URL, so you can bookmark the view to return to it later.
## FAQs
If you are a responder on the affected schedule with update permissions, or have previously edited it, you will receive a notification whenever someone on that schedule is deactivated (via Slack, Okta, or another provisioning service) or otherwise loses their on-call seat. You are then recommended to update the schedule to ensure you maintain on-call coverage.
By default this notification is sent by email. Your organization can also opt in to receiving it as a Slack (or Microsoft Teams) direct message from **Settings → On-call → Notifications**.
If an escalation reaches a deactivated user, we will automatically escalate to the next escalation level. If you run a [schedule coverage policy](/on-call/coverage-policies), the gap left by the missing responder is flagged there too.
# Bulk acknowledging escalations
Source: https://docs.incident.io/on-call/bulk-acknowledge
## Bulk acknowledging escalations
When you have escalations that are all related, we allow you to bulk acknowledge in the mobile app.
This is useful when you want to be focussed on dealing with the incident without getting distracted by alerts that are going through the same escalation you're already handling.
## Automatically acknowledging escalations
When there are 2 or more escalations, we'll provide you with an option to let us automatically acknowledge for a given time period after you have acknowledged all alerts.
This is useful when you're already working on the problem and would like anything that comes through the same alert route to not disturb you.
# Import holidays with calendar feeds
Source: https://docs.incident.io/on-call/calendar-feeds
Import your team's time-off from any calendar or HRIS that provides an iCal feed
If your calendar system or HRIS provides an iCal feed, you can import your team's personal holidays (time-off, vacation, PTO) into incident.io. We'll then surface those holidays alongside your On-call schedule shifts.
If you're on the Enterprise plan and use Workday, HiBob, or BambooHR, you can connect them directly instead of managing a calendar feed. See [Workday](/on-call/hris-workday), [HiBob](/on-call/hris-hibob), or [BambooHR](/on-call/hris-bamboohr). Otherwise, a calendar feed works on any plan.
## Add a calendar feed
To get started, you'll need a URL for the calendar feed that contains your team's holidays. We provide tips on how some popular systems let you set up calendar feed subscriptions [below](#getting-a-calendar-feed-url).
You'll need the **Manage vacation user feeds** permission to add or edit calendar feeds.
1. Head to **Settings > Integrations** and select [Calendar feeds](https://app.incident.io/~/settings/integrations/calendar_feeds)
2. Click **Add calendar feed** and enter the URL of the calendar feed you've generated in your HRIS or calendar system, and a name for the feed.
3. That's it. Your calendar feed is parsed and ready to be used within schedules! If we find a holiday that matches a responder on your schedule, we'll surface that event in the timeline view.
We match users to holiday events by email where they're listed as an invitee on the event. When a feed doesn't include emails, we fall back to matching by name. Name matching is best-effort, so users might not always match perfectly.
If you're not seeing a holiday alongside your On-call schedule as expected, please [let us know](mailto:support@incident.io) and we'll take a look!
Once your feed is set up, see [Acting on time off](/on-call/acting-on-holidays) to arrange cover.
***
## Getting a calendar feed URL
To help you get set up, we've detailed how to get a calendar feed URL from some popular systems below.
#### BambooHR
* See [Connect BambooHR](/on-call/hris-bamboohr) for how to import time-off via a calendar feed
#### CharlieHR
* Follow the steps in [this help article](https://help.charliehr.com/en/articles/839648-importing-your-time-off-calendar-to-google-calendar) to get a calendar feed URL
* Follow the steps above to use this calendar feed in incident.io!
#### HiBob
* See [Connect HiBob](/on-call/hris-hibob) for how to import time-off via a calendar feed
#### Personio
* Follow the steps in [this help article](https://support.personio.de/hc/en-us/articles/360000286117-Add-a-Personio-Calendar-via-an-iCal-link) to get a calendar feed URL
* Follow the steps above to use this calendar feed in incident.io!
#### Rippling
* Follow the steps [in this video tutorial](https://www.youtube.com/watch?v=XWZsfwbF0jg) to get a calendar feed URL
* Replace the webcal:// protocol with the https\:// protocol in the URL
* Follow the steps above to use this calendar feed in incident.io!
#### Google Calendar
* If you have a custom calendar in Google Calendar, you can also bring it in!
* In the sidebar, hover over the calendar you care about and open its options menu
* Select **Settings**
* At the bottom of the page, in the **Integrate calendar** section copy the URL shown under **Public address in ical format** - note that you might [need to configure this calendar to be public](https://support.google.com/calendar/answer/37083?sjid=15786370471486530353-EU#link\&zippy=%2Cshare-a-link) for this to appear.
* Follow the steps above to use this calendar feed in incident.io!
Google Calendar Embed URLs (which look like `https://calendar.google.com/calendar/embed?src=...`) are for displaying a calendar on a webpage and won't work as a calendar feed. The correct public iCal URL will look like `https://calendar.google.com/calendar/ical/.../basic.ics`.
Other systems may support calendar feeds, as we don't have access to all their documentation. If you use a system which isn't listed here, and are successful with this feature, please [let us know](mailto:support@incident.io)! We'd love to know how you end up using it.
# Using Catalog with On-call
Source: https://docs.incident.io/on-call/catalog-integration
Catalog is our powerful engine, enabling seamless automation of configurations across both On-call and Response products. At its core, Catalog lets you map your organization’s structure, allowing us to route alerts to the appropriate teams, support customer-facing teams in identifying the right contacts, and streamline configuration to accelerate migration.
Catalog offers flexibility and versatility to meet your needs, along with default settings to help you get started. Integrating a third-party service catalog, like Backstage, is also quick and easy.
## How we page
When something goes wrong, it’s essential to involve the right people immediately. Paging or escalation can happen automatically from your alert source or manually by someone initiating a page or an incident
In both cases, to ensure the right people are paged, it’s essential to connect your Catalog types with the correct escalation paths. For example, you can link Teams, Services, and Features to their respective escalation paths for streamlined paging.
If you attach teams to your escalation paths, we will automatically add this link to Catalog for you, to make paging by team easier.
## Escalating and creating incidents automatically from your alerts
Once your Catalog is set up with types connected to escalation paths, you can configure *Alert Routing* to dynamically route escalations to the appropriate team and individual.
This means that you can use one route for even 100 teams without creating separate configurations for each.
1. Head to alert route
2. Go to escalations
3. Escalate via dynamic value
4. Create an expression ie. From Services → Teams → Escalation paths
5. Save
Now every time an alert comes in, we'll read what service it will have and route it depending on that to the right team!
Learn how to **automatically** escalate and create incidents [here](/alerts/getting-started).
## Escalating and creating incidents manually
When a customer reports an issue, team members often need to manually escalate or create an incident. They can do this through the web dashboard or by using the `/inc` or `/inc escalate` commands. With Catalog, customer-facing teams don’t need to know exactly who owns a feature; they can simply escalate based on the feature, and the Catalog will route it to the correct team.
Learn how to **manually** escalate and create incidents [here](/on-call/manual-incidents).
## Configuring your Catalog
To set up your Catalog with On-call, we’ve created simple defaults to help you get started. In this section, we’ll share some example structures to guide you along the way!
#### 1. Determine the structure of your Catalog
The structure of your Catalog depends on your system and organization structure. A common simple structure is
* Teams
* That own Services
* That power features
For larger companies, there might be more grouping of teams into domains
* Domains
* That includes teams
* That own Services
* That includes features
#### 2. Create them as Catalog Types
After you have decided on which Types you need, it's time to import those types from your third-party service catalog or manually create them.
#### 3. Connect types to Teams
To ensure your On-call configuration functions correctly, connect all necessary types using Attributes and Derived Attributes, which can be edited within each Type. Make sure the Type is selected from the Catalog and is not set as Text or String.
The Catalog is very flexible and can be used in thousands of different ways to suit your company, so please contact us if you have a specific use case you'd like to run through with us at [support@incident.io](mailto:support@incident.io).
## Parsing Catalog values from alerts
To finalize setup, ensure the metadata from your alerts—such as labels—connects with the Catalog entries you've created for your types. Here are some examples of how alert metadata can map to your Catalog:
* Alert → Service → Team → Escalation Path
* Alert → Feature → Team → Escalation Path
* Alert → Team → Escalation Path
* etc...
#### Attributes
When setting up your alert source, start by sending an initial payload that includes the typical metadata for your alerts. Next, organize this metadata so it can drive escalations and other automated actions on the platform—these elements are called *Attributes*.
You can create Attributes that connect to Catalog types or store them as text as needed. If your Catalog is already configured, we’ll automatically identify matches and suggest attributes based on those entries.
#### Aliases & External IDs
Sometimes, your payload may use different names or formats for the same metadata. The *External ID* is how your systems identify this entry, and it cannot be changed once set.
Use *Aliases* to reference this Catalog entry across other tools. Aliases should be unique and permanent, allowing you to rename the Catalog entry without changing the alias.
Aliases are helpful when names change, such as a team name update. This allows you to change the name of your type while adding the previous name as an alias, ensuring continued recognition without interruption.
# Can I change the timezone of an on-call schedule?
Source: https://docs.incident.io/on-call/change-timezone
## Context
When creating on-call schedules, the timezone is set during creation. Users may want to change the timezone of an existing schedule, particularly when working with teams across different regions or after importing schedules from other platforms.
## Answer
The timezone of an on-call schedule cannot be changed after creation. This is by design, as changing the timezone could affect existing schedules and rotations.
If you need a schedule in a different timezone, you will need to create a new schedule with the desired timezone.
However, there are several ways to work with different timezones in existing schedules:
1. Use the daily or 3-hour view to see multiple timezone conversions:
* Switch to the 3-hour or 1-day view of your schedule
* Click the timezone selector to add additional timezone conversions
2. When creating overrides:
* The times will be shown in the schedule's original timezone
* Use the click-and-drag feature in the calendar view to create overrides visually
* Refer to the timezone conversions in the daily view to confirm the correct times
Note: When viewing schedules, the system may display timezone abbreviations (like EST/EDT or PST/PDT) based on whether Daylight Saving Time is in effect. The schedule's base timezone remains unchanged.
# Mobile app in China
Source: https://docs.incident.io/on-call/china-mobile-app
Setting up the incident.io mobile app for responders in Mainland China.
There are two versions of the mobile app: the **incident.io app**, distributed everywhere except Mainland China, and the separate **事件incidentio app** for Mainland China.
The **incident.io app** is only reliable outside Mainland China, and the **事件incidentio app** is only reliable
inside Mainland China.
Responders in Mainland China need the 事件incidentio app to reliably receive notifications.
## If you've got both apps installed
The 事件incidentio and incident.io apps are not interchangeable, but you can run both on the same device if that suits how you travel.
If you do, make sure both are set up correctly. [Test notifications](/on-call/notifications#testing) are the best way to do this, but you'll need to test each app independently.
Test notifications might fail if the device is outside the relevant app's supported region - i.e. you might need to be
inside Mainland China to successfully test 事件incidentio app notifications.
## Android
The 事件incidentio Android app is distributed through Chinese app stores rather than Google Play.
Make sure your responders in Mainland China install the 事件incidentio app, not the incident.io app. If they're using
the wrong one, notifications won't reliably arrive — and there's no warning that anything's wrong.
Install from one of these stores:
* [Xiaomi](https://app.mi.com/details?id=com.incidentio.incident.io_cn) (including Redmi)
* [Vivo](https://h5coml.vivo.com.cn/h5coml/appdetail_h5/browser_v2/index.html?appId=4552589)
* [Honor](https://appmarket-h5.cloud.honor.com/h5/share/latest/index.html?shareId=2041417008628764672\&shareTo=copyLink#/)
* [Huawei](https://appgallery.huawei.com/#/app/C117053195)
* OPPO — search for `事件incidentio` in the store
### Device support
Push notifications are reliable on devices from these five manufacturers: Xiaomi (and Redmi), Vivo, Honor, OPPO, and Huawei. We integrate with each vendor's own push channel, which is the only way to get reliable delivery in China.
For other Android brands, we fall back to a generic channel that's much less reliable. If you've got responders on other devices, recommend SMS or voice as their primary notification method rather than push.
### Custom notification sounds
The custom notification sounds available in the incident.io app aren't available in the 事件incidentio app. Notification channels use your phone's default sound instead.
Use the [Android notification setup guide](/on-call/android-notifications) for help with adding the contact card, Do Not Disturb exceptions, and battery settings — it all works the same way as in the incident.io app.
## iOS
The 事件incidentio app uses Time Sensitive notifications in place of Critical Alerts. These bypass Focus modes if
you've opted in, but they don't bypass silent mode — so push notifications alone won't wake someone up reliably.
For high-urgency pages, configure SMS and voice as the primary methods for responders in Mainland China. Push is still useful for low-urgency rules and shift change reminders.
Use the [iOS notification setup guide](/on-call/ios-notifications) for help with saving the contact card and enabling Emergency Bypass — we recommend doing both so that incoming voice calls bypass Do Not Disturb even when push can't.
# On-call in China
Source: https://docs.incident.io/on-call/china-on-call
How on-call notifications work for responders in Mainland China.
On-call in China is in early access. Speak to your account team to get set up.
Responders in Mainland China can receive pages via SMS, voice, and the Android and iOS apps.
We use **事件incidentio app** to refer to the mobile app distributed in Mainland China, and **incident.io app** for the one distributed everywhere else. The two are separate apps with separate setup — responders in Mainland China need the 事件incidentio app, not the incident.io app.
The mechanics of each channel are different enough that we've written separate guides for them:
* [Mobile app in China](/on-call/china-mobile-app) — why there's a separate app, which devices are supported, and what iOS can and can't do
* [SMS and voice in China](/on-call/china-sms-and-voice) — how messages are identified, how to add a Chinese phone number, and the channels that aren't available
## What's different
A quick orientation before you dig into the details:
* **The 事件incidentio app is a separate build** distributed through Chinese app stores rather than Google Play. Responders in Mainland China need to install this one — the incident.io app won't reliably deliver notifications inside Mainland China.
* **The iOS 事件incidentio app can't bypass silent mode.** We use Time Sensitive notifications, which bypass Focus modes but not silent mode. For high-urgency pages, recommend SMS or voice.
* **SMS messages don't come from a fixed number.** Chinese carriers assign a varying sender number per message, so users identify our SMS by a signature prefix in the message body — `【臻创互联】` — rather than by a saved contact.
* **Adding a Chinese phone number has an extra step.** Step 1 (adding the number) must happen from outside Mainland China. Step 2 (verifying it) can happen anywhere.
* **Live call routing isn't available** for Chinese numbers.
## On-call readiness in China
The available notification methods are different in Mainland China, so a single notification policy that covers everyone will misfit one group of responders. We recommend creating a separate [notification policy](/on-call/notification-policies) for Mainland China — and in particular, leaning on SMS and voice for high-urgency rules rather than push, since iOS can't reliably wake responders through the app there.
Scope the policy to your China responders using a catalog attribute — for example, filtering by Office:
[On-call readiness insights](/on-call/on-call-readiness-insights) shows which app each responder has installed, so you can confirm that responders in Mainland China are using the 事件incidentio app rather than the incident.io app — the most common foot-gun, and one we can't catch automatically.
# SMS and voice in China
Source: https://docs.incident.io/on-call/china-sms-and-voice
How SMS and voice notifications work for responders in Mainland China.
SMS and voice calls in Mainland China go through a different provider than the rest of the world, and the mechanics are different enough that they're worth understanding before you set responders up.
## SMS
### Identifying our messages
SMS messages in Mainland China don't come from a fixed number, so you can't identify them by sender or save the sender as a contact. Look for the **signature prefix** at the start of every message — ours is `【臻创互联】` (Zhenchuang, our partner in China).
Chinese carriers assign each SMS its own sender number, usually starting `106…`, and it can vary from message to message. The contact card on your phone will still match incoming voice calls from us, but SMS messages need to be identified by the signature.
### Overnight delivery
SMS delivery overnight can be unreliable in Mainland China. Pair SMS with another method like a voice call for high-urgency rules — as with SMS anywhere, we don't recommend it as the only high-urgency channel.
Chinese carriers apply their own traffic policies overnight and can hold or drop messages they consider non-urgent. We can't predict or work around this.
## Voice
Voice calls in Mainland China come from a fixed number, so you can save it as a contact and treat it like any other call. VoIP numbers work too. The [iOS](/on-call/ios-notifications) and [Android](/on-call/android-notifications) contact card setup applies here, including Emergency Bypass on iOS and Do Not Disturb exceptions on Android.
## Adding a Chinese phone number
Chinese data protection law means we can't collect personal data — including a phone number — from someone inside Mainland China. So adding a Chinese number to incident.io is a two-step process, and the first step has to happen from outside the country.
There are two ways to do it:
1. **Self-serve**: the user [adds and verifies their number](/on-call/notifications) themselves from outside Mainland China — for example, while travelling or visiting another office. Once added, they can use it from anywhere.
2. **Manager-assisted**: a manager [adds the number on the user's behalf](/on-call/contact-methods) from outside Mainland China. The user then verifies it from inside Mainland China using the 事件incidentio app (not the web dashboard).
## Live call routing
We don't offer [live call routing](/on-call/live-call-routing) numbers in Mainland China. None of our providers operate inside the country for this. If you need a public-facing routing number for callers in Mainland China, you'll need to use an international number.
# Can I escalate to multiple levels if the same person is on consecutive escalation paths?
Source: https://docs.incident.io/on-call/consecutive-escalation
## Context
When handling incidents, users may need to escalate to different levels in their escalation path. Sometimes, the same person might be assigned to multiple consecutive levels in the escalation path, and users need to understand how the escalation feature works in such scenarios.
## Answer
The escalation button functionality is limited to the next immediate level in your escalation path, regardless of who is assigned to that level. Here's how it works:
1. When you acknowledge an escalation in an incident channel, you'll see a button to escalate to the next level
2. Before the escalation occurs, you'll be shown who will be paged and the notification message that will be sent
3. The escalation button will only appear on the original acknowledged escalation
4. If the same person is on consecutive levels, you cannot skip levels to reach a different person (such as a manager) at a higher level
Note: The escalation button will not be displayed on subsequent escalations after the initial one, even if the same person acknowledges multiple levels.
# Adding contact methods for another user
Source: https://docs.incident.io/on-call/contact-methods
We use your contact methods specified in your [notification preferences](/on-call/notifications) to notify you of escalations and upcoming shifts.
To add a contact method on another user's behalf, you can navigate to their settings from the team members page and edit their preferences.
Adding a phone number for a responder in Mainland China has an extra constraint — the number must be added from
outside Mainland China. See [SMS and voice in China](/on-call/china-sms-and-voice#adding-a-chinese-phone-number) for
the details.
You will only see this option if you have the **Manage user notification preferences** permission. All admins have this permission by default: this can be configured in Settings > Permissions.
You can configure this permission globally, add it to a custom role, or configure it at the team level. Find out more about [custom roles](/admin/user-permissions#custom-roles) and [team roles](/admin/team-roles) in these help center articles.
You can then add a new contact method, e.g. a phone number. This will not attempt contact with the user automatically, and they will need to verify the method themselves before we can reach them.
If a user has an unverified phone number and has the mobile app installed, then they will see a banner on the home page. This will direct them to complete verification. The current verification status of contact methods is visible from the team members page and the user's notification preferences page.
# Schedule coverage policies
Source: https://docs.incident.io/on-call/coverage-policies
Check that your schedules have someone on call around the clock, and catch gaps before they turn into a missed page.
A schedule coverage policy checks that your [schedules](/on-call/building-schedules) have someone on call around the clock (24/7). It looks ahead over the next 60 days and flags any window where no active responder is covering the schedule, so gaps get spotted and filled before they turn into a missed page.
Gaps can appear for all sorts of reasons: a rotation that ends without a replacement, working hours that don't add up to full coverage, or a responder being deactivated (or losing their on-call seat) while they were still on an upcoming shift.
Schedule coverage policies are a [policy](/admin/policies) type, available on Pro and Enterprise plans.
## Creating a coverage policy
Create a coverage policy from [Settings → Policies](https://app.incident.io/~/settings/policies), the same place you manage every other [policy](/admin/policies). As with other policies, you choose who's notified and on what cadence, and outstanding gaps appear in the policy's **Outstanding** tab, on team **Tasks** pages, and in [policy reports](/admin/policies#policy-reports).
## Choosing which schedules to cover
When you create a coverage policy, you decide which schedules it applies to. You can select schedules directly, or add conditions that match on their [catalog](/catalog/overview) attributes, including the **teams** that own each schedule. This lets a policy target "every schedule owned by the Platform team" and automatically pick up new schedules as they're created.
## Evaluating at the schedule or rotation level
A coverage policy can be evaluated at one of two levels:
* **Schedule**: coverage is checked across the schedule as a whole. As long as *some* rotation has an active responder at every moment, the schedule is covered.
* **Rotation**: coverage is checked for each rotation independently. Every rotation on the schedule must be covered around the clock in its own right.
Rotation-level evaluation is useful when you rely on specific rotations directly. For example, when an [escalation path](/on-call/escalation-paths) points at a single rotation rather than the whole schedule, you need each one to hold its own coverage.
Conditions match schedules, not individual rotations. A rotation-level policy therefore requires *every* rotation on a
matching schedule to be covered.
## Who gets notified
As with other policies, you choose who's responsible for resolving a coverage gap. You can assign one or more people, such as everyone responsible for a schedule, and each assignee is reminded on the cadence you configure.
### When reminders are sent
Because a coverage gap is a window of time in the future, you can anchor each reminder to one of two moments:
* **When the gap is identified** — remind immediately, or a set number of days after the gap is first detected. Good for nudging someone to fill a gap as soon as it appears, even if it's weeks away.
* **When the gap starts** — remind a set number of days before the gap starts, when it starts, or a set number of days after.
You can add several reminders across both anchors, up to 31 days out.
## Surfacing and dismissing gaps
Coverage gaps show up in two places:
* **On the policy**, in the **Outstanding** tab of the policy's side panel.
* **On the schedule**, where gaps are surfaced with a "needs cover" banner you can cycle through to jump straight to each one.
Sometimes a gap is expected and doesn't need filling. You can dismiss a coverage gap with a reason from either place. Dismissing a gap requires the **Dismiss policy violations** permission, and dismissed gaps stay dismissed across future evaluations.
# What determines if you're on call?
Source: https://docs.incident.io/on-call/determining-on-call
In our mobile app and our dashboard, we'll indicate whether you're on-call or not. However, if you're using working hours across schedules and escalation paths, it can be unclear how this works. Below, we've outlined how we determine whether you're on call.
In short, we will consider you as on-call if you *can currently receive high urgency notifications for an escalation, before anyone else.*
**You're only on call if you're on an escalation path**
The only way to be escalated to (paged) through incident.io is via an escalation path, or directly. There is no way to escalate to a schedule. Therefore, if you're on a schedule but no escalation path, we'll tell you that you're not on call.
We'll account for you being on this escalation path either through a schedule, or directly.
**If you're on an escalation path through a schedule, you must be currently active on that schedule**
If you're on call through a schedule, you must be active on that schedule. Additionally, the current time must be within the working hours defined, if it's not a 24/7 schedule.
This also means that you will *not* be considered to be on call if you are on a schedule but not currently active on it, even if your level in the escalation path escalates via round-robin, or to all users on the schedule.
**You are currently the first reachable person on the path, with high-urgency notifications**
Lastly, we look at the path itself. We will only consider you to be on call if you are on the first reachable level, that level is currently active with respect to working hours (if you branch by working hours), and the level is configured to send high-urgency notifications.
This means that:
* If you are on level 2 with high urgency, but no one is currently on call for level 1, you are considered on call, as you would be the first person to be notified.
* If you are on level 1 *outside working hours*, and the current time is within working hours, you are not on call.
## Show your on-call status in Slack
You can set your Slack status to automatically update when you're on call, so your colleagues can see at a glance that you're on the pager. When your shift ends, your status resets to whatever it was before.
Each user needs to connect individually via a personal "Add to Slack" flow in their user preferences.
# Direct HRIS integrations
Source: https://docs.incident.io/on-call/direct-hris-integrations
Connect Workday, HiBob, or BambooHR directly to bring in your team's time off
Connect a supported HRIS directly to bring in time off without managing a calendar feed. Because we sync your users straight from the HRIS, we can always match each time off entry to the right person, rather than the best-effort matching a [calendar feed](/on-call/calendar-feeds) relies on.
Direct HRIS integrations are available on the [Enterprise plan](https://incident.io/pricing):
* [Connect Workday](/on-call/hris-workday)
* [Connect HiBob](/on-call/hris-hibob)
* [Connect BambooHR](/on-call/hris-bamboohr)
We only pull in what we need to match time off to your schedules: a list of your users and their email addresses, and their vacation data. We don't read anything else from your HRIS.
You'll need the **Manage organisation settings** permission to install a direct HRIS integration.
Using an HRIS that isn't listed here? If you're on the Enterprise plan, [reach out](mailto:support@incident.io) and we'll see what we can do. Otherwise, most systems can be brought in with a [calendar feed](/on-call/calendar-feeds).
## Time off policies
When you connect an HRIS directly, we bring in the time off policies your team uses, like annual leave or bereavement. You control how each policy appears in your On-call schedules, so you can keep sensitive HR categories private.
For each policy, choose one of:
* **Visible**: the policy name appears in on-call schedules (e.g. "Jane Smith - Annual leave"). Use for everyday policies like annual leave or vacation.
* **Private**: entries appear with no mention of the policy (e.g. "Jane Smith - Out of office"). Use for sensitive policies like medical appointments or bereavement.
* **Ignore**: entries don't appear in schedules at all. Use for things that aren't really time off, like working from home.
Changes apply on the next sync.
You'll need the **Manage HRIS time off policy types** permission to change how policy types are handled.
# Can we change the date format in email notifications?
Source: https://docs.incident.io/on-call/email-date-format
Yes! You can make this change within your Slack Preferences by clicking your profile picture → preferences → Language & Region → change the Language to your desired choice.
We derive your locale from your Slack settings. For example:
## If you have it configured to the English (UK)
You would get a date format of DD/MM/YYYY and a 24 hour time format
## If you have it configured to English (US)
You would get an MM/DD/YY format and a 12-hour time format
# How do escalation delays work when no one is on-call for a level?
Source: https://docs.incident.io/on-call/escalation-delays
## Context
When setting up escalation paths, you can configure delays between different escalation levels. However, there may be confusion about how these delays work when there is no one scheduled to be on-call for a particular level.
## Answer
While escalation paths allow you to set delay times between different levels (for example, a 5-minute delay between Level 2 and Level 3), these delays are only applied when there is at least one person on-call at that level who can be paged.
Important behavior to note:
If there is no one on-call for a particular level, the system will automatically and immediately progress to the next level without waiting for the configured delay time
The configured delay time only takes effect when there is at least one user available to be paged at that level
For example:
* If you have a 5-minute delay configured between Level 2 and Level 3
* And there is no one scheduled for Level 2 on-call
* The system will skip Level 2 immediately and proceed to Level 3 without waiting for the 5-minute delay
The same applies to [per-level retries](/on-call/escalation-paths#retry-a-level-before-moving-on): a level with nobody on-call is skipped straight away, so it makes no attempts at all.
# Smart escalation paths
Source: https://docs.incident.io/on-call/escalation-paths
## Escalation path branches
You might have people who are on-call just during business hours, or where you only want to wake people up when the priority is the highest for an alert. You can now set up rules around priority and/or working hours to ensure you page the right people at the right time without causing additional noise.
The instructions below help you create multiple escalation paths with rules, but you can still create simple escalation paths with the feature as in [this help article](/on-call/getting-started).
## How does it work?
You can start creating a new escalation path from scratch or edit your current paths. With this feature, you can
* Set up working hours for all levels in the escalation path
* Configure priorities in incident.io and connect them to your alert source
* Configure notifications for your devices for high and low-urgency
* Create branches based on priority and/or working hours
* Choose which levels should send high or low-urgency notifications
* Choose to escalate either within a time window or based on your working hours
## 1. Set up working hours for all levels in the escalation path
You can define one or more named sets of working hours for your escalation path — for example, separate configs for your UK and US teams, each with their own days, times, and timezone. These are then referenced in branches (to route escalations differently based on the time of day) and in ack deadlines (to wait until a team's working hours begin or end before escalating further).
## 2. Configure priorities and connect them to your alert source
To use priorities in the escalation path branches, you can create them in [Alert Attribute settings](https://app.incident.io/~/alerts/configuration/attributes). Priorities are now a first-class citizen in incident.io, which means that you wouldn't need to create those as a custom field in the catalog just to connect with your alert source.
You can create priorities locally just in incident.io or bringing your priorities from your Alert source. We'll show both cases below.
### Create your priorities in incident.io
1. Head to [Alert Attribute settings](https://app.incident.io/~/alerts/attributes)
2. Create Priorities, organize them with drag and drop and choose a default value
3. After creating the priorities, head to your [Alert sources](https://app.incident.io/~/alerts/sources) to set up the default priority per source.
### Bring your priorities from your alert source i.e. Datadog
1. Go to your [Alert sources](https://app.incident.io/~/alerts/sources/) and choose an alert source
2. Go to Configure tab and scroll down to Priorities
3. Choose to use a variable and Add new Expression
4. Choose query
5. Choose the payload and Parse
6. Write to field `$.metadata.priority` (Example, can be a different payload variable name)
7. Choose Alert priority from the drop-down
8. Choose the default if the query doesn't return the Alert priority
9. Save the setting by clicking 'Add'
10. Save the alert source
You will also be able to see your priorities in Catalog if created or brought through your Alert source.
## 3. Configure notifications for your devices for high and low-urgency
If you want to enable your workflows to use different notifications depending on priority or working hour branches, you can head to your [Preferences](https://app.incident.io/~/user-preferences/on-call-notifications) and choose the notifications you'd like to receive in both cases.
## 4. Create branches based on priority and/or working hours
Now that you have all configurations created, you can start your path with or without conditions. Conditions we offer at the moment are working hours and priority.
You can choose to start from either
You can also configure a branch to take no action, which is useful for intentionally suppressing escalation under certain conditions — for example, silencing low-priority alerts outside working hours.
If you want to use both priority and working hours as rules, you should create three branches, like below. You can choose to start your escalations either with working hours or priorities. The example below will do the next
* 1st branch will send Alerts **within working hours** with **high urgency notifications** to the person on call from the Payments team and wait 10 minutes until escalating to the next level
* Second branch
* **If P1**, will send Alerts **outside of working hours** with **high urgency notifications** to the person on call from the Payments team and wait 5 minutes before escalating to the next level
* **If other than P1**, will send Alerts **outside working hours** with **low urgency notifications** to the person on call from the Payments team and wait until working hours begin for that person to acknowledge, before escalating to the next level
## 5. Choose which levels should send high or low-urgency notifications
Earlier in this article, we showed how every person can set up their preferences on high and low-urgency alerts. To set them up in the Escalation path, just choose either High or Low in every level to choose how you'd want to notify the users.
## 6. Choose to escalate either within a time window or based on your working hours
If you have used Working hours as a condition in your branch, you'll receive a few new options in escalation delays: Working hours begin and working hours end.
This means that people who are on call will receive the notifications at that moment, but we'll wait until that time before we escalate to the next level
***
## Escalate to a channel
Choose when an alert should be escalated to a Slack or Microsoft Teams channel of your choice where anyone can acknowledge and start resolving the alert.
1. Head to Escalation paths
2. Click 'Level' to choose a channel
3. Search for the channel — both public and private channels are supported
4. Save your escalation path
**Example use cases**
* You can send all escalations to a shared Slack channel to let a group of people know that something is wrong, but still escalate to an actual responder at the same time by selecting "Don't wait" as a time to acknowledge option.
* You can set up a branch to deviate low urgency escalations to a Slack channel.
#### Good to know
* If you have an escalation path that first pages a slack channel, then the person being on call in the next level will be shown as 'Level 1' in your On-call status
* If you have an escalation path that first pages someone else, then a slack channel, then you, you'll be shown as 'Level 2' in your On-call status
***
## Page a schedule
When you page a schedule from an escalation level, you can choose who to notify. After first selecting a schedule, the dropdown gives you three schedule-wide options, plus a sub-menu for narrowing the level to a specific rotation:
* **Currently on-call**: page the person on call across the schedule right now
* **Next on-call**: page the next person scheduled to come on call
* **Everyone on schedule**: page everyone on call at the same time
* **For a specific rotation**: narrow any of the above to a single rotation within the schedule
### Currently on-call
The default when you select a schedule. Pages whoever is on call right now, combining all rotations in the schedule.
### Next on-call
Pages whoever is scheduled to come on call next. This is most useful as a fallback level. Pair it with **Currently on-call** on an earlier level so that if the current on-call doesn't acknowledge, the escalation reaches a different person.
**Next on-call** always finds a real person to page:
* **If someone is currently on call**, it pages whoever is due to take over from them, skipping the current on-call user, even if their next shift is back-to-back.
* **If nobody is currently on call** (for example, outside working hours), it pages the next person coming on, even if that isn't until later in the week.
### Everyone on schedule
Page everyone at the same time in a schedule. When choosing this, everyone in the same level will be paged at the same time.
By choosing 'Everyone' it means that we will page everyone in that level. If a person from this level acks, we will not escalate to the next level. By default, we will continue to notify all people in the level until their notification preferences end, though you can configure the path to cancel notifications for others once someone acknowledges. If the level is set to notify more than once, the first acknowledgement also stops any further attempts, for everyone on the level. Read more about notification preferences [here.](/on-call/notifications)
### For a specific rotation
Choosing this opens a sub-menu listing each rotation in the schedule. Pick a rotation, then choose **Currently on-call**, **Next on-call**, or **Everyone** to apply that routing option to just that rotation.
This is most useful when a schedule has multiple rotations (for example L1, L2, L3) and you want different escalation levels to target different rotations.
You can also target all users on a **specific rotation** within a schedule, rather than everyone across all rotations. Use this with round robin or 'all at once' in the same way as schedule-wide paging.
### How to set it up
1. Head to Escalation paths
2. Open a level and choose a schedule
3. Pick a routing option from the dropdown: **Currently on-call**, **Next on-call**, **Everyone on schedule**, or **For a specific rotation**
4. If you picked **For a specific rotation**, choose the rotation, then choose the routing option for that rotation
5. Save the path
#### Good to know
* 'All at once' setting will only page those people in a schedule who are on call
* For cycling through responders within a level, see [Round Robin in Escalation paths](/on-call/round-robin)
***
## Retry a level before moving on
A level notifies its responders once, then moves on to the next level if nobody acknowledges in time. You can instead set a level to notify the same people several times before it moves on, so you give the person on call more than one chance to respond before you widen the page to a bigger group.
Open a level in the escalation path editor and click **Notify once**. Choose **More than once**, then set how often to notify and how many attempts to make. The level then reads, for example, **Notify every 5m, up to 3 times**.
The first notification counts as attempt one, so three attempts means three notifications in total. Each attempt re-runs every responder's notification rules from the start, so a responder who is set up to receive a Slack message and then a phone call gets that whole sequence again on each attempt.
Retries stop as soon as somebody acknowledges. On a level where everyone must acknowledge, the level still waits for the remaining people until it expires, but nobody is notified again.
The level's time to acknowledge still decides when the escalation moves on, and it is measured from when the escalation arrived at the level. Retrying does not extend it. This has two consequences:
* A level can move on before it has made all of its attempts. The editor warns you when this will happen. To fit all of the attempts in, give the level a longer time to acknowledge, or notify less often.
* A level that has used all of its attempts does not move on early. It waits for the rest of its time to acknowledge, then escalates.
* You can make between 2 and 10 attempts.
* The interval between attempts is a whole number of minutes, and at least 1 minute.
* A level that uses [round robin](/on-call/round-robin) cannot retry, because round robin already works through the level's responders on a timer. Choose one or the other for a given level.
* A level that notifies a Slack or Microsoft Teams channel cannot retry.
Each attempt starts your notification rules again from the beginning, so a rule with a delay longer than the interval between attempts only completes on the final attempt. If a level notifies every 5 minutes and your rules call you after 7 minutes, the call only happens on the last attempt. Read more about notification rules [here](/on-call/notifications).
## Retry across the path
A **Retry** node sends an unacknowledged escalation back through the path from an earlier point, so a whole sequence of levels runs again. Add it after your last level, choose which node to restart from, and set how many times to repeat.
This is a different scope to a per-level retry. A per-level retry notifies one level again and never leaves that level. A Retry node runs the path again and re-evaluates the conditions on the way, so a branch on working hours or priority can send the escalation down a different route the second time.
Retries across the path stop when somebody acknowledges, or when the repeats run out.
There is a third kind of retry, which continues to page while the alert is still firing, after an escalation has already been acknowledged. See [Repeating acknowledged escalations](/on-call/repeating-acknowledged-escalations).
***
## Delay escalation
Add a delay node to pause an escalation before it proceeds to the next level. This is useful for alerts that may resolve on their own, or for holding off on paging someone until working hours. Add a delay node in the escalation path editor just like any other step. Choose your delay mode and save the path. When an alert triggers the escalation, it pauses at the delay node for the configured period. If the alert resolves while waiting, the escalation stops entirely.
Delay nodes have two modes:
* **Delay for a fixed duration**: Pause for a set number of minutes (e.g., 5, 10, or 15 minutes) before continuing. If the alert resolves during the delay, nobody gets paged.
* **Delay until working hours**: Hold the escalation until the configured working hours begin, so responders aren't woken up overnight for non-critical alerts.
***
## Restoring a previous version
If you make a change to an escalation path and need to undo it, you can preview and restore previous versions from the escalation path's dropdown menu.
***
## Read more about Escalation paths
[Dynamically setting an escalation path](/alerts/dynamic-escalation)
[Escalating to the right team from an alert](/alerts/team-routing)
[Round Robin in Escalation paths](/on-call/round-robin)
If you have any feedback or feature requests on the feature, please send us a message to [support@incident.io](mailto:support@incident.io) - we'd love to hear from you!
# Escalation status definitions
Source: https://docs.incident.io/on-call/escalation-statuses
## Background
There is a lot of terminology used in the on-call space that can have different meanings depending on the paging provider you use. In this help article we aim to clarify what alerts and escalations, common on-call terms, mean in the world of incident.io On-call.
## Alerts vs. escalations
Most importantly, alerts and escalations are different things! Within incident.io On-call, an alert is an event or issue that can trigger an escalation.
An example scenario:
*An event (alert) fires from Datadog (alert source) and pages (escalation) the person on-call.*
### Alerts
An alert will include details about the event or issue, including:
* Alert source (e.g. Datadog, Sentry)
* Alert attributes (e.g. team, feature)
* Timestamps
* Deduplication keys
* Status (see more details below)
* and more
See an example alert:
An alert can only be one of two different statuses:
* `Firing` - This means there is an event or issue that is currently ongoing and needs to be addressed.
* `Resolved` - This means the event or issue no longer exists, or that the alert has been addressed. An alert can be resolved automatically from the alert source or manually in our dashboard or mobile app.
### Escalations
An escalation will include information about who was paged. An escalation could be created automatically from an alert or from a manual escalation (ie. `/inc escalate` or `/inc page`). Escalation information can include:
* Who was paged / notified
* How users were paged / notified (e.g. email, mobile app, Slack, SMS, WhatsApp, phone)
* Alert source
* Alert route
* Escalation path
* Timestamps
* Statuses (see more details below)
* An escalation can be any of the following statuses:
* `Pending` - This is the state before an escalation has started notifying anyone. You can configure an escalation to wait before paging people
* `Triggered` - This is when an escalation is actively triggered, is actively moving through levels, and is not yet acknowledged
* `Acknowledged` - An escalation has been ack’d by someone on the escalation path. Acknowledged escalations won’t automatically escalate to further levels, but will continue to page any existing users that haven’t yet acknowledged via their chosen contact methods. A level that is set to notify more than once makes no further attempts once anyone has acknowledged. After acknowledging, you can choose to manually escalate to the next level if you need additional help.
* `Resolved` - An escalation that has been acknowledged, and is no longer paging anyone. This occurs when all users have acknowledged, or when a single user has acknowledged, and the escalation time to acknowledge has passed. Note that this state is only available via our API. In the dashboard, `Resolved` escalations are shown as `Acknowledged` for simplicity.
* `Expired` - This means that an escalation has finished running through the entire escalation path, including any per-level retries and any retries across the path, but has gone unacknowledged
* `Cancelled` - If the escalation isn’t actively acknowledged, but some other event means it shouldn’t progress, such as the attached alert being resolved.
* `Snoozed` - An escalation has been temporarily paused by a responder. Notifications stop and the escalation does not advance through further levels until the snooze expires, at which point it returns to `Triggered`. See [Snoozing escalations](/on-call/snoozing-escalations) for more details.
* `Delayed` - The escalation has reached a delay step in the escalation path and is paused, waiting for a configured amount of time (or a working hours window) to pass before it advances to the next level. No one is notified while an escalation is delayed.
* `Pending repeat` - The escalation has terminated while the underlying alert is still firing, and is waiting to repeat from the start of the path. See [Repeating acknowledged escalations](/on-call/repeating-acknowledged-escalations) for more details.
## Important things to note
Two important things to remember with alerts and escalations are:
* You **cannot acknowledge an alert**, only an escalation.
* An **alert can only be resolved**, either manually within incident.io or automatically within the alert source.
## Resolving alerts
To help clarify how alerts work in practice, below are ways that you can resolve an alert within incident.io:
1. **Manually resolving an alert within the dashboard or mobile app** If you go to the Alerts section in the dashboard or mobile app, and go to an individual alert, you can resolve that alert. This can be found in the top right of the alerts detail page, such as:
2. **Manually resolving an alert from Slack or Microsoft Teams** If you send alerts to a Slack or Microsoft Teams channel via an alert route, similar to the dashboard, you can resolve that alert directly from Slack or Microsoft Teams.
3. **Alert resolves itself at the source** This means that the alert coming from an alert source has auto-resolved and we are now reflecting its most common state. Things to note:
* Some sources like Grafana cannot be manually resolved. This is because they send us an event when the issue is resolved, without any intervention required.
4. **Alert is auto-resolved after a timeout** If the alert source has [auto-resolve](/on-call/alert-sources#auto-resolve-alerts) enabled, alerts will automatically resolve after the configured duration. The timer starts from when the alert first fires. This is useful for alert sources that don’t send resolve payloads, such as email sources. If **Skip auto-resolve if alert is attached to an active incident** is enabled, auto-resolve will be deferred until the incident is no longer active.
## Routing alerts
Alert routes let you configure what should happen to escalations (and incidents) they create, if the alert resolves. You can:
* **Auto-cancel escalations if alert is resolved** Within the alert route - you can auto-cancel escalations if the alert is resolved.
* **Auto-decline triage incidents if alert is resolved** This is a feature available on the alert route. If the alert resolves before moving into a ‘true’ incident, we will auto-decline the triage incident.
* **Resolved escalations** This is a *status* for escalations, in addition to: pending, triggered, acknowledged, cancelled, expired or *resolved*. One thing to note is if you page multiple people on a level, the escalation will remain "acknowledged" until everyone on the level responds (either with an acknowledge or nack), which it then changes to “resolved.”
# Escalations with On-call
Source: https://docs.incident.io/on-call/escalations
## What are Escalations?
On-call schedules allow you to have the right people available when incidents happen. [Escalation Paths](/on-call/getting-started) ensure a thorough response plan if a responder can not acknowledge an incident and have the next people on line to be notified about an incident.
## Alert routes and escalation paths
To get your alert sources, routes and escalation paths to connect, we'd recommend doing below as you'll connect the Alert Routes to your escalation paths in the Alert Routes setting.
1. Connect Alert Sources
2. Create Schedules
3. **Create Escalation Paths**
4. Create Alert Routes from the metadata coming from your Alert Source
5. Add which Alert routes you'd like to escalate
Escalation paths will only be triggered when they're connected to an alert source via an alert route, used within a workflow escalation step or selected when manually escalating an incident - you can find more details on this [here](/on-call/getting-started)
## How to set up escalation paths
To start setting up, head to [Escalation Paths](https://app.incident.io/~/on-call/escalation-paths) and create a new one. With a new Escalation path, you will be able to choose between a schedule or a user.
Schedule allows you to escalate to those that are currently on-call within any given schedule.
User allows you to choose specific individuals in your organization that you'd like to escalate to.
## Manually escalating
You can find details on how users can manually escalate in [How do I escalate manually?](/on-call/manual-escalation)
## Who can respond to an escalation
By default, anyone in your organization can acknowledge, snooze, or cancel any escalation. If you'd rather keep that within the team responsible for it (the team that owns the underlying alert, or the escalation path it was sent to), you can set up [team-based permissions](/admin/restrict-escalation-response).
Even with those restrictions in place, anyone who's actually paged by an escalation can always acknowledge or snooze it, so you can never be paged by something you're not allowed to silence. For the full set of rules, see [Alerts and teams](/alerts/team-routing#owning-teams-and-permissions).
# Getting started with On-call
Source: https://docs.incident.io/on-call/getting-started
## On-call Overview
Welcome to **incident.io's On-call** ! On-call is powered by our **Catalog** and consists of three main components:
* **Alerts**: Configure alerts from your observability tools.
* **Escalations**: Route alerts to the appropriate escalation paths, schedules, and team members.
* **Schedules**: Define who is on-call to receive escalations.
Once these are set up, we’ll page the right people so they can acknowledge the alert and jump into resolving the issue. We'll also go through how to manually create incidents in this article.
*Full flow on how alerts and incidents are created and the right people paged*
***
## 1. Setting up your teams
To route your alerts to the right people, you need to configure your teams. You can configure teams right here in incident.io, or bring them in from a 3rd party source, such as Slack, Cortex, Backstage, or your identity provider using SCIM.
1. Head to [Settings → Teams](https://app.incident.io/~/settings/teams)
2. Click 'Get started' to use our **Wizard** to connect your teams from a third-party tool, or create your own.
You can also structure your Catalog using **Services** or any custom type instead of teams. Learn more about Catalog powered On-call [here](/on-call/catalog-integration).
## 2. Building a Schedule
Next, create a schedule for your team. Schedules define when individuals are on-call and can be used in escalation paths.
1. Head to [Schedules](https://app.incident.io/~/on-call/schedules)
2. Create a new schedule or import it from your previous tool
3. Configure your schedule suited for your team:
4. **Handover times** (e.g., every Monday at 9 AM)
5. **Active hours** (e.g., all day or just during business hours)
6. **On-call individuals** (by default we'll add everyone on your team)
7. **Additional rotas**, like
8. **Follow-the-sun** for 24-hour global coverage.
9. **Shadowing for** onboarding new on-call members.
Overrides can be created in the schedule's detail view, from the **Schedules** tab, or by using `/inc cover` in Slack. Learn more about Schedules [here](/on-call/building-schedules).
## 3. Configuring an Escalation path
Escalation paths define who to notify and in what order when alerts occur.
1. Head to [Escalation paths](https://app.incident.io/~/on-call/escalation-paths)
2. Create a new Escalation path and name it
3. Connect your path to the team that should route to it
4. Set up the path with
* **Who to notify at each level** (which can be schedules, individuals or Slack channels).
* **Notification timing** (how long to wait before escalating to the next level)
* **Per-level retries** (how many times to notify a level before moving on)
* **Retries across the path** (how many times to send an unacknowledged escalation back through the path)
Customize escalation paths further with working hours, priorities, or round-robin notifications. Learn more about Escalation paths [here](/on-call/escalation-paths).
## 4. Creating incidents from alerts
Finally, bring in alerts from your observability tools and route them to page your teams and create incidents automatically.
### Connecting your alert source
1. Head to [Alert Configuration](https://app.incident.io/~/alerts/configuration)
2. Choose your alert source
3. If there's no direct integration available for your source, connect via HTTP.
4. Follow the instructions to connect your source, and send your first test alert.
5. Configure your alert attributes and priority using our AI suggestions
* Choose to use **attributes** or **priority** from the alert payload or set them as a **static field**
* Make sure to have an attribute which will tell your alert who it should page. If you page by Team, you can always navigate from a team to its escalation paths. If you page by something else like Service, your alert should be able to resolve to an escalation path via Catalog.
**Attributes** provide extra context to your alerts, like services, affected features, or environments. Learn more about Attributes [here](/alerts/getting-started) and Priorities [here](/on-call/priority-urgency-severity).
### Routing your alerts to start escalating and creating incidents
Now set up your alert routes to escalate and create incidents automatically.
1. Create a new Alert route in [Alert configuration](https://app.incident.io/~/alerts/routes/create)
2. Select the sources you want to include
3. Filter the alerts you want or don't want to trigger incidents
4. Enable Escalations, choosing either
* **Dynamic escalation** paths based on your team or service attribute (recommended), or
* **Static paths** to use the same escalation path for all alerts
5. Enable incident creation
* Automatically create incidents or filter which alerts should trigger them.
* Configure **grouping** so similar alerts are handled together \[ [Learn more](/alerts/grouping-alerts) ]
* You can also choose Mode=Test to create test incidents
No need to create a route for each team! See best practices for alert routing here. Learn more about Alert configuration [here](/alerts/getting-started).
## 5. Creating incidents manually
Alerts might create most of your incidents, but for example, customer-facing teams might need to raise incidents manually. To ensure your customer-facing teams don't need to know the specific teams who own a feature, we'll use the Catalog to escalate to the right team based on the feature. Here's how to help them create incidents and automatically page the right people!
1. Head to the [Catalog](https://app.incident.io/~/catalog) and create a new type like Features.
2. Go to Settings and [Custom fields](https://app.incident.io/~/settings/custom-fields) to create a Custom field ie 'Affected Features'
3. Then go to [Forms](https://app.incident.io/~/settings/forms), 'Declare' and add 'Feature' to the form
4. Then head to Workflows and create a new workflow
* Choose the template 'Escalate via incident.io'
* Edit the step 'Escalate via incident.io and create an expression that navigates from the Feature to the Escalation path
5. Save draft and set live!
Now when someone manually creates an incident, we'll ask what features are affected and then escalate the incident to the right people.
You can also edit the Escalation form that comes when you use the command `/inc escalate`. Find more specific instructions for configuring manual paging [here](/on-call/manual-escalation).
***
## Start testing
Everything’s ready! Send some test alerts to see how your on-call setup works. You can disable escalations or incidents in the alert route during testing if needed.
**Read more about**
[Migrating to incident.io: On-call readiness](/on-call/on-call-readiness-insights)
[Responder set up](/on-call/responder-guide)
When responders are added to a schedule or escalation path, they’ll automatically receive notifications to set up their on-call configuration with sensible default settings.
If you have any questions or concerns about configuring your on-call program, please message us via your Slack Connect channel, or at [help@incident.io](mailto:help@incident.io).
# How do I sync on-call schedules to Google Calendar?
Source: https://docs.incident.io/on-call/google-calendar-sync
## Context
Teams often need to sync their on-call schedules with Google Calendar to improve visibility of upcoming shifts and help team members plan ahead. This can be particularly useful for teams who want to share on-call schedules with their colleagues or maintain better visibility of their upcoming on-call responsibilities.
## Answer
You can sync your on-call schedules to Google Calendar directly from the Schedules page. Here's how:
1. Navigate to your schedules page
2. Look for the "Sync Calendar" option at the top right of the schedule
3. Click on it to configure your calendar sync preferences
Important notes about calendar sync:
* You can choose to sync all shifts in a schedule, not just the ones you're assigned to
* The sync will include shifts for the next 3 months only
* The calendar will automatically update as new shifts are scheduled
* You can sync to either your personal calendar or a shared team calendar
For additional shift notifications, you can configure on-call notification preferences in your user settings for up to 24 hours in advance of your shifts.
# Holidays in On-call schedules
Source: https://docs.incident.io/on-call/holidays
See your team's holidays and time off on your On-call schedule, and arrange cover in advance
Spotting an overlap between someone's time off and their on-call shift early means you can line up cover calmly, rather than scrambling on the day.
## Bring in holidays and PTO
There are a few ways to get holidays and time off into incident.io, and you can mix and match them to suit your team. Calendar feeds work on any plan and cover most systems. Direct HRIS integrations require the Enterprise plan, but always match each entry to the right person and add control over how each time off policy appears.
Subscribe to one or more countries' public holidays, per schedule.
Import your team's personal time-off from any calendar or HRIS that provides an iCal feed.
Connect Workday, HiBob, or BambooHR directly.
## Act on holidays and PTO
Once holidays are flowing in, we'll surface the relevant ones alongside your On-call schedule shifts.
Arrange cover by creating an override, or set up a vacation policy to automatically flag upcoming overlaps.
# Connect BambooHR
Source: https://docs.incident.io/on-call/hris-bamboohr
Bring your team's time-off into On-call schedules from BambooHR
Bring your team's time-off from BambooHR into incident.io, so we can surface holidays alongside your On-call schedule shifts.
## Import via calendar feed
For most teams, a calendar feed is the simplest way to bring in BambooHR time-off:
* Follow the steps in [this help article](https://help.bamboohr.com/s/article/587318) to get a calendar feed URL
* Follow the steps in [Import holidays with calendar feeds](/on-call/calendar-feeds#add-a-calendar-feed) to use this calendar feed in incident.io
## Connect BambooHR directly
Direct HRIS integrations are available on the [Enterprise plan](https://incident.io/pricing), and you'll need the
**Manage organisation settings** permission to install one.
There are two ways to connect BambooHR directly. **OAuth** is the quickest for most teams and connects by redirecting you to log in with BambooHR. Or you can use an **API key** which you generate in BambooHR before entering into the connect flow.
Both methods connect using a specific BambooHR user's access, so make sure that user has **Full Admin** access, or a custom access level with access to the user and time off information incident.io needs.
1. First, head to [Settings → Integrations → BambooHR](https://app.incident.io/~/settings/integrations/bamboohr) within the incident.io dashboard
2. Enter your BambooHR **subdomain** (the part before `.bamboohr.com` in your BambooHR URL)
3. You'll be redirected to BambooHR. Log in with your BambooHR account credentials to authorize the connection.
4. Once you're redirected back, your account is linked.
1. First, head to [Settings → Integrations → BambooHR](https://app.incident.io/~/settings/integrations/bamboohr) within the incident.io dashboard
2. Enter your BambooHR **subdomain** (the part before `.bamboohr.com` in your BambooHR URL, for example `acme`)
3. In BambooHR, click your **profile avatar** in the bottom left corner and select **API Keys**
4. Click **Add New Key**, enter an **API Key Name**, then click **Generate Key**
5. Copy the generated key and paste it into the incident.io connection flow to finish linking
The key inherits the access of the user who created it, and stops working if that user loses access or is deactivated. Generate it from a user (or a dedicated service account) with stable, appropriate access.
# Connect HiBob
Source: https://docs.incident.io/on-call/hris-hibob
Bring your team's time-off into On-call schedules from HiBob
Bring your team's time-off from HiBob into incident.io, so we can surface holidays alongside your On-call schedule shifts.
## Import via calendar feed
For most teams, a calendar feed is the simplest way to bring in HiBob time-off:
* From the sidebar menu, [head to the people's time off view](https://app.hibob.com/time-off/peoples-time-off/calendar)
* In the top right, click Filters and select which parts of your organization or which people whose holidays you want to subscribe to
* If you care about everyone, add "None", otherwise HiBob just generates a feed of company events without people's names
* On the top right, click "Sync with external calendar", pick "Filtered view" and copy the URL
* Follow the steps in [Import holidays with calendar feeds](/on-call/calendar-feeds#add-a-calendar-feed) to use this calendar feed in incident.io
## Connect HiBob directly
Direct HRIS integrations are available on the [Enterprise plan](https://incident.io/pricing), and you'll need the
**Manage organisation settings** permission to install one.
To connect HiBob, you'll create a service user in HiBob, give it a permission group, and paste its credentials into incident.io. Keep both HiBob and incident.io open as you work through the steps below.
### 1. Start the connection in incident.io
First, head to [Settings → Integrations → HiBob](https://app.incident.io/~/settings/integrations/hibob) within the incident.io dashboard and click **Connect** to start. The connection flow will ask for a service user ID and token, which you'll create in the next steps.
### 2. Create a service user in HiBob
1. In HiBob, head to **System Settings**
2. Within **Integrations**, select **Service users**
3. Click **Create service user**
4. Enter a **Display name** and click **Create**
5. Copy the **ID** and **Token** shown on the confirmation screen and keep them somewhere safe. You'll need them to finish linking, and the token won't be shown again.
6. Click **Go to permission groups**
### 3. Create a permission group
1. Click **Create permission group**, then select **Service user**
2. Enter a **Group name** and select the service user you just created under **Select service users**
3. Click **Create** and confirm the changes
4. Open the **People's data** tab and click **Access data for**
5. Click **Edit permissions** and choose **Select people by condition**
6. In the pop-up, select the relevant **Lifecycle statuses** (typically **Hired**, **Employed**, and **Terminated**) and click **Apply**
7. Grant the group the following permissions, then click **Save** and **Apply**:
* **People > Basic info**
* **People data > Employment**
* **People data > Lifecycle**
* **Time off > Balance**
* **Time off > See who's out today**
### 4. Finish linking in incident.io
Back in incident.io, enter the service user **ID** and **Token** from step 2 to finish linking your account.
# Connect Workday
Source: https://docs.incident.io/on-call/hris-workday
Bring your team's time-off into On-call schedules from Workday
Bring your team's time-off from Workday into incident.io, so we can surface holidays alongside your On-call schedule shifts.
## Connect Workday directly
Direct HRIS integrations are available on the [Enterprise plan](https://incident.io/pricing), and you'll need the
**Manage organisation settings** permission to install one.
Connecting Workday takes a few steps in Workday itself, so you'll need **administrator** permissions there. You'll gather a handful of details along the way and paste them into incident.io: your web services endpoint, tenant name, client ID and secret, token endpoint, and a refresh token. Keep both Workday and incident.io open as you work through the steps below.
### 1. Start the connection in incident.io
First, head to [Settings → Integrations → Workday](https://app.incident.io/~/settings/integrations/workday) within the incident.io dashboard to begin the OAuth flow. It'll prompt you for each value below in turn.
### 2. Find your web services endpoint
1. In Workday, search for **Public Web Services**
2. Find **Human Resources (Public)**, open its three-dot menu and choose **Web Services > View WSDL**
3. Scroll to the bottom of the page (it can take a few seconds to load) and copy the URL prefix under **Human\_ResourcesService** (it looks like `https://wd2-impl-services1.workday.com/ccx`)
4. Enter this as the **Web Services Endpoint URL prefix** in incident.io, then continue
### 3. Enter your tenant name
1. Your tenant name is part of that web services URL (for example `acme`)
2. Enter the tenant name in incident.io, then continue
### 4. Register an API client
1. In Workday, search for the task **Register API Client for Integrations**
2. Enter a **Client Name**
3. Under **Scope (Functional Areas)**, select **Staffing**, **Time Off and Leave**, **Tenant Non-Configurable**, **Public Data**, and **Contact Information**
4. Check both **Non-Expiring Refresh Tokens** and **Include Workday Owned Scope**, then click **OK**
5. Copy the generated **Client ID** and **Client Secret**, then click **Done**
6. Enter the Client ID and Client Secret in incident.io, then continue
### 5. Generate a refresh token
1. In Workday, search for **View API Client** and open the **API Clients for Integrations** tab
2. Copy your **Token Endpoint**
3. Open the API client you created in step 4, then use its three-dot menu to choose **API Client > Manage Refresh Tokens for Integrations**
4. Add a Workday user in the **Workday Account** field and copy the generated **Refresh Token**
5. Enter the Token Endpoint and Refresh Token in incident.io, then submit to finish linking
# Importing schedules and escalation policies from PagerDuty and OpsGenie
Source: https://docs.incident.io/on-call/import-pagerduty
If you're looking to migrate from PagerDuty to incident.io On-call you can make use of the escalation policy import feature (accessible via the [Escalation paths page](https://app.incident.io/~/on-call/escalation-paths) ) to quickly and easily import your PagerDuty escalation policies, schedules and users.
***
To use the feature, you'll need access to incident.io On-call and a PagerDuty integration. See [here](/integrations/pagerduty) for details on our PagerDuty integration and how you can connect it to your incident.io account. As part of the integration process, we'll do what we can to link users in PagerDuty to users in the incident.io app. Learn more about this process [here](/catalog/connected-users).
Once your PagerDuty integration is connected and your PagerDuty users have been added to the incident.io catalog, you can start importing escalation policies and schedules from PagerDuty.
If you're an OpsGenie user, we also support importing schedules and escalation policies from OpsGenie, so if you have overrides on your schedules in Opsgenie, now when you import those schedules (or escalation paths/policies that reference those schedules) we'll now automatically import any overrides on that schedule too.
Current API limitations mean that we'll sync your schedules and escalation policies from an external provider once a day (at around 1000UTC). This means that any changes you make to external escalation policies and schedules won't be visible to incident.io until 1000UTC the following day.
You can import schedules or escalation policies via the *Escalation paths* and *Schedules* tabs in the *On-call* section of the dashboard. We'd recommend that you start with escalation policies, as importing an escalation policy will also import all of its referenced schedules and reference them in the created escalation policy.
When you import from PagerDuty, we'll replicate the behavior of your existing escalation policies and schedules but won't connect them to alert sources or routes. This lets you verify and experiment with your configuration without paging any users.
***
Opening the import escalation policies drawer will list your PagerDuty escalation policies and the state that they're in. Select any that you'd like to import from the *Ready to import* list and they'll be imported, along with any schedules that they reference
Some schedules and escalation policies can't be imported and will appear in the *Incompatible* tab. A common cause of this is when we're unable to identify all of the users on the escalation path (or schedules) as users in incident.io. This [document](/catalog/connected-users) contains information about connecting external users to incident.io.
Some schedules and escalation policies aren't feature-compatible with incident.io On-call. This means that we're unable to replicate exactly the features that your escalation policy or schedule makes use of. We're always making improvements to our support for On-call features, so get in touch if you need a feature that we don't support.
***
### Skipping onboarding notifications during import
When you import schedules or escalation paths, any users going on-call for the first time will normally receive an onboarding notification (via email, Slack, and push notification) letting them know they've been added to on-call and prompting them to set up their contact methods and notification preferences.
If you'd prefer not to send these notifications during import, you can turn them off. When confirming the import and promoting users to on-call responders, you'll see a **Send onboarding email notifications** toggle. Turn this off to skip sending the onboarding notification.
Even when notifications are skipped, users are still marked as onboarded internally — so they won't receive duplicate
notifications if you import additional schedules later. Users will still receive the standard "You are currently on
call" notification at the start of their first on-call shift, whenever that may first happen.
This option is not available for SCIM customers, as users need to be imported manually before they can be added to
schedules.
Once imported, you can view and edit the created escalation policy (and schedules) through the On-call dashboard. When you're happy with the results, you can create alert sources and routes to send alerts to your escalation policy to create escalations and begin paging users.
Importing schedules and escalation policies is a one-time operation. Once they've been imported, we won't continue to sync them with PagerDuty. If you'd like to update a schedule or escalation policy with changes from PagerDuty, you can delete the existing schedule or escalation policy in incident.io and re-import it.
# Importing and duplicating schedules
Source: https://docs.incident.io/on-call/importing-schedules
When it comes to on-call, being consistent with schedules is important with any team. We do recommend building schedules in incident.io from scratch, but if you have tens of schedules for your teams you can either duplicate or we'll guide you to migrate your current schedules to incident.io.
## Duplicating schedules
To duplicate schedules, just head to your [Schedules](https://app.incident.io/~/on-call/schedules), click the menu on the right side and find the 'Duplicate' -button in the menu.
## Importing schedules
At the moment we help you to bring schedules over from PagerDuty and OpsGenie.
1. Head to your Schedules and choose 'Import schedules' from the top right.
2. See all your schedules that are available for importing and choose a schedule from the list
3. After choosing schedule we will open it up in our editor where you can review the schedule and then save it
When importing schedules, you can choose whether to send "first time on-call" emails to the users being added. Disable
this to avoid a flood of emails during bulk migrations.
If you are getting an error, it might be due to some users not existing at incident.io - Please review the error message and if there are still challenges, please contact us via [support@incident.io](mailto:support@incident.io)
**Looking for an integration to bring over your schedules that isn't there?** We're constantly building new integrations and helping customers to get their schedules over. If there's something you'd like to see, please send a message to [support@incident.io](mailto:support@incident.io) !
# Setting up notifications on iOS
Source: https://docs.incident.io/on-call/ios-notifications
**Download our mobile app**
If you'd like the best possible experience as a responder, download our mobile app [here](https://apps.apple.com/us/app/incident-io/id6471268530).
For responders in Mainland China, see [Mobile app in China](/on-call/china-mobile-app) — Critical Alerts aren't
available in the 事件incidentio app, so push notifications can't bypass silent mode.
When you are paged, we'll try and contact you according to your [notification rules](https://app.incident.io/~/user-preferences/on-call-notifications).
By default, assuming you've enabled them, this will include:
* Push notification
* Phone call
* SMS
* Email
* Slack direct message
* WhatsApp message
For push notifications, phone calls, and SMS messages, there are steps you can take to ensure you get notified, regardless of what your phone's silent mode and do-not-disturb settings are set up like.
***
## Phone calls + SMS
To receive phone calls and SMS that bypass silent mode and Do Not Disturb, you'll need to save the incident.io contact and enable Emergency Bypass.
1. Add the incident.io contact card to your phone's contacts
* Open the **incident.io** app, go to **Settings** → **Contacts**, and enable the **incident.io contact** toggle to keep the contact automatically updated
2. Open the **Contacts** app and tap **Lists** in the top-left corner
3. Select **All Contacts** — do not use the "incident.io" section (see note below)
4. Find and open the **incident.io On-call** contact
5. Tap **Edit**, then tap **Ringtone**
6. Enable **Emergency Bypass** so calls ring even when your phone is silenced
7. Repeat for **Text Tone** if you want SMS alerts to bypass silent mode
8. Tap **Done** to save
**Note for iOS 18+ users:** You may see an "incident.io" section in your Contacts app. There's a known Apple bug
where editing contacts from this section causes the screen to become stuck. Always edit from "All Contacts" instead.
We've reported this to Apple.
**Testing:** Send yourself a test page from your incident.io dashboard while your device is locked and silenced to confirm calls come through.
In some iOS versions the automatic contact can't be edited, which means you may not set up DND bypass, so to work around this, we can create an editable version.
You can enable this by going to Setting → Contacts → Can't set up Do Not Disturb bypass
### Call screening
iOS can screen calls from unknown numbers before they reach you, using features like [Screen Unknown Callers and Silence Unknown Callers](https://support.apple.com/en-gb/guide/iphone/iphe4b3f7823/ios). When these are on, an on-call phone call from an unknown number may be intercepted, sent to voicemail, or answered by an automated screening assistant instead of ringing your phone.
This causes two problems for on-call:
* You might miss the call entirely, because it never rings through to you.
* The screening assistant can interact with our call and register a keypress, which we may record as you acknowledging the escalation even though you never picked up.
We can't change how iOS call screening answers calls. The fix is to make sure our number counts as a known contact so screening lets it straight through:
1. Save the incident.io contact card and enable **Emergency Bypass**, following the steps above.
2. Confirm the incident.io On-call number is saved in your **Contacts**. Screening applies to unknown numbers, so a saved contact won't be screened.
3. Send yourself a test page while your device is locked to confirm the call rings through as expected.
If you rely on iOS call screening, you must have the incident.io contact card saved. Without it, screening can silence
our calls or auto-answer them, and an auto-answered call can be misrecorded as an acknowledgement.
## Push notifications
iOS has a concept of `Critical notifications`, which are push notifications that'll make a noise, regardless of whether your phone is on silent, or if you are in sleep/do-not-disturb. The incident.io app supports these natively so as long as you agreed to these notifications during set up of the app, you'll receive them. If you did not agree to them, you'll see a warning on the home screen of the app.
To enable these notifications, open the `Settings` app on your phone, scroll down to incident.io, select `Notifications` and then enable critical notifications.
Please note that the following settings in iOS could interfere with push notifications:
**[Announcing notifications](https://support.apple.com/en-gb/guide/airpods/dev8c670727e/web):** if you have toggled
"Announce notifications" in your incident.io app settings, sounds might go through connected AirPods or other devices
when your device is locked.
**Screen Time:** if you have a time limit set on your device, iOS might not deliver notifications correctly. Consider
adding the incident.io app to your list of "Always on" apps.
**Apple Watch**
If you have an Apple Watch paired with your iPhone, notifications are delivered to your watch by default when it's on your wrist and your iPhone is locked. This means your iPhone won't make a sound — the notification goes to your watch instead.
If you'd prefer to always receive incident.io notifications on your iPhone, open the **Watch** app on your iPhone, tap **Notifications**, find **incident.io** in the list, and select **Off**. This will stop notifications from being mirrored to your watch, so they'll always play on your phone.
Connected **headphones or earbuds** (such as AirPods or other Bluetooth audio devices) can also affect where notification sounds are routed. If you have "Announce Notifications" enabled, sounds may play through your AirPods instead of your phone's speaker when your device is locked.
**Custom notification sounds**
For push notifications, you can pick a custom notification sound from Notifications > **Notification sounds**. If you want the notification to make a sound for a long time, we have notification sounds ranging from 1 second to 2 minutes long.
**Contact card**
If you're unable to provide contacts permission, you can still manually download our contact card [here](https://app.incident.io/api/mobile/responder_vcard) - however you'll need to periodically update it yourself as we may add phone numbers from time to time.
## WhatsApp
You can receive escalations as WhatsApp messages, and acknowledge or mark yourself as not available straight from the buttons in the message. We support WhatsApp messages only, not calls.
To make sure your pages come through, allow the WhatsApp app to override Do Not Disturb: head to **Settings → Focus → Do Not Disturb**, tap **Apps** under **Allowed Notifications**, and add **WhatsApp**.
# Can I sync or link multiple on-call schedules together?
Source: https://docs.incident.io/on-call/link-schedules
## Context
Organizations often need to coordinate multiple on-call schedules, such as having primary and secondary on-call rotations, or syncing schedules between different teams. Common scenarios include:
* Having primary and secondary on-call rotations with the same team members
* Coordinating schedules between related teams (e.g., Engineering and DevOps)
* Ensuring the same person isn't scheduled for multiple rotations simultaneously
## Answer
Currently, schedules operate independently and cannot be automatically linked or synced with each other. Each schedule needs to be managed separately.
Here are the available options for managing multiple schedules:
1. **Manual Schedule Management** : Create and maintain separate schedules, being mindful to manually check for conflicts when making changes or adding overrides.
2. **API Integration** : Use the [Schedules API](https://docs.incident.io/api-reference/schedules-v2/) to:
* Monitor for scheduling conflicts
* Create automated checks for overlapping assignments
* Build custom logic for schedule coordination
3. **Escalation Paths** : For primary/secondary coverage, use escalation paths with different schedules.
**Note:** The platform is working on enhanced team-first approaches to on-call configurations which may provide better schedule coordination capabilities in future updates.
# Live call routing
Source: https://docs.incident.io/on-call/live-call-routing
Live call routing lets you set up a phone number that can be used to get hold of someone on-call.
Live call routing isn't available for numbers in Mainland China — none of our providers operate there for this. See
[On-call in China](/on-call/china-on-call) for what's supported.
## Request a number
To get started, go to Settings → Call routes, click ' **Request number** '.
Set a name for the number for your internal use - e.g. "Urgent support" or "Regulatory line". Select the country code, phone number type and let us know any other requirements for the number, for example an area code.
Depending on the type of phone number you've requested, you might have to enter additional information so we can provision your number. The form will take you through the required steps.
Once you've requested a number and your information has been reviewed, we'll get to work setting your number up. We'll be in touch within a couple of days about any specific requests.
## Configure who to call
Calls to your phone number can be routed to the people currently on-call for a schedule, everyone on a schedule, specific individuals, or a mix of all three.
On each level, we'll try calling each person for 30 seconds. If they don't pick up, we'll try the next person. Once we've tried everyone on level 1, we'll try the next level, until we run out of options — at which point we end the call, or send the caller to [voicemail](#send-calls-to-voicemail) if you've added one.
## Configuring the call experience
You can also customize your call route:
* **Restrict who can call**: choose **Only specific phone numbers can call this number** to limit calls to an allowlist.
* **Set the voice language** we use for spoken prompts and greetings. If you'd like a language that isn't listed, please get in touch.
To make callers press a key before we connect them — for example, to filter out spam or accidental calls — add a [phone tree](#route-callers-with-a-phone-tree) with a single option, such as "For support, press 1".
## Route callers with a phone tree
Instead of sending every caller to the same people, present a phone tree (also known as an IVR menu) so callers can choose where their call goes — for example, "For urgent support, press 1. For billing, press 2." A single number can then reach several teams, so you don't need a separate number for each one. A phone tree with a single option also works as a simple "press 1 to connect" step, which helps filter out spam and accidental calls.
To build a phone tree, edit a call route and turn on **Use a phone tree (IVR)**. Add an option for each choice a caller can make:
* **Keypad digit**: the number a caller presses to choose this option (1–9).
* **Menu prompt**: what we read out for this option (e.g., "For billing, press 2"). We speak this in the route's voice language, exactly as written.
* **Routing**: who this option calls. Each option has its own routing, using the same [routing options](#configure-who-to-call) as a call route without a menu, and can end in [voicemail](#send-calls-to-voicemail).
You can add up to nine options. If a caller doesn't press a valid option, we repeat the menu a few times and then end the call. The option a caller selected is shown on the alert we raise, so responders know why they're being called.
## Send calls to voicemail
Call routes can send an incoming call to voicemail — either when none of your responders are available to answer, or by routing the call straight to voicemail without paging anyone.
To add voicemail, edit a call route's routing and choose **Send to voicemail** at the end of a path. Set a **Greeting**, which we read to the caller before recording their message. As with menu prompts, we read the greeting in the route's voice language, exactly as written.
Some regions require callers to be told they're being recorded. Include this in your greeting if it applies to you.
Once the caller hangs up, we attach a recording of the voicemail to the call and to the alert it produces, and add a transcript a few minutes later. You can play the recording back from the alert in the dashboard.
How voicemail affects the alert depends on how the call reached it:
* **Routed straight to voicemail**: we don't fire an alert until the call ends, so you're only paged once there's a message to listen to.
* **Fell through to voicemail after no one answered**: the alert fires when the call comes in, as usual.
Either way, alerts for calls that went to voicemail don't auto-resolve — someone needs to listen to the message and follow up. Calls answered by a person resolve automatically when the call ends.
## Creating an incident
Once you've requested your first live call routing number, a new 'Incoming calls' alert source will appear under **Alerts → Configuration**. You can use this to declare an incident whenever a call comes in. Anyone we route the call to will automatically be invited to the incident channel.
[Learn more about configuring alerts](/alerts/getting-started)
**Note**: Incoming call alerts resolve when the call ends, unless the caller [left a voicemail](#send-calls-to-voicemail) — those stay open so someone can follow up. We recommend disabling ' **Decline triage incidents if the linked alerts are resolved** ' for alert routes using this source.
## FAQs
Your customer only sees the phone number we purchase on your behalf. If you have specific requirements for this number (e.g. a specific country or area code, a toll-free number), please let us know when requesting a number.
Calls routed to responders will come from your live call routing number. We recommend [adding this number to your phone's do-not-disturb bypass](/on-call/mobile-notifications) settings.
Please see our [Pricing](https://incident.io/pricing) page for details on how many numbers are included on each of our plans. Anyone on a call route needs an On-call seat. Please get in touch with your customer success manager if you require more numbers.
All the countries we support are listed within the form. Some countries have regulatory requirements that your business will need to meet for us to be able to provision a number. If you've got a request for another type of number, please select "Other" for the country, write in your request details, and we'll be in touch!
We read them in the call route's voice language, exactly as you write them — they aren't translated. Set the language when configuring the call route.
Up to five minutes. If a caller is still talking after that, we stop recording and process what we have.
It's not currently possible to manage call routes via the API. Call routes usually require us to collect some regulatory information to be set up, which doesn't map well to an API.
If you'd be interested to create 'skeletons' of call routes from the API, delete them from the API, or update them from the API once they've been set up, do [contact support](mailto:support@incident.io) to let us know!
# How do I escalate manually?
Source: https://docs.incident.io/on-call/manual-escalation
Sometimes there are situations in which you need to notify your on-call responders without a corresponding alert - imagine the case where you've discovered a critical issue and it hasn't triggered your alerts but you want to make sure the team are notified. In these cases, you can trigger a *manual escalation* which behaves just like an escalation triggered by an alert.
You can page someone either as part of an incident, or before declaring an incident. Both of which can be done in Slack (by typing `/inc page`), in the mobile app and in the web dashboard. The escalation form supports a unified search mode where you can search across escalation paths, users, and catalog types in a single field — you can enable this in your escalation form settings.
To escalate via the web dashboard without an incident, look for the "Declare incident" button and use the dropdown on its side to open the "Escalate to someone" page.
To escalate via the web dashboard within an incident, open the overflow menu with the 3 dots at the top right and choose "Escalate to someone".
From there you can manually escalate the incident to any of your configured escalators. This will start the notification process and associate the escalation with the relevant incident.
To make the most of on-call, we'd recommend that you aim to configure your alert sources and routing to escalate automatically in as many situations as possible.
If we don't have an integration for a tool that you use, you can try using our [HTTP webhooks](/on-call/getting-started) and if that doesn't work for your use case, get in touch via your Slack Connect channel, or at [help@incident.io](mailto:help@incident.io) and we'll see what we can do.
## How to customize the escalate form
When someone escalates (e.g. using `/inc escalate`, or clicking on an `Escalate to someone` quick action), what they're presented with depends on what escalators you have installed.
If you have multiple escalators installed (e.g. you've connected PagerDuty **and** you're using incident.io On-call) then by default someone will be asked which escalator to use when they're escalating.
However, you can customize this in a number of ways...
### Customize which escalator to use
If you'd like to always go to a particular incident.io, PagerDuty, Opsgenie or Splunk On-call escalation form, you can do this by going to the incident.io dashboard, then choosing `Settings → Forms → Escalate` and choosing one of those.
### Escalating to users
If you choose to escalate `Dynamically using Catalog` and you have multiple providers available to escalate with (e.g. incident.io, PagerDuty, Opsgenie), then users will be searchable across those providers.
By default, if a user has an incident.io on-call seat, they'll be paged using incident.io. However, they can customize this in their preferences or by pressing the edit icon beside the **User** input.
When you open this edit drawer, you can see all the users across both providers, and where it's possible, you can change the preferred provider for users in your organization.
If a user has an account in external provider (e.g. PagerDuty) and doesn't have a related incident.io account, then they'll only be pageable via that external provider.
If a user is showing up twice, it might be that their email in the external provider does not match their email in incident.io. You can manually link the accounts in Catalog by finding the user under the "Users" catalog type and then choosing their account in the external provider.
### Escalating using a Catalog type
By default, you can escalate by letting users choose from a person or an escalation path that they'd like to page. However, if you're a person escalating, you might not always know who to escalate to, or which escalation path to use.
For example, you might work in customer support and you spot an issue with Login. You might not know which team is responsible for Login, so you don't know who to escalate to.
You can customize the Escalate form so that you can search for any Catalog type, and so long as you tell us how that Catalog type relates to an Escalation Path, we'll escalate to the appropriate people. For example:
* You could let people search for `Features`. Then your `Features` type has a related `Team`, which has an `Escalation path`, so we'll automatically escalate to the team that own that feature.
* You could let people search for `Services`, which have an associated `Team`, which has an `Escalation path`, so we'll automatically escalate to the team responsible for that service.
To set this up, go to `Settings → Forms → Escalate` and scroll down to `Add another field`. Here you can choose which Catalog type you'd like to let people search for.
Once you've chosen a Catalog type, you'll need to tell us how to map from this type to a related escalation path.
### What if I'm in the middle of migrating to incident.io?
If you're in the middle of migrating, or you're testing out incident.io on-call, you can default to escalating via incident.io, but still escalate to other providers for certain teams.
To get started with this, you need to set up a Catalog type that people can search for. This is most often a `Team` type.
You'll then want to give your `Team` type some attributes such as:
* Escalation path - so you can tell us how to escalate using incident.io
* PagerDuty service - if you're using PagerDuty, so you can tell us which teams should still be contacted using PagerDuty
* Opsgenie team - if you're using Opsgenie, so you can tell us which teams should still be contacted using Opsgenie
Once you've set up your Catalog type, update each of its entries to have appropriate values for each of those attributes.
For example, in the screenshot below the `On-call` team can be escalated to using incident.io via the `ONC` escalation path. And the `Infrastructure` team can be escalated to using PagerDuty for the `Database` service.
Once you've set up the Catalog type, you need to plug that into your escalation form. Go to `Settings → Forms → Escalate` and choose `Add another field`. Pick your Catalog type and then tell us how to map from that Catalog type to an escalation path.
Then press `Escalate to another service` and tell us to map from that type to either a PagerDuty Service or an Opsgenie Team.
Once that's done, choose `incident.io` as the place to 'send manual escalations to', as otherwise we'll still ask users which escalator to use each time they escalate. When `incident.io` is selected, if you've defined other escalators using Catalog, we'll still escalate using those other escalators, not just incident.io.
# Creating incidents manually
Source: https://docs.incident.io/on-call/manual-incidents
When something goes wrong, it's crucial to involve the right people immediately. Escalation can be triggered automatically by your alert source or manually by paging the responsible team.
In this article, we'll go through how you can escalate to the right teams and declare incidents manually by using Catalog, Custom fields and Workflows.
## Creating incidents manually
To create incidents your team can use the [Web Dashboard](https://app.incident.io/~/dashboard) or `/inc` command in Slack or MS Teams.
Next, they'll see a modal in either Slack or the Web Dashboard, where they can add more details about the incident. Thanks to our Catalog configuration, the appropriate contact is identified automatically through the Feature → Team → Escalation Path connection.
In the below form we have used 'Affected feature' that has been connected to a team, and then to an escalation path so by choosing the Feature we know who we should page! Below we'll go through how to configure the below form and enable the workflow to automate paging the right teams when someone manually creates an incident.
For both incident declaration and escalation forms, you can configure fields with information essential for responders, guiding the person escalating on whom to page. Options include selecting by feature, team, or even a service.
## How to set up manual incident creation
While alerts may generate most incidents, customer-facing teams may occasionally need to raise incidents manually. To make this easier, use the Catalog to escalate incidents to the appropriate team based on the feature—no need for customer-facing teams to know exactly who owns what.
Here's how to help your teams to create incidents and to page the right people
1. Head to the [Catalog](https://app.incident.io/~/catalog) and create a new type like Features.
* Ensure that the Features are connected to teams
2. Go to Settings and [Custom fields](https://app.incident.io/~/settings/custom-fields)
* Create a new Standard custom field for Features
3. Then go to [Forms](https://app.incident.io/~/settings/forms) and go to 'Declare'
* Add 'another field' and choose 'Feature'
4. Then head to Workflows and create a new workflow
* Choose the template 'Escalate via incident.io'
* Ensure that Status for incident is either Triage or Active
* Edit the step 'Escalate via incident.io and create an expression that navigates from the Feature to the Escalation path
5. Save draft and set live!
Now when someone manually creates an incident, we'll ask what features are affected and then escalate the incident to the right people.
## Escalations
You are also able to escalate incidents further or just escalate before creating incidents.
To page, team members can go to [Escalations](https://app.incident.io/~/on-call/escalations) in our Web Dashboard or use the `/inc escalate` command in Slack or Microsoft Teams.
After initiating, they'll see a modal in either Slack or the Web Dashboard where they can select the appropriate feature. Thanks to our Catalog configuration, we know exactly whom to page by linking Feature → Team → Escalation Path.
To set up the 'Escalate' -form, just follow the same steps as we did in the 'Declare' -form [above](#how-to-set-up-manual-incident-creation)
## Creating incidents with a third-party paging tool
If you're still using a third-party paging tool, like PagerDuty or Opsgenie, you can send alerts to us through those tools or directly from your observability tools. Sending alerts directly from the source allows for smarter grouping by Service and time period, especially when using the Catalog.
#### Creating incidents
Incident creation through a third-party paging tool works similarly, though escalation configurations aren't available on our side.
* You can create incidents from Alerts with a third-party paging tool. Read more about automatically creating incidents [here](/alerts/getting-started)
* Creating incidents manually with `/inc` command
#### Escalating incidents
You can escalate incidents via a 3rd party tool - the set up is exactly the same as the rest of the article, but the workflow will need to include
* Step - 'Escalate via third party', instead of incident.io
If you want to do smart escalations, you'll have to map your Features to Teams, AND Teams to PD/OpsGenie Esc Paths in the Catalog
Using both our On-call and Response product can create a lot of benefits like unified data flow, continuous feedback on your alerts and so, better noise management all under in a single pane of glass. Learn more about our On-call [here](https://incident.io/on-call).
# Mirroring schedules to PagerDuty
Source: https://docs.incident.io/on-call/mirroring-schedules-to-pagerduty
### What is mirroring?
When migrating to incident.io on-call, you can [import](/on-call/importing-schedules) schedules and escalation policies from PagerDuty and Opsgenie to speed up your onboarding.
In some cases though, you might be in the process of moving your alert configuration over to incident.io, and you still need to page via PagerDuty, which means you still need to keep your PagerDuty schedule up to date.
To help with this, you can enable schedule mirroring in incident.io, which lets you manage a schedule and its overrides in incident.io, and have the changes be automatically reflected in one or more PagerDuty schedules.
***
### Does this affect how I'm paged in PagerDuty?
Mirroring is solely related to managing your PagerDuty schedule and mirroring alone will not change the way you get paged.
It works by looking at your incident.io schedule whenever anything changes (e.g., you add or delete an override) and then comparing that with your PagerDuty schedule over the next two weeks. If it sees a difference in the two, it'll create the relevant overrides in PagerDuty to keep that schedule up to date. That means, if someone were to make edits in PagerDuty, they'd be overwritten the next time anything changes on the incident.io schedule.
***
### Set up
To set up schedule mirroring, open your schedule in incident.io, click on the three dots in the top right corner, and choose "Mirror in PagerDuty".
Click on "Yes" to enable mirroring and then choose which schedules in PagerDuty you'd like to mirror into.
### Other details
As PagerDuty does not support having multiple users on-call simultaneously, nor does it allow for placeholder shifts (where no one is on call), there are some important considerations:
**Fallback User**
You must designate a "fallback" user to be used by mirroring when there are gaps in your incident.io schedule or if you manually override to no user assigned to a shift. If gaps are not anticipated, you can select any user as the fallback. However, in cases where gaps might occur, it is common to create a "bot" user in PagerDuty to serve as a fallback user.
**Schedules with Many Rotations/Layers**
If your incident.io schedule involves multiple layers or overlapping rotations that point to the same PagerDuty schedule, incident.io will assign the first user listed in PagerDuty, as only one person can be on-call per schedule in PagerDuty.
To address these limitations, organizations often create multiple PagerDuty schedules — one for primary rotation and another for "shadow" users. To accommodate this, incident.io allows a single schedule to map to multiple PagerDuty schedules. Simply select "Many Schedules" as your destination and configure the appropriate rotas for each PagerDuty schedule.
**Users Without Linked PagerDuty Accounts**
When installing the PagerDuty integration with incident.io, users from PagerDuty are automatically added to the Catalog, and accounts sharing the same email address in both platforms are linked. However, mismatches may occur due to different email addresses or missing user accounts in incident.io. If a mismatch exists during mirroring setup, a warning banner will notify you about unlinked users. To resolve this, create the user in PagerDuty if they do not exist, and explicitly link the relevant PagerDuty user in the Catalog. For further assistance, refer to the [documentation](/catalog/connected-users).
**Sync Period**
incident.io syncs schedules only up to the next two weeks. This design limits API requests, as schedules are continuously updated in PagerDuty when changes occur in incident.io. Since PagerDuty rate limits apply per API key, this approach minimizes resource usage.
### Mirroring via the API
You can also manage schedule mirroring programmatically using the [Schedule Replicas API](/api-reference/schedule-replicas-v2/).
In the API, mirrors are called "schedule replicas". A replica links an incident.io schedule (or specific rotations/layers within it) to an external schedule in PagerDuty or Opsgenie.
#### Creating a replica
To mirror a schedule, send a `POST` request to create a replica:
```bash theme={null}
curl -X POST "https://api.incident.io/v2/schedules/{schedule_id}/replicas" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"schedule_replica": {
"replica_provider": "pagerduty",
"replica_provider_id": "PO8107X",
"replica_fallback_user_id": "PA7AXXN",
"sources": [
{
"rotation_id": "01G0J1EXE7AXZ2C93K61WBPYEH",
"layer_id": "01G0J1EXE7AXZ2C93K61WBPYEH"
}
]
}
}'
```
The required fields are:
| Field | Description |
| -------------------------- | ---------------------------------------------------------------------------------------------- |
| `replica_provider` | The external provider to mirror to. One of `pagerduty` or `opsgenie`. |
| `replica_provider_id` | The ID of the schedule in the external system (e.g. your PagerDuty schedule ID). |
| `replica_fallback_user_id` | The external user ID to use when nobody is on-call (e.g. a PagerDuty user ID). |
| `sources` | An array of `rotation_id` / `layer_id` pairs specifying which parts of the schedule to mirror. |
You can find schedule, rotation, and layer IDs using the [Schedules API](/api-reference/schedules-v2/). Use `GET /v2/schedules/{id}` to see the rotations and layers available for a given schedule.
#### Listing and viewing replicas
To list all replicas for a schedule:
```bash theme={null}
curl "https://api.incident.io/v2/schedules/{schedule_id}/replicas" \
-H "Authorization: Bearer "
```
To view a specific replica:
```bash theme={null}
curl "https://api.incident.io/v2/schedules/{schedule_id}/replicas/{replica_id}" \
-H "Authorization: Bearer "
```
The response includes sync status information such as `last_synced_at` and `last_sync_error`, as well as `user_statuses` showing how incident.io users have been mapped to external users.
#### Deleting a replica
To stop mirroring, delete the replica:
```bash theme={null}
curl -X DELETE "https://api.incident.io/v2/schedules/{schedule_id}/replicas/{replica_id}" \
-H "Authorization: Bearer "
```
As with disabling mirroring via the UI, this will remove the overrides that incident.io has created in the external schedule.
***
### Turning off mirroring
If mirroring is disabled, incident.io will delete its overrides in PagerDuty for schedules within the upcoming two-week period.
# Setting up notifications on iOS and Android
Source: https://docs.incident.io/on-call/mobile-notifications
**Download our mobile app**
If you'd like the best possible experience as a responder, download our mobile app [here](https://app.incident.io/qr).
This page covers the incident.io app. For responders in Mainland China, see [Mobile app in
China](/on-call/china-mobile-app) — there's a separate 事件incidentio app and the setup is different.
## Signing in
You can sign in to the mobile app in two ways:
* **Directly on the app**: Open the mobile app and sign in with Slack, Microsoft Teams, or SAML
* **QR code from the dashboard**: In the web dashboard, open the sidebar or use the command palette (`Cmd+K` / `Ctrl+K`) and select **Sign in on mobile**. Scan the QR code with your phone's camera to open the app and sign in automatically
If your organization uses SAML, the QR code takes you through your identity provider — SAML enforcement is always respected.
## Platform setup
Once you've signed in, see the relevant instructions for your platform:
[Setting up notifications on iOS](/on-call/ios-notifications)
[Setting up notifications on Android](/on-call/android-notifications)
## FAQs
If sign-in hangs after you are redirected to your identity provider (e.g., Okta), check Safari's privacy settings on
your iPhone:
1. Open **Settings → Apps → Safari → Advanced**.
2. Make sure **Block All Cookies** is off.
3. Go back to **Settings → Apps → Safari** and make sure **Prevent Cross-Site Tracking** is off.
Close and reopen the incident.io mobile app, then try signing in again.
# On-call notification policies
Source: https://docs.incident.io/on-call/notification-policies
Ensure every on-call responder is properly set up to receive pages.
On-call notification policies let you define minimum notification requirements for responders across your organization. Instead of hoping everyone configures their notifications correctly, set a policy that specifies exactly which contact methods and timing your on-call teams need, and we'll handle the rest.
When a policy is active, responders who don't meet the requirements are automatically notified and directed to update their preferences. You can also track compliance across your teams from the team members page.
If you have responders in Mainland China, consider setting up a separate policy for them. The available notification
methods are different — see [On-call in China](/on-call/china-on-call).
## Creating a notification policy
1. Navigate to [**Settings → Policies**](https://app.incident.io/~/settings/policies)
2. Select one of the **On-call notifications** templates, or create a custom policy using **Create new policy**
3. Define the notification requirements your on-call responders must meet
You can set requirements as broad or specific as you need. For example, you might require that all on-call responders have at least a mobile app notification, a voice call, and an SMS notification configured.
Start with the on-call notification template for sensible defaults, then adjust the requirements to match your organization's needs.
## How compliance works
Once your policy is active, we check each responder's [notification preferences](https://app.incident.io/~/user-preferences/on-call-notifications) against your defined requirements. Responders who don't meet the policy are considered non-compliant and receive reminders through multiple channels:
* **Slack**: a direct message linking to their notification preferences
* **Email**: a reminder with instructions on what needs updating
* **Dashboard**: a notification in the home page timeline panel
Each reminder directs the responder to their [notification preferences](https://app.incident.io/~/user-preferences/on-call-notifications), where they can see exactly which settings need to change to meet the policy.
## Tracking readiness across your teams
A few places help you stay on top of who still needs to update their setup:
* **Team Tasks tab**: each team's **Tasks** tab lists open policy violations alongside post-incident tasks, with the affected user, team, and policy shown for each one. Use this to quickly identify responders who haven't met the policy. The team **Overview** tab also summarizes the same in an **Open tasks** panel.
* **Team members page**: the **On-call notifications** column shows a ready or not-ready indicator for each user based on your active notification policy.
* **On-call readiness insights**: a historical view of notification configuration trends and per-user breakdowns ([On-call readiness insights](/on-call/on-call-readiness-insights)).
## Policy reports
Schedule recurring reports to stay on top of on-call readiness across your organization. On-call readiness reports group outstanding violations by user, so you can see exactly who still needs to update their setup.
See [Policy reports](/admin/policies#policy-reports) for cadence, delivery channels, and setup.
## Related pages
* [On-call notifications and preferences](/on-call/notifications): how responders configure their individual notification settings
* [Contact methods](/on-call/contact-methods): adding and managing phone, SMS, and other contact methods
* [On-call readiness insights](/on-call/on-call-readiness-insights): track notification configuration trends across your organization
* [Policies](/admin/policies): the broader policy framework for managing on-call, post-mortems, follow-ups, and debriefs
* [Policy reports](/admin/policies#policy-reports): scheduled summaries of outstanding policy violations
# On-call notifications and preferences
Source: https://docs.incident.io/on-call/notifications
On-call uses multiple channels (Mobile app, phone, SMS, Slack, email and WhatsApp) to notify you of upcoming shifts and escalations.
You'll be able to use either the dashboard or the mobile app to add your contact methods and set notification rules.
Responders in Mainland China have a few setup differences — see [On-call in China](/on-call/china-on-call).
## Contact methods and notification preferences
Set up all contact methods you'd like to use within the incident.io dashboard. You can find your preferences by clicking your profile and then choosing preferences.
Your Slack and email notifications should already be setup for you here by default but we'd also highly recommend adding your phone and downloading [the mobile app](/on-call/ios-notifications) is one of the most popular contact methods when escalations arise.
After having all the methods you want to use for notifications, you can choose how we should notify you when you are on-call or are being escalated to e.g. via app, SMS, Phone Call, Slack etc.
We have sensible default rules for your notifications but you can edit those rules depending on what works best for you. For example, you can add up to 10 levels of incrementally delayed notifications.
Each notification method can also be individually configured to bypass Do Not Disturb — so you can, for example, send a quiet push notification immediately and only escalate to a loud, DND-bypassing call after a minute if unacknowledged.
If an escalation level is set to [notify more than once](/on-call/escalation-paths#retry-a-level-before-moving-on), every attempt starts your rules again from the beginning. A rule with a delay longer than the interval between attempts therefore only completes on the final attempt. For example, if a level notifies every 5 minutes and your rules call you after 7 minutes, the call only happens on the last attempt.
Additionally, it's important to have reminders to know when you are about to be on-call. Below On-call notifications, you can adjust your shift change rules to get reminders before your shift starts, or when your shift ends.
## Mobile app settings
Download the incident.io mobile app and sign in using one of these methods:
* **Slack, Microsoft Teams, or SAML**: Open the mobile app and sign in directly
* **QR code from the dashboard**: Open the sidebar or command palette in the web dashboard and select **Sign in on mobile**. Scan the QR code with your phone's camera to sign in instantly — no need to type credentials on your phone
If your organization uses SAML, the QR code will take you through your identity provider's sign-in flow. SAML enforcement is always respected.
Once signed in, we'll guide you through an onboarding flow to set up the right notifications:
1. Enabling Push Notifications
2. Enabling Critical Notifications
3. Saving our Contact Card on your phone
4. Verifying your phone number
5. Bypassing the 'Do not disturb' mode
Doing all the above ensures that you will not miss any important updates or notifications! You will be able to review all settings in the mobile app later on.
## Testing
After setting up all notifications and preferences, you can test that all notifications paths work. Just click "Test" on mobile or the bell icon on the web app and you should receive a test message to the right channel.
## Mobile app preferences
Additionally, you will be able to change appearance between Light and Dark mode on the settings page of the mobile app. You can also just follow the device's theme you have set up.
You can find more details about bypassing the 'Do not disturb' mode in iOS and Android in [this help article](/on-call/mobile-notifications)
## Adding contact methods for other users
If you need to add a contact method on behalf of another user, admins can do this from the team members page. See [Adding contact methods for another user](/on-call/contact-methods) for details.
## FAQs
For non-mobile numbers — VoIP, Google Voice, or landlines — we default to voice calls only because most can't reliably receive SMS. Mobile numbers get both SMS and voice by default.
If your number does in fact receive SMS, you can enable it from your notification preferences (see below).
Some VoIP and Google Voice numbers can receive SMS even though we can't detect this automatically. To enable SMS:
1. Open your [notification preferences](https://app.incident.io/~/user-preferences/on-call-notifications) and find your phone number
2. Send a test SMS to confirm the number actually receives it
3. Toggle on SMS support and confirm that you've checked the number does support SMS
We require a successful test send before enabling SMS so you don't add a notification rule to a number that can't receive one.
Yes. You can turn off either capability from your notification preferences — useful if your number is voice-only or SMS-only.
Before disabling a channel, remove any notification rules that depend on it. We block the change if a rule would be left targeting an unsupported channel.
Some countries don't support SMS or voice routing through our providers. If a capability can't be delivered to your
country, we block the override. See [supported countries](/on-call/supported-countries) for the full list.
When you enable SMS on a non-mobile number, we send a one-off message explaining how to opt out (reply STOP) or get help (reply HELP). This is a US carrier compliance requirement and sends once per number.
# On-call Readiness Insights
Source: https://docs.incident.io/on-call/on-call-readiness-insights
When you get started with incident.io On-call, you'll want to make sure your teams have set up their notifications correctly so they're reachable when something goes wrong.
The onboarding flow in the mobile app helps team members pick sensible defaults, but as an admin you need a way to see what everyone is actually set up with. On-call readiness insights show you how many users are reachable by each method, who has gaps, and how reachability is trending over time, for both high and low urgency notifications.
High urgency notifications must reach a responder immediately. They use methods like phone calls, push alerts, and SMS, and bypass Do Not Disturb where possible. Low urgency notifications keep the same people informed without breaking their focus, which is why many teams configure both: high urgency for pages, low urgency for awareness.
When responders download the [incident.io mobile app,](https://app.incident.io/qr) they'll be walked through an onboarding flow to add sensible defaults.
## Reachability at a glance
At the top of the dashboard you'll see a row of KPI tiles, one per notification method (Phone, SMS, WhatsApp, and App), showing the share of on-call users currently reachable by that method at high urgency. Click a tile to highlight the corresponding column in the table below. The selection is reflected in the URL, so you can share a link with a method already focused.
Alongside the reachability tiles, the final card shows one of two things:
* **Policy violations**: the share of on-call users who don't satisfy your [on-call readiness policy](/on-call/notification-policies). This appears once you've configured a readiness policy.
* **Multiple methods at high urgency**: the share of on-call users with two or more high-urgency methods configured. This is shown when no readiness policy is in place, as a useful proxy for redundancy.
Without a readiness policy configured, the dashboard surfaces the Multiple methods card instead, alongside a per-user breakdown that counts how many methods each responder has set up:
## Filter by escalation path or schedule
The KPI cards, table, and trend chart all respect the filters in the top bar. You can filter by escalation path, schedule, or both. This is useful if you're migrating one team at a time, or if different teams have different processes in place.
## Drill down into each user's configuration
Below the KPI row, the **Readiness by user** table lists every on-call user and the notification methods they have configured. A legend at the foot of the table maps the cell colours: configured, missing-and-required-by-policy, and not configured. Click a row to open that user's [notification settings](/on-call/notifications) in a drawer.
When both high and low urgency methods are in scope, a segmented **High urgency / Low urgency** toggle appears in the top-right of the panel. Each option shows an amber warning badge with the number of users who have a policy gap at that urgency, so you can flip between the two views and see where attention is needed.
Use the **Export** button next to the toggle to download the current table as a CSV. The export includes paired high/low urgency columns for each method, the user's overall status, and any applicable on-call readiness policies.
## Notification configuration trends
The **Adoption over time** chart at the bottom of the dashboard tracks how your users' notification configuration is changing. This is useful for following a migration. For example, you can watch whether onboarding sessions are driving readiness up over time. The chart uses the date range and aggregation (day or week) from the top of the page, with the last 12 weeks selected by default.
## Mobile install breakdown
If your org has the mobile install breakdown enabled, you'll see an extra panel showing the state of each user's mobile app install: platform, app version, whether the app is installed, whether push is enabled, and the signals that govern whether a page can break through Do Not Disturb. This panel is currently in early access. Reach out if you'd like it enabled for your account.
A couple of columns are platform-specific because iOS and Android handle Do Not Disturb differently:
* **Critical**: iOS only. Critical notifications make a sound regardless of silent mode or Focus / Do Not Disturb. See [iOS notifications](/on-call/ios-notifications) for the user-side setup.
* **DND**: Android only. Reflects whether the app has been granted Do Not Disturb access, which lets push notifications break through. See [Android notifications](/on-call/android-notifications) for details.
* **Contact**: how iOS bypasses Do Not Disturb for phone and SMS. We can tell whether each responder has the incident.io contact card installed, but we can't see whether they've enabled Emergency Bypass on it, so a green check confirms the contact is saved but not that DND bypass is wired up end to end.
For users on platforms where a signal doesn't apply, the cell renders as a neutral dash rather than a pass or fail.
### China region
If anyone in your organization needs to use the China-specific build of the incident.io mobile app, the Mobile install breakdown panel adds a **Region** column showing whether each device is registered against the **Global** or **China** app. This makes it easy to confirm that responders in mainland China are installed against the right build.
The China app is a separate build of the mobile app for users who can't reach the Global app's push infrastructure. See [Supported countries for On-call notifications](/on-call/supported-countries) for the wider picture on regional availability.
## FAQs
The trailing card swaps based on whether you've configured an on-call readiness policy. With a policy in place, it shows **Policy violations** so you can track adherence. Without one, it shows **Multiple methods at high urgency**, a useful proxy for redundancy when you don't yet have a defined bar to measure against.
A user is in violation if they're missing one or more notification methods required by an [on-call readiness policy](/on-call/notification-policies) that applies to them. Policies can require specific methods at high urgency, low urgency, or both. The status pill on each row counts unmet statements rather than missing cells, so a policy like "app OR email at high urgency" only counts once if both are missing.
The dashboard reads live notification configuration each time you load the page. The adoption-over-time chart is sampled daily, so changes a user makes today will show up on tomorrow's data point.
The Mobile install breakdown is currently in early access and rolled out per organisation. If you'd like it enabled for your account, reach out to the incident.io team.
Yes. Click any row in the **Readiness by user** table to open that user's [notification settings](/on-call/notifications) in a side drawer, including which methods they have configured at which urgencies.
# Delaying an out of hours escalation until working hours begin
Source: https://docs.incident.io/on-call/out-of-hours
When folks are asleep, the last thing they need is a low priority alert or escalation waking them up in the middle of the night. With our [smart escalation paths](/on-call/escalation-paths) you can now happily remain unconscious when this happens by holding these until working hours begin.
## 1. Handling an out of hours escalation
Below you can see an example of how we can hold an escalation by setting the time to acknowledge to until `Working hours begin` in our outside working hours branch.
Escalations can be created from [alerts through alert routes](/alerts/escalations-from-alerts), [via workflows](/on-call/getting-started) e.g. automated escalations sent when a human declares an incident or directly from someone triggering [a manual escalation](/incidents/escalating).
Let's walk through how this works by considering what happens when an alert arrives outside of our configured working hours for this escalation path.
When the escalation from my alert hits my escalation path, it would immediately go into my second branch which sends a slack escalation into the team's slack channel.
That escalation would then not proceed any further in my escalation path until working hours begin because of my time to acknowledge setting (highlighted in yellow).
When working hours begin, my escalation would then hit the **Retry** node, taking it back to the start of my escalation path. Now that we're in working hours, my escalation would go down my primary branch which results in a high priority escalation to the individual on-call for my infrastructure team's schedule.
You could also consider just sending a [low-priority notification](/on-call/escalation-paths) to a schedule instead of a Slack message.
**Word of warning:** It's important to note that if an escalation hits a node of an escalation path with a schedule where no-one is on-call, it will skip that node and move on to the next one. This can then have bad consequences e.g. If I put an escalation node in my OOH's branch that had a schedule with no-one on it OOH's, it would be skipped and this would result in the escalation just being retried across the path, according to the settings on your **Retry** node.
We'd therefore typically advise always keeping a schedule 24/7 where possible (i.e. someone is always on call) and letting the escalation path manage how escalations are handled out of hours.
## 2. Handling an out of hours escalation with priorities
You can also extend this to use escalation priorities to further enhance your escalation path. Below you can see that we've added another conditional branch on priority to ensure that we only wake people up when our escalation priority is Urgent or Critical, for any other OOHs alerts, it would then follow a similar branch to what we've just configured above.
You can find further details on how to configure your alert / escalation priorities [here](/on-call/escalation-paths). These will then be available to use within your alerting configuration, workflows and escalate forms to help determine the path your escalations should then take.
# Cover me, overrides and schedules
Source: https://docs.incident.io/on-call/overrides
## Schedules
When you or your team member has built schedules for your On-call, you are now able to view them from the incident.io dashboard or your mobile.
#### Dashboard
Just head to your [Schedules](https://app.incident.io/~/on-call/schedules) and you'll be able to view the final schedule, but also add overrides.
#### Mobile
In mobile, you'll be able to view your schedules or all schedules. Just open the incident.io mobile app and click the calendar icon to get to the screen.
## Sync your on-call shifts to your calendar
We only show shifts within the next 3 months, not beyond that. We believe 3 is a good balance between providing great visibility and keeping the schedules up-to-date.
Bring your own or all shifts to your Google or Outlook calendar by just copying a URL.
1. Head to [schedules](https://app.incident.io/~/on-call/schedules)
2. Click sync schedule from the top right
3. Choose if you want your shifts or all shifts from the schedule
4. Copy the URL and bring it to your calendar app!
## Cover me
Ask for cover for a shift and we’ll send notifications to the people in your schedule to ask, and if they say yes - we’ll let you know it was accepted! If accepted, an override is created automatically.
When requesting cover, the cover request will be sent to all people in the schedule. When someone has accepted the request, we will remove the possibility from others accept it and you will get a confirmation who has taken the shift. You can request for cover for partial hours too.
#### Slack
1. Type `/inc cover me` to any channel the incident.io slackbot is in.
2. This will then open up a screen to add details of the shift you want covering for
3. Add more details why you need cover
4. Receive a confirmation of the request
#### Mobile
To request cover in mobile, head to Schedule view. You can either:
* Click the top right icon and choose the 'Request cover' -tab.
* Click a shift, and drag the section you want to request cover for.
Below you'll also see what a cover request looks like when someone is in the receiving end. After someone has accepted cover, the override will be made automatically.
**Dashboard**
* You can view, create and respond to cover requests in the dashboard
* You can 'offer to cover' for some or all of the requested time, with a message attached
* You can send a reminder from an open cover request, which will send a push notification to those who haven't responded yet
* You can add more people to a cover request after creating it, if you forgot someone who might be available
## Overrides
If someone can’t make a shift because they are on holiday or have an appointment, anyone can create an override by choosing when and who they want to override the shift with. This can be done via mobile or the dashboard.
#### Dashboard
* To create an override, you can:
* Click "Create an override" from the top right of a schedule
* Click on the shift you want to override
* Like on mobile, drag and drop the section of a schedule you want to override
* To edit an override, click on the overridden shift you want to edit
* To delete an override, you can do it from the edit screen, or by selecting "Delete" on the tooltip
#### Mobile
To create an override in mobile, head to Schedule view. You can either:
* Click the top right icon and select the 'Create override' -tab.
* Drag and drop the portion of a shift you want to create an override for
You can edit or delete an override by tapping an overridden shift and selecting what you want to do.
# Create an on-call pay report
Source: https://docs.incident.io/on-call/pay-report
Our pay calculator provides a quick and easy way to pull compensation for your on-call responders without having to manage internal tooling and scripts to do the same.
This help article will walk through two different approaches in how you can calculate pay using:
1. Single pay configuration
2. Multiple pay configurations
To get started, you'll need to head over to the 'Pay calculator' tab within the On-call section of [https://app.incident.io](https://app.incident.io/). Friendly reminder that only On-call customers will be able to use the calculator to generate reports!
## Single pay configuration
For most organizations, leveraging a single pay configuration will suffice as it supports those that pay *all* of their on-call responders the same rate.
To generate a report, you will need to first create a pay configuration via the 'Configure' button on the top right.
From here you can set your pay configuration to include all the rules for paying your on-call responders, including:
* Currency to be paid in
* Holidays
* Daily or hourly pay rates
* For example, if you pay £10 / hr every day, except Monday - Friday 9am - 5pm during working hours, this would look like:
Once you have set your pay configuration rules, you can create a new report. Steps to generate a report include:
1. **Settings** Please create a name and specify the time range for your pay report (ie. the past month)
2. **Schedules** Here you can select any schedules that should receive compensation for being on call.
3. **Payments** Within Payments, you should select 'Same pay rules for everyone' and then select the payment configuration you set to apply to the report.
4. **Holidays** Please check that you have accounted for any holidays that require additional or different payment. You can either import public holidays from our tool or you can manually add (useful if you have separate company holidays!).
5. **Generate** Once you've completed all the above steps you can generate your report in a draft state so you can review before finally publishing!
## Multiple pay configurations
Now, if your organization pays on-call responders different rates depending on different factors, you will want to generate a report using multiple pay configurations. Examples of this include:
1. Location-based compensation
2. Role-based compensation
3. Tier 1 vs Tier 2 engineer compensation
We will walk through a location-based model below, but the approach will apply to any of these types of scenarios.
To start, you will need to set up all your different pay configurations via the 'Configure' button on the top right.
So, for a location-based model, you may want to set up configurations as such:
* Team United Kingdom
* **Currency**: £
* **Timezone**: London (GMT)
* **Hourly pay rates**: £10 / hr every day, except Monday - Friday 9am - 5pm during working hours
* **Holidays:** United Kingdom
* Team USA
* **Currency**: \$
* **Timezone**: New York (EST)
* **Hourly pay rates**: \$15 / hr every day, except Monday - Friday 8am - 6pm during working hours
* **Holidays:** United States
* Team Australia
* **Currency**: AUD
* **Timezone**: Melbourne (GMT+10)
* **Hourly pay rates**: \$10 / hr every day, except Monday - Friday 9:30am - 5:30pm
* **Holidays:** Australia
Next, you will want to go to the Catalog and connect Users to an Office. This is how you will be able to connect the pay configurations to the appropriate on-call users during report generation. So, for example, I can make connections that look like so:
* Anna is in the Melbourne Office
* Sarah is in the NY office
* Ben is in the London office
To do this, you will need to create a Catalog type, such as **Office**, with different name values and associate the Users with those locations. Then in the User catalog type, create a derived attribute called Office that has the path **Office > Users**.
*Note: If you need additional help working with the Catalog, please refer to help content* [here](/catalog/catalog-setup)
Once you have set your pay configuration rules *and* have connected locations to users in the Catalog, you can create a new report. Steps to generate a report include:
1. **Settings** Please create a name and specify the time range for your pay report
2. **Schedules** Here you can select any schedules that should receive compensation for being on call.
3. **Payments** Here you should select 'Different pay rules for different groups.' From here you will want to use If expressions to connect Users → Office → Pay configurations. See screenshot for an example of how this can be set up:
4. **Holidays** Please check that you have accounted for any holidays that require additional or different payment. You can either import public holidays from our tool or you can manually add (useful if you have separate company holidays!).
5. **Generate** Then you can generate your report in a draft state so you can review before publishing!
We also have a helpful Loom to walk you through this type of report generation, which you can find [here](https://www.loom.com/share/05d4d78fdcfa41e9915d3a9d078d8055?sid=0410146b-74fd-4ee7-892a-c745dbb35eec).
## Exporting a report
Once you've published a report, you can export it in two formats:
* **Summary for payroll**: a single CSV with total pay per person, ready to hand off to your finance team or import into payroll
* **Schedule by schedule**: a ZIP containing one CSV per schedule, with a full shift-by-shift breakdown (useful if you need to audit or verify individual shifts)
## Additional tips for generating reports
1. **Deduplication:** If you have users that are on-call for multiple schedules at once, and want to deduplicate payments, please select 'Pay only once for overlapping shifts' while generating a report.
2. **Create using old report:** You can create a new report based on a previous one (which will reuse the same schedules and pay configurations so you don't have to reselect everything each month!).
# Understanding priority, urgency, and severity
Source: https://docs.incident.io/on-call/priority-urgency-severity
In incident.io, there are three concepts that represent the importance of something.
In alerts and escalations, these are **priorities**, which allow you to configure [branches in your escalation path](/on-call/escalation-paths).
When you notify someone about an escalation, that's done with an **urgency**, which determines how a user is notified. Users can configure separate notification settings for high and low-urgency notifications.
Lastly, once you create an incident, that has a **severity**. An incident's severity indicates how significant this incident is. These are kept different from alert priorities, as the way you determine incident severity may differ from the priority of a single alert.
For example, you may have an alert with an urgent *priority* that you want someone to look at immediately, therefore sending them a high *urgency* notification. However, the problem may only be impacting a small part of your application, or a single customer in an edge case, so you deem the incident *severity* to be minor.
# Public holidays
Source: https://docs.incident.io/on-call/public-holidays
Subscribe to one or more countries' public holidays, per schedule
Subscribe to one or more countries' public holidays per schedule. This is done per schedule, as On-call schedules are often configured per team, which might work in different regions of the world.
To make this setup as simple as possible, when you create or edit a schedule we'll automatically suggest public holiday subscriptions based on the schedule's timezone.
To subscribe to public holidays:
1. Head to your [Schedules](https://app.incident.io/~/on-call/schedules) list, and click **New schedule** or click **Edit** on an existing schedule
2. In the **Public holidays** section, click **Add** and search for the country whose holidays you want to subscribe to
3. Repeat if needed, and that's it!
Once you've subscribed, we'll surface these holidays alongside your schedule shifts. See [Acting on time off](/on-call/acting-on-holidays) to arrange cover.
# How do I remove someone from an on-call schedule rotation?
Source: https://docs.incident.io/on-call/remove-from-rotation
## Context
When managing on-call schedules, you may need to remove team members from a rotation due to role changes, departures, or schedule adjustments. It's important to understand how these changes affect the existing rotation and upcoming shifts.
## Answer
When removing someone from an on-call schedule, you have two options for managing the transition:
## Option 1: Defer Changes
If you want to avoid disrupting the current rotation:
1. Edit the schedule rotation
2. Remove the team member from the rotation
3. When prompted, select "Defer Changes"
4. Choose when you want the changes to take effect
## Important Notes
* After making changes, check the "This rotation has upcoming changes" section to review and edit any scheduled changes
* Verify the upcoming shifts to ensure the rotation order is as expected
* If you need to make adjustments to when the changes take effect, you can modify the "effective from" date
## Option 2: Change handover time
If you want the changes to take effect now, you can change the handover time of the schedule. We use handover time for our rotation calculations.
1. Edit the schedule rotation
2. Remove the team member from the rotation
3. Change the handover time forward a week to compensate for the user being removed.
4. Check the order is still the same, as you would expect.
Best Practice: Always review the upcoming schedule changes before finalizing them to ensure the rotation sequence meets your team's needs.
# Repeating acknowledged escalations
Source: https://docs.incident.io/on-call/repeating-acknowledged-escalations
Automatically repeat an acknowledged escalation while the associated alert is still firing.
You can configure your escalation path such that when an escalation is acknowledged, but the associated alert is firing,
we will repeat that escalation from the start - until the alert resolves.
This is useful for teams who want to ensure a firing alert doesn't go unaddressed, if it was initially acknowledged but never fixed.
You may know of this feature as "acknowledgement timeout".
## How it works
Configure a repeat interval on an escalation path. When an escalation using that path is acknowledged while the alert is still firing:
1. The escalation moves to a **Pending repeat** status — the pages stop, but the escalation stays active
2. After the configured interval, the escalation repeats from the first level of the path
3. If the alert resolves while waiting, the escalation cancels immediately — no further pages are sent
Re-escalations restart from the top of the path, so if your on-call rotation has changed since the original page, the right person will be paged.
Repeat intervals can be configured per escalation path.
## Configuration
Set a repeat interval in your escalation path settings. The minimum interval is 5 minutes and the maximum is 4 days.
To configure:
1. Go to **On-call → Escalation paths** and open a path
2. Toggle the **Repeat if the alert is not resolved** setting
3. Set your desired interval — how long to wait before re-paging after the escalation ends
### Delay repeats on incident activity
You can optionally configure the repeat timer to reset whenever there's activity on the associated incident. When enabled, posting an incident update, changing the incident summary, or a Scribe key moment will push the repeat timer forward — so responders actively working an incident won't be re-paged mid-investigation.
Enable **Delay repeat on incident activity** alongside your repeat interval in the escalation path settings.
## Limits
* **Minimum interval**: 5 minutes
* **Maximum interval**: 4 days
* **Repeat window**: Re-escalations stop after 7 days from when the original escalation was created, even if the alert is still firing
Resolving the alert is how you stop repeats. You can do this manually from the dashboard, mobile app, or Slack, or
from your external system when the alert cannot be manually resolved. Any escalation in **Pending repeat** status will
cancel immediately when the alert resolves.
No. Snoozing an escalation pauses it at its current point in the escalation path, so the repeat logic doesn't apply
while an escalation is snoozed. If the escalation later resolves or expires from the snoozed state, the repeat config
will apply at that point.
## Other ways to retry an escalation
This page covers retries while the alert is firing, which page again after an escalation has been acknowledged. Escalation paths also retry in two other ways, both of which run while an escalation is still unacknowledged:
* **Per-level retries** notify a single level again before the escalation moves on. See [Retry a level before moving on](/on-call/escalation-paths#retry-a-level-before-moving-on).
* **Retries across the path** send an unacknowledged escalation back through the path from an earlier point. See [Retry across the path](/on-call/escalation-paths#retry-across-the-path).
# Get started as an On-call responder
Source: https://docs.incident.io/on-call/responder-guide
Being on-call is a critical responsibility, and we’re here to make sure you're fully prepared. This quick guide will help you get set up with the right configuration and easily manage your on-call shifts in the future!
## How to set up
When you’re invited to be an on-call responder, you’ll receive an email from us. After that, it’s time to set everything up! Here’s what we recommend:
1. **Download the mobile app**
2. **Check your notification settings**
3. **Learn how to request cover and create overrides**
4. **Know how to acknowledge (ack) when you get paged**
***
## 1. Downloading the mobile app
1. To get started, download our app from your phone’s app store:
* [Apple Store](https://apps.apple.com/ie/app/incident-io/id6471268530)
* [Google Play Store](https://play.google.com/store/apps/details?id=com.incidentio.incidentio\&hl=en_GB\&pli=1)
2. Once the app is installed:
* **Sign in**
* Enable **push notifications**
* Enable **critical alerts**
* **Verify your phone number**
3. Discover the app Explore the app to get familiar with these key features:
* **View incidents** and escalations
* **See your schedules**
* **Test notification sounds**
After you have enabled all permissions, we create sensible defaults in your notification settings. These are:
**High Urgency**
* Immediately via App and Slack/MS teams
* After 1 minute via phone
* After 3 minutes via SMS
* After 5 minutes via email
**Low Urgency**
* Immediately via email and Slack/MS teams
## 2. Checking your notification settings
Want to customize your notifications? You can easily adjust the order of how you get alerted by going to [Preferences](https://app.incident.io/~/user-preferences/on-call-notifications) in the web dashboard.
You can also add more contact methods and change how you want to be notified about upcoming shifts.
## 3. Request cover and create overrides
Managing your shifts is simple through the **web dashboard**, mobile app, or Slack/MS Teams.
* **Create an override** to swap out your scheduled shift
* **Send a cover request** to ask another team member to cover your shift
Read more about managing schedules, overrides and cover requests [here](/on-call/overrides) !
## 4. Acking a page
When you receive a page, you can **acknowledge** it through any method. This lets you jump straight to the incident channel and start investigating.
If you have multiple escalations for related issues, you can **bulk acknowledge** them in the mobile app. Read more about bulk and auto acking [here](/on-call/bulk-acknowledge).
## Other useful commands
* `/inc` or `/incident` - Creates a new incident
* `/inc cover me` - Create a cover request for your shift
* `/inc whoisoncall` - See who is on-call
# Rotation calculation in Schedules
Source: https://docs.incident.io/on-call/rotation-calculation
Understanding how Rotations work is important when it comes to adding or removing users from an On-call schedule.
## How are Rotations calculated?
Rotations are calculated based on the Handover time of a Schedule's rota, this means that if you add a new user to a schedule, it may affect the order of the users on the schedule.
You can see below that if I try to add two new users to this schedule it changes the person that is currently on-call.
To offset this change, you need to change the handover time back 2 weeks as we are generating the new rotation based on the handover time.
## How to delay changes?
Alternatively, and the recommended way, to make sure the current on-call user is not affected by adding a new user, you can delay the change to happen after the current rotation has ended. Using the example above, we will prompt you to delay changes as this will affect the current user on-call, and we will automatically set the delay for you.
## Using Terraform to manage your schedule?
If you are using Terraform to manage your schedules it can be a bit hard to see what your upcoming changes will do, so to best utilize delaying your changes to make sure the current on-call user is not affected, use `effective_from` to delay changes. More details in our [Terraform provider](https://registry.terraform.io/providers/incident-io/incident/latest/docs/resources/schedule#example-usage).
# Round Robin in Escalation paths
Source: https://docs.incident.io/on-call/round-robin
When setting up Escalation paths you might want to balance the load between people or ensure someone from a specific schedule acknowledges the page. This is where Round Robin comes in handy. We offer two kinds of Round Robins that solve both cases
## Round Robin - Select one user per escalation
In a classic Round Robin everyone chosen in the level or schedule will take turns for each incoming escalation. We always start with the user who was paged longest ago for this escalation path.
Example being that we have a schedule that has Josh, Eric and Tanya. In Escalation A, Josh will get paged, Escalation B it will be Eric and then in C it will be Tanya. If Josh misses the escalation or nacks, the escalation will continue to the next level.
1. Head to Escalation paths
2. Choose a level and either a schedule or people from the dropdown
3. Choose 'Currently On-call' or 'Everyone'
4. Click 'All at once' and then Round Robin
5. Choose Default
## Round Robin - Cycle responders
In level specific Round Robin we keep trying people for a single incoming alert, so it will page each person in that level with every chosen minutes. We always start with the user who was paged longest ago for this escalation path.
Example being that in a Schedule we have Lucas, Leo and Martha. Cycling responders every 3 minutes means that first Lucas will be paged, then waiting for 2 minutes and if Lucas misses an escalation or nacks, we will try Leo next and then 2 minutes later we will try Martha. When next escalation comes in, we will start from Leo.
1. Head to Escalation paths
2. Choose a level and either a schedule or people from the dropdown
3. Choose 'Currently On-call' or 'Everyone'
4. Click 'All at once' and then Round Robin
5. Choose 'Cycle responders' and then the time between cycling
A level that uses either kind of Round Robin cannot also be set to notify more than once, because Round Robin already works through the level's responders on a timer. For a given level, choose either Round Robin or [per-level retries](/on-call/escalation-paths#retry-a-level-before-moving-on).
***
## Read more about Escalation paths
[Smart escalation paths](/on-call/escalation-paths)
[Dynamically setting an escalation path](/alerts/dynamic-escalation)
[Escalating to the right team from an alert](/alerts/team-routing)
If you have any feedback or feature requests on the feature, please send us a message to [support@incident.io](mailto:support@incident.io) - we'd love to hear from you!
# How do I assign on-call roles from schedules to incident roles?
Source: https://docs.incident.io/on-call/schedule-to-incident-roles
## Context
When managing multiple on-call schedules with different roles (like Incident Manager, Incident Commander, DevOps), you may want to automatically assign the current on-call person from each schedule to their corresponding incident role when an incident is created.
## Answer
You can automatically assign on-call members to incident roles using a workflow with custom expressions. Here's how to set it up:
1. Create a new workflow or edit an existing one
2. Use the "assign an incident role to user" for any role you wish to set in the workflow
3. For each role you want to assign, use the following expression:
Make sure to use the exact schedule name in the expression to target the specific on-call schedule
This allows you to pick the current on-call user on a schedule and assign them to a specific role.
Example setup:
**Alternative Approach:** You can also use the "Auto-assign incident lead" [template workflow](https://app.incident.io/~/workflows/create?template=assign_paged_as_lead) to set roles based on who acknowledges an escalation. This is useful when you want to ensure the assigned person has actually acknowledged the incident.
# Swap shifts
Source: https://docs.incident.io/on-call/shift-swaps
Swap an on-call shift with a teammate, or request cover and offer a swap in return.
Sometimes you can't make a shift. Maybe you're away for the weekend, on holiday, or out for a longer stretch, and asking someone to simply absorb that much on-call is a big ask. Swapping shifts lets you trade your shift (or part of it) for one of theirs, so the time evens out and nobody's just doing you a favor. Nobody changes places in the rotation, and everyone goes back to their normal schedule for every shift after the swap.
If you only need a couple of hours off, you can send a [cover request](/on-call/overrides) instead and let someone pick it up.
There are two ways to swap: [create a swap directly](#swap-shifts-directly) when you already know who you want to trade with, or [offer a swap through a cover request](#swap-shifts-through-a-cover-request) when you don't.
## Swap shifts directly
Use a direct swap when you've already agreed a trade with someone and just want to record it quickly. Both overrides are created in one go.
1. Head to your [schedules](https://app.incident.io/~/on-call/schedules) and click **Create override → Swap shifts**.
2. Select the shift you want to give up. You can drag down a shift to swap only part of it (e.g. just the Thursday and Friday of your week).
3. Choose the person you want to swap with, then select the shift of theirs you'll take on in return.
4. Save to create both overrides.
By default we snap your return shift to the same duration, so you're offering a like-for-like trade. You can also make an uneven swap, for example taking on Flo's Wednesday, Thursday, and Friday in exchange for just your Thursday.
Press **Cmd + K** anywhere in the dashboard and choose **Swap** to jump straight into creating a swap.
## Swap shifts through a cover request
If you don't know who to swap with, or you'd rather offer people a choice, use a [cover request](/on-call/overrides). Cover requests now include a calendar view and the option to offer a swap in return.
### Offer a swap when requesting cover
When you create a cover request, you can offer to take on one or more of the recipients' shifts in return:
1. Create a cover request for an upcoming shift and choose who to ask.
2. Select **Offer a swap** and pick the shifts you'd be happy to take in return (e.g. Flo's shift, or either of Bea's shifts).
3. Send the request.
Everyone you asked can still cover you outright. Anyone whose offered shift you selected also gets the option to simply accept the swap, taking your shift and handing you theirs in one step.
### Respond to a cover request with a swap
If someone sends you a cover request without offering a swap, you can still respond with one, saying "I'll take this if you take my shift instead":
1. Open the cover request and choose to respond.
2. Select **Swap shifts** and pick one of your own shifts to hand over in return.
3. Send your response. If they accept, we create the matching override on the other side of the swap automatically.
## FAQs
No. A swap is a one-off trade for the shifts you pick. Both people keep their normal place in the rotation, so every
shift after the swap is unaffected.
No. We snap to an equal-duration swap by default, but you can make an uneven swap, for example trading three of your
days for one of someone else's.
A cover request asks someone to take your shift. A swap trades two shifts so both people give up one and take one.
You can combine the two by offering a swap as part of a cover request, or by responding to a cover request with a
swap.
# On-call Shortcuts Cheatsheet
Source: https://docs.incident.io/on-call/shortcuts
What are some of the different slack commands that are available for the on-call product specifically, you may be asking? Well here they are in their full glory!
| On-call Command | Description |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `/incident escalate` `/incident page` | Pull in other teammates for help. `/incident page` can be used outside of incidents! |
| `/incident whoisoncall` `/incident oncall` | See who is currently on-call for a given team or escalation path |
| `/incident coverme` `/incident cover` `/incident cover me` | Request on-call cover for an upcoming shift |
# How do I set up Slack notifications for on-call schedule changes?
Source: https://docs.incident.io/on-call/slack-schedule-notifications
## Context
Teams often need to notify members when on-call schedules change, including who is coming on/off duty. Setting up automated Slack notifications helps keep everyone informed of these schedule changes.
## Answer
You can configure automated Slack notifications for on-call schedule changes using workflows. Here's how to set it up:
1. Navigate to Workflows and create a new workflow
2. Select "An On-call schedule shift changes" as the trigger
3. Add a Slack message action and choose your destination channel
4. In the message, you can use these variables to display shift information:
* "Previously on-call users" - Shows who was on call
* "Currently on-call users" - Shows who is now on call
Important notes:
* Individual users can set up personal notifications through User Preferences for shift notifications
# Why can't I ack my page via SMS?
Source: https://docs.incident.io/on-call/sms-ack-issues
If you're having trouble acknowledging escalations via SMS in the UK, this is likely due to restrictions of your mobile plan. Some mobile operators, such as Smarty, VOXI, and giffgaff, will not allow you to reply to shortcode numbers.
## Why does this happen?
Sending messages to shortcode numbers is not included in standard "unlimited messaging" on phone plans. With prepaid plans, your provider needs to ensure you have sufficient credit available before allowing these premium messages.
Unlike traditional monthly contracts where charges can be added to your next bill, prepaid plans require you to have credit available upfront. To protect customers from unexpected charges, many prepaid providers disable shortcode messaging by default.
For that reason, some providers prevent you from sending SMS to shortcode numbers entirely. Others may allow you to configure this.
## Which phone plans are affected?
This limitation typically affects:
* Mobile Virtual Network Operator (MVNO) prepaid plans
* Pay-as-you-go services
* Some budget-focused mobile plans
Common providers where you might experience this include:
* Voxi
* Smarty
* Giffgaff
* Other prepaid services
## What can you do?
Depending on your provider, you may have several options:
1. Check your account settings - Some providers allow you to enable shortcode messaging in your account settings.
2. Contact your provider - Reach out to your mobile provider's customer service to understand if they offer any options for enabling shortcode messaging, if it's not available in your settings panel.
3. Acknowledge pages via some other method - You can always open the mobile app to acknowledge an escalation, even if you weren't paged through the mobile app!
# Snoozing escalations
Source: https://docs.incident.io/on-call/snoozing-escalations
Temporarily snooze an escalation when you need more time before responding.
Snoozing lets you temporarily pause an escalation when you've seen the alert but aren't ready to act on it yet. Instead of ignoring the page or acknowledging prematurely, snoozing gives you a defined window before the escalation resumes and notifies you again.
This is useful when you're paged about a known issue, need to finish something before investigating, or want to be reminded of an issue at a better time.
## How snoozing works
When you snooze an escalation:
1. The escalation moves to a **Snoozed** status and all notifications pause
2. After the snooze duration expires, the escalation returns to **Triggered** and resumes notifying as normal
3. The snooze is recorded in the escalation timeline, including who snoozed it and for how long
Snoozing is available from Slack, the dashboard, and the mobile app.
When you snooze an escalation, you'll be asked to provide a justification. This helps your team understand why the
escalation was deferred.
## What happens while snoozed
* **Notifications pause**: No further pages are sent while the escalation is snoozed. The escalation does not advance through further levels in the escalation path.
* **Escalation stays active**: Snoozed escalations still appear in your active escalation lists. They haven't been resolved — they're just paused.
* **Alert resolves**: If your alert route is configured to auto-resolve and the underlying alert resolves while the escalation is snoozed, the escalation resolves too — no page is sent when the snooze expires.
* **Timeline tracking**: Snooze and unsnooze events appear in the escalation timeline, so your team has a full audit trail.
## Snoozing and compliance (MTTA)
A snooze counts as an acknowledgement for MTTA (mean time to acknowledge). The responder has seen the escalation and made a deliberate decision to defer it, which is distinct from an escalation going unnoticed.
No. Snoozing is not available for escalations that require multiple people to acknowledge. This is because a single
responder snoozing would pause notifications for all required acknowledgers.
The escalation does not advance to the next level while snoozed. When the snooze expires, the escalation resumes from
the same level in the path where it was snoozed.
Anyone with permission to view and respond to escalations can snooze them. This follows the same permissions as
acknowledging an escalation.
# Supported countries for On-call notifications
Source: https://docs.incident.io/on-call/supported-countries
incident.io offers On-call notification support for: mobile app, SMS, WhatsApp, phone call, Slack and email. Depending on your country, the availability of some notifications, more specifically telecommunication notifications, may vary due to local regulations, carrier restrictions, etc.
This document will share the latest information on country deliverability support for our notification channels.
Last updated on **May 2026.**
Mainland China is supported in early access through a separate setup. See [On-call in China](/on-call/china-on-call)
for the details — including which channels are available and how to add a Chinese phone number. Hong Kong and Taiwan
use the standard setup.
incident.io **strongly** recommends that the mobile app is the primary notification method for getting paged. While we provide SMS and phone notifications as well, factors like local carrier restrictions and government regulations can occasionally make it harder to receive or respond to these particular notification formats.
## Mobile app notifications
The mobile app is currently supported worldwide, with a few limited exceptions. These exceptions include countries facing US sanctions, or lack of Apple Store or Google Play Store presence. These countries include:
* Cuba
* Ethiopia
* Iran
* North Korea
* Sudan
* Syria
* Uzbekistan
Mainland China uses a separate app — see [Mobile app in China](/on-call/china-mobile-app).
As a reminder, we strongly recommend that the mobile app is the primary notification method for On-call notifications and supplements any SMS or phone notification rules.
## WhatsApp notifications
WhatsApp notifications are available to any number with an active WhatsApp account, in nearly every country. The exceptions are countries where WhatsApp itself is blocked:
* China
* North Korea
* Syria
Deliverability in other countries may occasionally vary due to local regulations. As with SMS, we recommend pairing WhatsApp with the mobile app rather than relying on it as your only high-urgency channel.
## SMS and phone call notifications
Please see below for country deliverability. Support is broken out to the following:
* Full support - This means the country allows for full SMS or phone call support including delivery and acknowledgement
* Partial support - This means the country may either have limited deliverability due to carrier restrictions, local government regulation and/or, for SMS notifications, lack of ability to acknowledge via SMS
* No support - This means the country has no support for these notification methods
If you do not see your country below, please ask us about our deliverability there via [help@incident.io](mailto:help@incident.io). It is likely either we have not had users in that country yet or we have not been asked directly about that country's deliverability.
If you see the country you need as only partially supported, please check with our team to determine what that means more specifically (ie. is it simply just unable to acknowledge via SMS or are there certain carrier restrictions to be aware of).
| Country | SMS support | Voice support |
| ------------------------ | ------------ | ------------- |
| Albania | Partial | Partial |
| Andorra | Partial | Partial |
| Argentina | Full | Full |
| Armenia | Partial | Partial |
| Australia | Full | Full |
| Austria | Full | Full |
| Azerbaijan | Partial | Partial |
| Bangladesh | Partial | Partial |
| Belarus | Partial | Partial |
| Belgium | Full | Full |
| Bolivia | Full | Full |
| Bosnia and Herzegovina | Partial | Partial |
| Brazil | Full | Full |
| Bulgaria | Partial | Full |
| Canada | Full | Full |
| Chile | Full | Full |
| China | Early access | Early access |
| Colombia | Full | Full |
| Costa Rica | Partial | Full |
| Croatia | Partial | Full |
| Cuba | No support | No support |
| Cyprus | Partial | Partial |
| Czech Republic | Full | Full |
| Denmark | Full | Full |
| Dominican Republic | Full | Full |
| Ecuador | Partial | Full |
| Egypt | Partial | Partial |
| Estonia | Full | Full |
| Ethiopia | Partial | No support |
| Finland | Full | Full |
| France | Full | Full |
| Georgia | Partial | Partial |
| Germany | Full | Full |
| Ghana | Partial | Partial |
| Greece | Partial | Full |
| Guatemala | Partial | Full |
| Guernsey | Partial | Partial |
| Guyana | Partial | Partial |
| Honduras | Partial | Partial |
| Hong Kong | Full | Full |
| Hungary | Full | Partial |
| Iceland | Partial | Full |
| India | Partial | Full |
| Indonesia | Partial | Full |
| Ireland | Full | Full |
| Israel | Full | Full |
| Italy | Full | Full |
| Ivory Coast | Partial | Partial |
| Japan | Full | Full |
| Jordan | Partial | Partial |
| Kazakhstan | Partial | Partial |
| Kenya | Partial | Full |
| Latvia | Partial | Partial |
| Lebanon | Partial | Partial |
| Lithuania | Full | Partial |
| Luxembourg | Partial | Full |
| Macedonia | Partial | Partial |
| Madagascar | Partial | Partial |
| Malaysia | Full | Full |
| Maldives | Partial | Partial |
| Malta | Partial | Partial |
| Mauritius | Partial | Partial |
| Mexico | Full | Full |
| Moldova | Partial | Partial |
| Montenegro | Full | Partial |
| Morocco | Partial | Partial |
| Nepal | Partial | Partial |
| Netherlands | Full | Full |
| New Zealand | Full | Full |
| Nigeria | Partial | Partial |
| Norway | Full | Full |
| Pakistan | Partial | Partial |
| Panama | Partial | Full |
| Peru | Partial | Full |
| Philippines | Full | Full |
| Poland | Full | Full |
| Portugal | Full | Full |
| Puerto Rico | Full | Partial |
| Romania | Partial | Full |
| Russia | No support | No support |
| Rwanda | Partial | Partial |
| Saint Lucia | No support | No support |
| Serbia | Partial | Partial |
| Singapore | Partial | Full |
| Slovakia | Partial | Partial |
| Slovenia | Partial | Full |
| South Africa | Full | Full |
| South Korea | Partial | Partial |
| Spain | Full | Full |
| Sri Lanka | Partial | Partial |
| Sweden | Full | Full |
| Switzerland | Full | Full |
| Taiwan | Partial | Full |
| Thailand | Partial | Full |
| Trinidad and Tobago | Partial | Partial |
| Tunisia | Partial | Full |
| Turkey | Partial | Full |
| Turkmenistan | Partial | Partial |
| Ukraine | Partial | Full |
| United Arab Emirates | Partial | Full |
| United Kingdom | Full | Full |
| United States of America | Full | Full |
| Uruguay | Partial | Partial |
| Uzbekistan | Partial | Partial |
| Vietnam | Partial | Full |
# Syncing schedules to Slack user groups
Source: https://docs.incident.io/on-call/sync-slack-groups
Keep Slack user groups in sync with your on-call schedules.
Sync your on-call schedules to Slack user groups so anyone can mention the group to reach the right people. Each sync rule can target either **all members** of a schedule or just **whoever is currently on-call** - and you can set up multiple rules per schedule for different use cases. Connect Slack user groups from any schedule's page.
## How syncing works
When you connect a Slack user group to a schedule, you choose what to sync:
* **All members** -the group always contains everyone on the schedule
* **Currently on-call** -the group updates at each handover to contain only whoever is on-call right now
incident.io keeps the group membership in sync automatically. When syncing to current on-call responders, the group updates immediately when a handover occurs or an override takes effect.
Connecting a Slack user group to a schedule **replaces all existing members**. Any previous members who aren't part of
the sync are removed.
## Common use cases
You can combine sync rules in any way that fits your team. Here are some common configurations:
### Dedicated on-call group
A single schedule syncs to a dedicated Slack user group for current on-call responders.
**Example:** The Platform team's schedule syncs to `@platform-on-call`. Mention the group to reach whoever is on-call right now.
### Separate groups for roster and on-call
A single schedule syncs to two different groups: one for all members and one for current on-call.
**Example:** The Platform schedule syncs to `@platform-schedule` (all members, for reaching anyone on the rotation) and `@platform-on-call` (current on-call, for urgent issues). This lets people choose whether they need everyone on the schedule or just whoever is on duty.
### Combined on-call group
Multiple schedules feed into a single Slack user group, combining responders from all connected schedules.
**Example:** A team with primary and secondary schedules wants a unified `@on-call-team` group containing both responders. Or, follow-the-sun coverage across regional schedules uses a single `@global-on-call` group that always contains whoever is currently on-call worldwide.
## Set up user group sync
**To connect a schedule to a Slack user group:**
1. Navigate to **On-call → Schedules** and select your schedule
2. In the top-right, select **Connect Slack group**
3. Configure the sync rule: choose an existing Slack user group or create a new one
4. Select **Save**
To add another sync rule to the same schedule, repeat these steps. Each rule can target a different Slack user group with different sync settings.
To connect additional schedules to the same group, repeat these steps on each schedule and select the same Slack user group.
To disconnect a schedule from a group, open the schedule settings and remove the sync rule.
## Managing shared user groups
When multiple schedules sync to the same Slack user group, any settings changes apply to all connected schedules.
You need edit permission on **all schedules** connected to a shared group to update its settings. If you lack
permission on any connected schedule, you won't be able to modify the shared group configuration.
## Slack permissions
Slack restricts who can modify user group membership. By default, only Workspace Admins and Owners can update user groups, which doesn't include the incident.io Slack bot.
Choose one of these options to enable syncing:
### Option 1: Allow workspace members to manage user groups
If your organization permits it, update your Slack workspace settings to allow all members to manage user groups:
1. Go to [Slack user group restrictions](https://slack.com/admin/settings#user_group_restrictions)
2. Set both user group permissions to **Everyone, except guests**
This gives the incident.io Slack bot permission to manage on-call user groups.
### Option 2: Use a privileged Slack account
If your organization restricts user group management to admins only, connect a Slack admin or owner account that incident.io can use to manage user groups.
Create a dedicated service account (e.g., "incident.io Admin") rather than using a personal account. The connected
user appears to take actions within Slack, which can cause confusion if it's a real person's account.
Follow the steps in [Set up privileged Slack access](/getting-started/slack-admin-setup) to connect an admin account.
## When no one is on-call
Slack doesn't allow user groups to be empty. When no one is on-call for any connected schedules, incident.io disables the group rather than leaving stale members in place. The group re-enables automatically when someone comes on-call.
If you have automations or workflows that depend on the group always being active, you can configure the sync rule to
include the incident.io bot user as a permanent member. This prevents the group from being disabled when no one is
on-call.
# How do I unmanage a Terraform-controlled schedule in the dashboard?
Source: https://docs.incident.io/on-call/unmanage-terraform-schedule
When schedules are created and managed through Terraform, they cannot be edited directly in the web UI. However, there may be times when you want to switch from managing a schedule via Terraform to managing it directly in the dashboard interface.
To change a schedule from being Terraform-managed to being manageable in the dashboard UI, follow these steps:
1. Navigate to the schedule you want to unmanage
2. Click "Edit" to open the schedule's edit drawer
3. Click the "Export" button
4. Scroll to the bottom of the export drawer
5. Click the "in the dashboard" link in the callout message
Once completed, you will be able to edit the schedule directly in the dashboard interface. This allows you to make changes such as modifying the order of responders or updating schedule details without using Terraform.
# Wait for investigation
Source: https://docs.incident.io/on-call/wait-for-investigation
Hold an escalation while AI investigates, so responders are paged with context
The **Wait for investigation** node pauses an escalation while our AI investigation runs against the incident. As soon as the investigation reaches a first hypothesis, the escalation continues. This means when responders are paged, there's already useful context for them in the mobile app and incident channel.
The node includes time limit, so you can configure how long you're willing to delay the escalation for.
## When to use it
Add this node near the top of an escalation path that's triggered by alerts, before the first level that pages a human. A short wait (3–5 minutes) gives the investigation time to surface an initial hypothesis without meaningfully delaying response.
This is most valuable when:
* You want responders to land in an incident channel with an early hypothesis already posted, instead of starting from a blank alert
* You're comfortable trading a small delay for richer context when the responder receives the page
## How it works
When an escalation reaches the node, it waits until either of these happens:
* The investigation produces a first hypothesis
* The configured delay limit elapses
Whichever comes first ends the wait, and the escalation continues down the path as normal.
### When the wait is skipped
The node only delays escalations created by alerts. It exits early in the following cases:
* **Manual pages and workflow-triggered escalations**: if a person pages the path directly, or a workflow does, we escalate immediately
* **No investigation will run**: if the incident doesn't match your [investigation auto-run settings](https://app.incident.io/~/investigations?drawer=investigation-settings), there's nothing to wait for, so we move on
* **The investigation errors**: if running the investigation fails, we stop waiting and continue the escalation
## Add it to an escalation path
1. Open an escalation path and click the + icon where you want to add the node.
2. Select **Wait for investigation**.
3. Choose a delay limit. We recommend **3–5 minutes**, which is how long investigations usually take to reach first hypothesis.
4. Save the escalation path.
## FAQs
The escalation stops entirely, just like with a regular delay node. Nobody gets paged.
No. Manual escalations skip the wait and page immediately. The delay only applies to escalations created from
alerts.
The escalation continues anyway once the timer elapses. The investigation keeps running and will post its findings
to the incident channel when it's ready.
# Why did verifying my WhatsApp number fail?
Source: https://docs.incident.io/on-call/whatsapp-verification-issues
What to do if verifying a WhatsApp number for on-call notifications fails.
Most of the time this is a quick fix. Try these steps in order before getting in touch.
1. **Update to the latest version of WhatsApp.** Most verification failures come from an out-of-date app. Update WhatsApp from the [App Store](https://apps.apple.com/app/whatsapp-messenger/id310633997) or [Google Play](https://play.google.com/store/apps/details?id=com.whatsapp), reopen it, and try verifying again.
2. **Check we can message each other.** If you're on the latest version and it still won't verify, send a hello message to **+44 7576 586600** on WhatsApp. This confirms WhatsApp will let our number reach you.
If you've done both and still can't receive a verification message, [reach out to us](mailto:support@incident.io) and we'll take a look.
# What is a debrief?
Source: https://docs.incident.io/post-incident/debriefs
A debrief is a Google Calendar event used for regrouping after an incident has been resolved. During a debrief, it's common to:
* Discuss the post-mortem
* Create follow-ups to stop the incident from happening again
* Invite incident responders and some key stakeholders
It may be called different names, but for now, we're referring to it as a debrief within incident.io.
If you are using our [Google Calendar integration](/integrations/google-calendar) and include the incident ID (e.g. `INC-108`) within the title or description of the Google Calendar event, then we will post the following in the incident Slack channel:
If you answer `"Yes, it's a debrief"` to this message, then we will pull through the details of the Google Calendar event and share them with the incident Slack channel:
## Removing a debrief
If you have followed the flow above to attach a Google Calendar event as a debrief to an incident, you can always remove it from the sidebar on the incident details page:
# Setting a default assignee for your post-incident tasks
Source: https://docs.incident.io/post-incident/default-assignees
When an incident enters [the post-incident flow](/post-incident/post-incident-flow), we create a set of tasks like `Create the postmortem` which must be addressed.
It's possible to rely on these tasks being picked up proactively, but if you're on our **Pro** or **Enterprise** plans you'll see the option to set a default assignee from the [task settings](https://app.incident.io/~/settings/post-incident-flow) ! This means that tasks are more likely to get done, and incidents progress through the post-incident flow quicker.
## Who should be the default assignee?
You might want all tasks to be assigned to the lead so they can delegate. Alternatively you might choose for some tasks to be assigned to a particular role (for example, the `Schedule a debrief` task might be assigned to the `Debrief scheduler` role).
You can also create an expression here, which means we'll assign different people under different conditions:
Our default is that the lead should be automatically assigned to all tasks, but you can change this in [Settings > Post-incident flow](https://app.incident.io/~/settings/post-incident-flow) by clicking "edit" on each task.
Note that the default assignee is optional, so if you don't want your tasks to be automatically assigned you can just clear the defaults we've set for you.
## When will they get assigned?
When an incident first enters the post-incident flow we will automatically assign the tasks for you.
Because we support expressions like "when the severity is critical" here, we'll also re-evaluate who should be assigned whenever an incident changes. So if it looks like the assignee should be someone else, we'll update the assignee and notify the new person.
## Can I override this?
Yes! If you assign a task manually, we will no longer try to assign that task automatically.
# Setting due dates and reminders for your post-incident tasks
Source: https://docs.incident.io/post-incident/due-dates
When an incident enters [the post-incident flow](/post-incident/post-incident-flow), we create a set of tasks like `Create the postmortem` which must be addressed.
While often not as urgent as solving the incident itself, the post-incident flow ensures you have recorded the right timestamps, fields, and learnings while the incident is still fresh in people's memories.
In order to help people prioritize what to work on next it can help to set expectations about when a task should be completed by.
## Deciding on a due date
Not every incident is equal. Some are more complex, some more serious in nature, others may involve completely different sets of teams. It might seem impossible to decide on a due date for tasks across all of that but thankfully you can easily set multiple conditions on when a task might be due.
To do so, begin editing a post-incident flow task and look towards the due date section. You are now able to set an expression powered by incident fields along with your own catalog of custom fields to decide on the values to return here.
In this example we're saying we want the post-mortem to be completed as soon as possible if the incident is of a `Critical` severity, otherwise you can take a bit longer:
## What does the due date do?
Once an incident transitions into a post-incident flow, all of the tasks will have their due dates set. Within the UI you are able to see when each task is due, and who it is currently assigned to.
When a task becomes overdue it will be highlighted in the UI:
## Automatic and manual reminders
If you are on our **Pro** or **Enterprise** plans you will be able to send automatic reminders to users; simply enable the option within your post-incident flow settings.
When a task assigned to a user becomes overdue we will send a gentle reminder to the user that this date has gone past so they can make sure they finish the task.
You can now also manually send reminders to people for specific tasks via the post-incident view. Clicking `Send reminder` will send a similar reminder message to the assignee reminding them to finish this post-incident task.
# External post-mortem documents
Source: https://docs.incident.io/post-incident/external-postmortems
Write your post-mortems in Google Docs, Confluence, Notion, or SharePoint.
incident.io also supports creating and writing your post-mortems directly in external tools like Google Docs, Confluence, Notion, or SharePoint. When someone creates a post-mortem from a template configured for external writing, the document is created in your external tool immediately, pre-populated with the structure from your template and context from the incident.
To set this up, create a template with the **External** writing mode and configure an export destination in **Settings > Post-mortems**. See [Templates](/post-incident/postmortem-templates) for more on how templates work.
## Status tracking
External post-mortems have the same status workflow as in-app documents: In progress, In review, and Completed. This means you get the same visibility into post-mortem completion across your organization, regardless of where the writing happens.
## Attaching an existing document
If you've already written a post-mortem outside of incident.io, you can attach it to an incident by pasting the URL. We recognize links from Confluence, Google Docs, Notion, and SharePoint automatically. The document appears in the incident's post-mortem section with a link to the external tool.
## Differences from in-app post-mortems
External documents don't have access to the in-app editor features: AI generation, real-time collaboration, mentions, or comments. If you want those, use the in-app editor and [export](/post-incident/postmortem-sharing-and-exporting) the finished document when you're done.
You can't have both in-app and external post-mortem documents on the same incident.
# Enforcing follow-ups are completed based on priority (policies)
Source: https://docs.incident.io/post-incident/follow-up-policies
### Introduction
You can use policies to define rules about how your organization completes follow-ups, however, you may want to configure this further based on the priority of the given follow-up.
This helpful article walks through creating a new policy that enforces that urgent follow-ups are completed within 3 days of the incident being resolved, and follow-ups with any other priority have 7 days to be completed.
### Steps
Head over to [Settings → Policies](https://app.incident.io/~/settings/policies), and click [New Policy](https://app.incident.io/~/settings/policies/create).
Select `Follow-ups` as the **Policy type**, and give the policy a **Name** and **Description**.
Within the **At what point should we enforce this policy? → SLA days** section, click the **Use an expression** button.
Select the `If... else...` expression type, and add a new expression rule:
* If `Follow-up → Priority is one of Urgent`, return `3`
* If no rule conditions are met, return `7`
This expression states that if a follow-up has a priority of `Urgent` then it should be completed within 3 days, and for any other priority the follow-up should be completed in 7 days.
Click the **Add** button to save the expression.
Within the **Follow-up requirements** section, create a new requirement:
* `Follow-up → Status is not one of Outstanding`
This requirement is enforcing that for the policy to be fulfilled, the follow-up must have a status that is not `Outstanding`, thus validating that it has been completed.
Click the **Create** button to save the policy.
# Assigning a Priority to Follow-ups
Source: https://docs.incident.io/post-incident/follow-up-priorities
[Follow-ups](/post-incident/follow-ups) are a way for your team to capture something that needs to be done after an incident is closed. These will come in all shapes and sizes, from an urgent task such as reverting a temporary workaround, to a low priority task such as investigating how to move to a new cloud provider. You are able to assign each follow-up a priority, to capture this level of importance within [incident.io](https://incident.io/).
In this article, we will show you how to configure and assign priorities to your follow-ups, as well as how they work with [policies](/admin/policies), [workflows](/workflows/getting-started), and reporting.
## Assigning a Priority
Set the priority via the dropdown in either the web or Slack experience.
## Configuring Follow-up Priorities
Navigate to the [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups) page to configure:
* If follow-ups are required to have a priority
* The amount of options available to choose from
* The name and description of each priority option
* The default priority option
If you export follow-ups to Jira, Linear, ClickUp, or [Notion](/integrations/notion-follow-ups), priority changes made in the issue tracker will sync back to incident.io — as long as priority names match. This is configurable from [Settings → Follow-ups](https://app.incident.io/~/settings/follow-ups).
## Using Priorities with Policies
Navigate to the [Settings → Policies](https://app.incident.io/~/settings/policies) page, and select **New Policy** and then choose **Follow-ups** as the **Policy type**.
Within the **Follow-up requirements** section, you are able to use **Follow-up Priority** alongside **Expressions** to determine the SLA that you want to set, allowing you to build a policy that says:
* "All high priority follow-ups must be completed within 3 days, medium priority follow-ups within 10 days".
* Note that in this example, Low priority follow-ups will have no SLA, so won't trigger a violation.
## Using Priorities with Workflows
Navigate to the [Workflows configuration page](https://app.incident.io/~/workflows), and select **New Workflow** and your workflow trigger (e.g. " **When a follow-up is created or changed"** ).
Click **Add condition** and choose **Follow-up Priority** to require that this workflow is conditional on the priority of a follow-up, thus allowing for workflows such as:
* "When a follow-up is created or changed, and the priority is set to urgent, then email the tech lead."
## Using Priorities with Reporting
Navigate to the [Follow-ups reporting page](https://app.incident.io/~/follow-ups), and select **Follow-up Priority** from the **Split By** dropdown in the top-right of the screen, this will update the **At a glance** table.
You can also make use of the **Follow-up Priority** filter on this page, by clicking **Filter** in the top-right of the screen.
# Follow-ups
Source: https://docs.incident.io/post-incident/follow-ups
We believe you create two types of actions during an incident – those that **need doing now** and those that should be followed up after an incident has been closed.
Actions that **need doing now** might be:
* Reboot that server
* Send some comms to an affected customer
While **follow-ups** could be:
* Improve test coverage of a given codepath
* Share the debrief document with all affected customers
You can learn more about actions [here](/incidents/actions).
## How do I create follow-ups?
There are three ways you can do this:
1. **React** with the `:fast_forward:` emoji to any Slack message within the incident channel
You can then export the follow-up to an issue tracker, via the Incident Homepage (or directly in Slack for any connected issue tracker).
2. Use the command **/inc follow-up,** to create new follow-ups and post any open follow-ups within the channel
3. Create the follow-up directly in your issue tracker, and paste a link into the Slack channel
4. **Import** an existing ticket from your issue tracker as a follow-up, from the incident homepage in the dashboard
## What can I do with follow-ups?
## Editing follow-ups
If a follow-up is exported to an external issue tracker like Jira, we'll listen for changes and keep the follow-up in line on our side.
If it isn't, you can manage it via Slack (using `/inc follow-ups`) or via the incident homepage from the Follow-ups tab.
You can also assign a **Priority** to a follow-up, to help drive Policies and communicate the difference between follow-ups. You can read more about [Follow-up Priorities](/post-incident/follow-up-priorities).
You can assign follow-ups to a **Team** as well as an individual user, which is useful when you know which team owns the work but not yet who will do it. Follow-ups can also be tagged with **Labels**, which sync with your issue tracker and can be used for filtering.
## Tracking follow-ups
You can track follow-ups from the [Follow-ups](https://app.incident.io/~/follow-ups) page in the web dashboard. This allows you to see the status of follow-ups across all your incidents, as well as take actions such as sending reminders and bulk-editing follow-ups.
# Define your post-incident process using the Post-incident Flow
Source: https://docs.incident.io/post-incident/post-incident-flow
After an incident is resolved, there are usually steps you can take to learn from it and improve for the future. By doing so, you may be able to prevent the incident from happening again or improve your response to similar incidents.
The Post-Incident Flow provides a way to define a set of tasks that should be completed after an incident is resolved, but before it is closed. You can also choose which types of incidents should go through this process. For example, you may only want to use this flow for major incidents.
***
## Configuring the Post-Incident Flow
To define the steps that you'd like to take to learn from your incidents, head into your [Settings > Improve > Post-incident flow](https://app.incident.io/~/settings/post-incident-flow). By default, we create a flow with two parts: `Documenting` and `Reviewing`.
Statuses in the post-incident section are unlike other statuses. They have the following key differences: 1. Post-incident statuses have tasks associated with them. These are things like "Create a post-mortem", or "Schedule a debrief". 2. Users don't manually move through post-incident statuses using `/inc update`. Instead, incidents are automatically moved through the statuses as their tasks are complete, or marked as 'Not doing'.
To configure the tasks for the post-incident flow, you can either add or edit an existing task. Each task has a customizable description that you can use to give instructions to your responders.
**Customers on our Enterprise plan can also:** 1. Configure different post-incident flows, which can be used for different incident types. 2. Create fully-custom tasks, with their title and description.
By default, there are several suggested tasks. Several of these are automatically resolved in response to actions in incident.io, such as 'Marking a post-mortem document as complete'. Currently, the suggested tasks we support are:
* **Reviewing the incident timeline** - which contains a link to jump to the incident timeline.
* **Creating a post-mortem document** - which will be automatically completed when a post-mortem document is attached to the incident.
* **Schedule the debrief** - which contains a button to create a Google calendar event with all the users involved in the incident.
* **Mark the post-mortem document as complete** - which will be automatically completed when the post-mortem document is marked as complete
* **Share the debrief document** - which is automatically completed when you share the post-mortem to a Slack channel
* **Review follow-ups** - which contains a link to open the incident's follow-ups
* **Assign the \{insert role} role** - which allows you to choose an incident role that must be assigned
Please note that if you add new tasks, these will only apply to future incidents going into the post-incident flow. Existing incidents will only contain tasks that were defined when that incident entered the post-incident flow. If an incident's post-incident tasks are deleted, it'll no longer automatically move to the next status. In these cases, you can manually move the incident to the next status via the dashboard.
## Requiring incidents to go through the post-incident flow
When closing an incident, users will get the option to opt-in to the post-incident flow. However, you can choose to automatically enter certain types of incidents into the post-incident flow.
In [Settings > Respond > Lifecycle](https://app.incident.io/~/settings/lifecycle), click 'edit' on the post-incident section. Enable the toggle to automatically put **all** incidents through the post-incident flow, then configure your conditions if you'd like this to only apply to certain kinds of incidents.
For customers on our Enterprise plan, this is where you configure which post-incident flow is used for each lifecycle.
## Using the post-incident flow
When closing an incident, responders will be prompted as to whether or not they'd like to go through the post-incident flow for this incident.
If you've enabled the option to automatically enter the post-incident flow, and the incident matches your conditions, you'll instead be entering the post-incident flow.
After confirming that, you'll enter your first status in your post-incident phase. We'll notify the incident Slack channel about this.
Similarly, if you open the incident in the dashboard, you'll see the details of each of these tasks. From here, you can mark tasks as completed, skip them, or assign them to a user. When a user is assigned a task, we'll send them a notification to let them know.
Once you've completed all the tasks in a post-incident status, we'll automatically move the incident to the next post-incident status. If it's your final post-incident status, then we'll mark the incident as closed.
## Opting an incident out of the post-incident flow
If an incident enters the post-incident flow, but you've decided that it's not worthwhile for this incident, you can opt-out. You can do this by typing in `/inc close` into your incident channel, or by selecting **Opt out of post-incident** in the overflow menu at the top right of the incident in the dashboard.
When you opt-out, you have to provide a reason about why you're opting out, which we'll include in the message we send to its Slack channel about the incident now being closed.
Admins can remove the ability to opt out by adjusting permissions in [Settings → Roles](https://app.incident.io/~/settings/roles).
If an incident is closed and the post-incident flow is skipped, it can still be started later. To do this, open the incident in the dashboard and change its status back to a post-incident status. There's no separate restart button—the flow begins again when the status changes. When restarted this way, the post-incident flow is created fresh, including any tasks and due dates. This can also be done through the API or with a workflow step for automated setups.
## Hiding the post-incident flow
If you don't want to use the post-incident flow you can [remove all your post-incident statuses](https://app.incident.io/~/settings/post-incident-flow) and you won't be prompted about it when closing incidents.
# AI-native writing
Source: https://docs.incident.io/post-incident/postmortem-ai
Generate first drafts, get inline review suggestions, and redraft sections with AI.
Gathering the context to write a post-mortem is time-consuming. Information has to be collected from Slack threads, monitoring tools, investigation findings, and conversations with the people involved. Then it all has to be condensed into something coherent and readable.
AI-native writing takes care of the heavy lifting. It can generate a first draft from your incident data, review your finished document with inline suggestions, and help you redraft sections that need improvement. You focus on the analysis and the learnings, and let AI handle the gathering and structuring.
AI features are available on Pro and Enterprise plans.
For private incidents, AI features are only available if your organization has opted in to sending private incident
data to AI subprocessors. See [Private incidents](/post-incident/postmortems-overview#private-incidents).
## First draft
### Getting started
To enable AI-generated post-mortems, you need a template with AI enabled on at least one section. The quickest way:
1. Go to **Settings > Post-mortems** and click **Add template**.
2. Select **Duplicate existing template with AI** to create a copy of one of your existing templates with AI enabled on all custom sections. Or pick one of our suggested templates, which come with AI pre-configured.
3. Optionally, open the template and customize the AI instructions on each section to guide what the AI focuses on.
You can also enable AI on an existing template by editing it and toggling AI on for individual sections.
Once your template is ready, create a post-mortem from an incident using that template and the AI will generate a first draft for you.
### How it works
The AI generates content for each section of your template individually, using everything it knows about the incident: the timeline, Slack or Teams conversations, investigation findings, custom fields, catalog data, images, and more.
The quality of the output depends on how you've configured your template. Each section can have its own AI instructions that guide what the AI focuses on. For example, you might tell it to focus on customer impact in one section and technical root cause in another. The section name and help text also feed into the generation, so being specific about what you're looking for in each section makes a real difference.
If a section doesn't have AI enabled, it's left with the template prefill content for the writer to fill in manually. This means you can mix AI-generated and manually-written sections in the same document — use AI for the sections where gathering context is the bottleneck, and leave the more reflective sections for humans.
The result is a starting point, not a finished document. It gets you past the blank page and gives you something to react to and refine, rather than having to write everything from scratch. You can edit any of the generated content, and use [Redraft](#redraft) to have AI rework specific passages.
## Review
Once you've written your post-mortem (or refined the AI-generated draft), you can ask AI to review it. Click the Review button in the document header and AI will read through your document, compare it against the incident data, and leave inline suggestions.
The review checks for things like:
* **Factual accuracy**: are there events missing from the timeline, or details that don't match what actually happened?
* **Completeness**: are there contributing factors or context that the document doesn't cover?
* **Structure and clarity**: is the narrative easy to follow? Is it blameless in tone?
* **Learning value**: are the lessons specific and actionable? Are the follow-ups concrete enough to actually get done?
Suggestions show up as highlighted annotations in the document, visible only to you. You can work through them one by one, or dismiss all suggestions at once. Leaving the document clears them as well — they're meant to be acted on in the moment, not left as permanent comments.
## Redraft
Sometimes you don't need a full review, you just need help with a specific passage. Select any text in the document and you can ask AI to rework it. You tell it what you want (rewrite this more clearly, fact-check this against the incident data, make this less technical, change the tone) and it gives you a suggested replacement.
This is useful for polishing sections after you've done the thinking but the writing isn't quite there yet. The AI has access to the full incident context, so it can fact-check claims against what actually happened and suggest corrections. On top of that, it can find and update anything you reference, replacing plain text with rich elements such as user mentions, PR references, incidents, custom fields, and more.
## Chat
The AI chat is a floating assistant available while you're writing. You can ask it questions about the incident ("what happened between 2am and 3am?", "who was on call when this started?", "what did the investigation find?") and it will answer based on the incident data.
You can also use it to help with writing. Ask it to draft a paragraph about the customer impact, or to summarize the resolution steps. If the conversation surfaces action items, the AI can create follow-ups directly from the chat. When the AI references existing text in your document, you can click the reference to scroll straight to that part of the document.
# Post-mortem API
Source: https://docs.incident.io/post-incident/postmortem-api
Programmatic access to your post-mortem documents, metadata, and status changes.
Everything you can see in the post-mortem list view is also available through our public API. This opens up a lot of possibilities for teams that want to integrate post-mortem data into their own tools, build custom reporting, or automate parts of their process that we haven't built a native feature for yet.
## What you can do
The API gives you access to your post-mortem documents and their metadata. Here's what's available:
### List and find post-mortems
You can [list all post-mortems](/api-reference/postmortemdocuments-v1/list) across your organization, or filter to find the post-mortems attached to a specific incident. This is useful for building dashboards, generating reports, or syncing post-mortem data with an internal tool.
### Fetch document metadata
Each post-mortem exposes metadata about the document: its status, the incident it belongs to, when it was created and last updated, and who has edited it. If you want to track post-mortem engagement (who's writing them, who's reviewing them, how quickly they're being completed), this is where that data lives. Use the [show endpoint](/api-reference/postmortemdocuments-v1/show) to fetch the full details of a specific document.
### Fetch content as Markdown
You can [fetch the full content of a post-mortem as Markdown](/api-reference/postmortemdocuments-v1/showcontent). This is the same content you see in the editor, rendered as plain Markdown text. This is really powerful if you want to do something with the content that we don't support natively. Maybe you want to feed post-mortems into an internal search engine, publish them to an internal wiki that we don't integrate with, or run your own analysis across all your post-mortems. The content is right there, in a format that's easy to work with.
This is the same output you get when using "Copy as Markdown" from the editor's overflow menu.
### Update status
You can [update the status of a post-mortem](/api-reference/postmortemdocuments-v1/updatestatus) programmatically. Move it from In Progress to In Review, or from In Review to Complete, without anyone having to open the UI. This is useful if you have an external review process (say, a pull request workflow or an approval system) and you want to update the post-mortem status when that process completes.
## Webhooks
We also support a [webhook that fires every time a post-mortem's status changes](/api-reference/postmortem-document-status-v1/updated-public). The webhook payload includes the post-mortem metadata and the new status.
This is the other side of the automation coin. Where the API lets you pull data and take actions, webhooks let you react to changes as they happen. Some things people use this for:
* **Trigger a notification** in a tool we don't have a native integration with (internal chat tool, email system, ticketing system).
* **Update an external tracker** when a post-mortem is completed, so your compliance or audit system knows that the post-incident process was followed.
* **Kick off a custom pipeline** that processes the post-mortem content. For example, extracting key metrics, updating a reliability scorecard, or feeding the content into an internal knowledge base.
The webhook fires on every status change, so you'll get a notification when a post-mortem moves to In Progress, In Review, and Complete. You can filter on your end to only act on the transitions you care about.
The [Incidents V2 API](/api-reference/incidents-v2/list) also includes `postmortem_document_ids` in incident responses, so you can discover which post-mortem documents are associated with each incident.
## Getting started
Check out our [API reference](/api-reference/introduction) for the full details on authentication and response formats. Here are the direct links to the post-mortem endpoints:
* [List post-mortem documents](/api-reference/postmortemdocuments-v1/list)
* [Show a post-mortem document](/api-reference/postmortemdocuments-v1/show)
* [Fetch content as Markdown](/api-reference/postmortemdocuments-v1/showcontent)
* [Update post-mortem status](/api-reference/postmortemdocuments-v1/updatestatus)
* [Post-mortem status changed webhook](/api-reference/postmortem-document-status-v1/updated-public)
# Managing your post-mortems
Source: https://docs.incident.io/post-incident/postmortem-management
Track post-mortem completion across your org with list views, the post-incident flow, and policies.
Writing post-mortems is one thing. Making sure they actually get written, reviewed, and completed across your organization is another. This is especially true as your team grows and the number of incidents increases. You need visibility into what's been done and what's outstanding, and you need a way to enforce standards without chasing people around.
## Post-mortem list view
The post-mortem list view gives you a single place to see every post-mortem across your organization. You can filter by status, severity, incident type, team, incident lead, participants, custom fields, and more, so you can quickly find the post-mortems that need attention.
Each row shows the post-mortem's status, the incident it belongs to, and how many follow-ups have been completed. This is the view you want if you're a manager or process owner who needs to keep track of how your team is doing with post-incident work.
Each team also has its own post-mortem list on their team page, pre-filtered to show only post-mortems for that team's incidents.
### Custom columns
By default, the list shows status, severity, incident duration, follow-ups, and last updated. You can customize which columns are visible by clicking the **Display** button in the toolbar. From there, you can add columns for any of your custom fields or incident roles, so the list shows exactly the information you care about.
### Saved views
If you find yourself applying the same filters and column configuration repeatedly, you can save it as a view. Saved views capture your current filters, sorting, and column selection, and are available to everyone in your organization. This is useful for things like "Critical incidents missing post-mortems" or "My team's in-review documents." You can switch between views, rename them, or delete them from the view dropdown.
## Post-incident flow
The post-incident flow is a guided sequence of tasks that kicks in after an incident is closed. You can include post-mortem related tasks in this flow, such as:
* **Export the post-mortem**: creates or exports the post-mortem document.
* **Draft the post-mortem**: prompts the responder to write the post-mortem and move it to review.
* **Mark post-mortem as complete**: a reminder to finish the review and mark the document as complete.
* **Share the post-mortem**: a prompt to share the completed document.
These tasks can have default assignees, so the right person is automatically responsible. You can use expressions to assign tasks conditionally. For example, the incident lead always gets the "Create post-mortem" task, but a specific team lead gets the "Review" task for critical incidents.
Tasks can also have due dates and reminders. You can set these up as expressions too, so critical incidents get a shorter deadline than minor ones. Reminders are sent automatically when tasks are overdue.
If a post-mortem isn't needed for a particular incident, the responder can opt out of the post-incident flow with a reason. This gives you visibility into why post-mortems were skipped without forcing people through a process that doesn't apply.
## Policies
Policies let you enforce post-mortem completion SLAs across your organization. You configure them in **Settings > Policies**, where you can create rules that define which incidents require a post-mortem (based on severity, type, or other properties) and set deadlines for completion. When a post-mortem is overdue, the responsible people are notified via Slack and email.
You can also set up recurring [policy reports](/admin/policies#policy-reports) that summarize outstanding post-mortems and deliver them to Slack or email.
Policies are available on Pro and Enterprise plans.
## Settings
Post-mortem settings are managed in **Settings > Post-mortems**. Here you can configure:
* **Default timezone** for timestamps in exported post-mortems.
* **Custom terminology** to rename "post-mortem" across the product.
* **Template expression** for dynamic template selection based on incident properties.
* **Export destinations** for Google Docs, Notion, Confluence, and SharePoint.
* **Share templates** for Slack announcements.
* **Auto-sync follow-ups** from external documents back into incident.io.
# Scribe for post-mortems
Source: https://docs.incident.io/post-incident/postmortem-scribe
AI note-taker that joins your debrief call and feeds the transcript into your post-mortem.
A lot of the most valuable post-mortem content comes out during debrief calls. People explain what they were thinking, fill in gaps that didn't make it into Slack, and surface context that only exists in their heads. The problem is that none of this makes it into the post-mortem unless someone is taking notes while also trying to participate in the conversation.
Scribe is an AI note-taker that joins your debrief call as a participant. It captures a live transcript of the conversation, generates takeaways, and feeds it all directly into your post-mortem document. The person writing the post-mortem gets access to everything that was discussed without having to scribble notes during the call.
Scribe is available on Pro and Enterprise plans.
## How it works
Scribe is connected to your post-mortem through the meeting notes block in the editor. There are a few ways to set it up:
* **Paste a meeting URL** if you already have a call link.
* **Select an existing debrief** that's already been scheduled for the incident.
* **Create a new call** directly from the meeting notes block by selecting your call provider. We create the call for you, no need to leave the editor.
Once you've linked a call, click **Invite Scribe** to have the bot join as a participant and begin recording. You can pause the recording at any point if the conversation goes off-the-record or the group takes a break, and resume when you're ready to continue. Once the call is over, it processes the recording and generates takeaways — key actions and outcomes discussed during the call. The transcript and takeaways appear right there in the meeting notes block, embedded in the document alongside the rest of your content. After the call, you can browse the full transcript entry by entry within the meeting notes block.
## Meeting link rules
Scribe needs a separate meeting link for the debrief call. You can't reuse the incident call link that was used during the live incident, because that's a different context with different participants and a different purpose. The debrief call should be its own event, ideally scheduled through the debrief flow so everything is linked up properly.
# Sharing & exporting post-mortems
Source: https://docs.incident.io/post-incident/postmortem-sharing-and-exporting
Share your post-mortem via Slack and export it to Google Docs, Notion, Confluence, or SharePoint.
A post-mortem that nobody reads is a post-mortem that nobody learns from. Once you've finished writing, you need to get it in front of the right people. There are two ways to do this: sharing via Slack to announce it, and exporting to get a copy into whatever tool your organization uses for long-term storage. You can also automate both of these with [workflows](/post-incident/postmortem-workflows).
## Sharing via Slack
Sharing posts a message to one or more Slack channels with a link to the post-mortem. This is how you announce that a post-mortem is ready and get eyes on it.
You can share from the post-mortem document or from the "Share post-mortem" task in the post-incident flow. When you share, you pick which channels to post to and review the message before it goes out.
### Share templates
You can configure a default share template in **Settings > Post-mortems** that controls what the Slack message looks like. The template supports variables like the incident name, severity, and other incident properties, so the message is automatically populated with the right context.
You can also configure default channels to share to, and choose whether to automatically include the incident's own Slack channel.
## Exporting
Exporting creates a copy of your post-mortem in an external tool. We support exporting to:
* **Google Docs**
* **Notion**
* **Confluence**
* **SharePoint**
Before you can export, you'll need to connect the relevant integration for your external tool. You can do this from **Settings > Integrations**. Once the integration is connected, set up export destinations in **Settings > Post-mortems**. Each destination points to a specific location in your external tool (a Google Drive folder, a Notion database, a Confluence space, etc.), and you can have multiple destinations if you need to export to more than one place.
When you export, the full post-mortem content is rendered into the destination, including the timeline and follow-ups. You can re-export after making edits to the document. Re-exporting does not overwrite your existing export, so there's no risk of losing data.
If an export fails (for example, due to a permissions issue or a deleted destination in your external tool), you'll see an error message explaining what went wrong. You can fix the issue and retry the export.
If you just want to grab the content without setting up an integration, you can use "Copy as Markdown" from the overflow menu in the editor.
## External writing mode
If your team prefers to write post-mortems entirely in an external tool, you can set up a template with the "External" writing mode (see [Templates](/post-incident/postmortem-templates)). With this mode, the post-mortem is exported to your external tool immediately when it's created, and you do all the writing there. See [External documents](/post-incident/external-postmortems) for more on this workflow.
# Post-mortem templates
Source: https://docs.incident.io/post-incident/postmortem-templates
Define the structure of your post-mortems with configurable sections, help text, and AI instructions.
Templates define the structure that your post-mortems follow. When someone creates a new post-mortem, they pick a template, and the document is pre-populated with the sections you've configured. This gives your team a consistent starting point without having to decide on the structure each time.
You can have as many templates as you need. A detailed root cause analysis template for critical incidents, a lightweight one for minor issues, and anything in between. You can even set up rules to automatically select the right template based on the incident's properties, so the person creating the post-mortem doesn't have to think about which one to use.
## Suggested templates
We provide three templates to get you started. You can use these as-is, duplicate them and customize, or create your own from scratch.
**Contributors, Mitigators and Risks (CMR)**: Our recommended template for high severity incidents. It captures the key factors that contributed to an incident, what helped mitigate it, and what you learned from it. Sections: Summary, Timeline, Contributors, Mitigators, Learnings and risks, Follow-ups.
**Root Cause Analysis (RCA)**: An industry-standard template for capturing the root cause, impact, resolution steps, and lessons learned. It's more structured than CMR, with sub-sections for technical analysis, customer impact, and business impact.
**Lightweight Lessons Learned**: A simple template for low severity incidents where you don't need extensive analysis. It puts the lessons learned section before the timeline, so you focus on what you learned rather than a blow-by-blow account.
## Creating a template
Go to **Settings > Post-mortems** and scroll down to the template section. Click **Add template** to create a new one from scratch, duplicate an existing one, or use one of our Suggested Templates. You'll need to give it a name. Once the template drawer opens up, you can select the writing mode:
* **In-app**: write your post-mortem in the incident.io editor with real-time collaboration, mentions, and AI features. This is what most teams use.
* **External**: exports the post-mortem directly to an external tool (Google Docs, Notion, Confluence, SharePoint) when it's created. Use this if your team prefers to write in another tool. See [External documents](/post-incident/external-postmortems) for more.
You can also configure a **document title** for the template. This is a dynamic field that controls the default title set on new post-mortem documents. You can use variables like the incident name or severity to generate titles automatically (e.g., `Post-mortem: {{incident.name}}`), so your team doesn't have to name each document manually. If you're planning on exporting your document, you can configure the **Export Title**, which will be used as the file name in your export destination.
Once you've created the template, you can add and reorder sections.
## Sections
Every template is made up of sections. There are a few preset section types, and you can add your own custom sections.
### Preset sections
* **Summary**: a high-level overview of the incident. This is always a good starting point for readers who want to understand what happened without reading the full document.
* **Timeline**: embeds the incident timeline directly in the post-mortem. This section can't be removed.
* **Follow-ups**: shows the follow-up items associated with the incident. This section can't be removed, but you can configure whether follow-ups are rendered as links or as a full table.
* **Key information**: a block of incident metadata (severity, duration, roles, etc.). This only appears in external post-mortems, not in the in-app editor.
* **Feedback**: a section for collecting feedback on the post-mortem process. Like key information, this only appears in external post-mortems.
### Custom sections
Custom sections are where you define the actual analysis your team should do. When you add a custom section, you can configure:
* **Name**: what the section is called in the document (e.g., "Root cause analysis", "Customer impact", "Lessons learned").
* **Help text**: guidance shown to the person writing the post-mortem. This is where you describe what you're looking for in this section. For example, "Outline any factors that played a role in this incident happening. Consider both technical and process-related contributors."
* **Template prefill**: pre-populated content that gives the writer a starting structure. For example, sub-headings for "Root cause", "Contributing factors", and "Technical analysis".
* **Custom fields**: you can include specific custom fields in a section, so the writer is prompted to fill them in alongside the written analysis. For example, an "Affected customers" custom field in an "Impact" section. This also encourages responders to keep custom fields up to date.
### AI on sections
If you're using an in-app template, you can enable AI generation for each custom section individually. When AI is enabled for a section, you can provide custom instructions that guide how the AI generates content for that section. For example, you might tell the AI to focus on customer impact rather than technical details, or to always include specific metrics.
When AI is enabled for a section, the template prefill field is hidden, because the AI generation takes its place. The AI uses the section name, help text, and your custom instructions to generate the content.
## Dynamic template selection
If you have different templates for different types of incidents, you can set up an expression that automatically selects the right template based on incident properties. Go to **Settings > Post-mortems** and look for the template expression configuration.
You set up branches with conditions. For example: "If severity is critical, use the RCA template. If severity is minor, use the Lightweight template. Otherwise, use the CMR template." The expression is evaluated when someone creates a post-mortem, and the matching template is pre-selected for them.
This is one of the ways you can right-size your post-mortem process. Critical incidents get a thorough, structured template. Minor ones get something lightweight that takes five minutes.
# Automating post-mortems with workflows
Source: https://docs.incident.io/post-incident/postmortem-workflows
Use workflows to automate sharing, exporting, and other post-mortem tasks.
Once you've got a post-mortem process running, there are parts of it that really shouldn't require a human to remember to do them. Sharing the finished document in Slack, exporting a copy to your knowledge base, notifying a specific team when a post-mortem for their service is completed. These are the kinds of things that should just happen.
Workflows let you automate all of this. You set up a trigger, add some conditions, and define what should happen. The trigger for post-mortems is **A document is created or updated**, which fires when a post-mortem is created or when its status changes. From there, you can build whatever automation makes sense for your team.
## Auto-creating post-mortem documents
You can use workflows to automatically create post-mortem documents when an incident reaches a certain point — for example, when it's closed or when a specific status is reached.
To set this up:
1. Create a new workflow with the trigger that matches when you want the document created (e.g. **An incident is updated** with a condition on status).
2. Add the **Create in-app post-mortem** step.
3. Select the template you want to use.
If the template has AI-enabled sections, the document will be AI-generated automatically — no manual input needed. See [AI-native writing](/post-incident/postmortem-ai) for more on setting up AI templates.
### Fully automated AI post-mortems in Google Docs
If your team works in external tools rather than the in-app editor, you can chain two workflows together:
1. **First workflow**: Automatically creates the post-mortem document (using an AI-enabled template).
2. **Second workflow**: Triggers on **A document is created or updated**, with a condition of `Document > is generated: Yes`, and runs an **Export post-mortem** step to send it to Google Docs, Confluence, Notion, or SharePoint.
The result: an AI-generated post-mortem, exported to your knowledge base, without anyone lifting a finger.
## Announcing completed post-mortems in Slack
This is probably the most common workflow people set up, and it takes about a minute to configure.
The idea is simple: every time a post-mortem is marked as complete, a message is automatically posted to a Slack channel. Your team sees it, they can click through to read it, and nobody had to remember to hit the share button.
To set this up:
1. Create a new workflow with the **A document is created or updated** trigger.
2. Add a condition that checks if the post-mortem status is **Complete**.
3. Add a **Post to Slack channel** step, pick the channel you want to announce in, and write the message. You can use variables to include the incident name, severity, and a link to the post-mortem.
This is different from the manual sharing feature (see [Sharing & exporting](/post-incident/postmortem-sharing-and-exporting)) because it happens automatically. You don't have to rely on someone remembering to share the document, and you can guarantee that every completed post-mortem gets announced in the same place.
You can also get creative with the conditions. Maybe you only want to announce post-mortems for critical incidents in a company-wide channel, but all post-mortems go to an engineering channel. You can set up multiple workflows with different conditions to handle this.
## Automating exports
This one is really useful for larger organizations. You want to write your post-mortems in incident.io because that's where the incident data lives, but you also need a copy in Confluence, Notion, Google Docs, or SharePoint because that's where your org keeps its long-term documentation.
You could remember to hit the export button every time, but that's exactly the kind of thing that gets forgotten on a busy week. Instead, you can set up a workflow to do it for you:
1. Create a new workflow with the **A document is created or updated** trigger.
2. Add a condition that checks if the post-mortem status is **Complete**.
3. Add an **Export post-mortem** step and select your export destination.
Now every completed post-mortem is automatically exported to your knowledge base. No manual step, no forgotten exports.
One thing to watch out for: if someone changes the status back and forth (say, from Complete to In Review and back to Complete), the workflow will fire each time the document hits Complete. To prevent duplicate exports, add a condition that checks whether the document has already been exported. That way the workflow only runs the export the first time.
## Other ideas
The trigger and condition system is flexible enough to support plenty of other use cases. A few ideas:
* **Notify a team lead** when a post-mortem for their service is completed, so they can prioritize reading it.
* **Create a follow-up** automatically when a post-mortem is completed, reminding someone to present the findings at the next team meeting.
* **Send a message to Microsoft Teams** if that's where your team communicates, rather than Slack.
The building blocks are all the same: trigger on document created or updated, filter with conditions, and pick your action.
# Post-mortems
Source: https://docs.incident.io/post-incident/postmortems-overview
Turn incidents into learnings with collaborative, AI-native post-mortem documents.
A good post-mortem is one of the most valuable things to come out of an incident. It forces you to understand what actually happened, surfaces the systemic issues hiding behind the surface-level problems, and gives your team a clear set of actions to make sure it doesn't happen again.
The problem is that writing them is painful. You're staring at a blank page after a stressful incident, trying to piece together context from Slack threads, monitoring dashboards, and email chains. By the time you've gathered everything, you've lost the motivation to actually write the thing. And even if you do, getting feedback and driving it to completion is another battle entirely.
We built our post-mortem experience to take the pain out of this process. The editor has all your incident data right there in the document: your timeline, the people involved, custom fields, catalog entries. AI can generate a first draft from your incident data so you don't have to start from a blank page. And once you've written something, your team can edit it together in real-time, leave comments, and move it through a clear status workflow.
## How post-mortems work
Every organization does post-mortems differently. Some teams write them collaboratively during a debrief call. Others have the incident lead draft it solo and pass it around for review. Some want a lightweight summary for minor incidents and a thorough root cause analysis for major ones. Our goal is to support all of these approaches, so you can set up a process that works for your team instead of adapting to ours.
Here's what you get:
* An **editor built for post-incident context**. Your timeline, the people involved, custom fields, catalog entries, and more are all available directly in the document and kept in sync as the incident evolves. If you've used Notion-style editors, you'll feel right at home, but this one is purpose-built for writing about incidents.
* **[AI that writes the first draft for you](/post-incident/postmortem-ai#first-draft)**, pulling from your timeline, Slack or Teams conversations, and investigation data. You can also use AI to review a finished document and get inline suggestions, or to redraft sections that need work.
* **Templates** that give your team a consistent starting point. You can set up different templates for different types of incidents, and configure which sections AI should help with.
* **Real-time collaboration** with live cursors, threaded comments, and @mentions. Multiple people can write and give feedback without leaving the document.
* A **status workflow** to track where each document is: In progress, In review, and Completed. You can move through these however makes sense for your team.
* **Sharing and export** to get your finished post-mortem in front of the right people, whether that's announcing it in Slack or exporting it to Google Docs, Notion, Confluence, or SharePoint.
* A **post-mortem list view** that gives you a filterable view of every post-mortem across your organization, so you can see what's been completed and what's still outstanding.
## Multiple documents per incident
You can create multiple post-mortem documents for a single incident. Each document has its own status and can use a different template. This is useful when you need both an internal technical post-mortem and a customer-facing summary, for example.
Creating multiple documents per incident requires a Pro or Enterprise plan.
## Private incidents
Post-mortems for private incidents work the same way, with a few restrictions. AI features (first draft generation, review, and redraft) are only available if your organization has opted in to sending private incident data to AI subprocessors in [Settings → AI governance](https://app.incident.io/~/settings/ai-governance#ai-incident-access). If this isn't enabled, AI features won't appear for private incidents.
Sharing via Slack is not available for private incidents, since the post-mortem may contain sensitive information. You can still export to external tools and manage access through those tools' own permission systems.
## Custom terminology
If your organization calls them something other than "post-mortems" (retrospectives, incident reviews, learning reviews, etc.) you can rename them in your post-mortem settings. The custom name is used throughout the product, including in Slack messages and the post-incident flow.
## What's next
The editor experience: creating a document and working in it with your team.
Set up the structure your post-mortems follow, with per-section AI configuration.
Generate first drafts, get inline review suggestions, and redraft sections with AI.
AI note-taker for debrief calls that feeds directly into your post-mortem.
Announce your post-mortem via Slack and export it to external tools.
Track completion across your org with list views, policies, and SLAs.
Automate sharing, exporting, and notifications when post-mortems are completed.
Programmatic access to your post-mortem documents, metadata, and content.
Write your post-mortems in Google Docs, Confluence, Notion, or SharePoint.
# Shoutouts
Source: https://docs.incident.io/post-incident/shoutouts
Sometimes, you need to shoutout a contribution by a coworker during an incident. Now you can with the shoutout command.
1. In an incident channel, type the command /inc shoutout or click the ' Give a shoutout' button.
2. Then select the user you want to shoutout, and write a message highlighting how awesome they are!
3. You can customize where shoutouts get posted in [the Automation settings](https://app.incident.io/~/settings/automation). This way you can collect shoutouts in a separate #gratitude channel.
# Generating your incident timeline
Source: https://docs.incident.io/post-incident/timeline
Post-mortems are a best practice and incredibly useful. Good post-mortems rely on someone (you?) building a clear and cohesive timeline of the incident.
But it can become a real nightmare to retroactively parse through 100s of Slack messages, screenshots, Sentry errors, GitHub PRs/commits etc. to get a clear picture of what happened.
Not anymore! **While your incident is playing out and you're focused on fixing, we'll be your scribe, hoovering up and digesting key events for you**
## Where's the timeline?
You can find an incident's timeline on the `Timeline` tab.
## Editing the timeline
We'll automatically create events on your timeline using your incident updates (e.g. severity changes, status changes) and pinned slack messages.
This should give an overview of your key moments, but you may want to add some extra color about these events, or add other important events. You can do this from inside our editor - just hit the `Edit` button.
The right panel here shows you what your timeline currently looks like. To change any of the titles or add a description, just hit the pencil icon.
## Adding other events
You can do this a few ways.
#### (1) Adding items from the activity log
On the left panel in the editor you'll notice every event that we detected during the incident. These include:
* Role changes
* Updates to the incident summary
* Actions (created, assigned, updated)
* Pull requests and commits in GitHub
* Errors in Sentry
* Images posted in the channel
If any of these events are important to the narrative, you can add them to the timeline by just hitting the plus icon button.
#### (2) Pinning messages from the Slack channel
While in an incident's `/inc-...` channel, simply **use the pin emoji** on a message, screenshot etc. to add it to the timeline! You can also use Slack's built-in "Pin to channel" command 👇🏼
*Items pinned will be stamped at the time of their actual posting, not at the time at which they were pinned. So* **don't worry if you forgot to pin items in the heat of the moment** *! We'll make sure to position them adequately on the timeline.*
#### (3) Adding a custom event
If the event happened outside of the incident channel (e.g. a code deployment, a message from a customer), you can still add it to the timeline as a custom event.
You just need to provide the timestamp and a title for the event.
## Then what?
Once you've curated your timeline, you might want to **create a post-mortem** in your document provider like Notion. We'll render a copy of the timeline in your document for you!
You may also want to **start a discussion** about particular events on the timeline. For instance, if there is ambiguity about why something happened that might be relevant to the debrief, you could start a discussion in advance. Just hover over an event to add a comment. Your comment will notify other responders who have been following the incident
# Writing & editing post-mortems
Source: https://docs.incident.io/post-incident/writing-and-editing
A collaborative editor with deep access to your incident data, catalog, and integrations.
Writing a post-mortem means gathering information from a dozen different places: Slack threads, monitoring dashboards, GitHub PRs, your service catalog. The post-mortem editor is designed to bring all of that into one place. It's a real-time collaborative editor with all the formatting you'd expect from a modern writing tool, but with deep access to your incident data, your catalog, and your integrations.
This is what makes it different from writing your post-mortem in Notion or Google Docs. You're not just writing text. You can reference a Slack message and it renders as a rich card. You can mention a catalog entry and it links directly to your service. You can pull in timestamps from your incident timeline without having to go find them. Everything stays in sync with the incident as it evolves.
## Creating a post-mortem
To create a post-mortem, go to an incident and click the "Create post-mortem" button. You'll be asked to select a template, and clicking "Create" will take you straight into the editor. If you have a post-incident flow configured with a "Create post-mortem" task, the button is right there in the task.
Once the document has been created, you're ready to start editing.
## The editor
The editor is fully collaborative. Multiple people can have the document open at the same time, and you'll see each other's edits as they happen. You can see who's present in the document, where their cursors are, and what they're highlighting. This works especially well when you're writing the post-mortem together during a debrief call.
### Formatting
The editor supports all the formatting you'd expect from a modern writing tool:
* **Headings** (H1, H2, H3) for structuring your document
* **Bold**, **italic**, **underline**, **strikethrough**, and **inline code** for inline formatting
* **Bulleted lists** and **ordered lists**
* **Blockquotes** for highlighting key points or quoting messages
* **Links** with full editing support
Highlight any text to open the formatting toolbar, where you can apply these styles quickly.
### Slash commands
Type `/` anywhere in the document to open the block menu. This gives you access to richer content blocks:
* **Callouts** for drawing attention to important information, warnings, or notes
* **Code blocks** with syntax highlighting for sharing configuration, logs, or scripts
* **Tables** for structured data (resizable columns, header rows)
* **Images** (upload directly, or insert from your incident's Slack or Teams channel)
* **Horizontal rules** for visual separation between sections
* **Incident timeline** to embed your full incident timeline directly in the document
* **Follow-ups** to embed the list of follow-up items associated with the incident. You can also create new follow-ups directly from the editor. See [Follow-ups](/post-incident/follow-ups) for more on how follow-ups work.
* **Meeting notes** to embed the transcript and takeaways from a Scribe recording of your debrief call
The incident-specific blocks (timeline, follow-ups, meeting notes) are kept in sync with the incident. If someone adds a new follow-up, it shows up in the embedded block automatically.
### Mentions
This is where a lot of the power of the editor comes from. Type `@` to reference data from across your incident and your organization. Mentions render as rich, interactive elements in the document, not just plain text.
**Incident data:**
* **Timestamps** from your incident timeline, so you can reference exactly when things happened
* **Durations** showing elapsed time since the incident started
* **Custom fields** associated with the incident
* **Follow-ups** associated with the incident
* **Other incidents**, if you need to reference related events
**People:**
* **Users** involved in the incident, with context about their role
* **Role assignments** (incident lead, communications lead, etc.)
**Catalog:**
This is where the editor really sets itself apart. You have access to your entire catalog setup, which means you can reference:
* **Services** affected by the incident
* **Teams** and team structures
* **Customers** and customer information
* **Infrastructure components**, environments, and anything else you've modeled in your catalog
Whatever you've structured in your catalog, you can reference it directly in your post-mortem. If you've set up relationships between services and teams, or between customers and their associated infrastructure, all of that context is available here.
**Integrations:**
* **Slack messages** from the incident channel, rendered as rich cards with the original message content
* **GitHub PRs** that were attached to the incident
* **Slack channels** for referencing where conversations happened
Hovering over any mention shows additional context. A user mention shows their role in the incident. A catalog entry links to the full catalog page. A Slack message shows the original content. Everything is interactive and connected.
### Images
You can add images to your post-mortem in two ways:
* **Upload directly** using the `/` menu or by dragging and dropping an image into the editor
* **Insert from Slack or Teams**: browse images that were shared in the incident channel, search by description, and select multiple images at once. No need to download screenshots from Slack and re-upload them.
## Comments
Select any text in the document and click the comment icon to start a threaded discussion. You can @mention people in comments to notify them. Comments can be replied to, resolved when addressed, and accessed later through the Resolved Comments sidebar in the overflow menu.
Comments are collaborative too. If someone adds a comment while you're in the document, it shows up in real time.
## Version history
The editor automatically creates snapshots of your document as you work. You can access version history from the overflow menu in the top header. From there you can preview any previous version and restore it if you need to. Restoring a version doesn't destroy anything, it creates a new snapshot with the restored content.
## Analytics
The overflow menu also shows you document analytics: who has viewed the post-mortem and when, and who has made edits. This is useful for tracking engagement, especially if your team has a review step in the process.
## Main document
When you have multiple post-mortem documents for an incident, one is designated as the "main" document. The main document's status is what syncs to the incident's overall post-mortem status, and it's the one used by default in workflows and exports. You can change which document is main from the document's overflow menu.
## Deleting a post-mortem
Post-mortems can be deleted from the overflow menu. Deleting removes all versions of the document permanently, but once deleted, you'll be able to create a brand new one. If you've modified your template since the last post-mortem was created, the new document will use the updated template.
# Status page APIs
Source: https://docs.incident.io/status-pages/api
Automate status page incidents, maintenance windows, and embed status data in your product.
incident.io provides two APIs for status pages: the **[Status Page API](#status-page-api)** for programmatically managing incidents and maintenance windows, and the **[Widget API](#widget-api)** for embedding status data into your own product.
Both APIs are for **public** and **customer** status pages only. Internal status pages do not support API access.
## Status Page API
Using the Status Page API, you can programmatically update your status page to make your customers aware of problems immediately or to schedule routine maintenance windows in advance. The approach via the API mirrors the steps in the incident.io dashboard.
### Prerequisites
To use the API, you need an API key with the required scopes. For read-only access (listing status pages, viewing structure, incidents, and maintenance windows), any valid API key will work.
For write requests (creating incidents, maintenance windows, and publishing updates), you need an API key with the "Create status page incidents, maintenance windows and publish updates" scope. You can create an API key in the incident.io dashboard.
You can find details of all endpoints in the [Status Page API docs](https://docs.incident.io/api-reference/status-pages-v2/).
### Status page incidents
**Creating a status page incident**
To declare a status page incident, you use the `CreateStatusPageIncident` endpoint.
* You will need the ID of your status page. This can be found using the `ListStatusPages` endpoint, which lists your status pages by name and ID.
* You will need to set an initial `incident_status` for the incident, give it a `name` and provide a `message` which will be used for publishing that initial update.
* Optionally, you can specify which components the incident has affected by providing their `component_statuses`. You will need the IDs of the components, which you can find using the `ShowStatusPageStructure` endpoint once you've already found out your page's ID.
* You're also required to provide a unique `idempotency_key` for the incident and whether to `notify_subscribers` to your status page.
**Publishing an update**
Once you've declared the status page incident, you can publish updates on the progress of the incident using the `UpdateStatusPageIncident` endpoint.
* You can update the `incident_status` and/or `component_statuses`, and provide a new `message` to your viewers and subscribers.
**Resolving a status page incident**
To resolve a status page incident, you again use the `UpdateStatusPageIncident` endpoint, setting the `incident_status` to `"resolved"`.
Any components affected by the incident will be reset to `"operational"` (within that incident).
**Updating the incident name (optional)**
During a status page incident, you may wish to update the incident's name, for instance because its nature has changed and its original name is outdated.
You can do this using the `UpdateStatusPageIncident` endpoint described in the API docs.
### Status page maintenance windows
Status page maintenance windows are similar to status page incidents, so this focuses on the important differences and features.
**Scheduling a maintenance window**
To schedule a status page maintenance window, you use the `CreateStatusPageMaintenance` endpoint.
* Unlike with status page incidents, you will need to provide a `start_at` and `end_at` when scheduling maintenance.
* You supply a `maintenance_status` rather than an `incident_status`.
* Optionally, you provide a list of the IDs of components affected by the maintenance.
**Publishing an update**
To publish a status update on a maintenance window, you use the `CreateStatusPageMaintenanceUpdate` endpoint.
In the incident.io dashboard, you can choose to manually or automatically update the status of a maintenance window. The API uses the **manual status updates** approach: you must publish updates in order to update the maintenance window's status, and move it from e.g. `"maintenance_scheduled"` to `"maintenance_in_progress"`.
**Completing a maintenance window**
When the maintenance is complete, you again use the `CreateStatusPageMaintenanceUpdate` endpoint to publish a final update, this time setting the `maintenance_status` to `"maintenance_complete"`.
If you're looking to automate status page updates triggered by incidents in the Response product, you may find [publishing via workflows](/status-pages/auto-publishing) more suited to your needs.
***
## Widget API
The **status page widget API** is a read-only JSON API that reflects the current content of your status page. Use it to embed status information directly into your own product — for example, displaying a banner at the top of your web page or a pop-up in your mobile app.
The widget API updates whenever you update your status page, and is a direct reflection of the data shown there.
To enable the widget API, go to your status page in the dashboard, then **Settings**, then **Widget API**.
Although the widget API **can** be called directly from a web app, we strongly recommend proxying it through your own backend with some level of caching. The response itself is highly cacheable. If we notice high levels of traffic for your status page, we will reach out to discuss this.
### Response structure
You can see a preview of the full JSON response from within the **Widget API** settings page. It contains three arrays — `ongoing_incidents`, `in_progress_maintenances` and `scheduled_maintenances`, allowing you to distinguish between those three different types of event. Each incident in those arrays will have dates associated with it.
Each incident also has an ID, name, status, the last update message, and several other fields. It also contains affected components. By implementing your own logic, you can use these components to decide (for example) whether to show a banner on a certain page or not. For example, if the incident contains "Login" as an affected component, your login page can filter on that.
### Authentication
The endpoint is unauthenticated and publicly accessible on the internet. You can see the URL from within the **Widget API** settings page.
***
## FAQs
Yes — use the [Status Page API](#status-page-api) to programmatically declare incidents, publish updates, resolve
incidents, schedule maintenance windows, and mark maintenance as complete. See the [API
docs](https://docs.incident.io/api-reference/status-pages-v2/) for endpoint details.
Yes — you can create and manage maintenance windows using the [Status Page API](#status-page-maintenance-windows).
This allows you to schedule maintenance, publish updates, and mark maintenance as complete, all programmatically.
Note that maintenance windows are only available on public and customer status pages.
Yes — the [Widget API](#widget-api) allows you to retrieve information about ongoing incidents and scheduled
maintenance. It works regardless of whether your status page is live or not. The Widget API is read-only — to create
or update incidents, use the [Status Page API](#status-page-api).
## Related resources
* [Status Page API docs](https://docs.incident.io/api-reference/status-pages-v2/)
* [Automatically publishing via workflows](/status-pages/auto-publishing)
# Automatically publishing to your status page
Source: https://docs.incident.io/status-pages/auto-publishing
Automatically updating your status page means you can make your customers aware of problems immediately, and remove a step from your incident response process.
With [Workflows](/workflows/getting-started), you can automatically publish to your status page when an incident is updated. Let’s have a look at how it’s done.
***
To automatically publish to your status page, we'll use Workflows. If this is your first time setting up a workflow, take a look at our [starter guide](/workflows/getting-started).
To automate status page updates, create a workflow with the trigger and conditions you want to cause an update to your status page. If you want to update your status page whenever an incident changes, we recommend using *When an incident is created or changed* as your trigger.
Next, add a workflow step, and select "Create or update a status page incident".
You’ll see a form like this:
1. **Status page components**
Which components do you want to mark as affected by this incident? This will show up on your status page and in emails to subscribers.
If you'd like this to be set dynamically, you can [use an expression](/workflows/expressions) based on your incident fields.
2. **Component impact**
This will be marked as the impact for all affected components referenced in your workflow. Once responding to an incident, you can update this, but all components must have the same impact to start with.
Just like status page components, you can use an expression to set this dynamically. For example mapping your incident severity to component impact.
3. **Name**
This is the public name of your incident and will be visible on your status page.
If you don't want a static incident name, you can use variables as part of the name. Just remember that your internal incident name may not be what you want to publish!
4. **Status**
Select the status you want us to set on your status page incident.
5. **Message**
This is a longer-form update you can use to communicate in more detail with your customers.
As with other fields, you can use expressions to insert dynamic variables into your message.
6. **Automatic resolution**
Resolving your status page incident is easily forgotten once an incident is closed, so if you want, we can do that for you. Set a message for auto-resolution, and we’ll publish that and mark your status page incident as resolved when you mark your internal incident as resolved.
This will show up as an update on your status page incident, and will also mark the incident as resolved and all affected components as operational.
### When will this workflow create a new incident vs update an existing one?
We decide this based on the linked internal incident. If there is a status page incident that has your trigger incident linked to it, we will update that status page incident. Otherwise, we will create a new one.
This also means that if you have two workflows that both update status page incidents, they will update the same incident if they are triggered by the same internal incident.
# Ordering status page components
Source: https://docs.incident.io/status-pages/component-ordering
**Status pages backed by Catalog types:**
* [Internal Status pages](/status-pages/create-internal)
* [Sub-pages](/status-pages/sub-page-setup)
* [Customer pages](/status-pages/customer-overview)
These status pages are backed by catalog types, you can choose from two ordering options.
1. Alphabetically ordered **(Default Setting)**
2. This is done by default in catalog types if no ranking is selected.
3. Ranked
4. You can choose to rank the values in the catalog types by clicking the edit button on the catalog type and choosing the rank option at the bottom.
**Status pages NOT backed by Catalog types:**
For single-page status pages that are not backed by a catalog type, the ordering is handled by dragging components in the order you would like, under
Status page → Settings → Components.
# Creating an internal status page
Source: https://docs.incident.io/status-pages/create-internal
Get an internal status page set up in three steps:
1. **Choose a name**
This name will be the page heading and the default bookmark name if people choose to bookmark the page in their browser or in Slack channels.
2. **Choose your components**
To keep things simple for responders, the components shown on the status page are based on a custom field. If you have a field like ‘Impacted Products’ or ‘Affected Services’, that’s probably a good place to start.
*Note: You can only use multi-select custom fields to power your components.*
If you want to simplify which components are shown on your internal page compared to the full list of options in the custom field, you can use an [Automated Custom Field](/catalog/catalog-setup) to combine options.
For example, if you have a list of ‘services’ and ‘features’ in your Catalog, you can add an attribute that lists which features are powered by each service:
You can now create a ‘Features’ custom field that is set automatically when the ‘Services’ custom field is set, translating from the technical services to the product features impacted:
Using the ‘Features’ custom field to power your internal status page keeps the complexity of how different services impact your product in the background and lets your customer success team understand what customers will be seeing.
### Component Ordering
If the custom field used on the internal status page is backed by catalog type as in the example above, you have 2 options for the ordering of components:
* Alphabetically
* Ranked
more info in this [article](/status-pages/component-ordering).
If not using a catalog-backed custom field, the ordering will be shown as it is set in the custom field.
3. **Customize your branding**
Choose between light and dark themes and add your logo and you’re ready to go!
## → What’s next?
By default, live incidents will be automatically added to your internal status page if they affect any of the components listed on your page. You can configure this under ' *Settings > Automation* '.
You can also add additional context to your internal status page by showing additional custom fields. Configure this under ‘Basic settings’ in the Settings tab.
# Getting started with customer status pages
Source: https://docs.incident.io/status-pages/customer-overview
## What are customer pages and when do I need them?
Customer pages give you the ability to provide your customers with a dedicated, authenticated status page, managed centrally. Customer pages are managed like our [sub-pages](/status-pages/sub-pages), but add a layer of authentication onto each page to limit access to a specific customer.
You may want to use customer pages if only a subset of customers are impacted by an incident. For example, if you run dedicated infrastructure for customers, or maintain components for a small set of high-value customers, you can use customer pages to give those customers a dedicated space, that always shows them when *their* experience of your product is experiencing issues.
## How do I setup customer pages?
Like our sub-pages, customer pages are powered by Catalog. When setting up your customer pages, you can either use an existing catalog type, or create a new one. Creating a customer page works just like [creating sub-pages](/status-pages/sub-page-setup).
## Managing access to customer pages
Access to customer pages is controlled by email address, using a sign-in link. This means users must have a valid email address which can receive emails.
Access is checked by the email *domain*, so if you specify *example.com* on your allowlist, *anyone* with that email domain, such as [john@example.com](mailto:john@example.com), can access the customer status page.
Since access is controlled via email, you should not add public email domains such as *gmail.com* to your allowlist. Doing so will result in anyone using that email provider being granted access to your customer page.
### Configuring the domain allowlist
Customer pages are access controlled by an email domain allowlist, controlled through the catalog.
For each sub-page, you can specify one or more email domains. Anyone with an email address matching that allowlist will be able to login to the page.
We check against the allowlist every time a user is on the status page – if you remove a domain from the allowlist, users matching that domain will immediately lose access.
### Sharing the page with your customers
The URL to a customer page is not publicly visible anywhere. For your customer to access your page, send them a link to their status page.
You can see the URL of your page either by visiting the page, or by going to edit the page in your settings.
# Can I customize the appearance of my status page?
Source: https://docs.incident.io/status-pages/customization
Currently, status page customization options are limited to:
* Adding your company logo
* Setting a custom favicon
* Setting a custom domain
The following additional customization options are not currently available features of the status page:
* Custom colors and branding
* Layout modifications
* Custom CSS styling
* Removing the incident.io footer branding
* Sending subscriber emails from your own email server / address
These customization capabilities have been logged as feature requests that we're tracking. If you'd like to add your vote, just let us know at [help@incident.io](mailto:help@incident.io)
# Can I customize the email sender address for status page email notifications?
Source: https://docs.incident.io/status-pages/email-sender
## Context
It's often desirable to be able to customize the "from" email address for status page notifications and subscription confirmations to use a custom domain instead of the default [no-reply@status.incident.io](mailto:no-reply@status.incident.io) address.
## Answer
Currently, all status page email notifications are sent from [no-reply@status.incident.io](mailto:no-reply@status.incident.io) and this cannot be customized. However, you can configure a reply-to email address that subscribers will be directed to when they reply to incident notifications.
Here's what you need to know about status page email notifications:
* All status page emails will be sent from [no-reply@status.incident.io](mailto:no-reply@status.incident.io)
* You can set up a custom reply-to email address for incident notifications:
1. Go to your status page settings
2. Navigate to the Subscriptions section
3. Enter your preferred reply-to email address
4. Click Save
* The reply-to address will only work for incident notification emails, not for subscription confirmation emails
Note: If this is a feature you'd like to see supported in the future, please let us know at [help@incident.io](mailto:help@incident.io) and we'll make sure to add your vote.
# Go-live checklist for your new status page
Source: https://docs.incident.io/status-pages/go-live-checklist
You've got your new status page set up and looking great. There's a few things to double-check before you're ready to go live.
## 1. Link your policies
There's two important policies to link to from your status page: your privacy policy, and your terms of service.
These are particularly important if you're allowing your customers to subscribe to updates from your status page, since they'll govern how those messages will be delivered, and how customers can unsubscribe.
We suggest that you chat with your organization's legal team first, but your organization's standard privacy policy and terms of service, usually found in the footer at the bottom of your main website, should suffice.
## 2. Enable search engine indexing
There's two main ways for your customers to find your status page: via a direct link, or via a search engine. To get your status page appearing in search results, you'll need to enable search engine indexing in the settings page:
We'd recommend adding a link to your status page from your own website too.
## 3. Set up a custom domain
Using your own domain name for your status page helps your customers know they're in the right place. We'd recommend using `status.your-domain.com`.
There's three steps to getting this set up:
First, enter the domain you'd like to use and click 'Save':
Next, log in to your DNS provider and configure the necessary records. You'll need to set a `CNAME`, which directs traffic to our servers.
You might also need to set a `TXT` record: this is a security measure to verify that you own the domain. You can remove this record once the domain is verified.
When you're done, click 'Check'. We'll make sure the DNS records look correct, and then start serving your status page on the custom domain.
## That's it!
You're ready to go live!
# Getting your status page ready to go 'live'
Source: https://docs.incident.io/status-pages/going-live
Creating your first status page within incident.io should only take a few minutes. You can then tangibly see what your page could look like and get any other pieces in place before you officially 'go live.'
This article walks through some of the things you may want to consider before officially turning your status page on for your customers.
### Add your Privacy Policy and Terms of Service
Under **Status Page Settings** → **Basic Settings**, you can add a link to your organization's Privacy Policy and Terms of Service.
This will provide the terms of engagement between you and your customers and additional information on how their information will be collected. If you have any questions or concerns, we'd suggest reaching out to your legal team for more clarification.
### Show in search results
We currently default your newly created status page to not be shown in search results, as you may be testing and playing around.
Once you are ready to turn on your new status page, we'd suggest ticking the box for 'Show in search results' so that your customers can easily find your status page. This can be found under **Status Page Settings** → **Basic Settings.**
### Enable additional settings
There are a bunch of settings that you may want to enable for your public status page that may be helpful for you. You can:
* Add **Google Analytics** tags
* Add a **reply-to email address** for your email subscribers
* Add a **support URL** to link from your public status page
* **Remove ability to subscribe** to incidents or your status page in general
All this and more can be found under **Settings.**
### Set up your custom domain
One of the last steps before you are ready to go with your shiny new status page is to set up your custom domain, if you have one! This is super easy to do if you hop on to **Status Page Settings** → **Custom domain.**
### Add your subscribers
We suggest that this step happens as close to the time between when you switch from your old status page provider to our solution so we can ensure your subscribers don't miss out on any incident updates.
In order to port over your existing subscribers, please drop us a message via your Slack Connect channel, or at [help@incident.io](mailto:help@incident.io) and we will get that set up for you.
### Remove your current status page integration
Last but very not least, the last step to officially move over to our page is to remove any old status page integrations from incident.io. This will ensure that your responders won't accidentally update the wrong status page during an incident.
To remove your integration, please go to **Settings** → **Integrations.**
***
So, to recap, we'd suggest the following items to get your status page set up for your customers:
* Adding links to your Privacy Policy and Terms of Service
* Allowing search engine indexing
* Enabling any other settings you may want for your page
* Setting up your custom domain
* Porting over your list of subscribers
* Removing your current status page integration
If you have any questions or concerns about getting your status page all set up, please drop us a message via your Slack Connect channel, or at [help@incident.io](mailto:help@incident.io).
# How do I add Google Analytics to my status page?
Source: https://docs.incident.io/status-pages/google-analytics
## Context
When managing a public status page, you may want to track visitor analytics using Google Analytics to better understand your page traffic and usage patterns.
## Answer
You can add Google Analytics tracking to your public status page through the page settings. Here's how:
1. Navigate to Status Pages in your dashboard;
2. Select your public status page;
3. Click on **Settings**;
4. Go to **Basic Settings**;
5. Under the **Customisation** section, locate the **Google Analytics tag** field;
6. Add your Google Analytics tag.
# High page view alerts
Source: https://docs.incident.io/status-pages/high-page-views
[incident.io](http://incident.io/) can send you alerts when your status page is receiving a higher number of views than normal.
This integrates with our alerts and triggers system, meaning that you can configure what actions we should take when we detect that this is happening.
## When will you alert me?
[incident.io](http://incident.io/) will send you an alert when we notice your status page has had an average amount of views that are three standard deviations higher than they would be in a normal 15 minute window.
In order for your page to be eligible to receive alerts it has to:
* Have been live for more than four days
* Have a custom domain attached
* Have not had a status page incident updated in the last 15 minutes
## How can I turn this feature on?
High page views is listed as an alert source in the triggers section of the product - there you’ll be able to choose what to do when you get an alert like this.
You can see the triggers that apply to this status page by going to Status Pages, clicking Settings, then “Page views”.
If you don’t have a trigger that applies, you’ll be guided to create one.
Once you’ve created a trigger that applies to your status page, it’ll show in this section.
If you want to see all your triggers, click to the “Alerts” section and you’ll be able to see all triggers that apply to all alerts.
## How can I turn this feature off?
You can set a trigger to ignore alerts which have the source “Status Page Views”; this means that when an alert is created, your trigger won’t cause it to be escalated.
You can see the triggers that apply to this status page by going to Status Pages > Settings > “Page Views”.
Either edit the trigger so it doesn’t apply to this alert source, or delete it all together.
# How do I import subscribers from another status page provider?
Source: https://docs.incident.io/status-pages/import-subscribers
## Context
When migrating from another status page provider to incident.io, you may want to transfer your existing subscribers to ensure continuous service monitoring for your users. This article explains how to import your subscriber list.
## Answer
While there isn't a self-service import feature, our support team can help import your subscribers. Here's how to migrate your subscribers:
1. Export your subscriber list from your current status page provider into a CSV file
2. Ensure the CSV contains:
* Email addresses of confirmed subscribers
* If applicable, component subscriptions for each subscriber
3. Contact our support team with your subscriber list at [help@incident.io](mailto:help@incident.io)
Important notes about the import process:
* Subscribers won't receive any confirmation emails during the import
* The import is silent and seamless - subscribers will only receive notifications for future incidents
* We recommend performing the import as the final step of your migration to avoid duplicate notifications if running two status pages in parallel
# Getting started with internal status pages
Source: https://docs.incident.io/status-pages/internal-overview
Watch this video to view a full demo of creating an internal status page, through to using it in your incident response process:
# Control who can publish to your internal status page
Source: https://docs.incident.io/status-pages/internal-permissions
If you wish to restrict who can publish incidents and updates to your internal status page, you can achieve this with a custom role.
All of this is managed via the 'Publish to status pages' permission:
By default, the 'responder' role allows anyone in your Slack workspace to update your status page. Learn how to configure this in our [article on customizing permissions](/admin/user-permissions).
# How to publish an incident to your internal status page
Source: https://docs.incident.io/status-pages/internal-publishing
Internal status pages allow your organization to get quick access to a summary of what the known issues are right now with your system - they allow you to display ongoing incidents in a clear way to non-technical stakeholders.
Incidents can be published to your internal status page in two ways: by either manually publishing it from within your incident channel, or by configuring a set of conditions to automatically publish matching incidents to the page.
## Manually publishing an incident to your internal status page
You can manually publish an incident to your internal status page using the `/inc sp` command from within your incident’s Slack channel.
If you have both external and internal status pages configured, you’ll be prompted to select which type of status page you want to update. Choose ‘Internal page’
Select the page you’d like to publish this incident to, and hit publish.
That’s it! You can navigate to your internal status page and you’ll now see the incident you’ve just published. If you want to remove this incident, you can do so via the dashboard.
Any new updates that are created for the incident via `/inc update` (or via the dashboard) will now appear in your status page, allowing you to get the latest updates for all ongoing incidents at a glance.
## Automatically publish incidents to your internal status page
Automatically updating your status page means you can make your audience aware of problems immediately, without any need for manual intervention.
Internal status pages are automatically published to by configuring automation rules.
You can think of these as criteria against which your incidents should be filtered, in order to be displayed on your status page.
## Configuring rules
To configure automation rules, head over to the ‘Settings’ tab, and then ‘Automation’.
We’ll automatically set you up a rule which means that any incidents affecting your components will be published to this internal page.
You can edit or delete this rule, or add new rules by clicking on ‘Add automation rule’.
You can chose whether or not a rule applies only when an incident affects one of the components listed on your status page, or applies to all live incidents:
## How does manual publishing affect my automation rules?
If you manually publish an incident to your status page that already matches your automation rules for the page, this will have no additional effect.
Removing the incident, however, means that you will need to manually publish it again if you want it to display on your internal status page.
## FAQs
No. Private incidents are excluded from internal status pages. If an incident is marked as private, it won't appear
on any internal status page — even if it matches your automation rules. To display it, you'll need to remove the
private flag first.
# How do internal status page subscriptions differ from public status page subscriptions?
Source: https://docs.incident.io/status-pages/internal-vs-public-subscriptions
The core concept is similar – you hit “Subscribe” and you’ll be kept in the loop – but the mechanism and options differ because of the audience:
* **Internal page:** Only available to people inside your organization. When they subscribe, [incident.io](http://incident.io/) will confirm how they want updates (Slack, email, or both if supported). Once subscribed, they are automatically following all incidents on that internal page. So if a new incident is added to the internal page, they’ll get a Slack DM and/or email about it immediately, and they’ll get every update posted to any incident on the page. They can manage subscriptions via the page (for instance, if they want to stop following a particular incident, they might do so on the page or by a link in the notification). Internal subscriptions are great for roles like Customer Success or Leadership who need to know every time a high-priority incident is happening and evolving.
* **Public page:** Available to anyone (customers, end users). When someone subscribes on a public page, they will usually need to confirm their email (to ensure it’s a valid subscription). They can choose to subscribe to the whole page (meaning any incident/maintenance event postings) or drill down to specific components. Public subscribers won’t get Slack DMs (since they are outside your Slack), but they will get emails. They also have the RSS option. Managing public subscriptions (unsubscribing or changing preferences) is typically done through links provided in the notification emails or on the status page itself.
In short, internal subscriptions leverage your company’s communication channels (Slack) and assume you want **all the things**, whereas public subscriptions are more controlled as not every incident needs to be communicated to external stakeholders.
# Status Pages maintenance automation
Source: https://docs.incident.io/status-pages/maintenance
## How do maintenance windows work?
A maintenance window is similar to an unscheduled incident, but with a few differences:
* It must have a set time window which confirms when you expect components to not be working as normal.
* Scheduled maintenance windows appear in your status page in advance, to help your customers plan around it.
* Optionally, maintenance windows can progress to ‘in progress’ at the start time, and then to ‘completed’ at the end of the maintenance window. Automated updates will not notify your subscribers. If you disable this, you’ll need to manually update the status of the maintenance window when it is in progress and when it is completed.
‘In progress’ maintenance windows will appear on your status page as ongoing issues for your customers to be aware of.
## How do I schedule a maintenance window?
Scheduled maintenance is only available for your public-facing status pages - internal pages cannot currently have
scheduled maintenance added to them.
Navigate to [Status pages](https://app.incident.io/~/status-pages) in your left-hand menu, and select the status page you want to add scheduled maintenance to. Then, click in to the **Maintenance** tab:
In the top-right of your screen, you'll now see a **Schedule maintenance** button:
Click this to open up the form:
This is similar to the ‘publish incident’ flow, but there’s a few differences. Let’s walk through the form.
1. First **choose a name** : we’ll use this anywhere that links to this maintenance window, and as the subject line in any emails to subscribers.
2. Next choose **whether to automate this maintenance**.
By default, we’ll automatically update your maintenance window to be ‘in progress’ at the scheduled start time, and to ‘completed’ at the scheduled end time.
3. Now select the **start and end time** of the maintenance window.
4. The **message** is where you explain the anticipated impact of this maintenance event.
This will be shown on the status page for this maintenance window, and optionally sent to your subscribers.
5. Finally select **which components will be affected**.
This helps your customers understand whether they’ll be impacted by this maintenance event.
***
As with an unscheduled incident, click ‘Review’ to double-check before you publish to your status page.
# Migrating from Atlassian Statuspage
Source: https://docs.incident.io/status-pages/migrate-from-statuspage
We can import your page setup, incident and maintenance history, and subscribers from Atlassian Statuspage in to a Public Status Page in incident.io.
We don't currently support importing from Atlassian Statuspage to Customer or Internal only status pages - but if this is something you'd like to see, please let us know!
To do this, you will need to have the integration with Atlassian Statuspage enabled within incident.io. This can be found under Integrations in the Settings section of the dashboard.
Once that has been enabled, just pop over to the Status Pages section of the dashboard and click on the 'Let's go' link to begin the migration.
Clicking on 'Let's go' will provide some details about what happens next, namely:
As mentioned in the UI, we won't import your subscribers until you are officially ready to make the switch. This ensures we don't miss importing any new subscribers during this transition phase.
Once you are ready to officially go live, just click on 'Go live' on the top banner of your status page (now in blue).
Then, we will do the rest and your page will be officially live for your customers!
## FAQs
As part of the migration, once you are ready to go live, all email subscribers will be automatically subscribed to your incident.io status page. We will not migrate webhook, Slack, or SMS subscribers at this time.
# Can I create status pages in multiple languages?
Source: https://docs.incident.io/status-pages/multiple-languages
When managing incidents and status pages, you may need to communicate with customers in different languages. This includes both the status page interface and incident notifications.
## Answer
Status pages can be natively localised into **French, Portuguese, and Japanese**. To enable this for your status page, contact us at [help@incident.io](mailto:help@incident.io) and we'll set it up for you.
For other languages, you can implement multi-language functionality through third-party translation services:
* [Unbabel](https://unbabel.com/)
* [Localize](https://localizejs.com/)
To implement translation services:
1. Sign up with either Unbabel or Localize
2. Set up your translation preferences in their platform
3. Send us the JavaScript widget for your status page at [help@incident.io](mailto:help@incident.io) and we'll do the rest (see [Localize documentation](https://help.localizejs.com/docs/quickstart-for-web) for an example)
Important notes:
* Email notifications for status page updates are currently only available in one language / cannot be translated
* Status page updates themselves can only be in a single language, so consider writing translated versions of the message in the same single update.
* Third-party translation services may incur additional costs
* Internal status pages cannot be translated, natively or via third-party tools
# Introduction to status pages
Source: https://docs.incident.io/status-pages/overview
At incident.io, we offer three types of status pages designed to effortlessly communicate real-time status updates publicly to all your users.
## Public Status Pages
This is your typical status page where you can publicly display any ongoing incidents, scheduled maintenance and general system uptime for any given component to all of your users.
Get started [here](/status-pages/going-live).
## Public Status Pages with Sub-Pages
Sub-pages are useful if you have users that need a more specific view of the health of all of the different services, systems, products, or regions that you offer/operate within.
For example, if you have a product offering with multiple products and the users of those products are independent from each other, you may want a sub-page per product. Another example is that you have a regional separation in your company, and you would like a status page for each of those regions.
Get started [here](/status-pages/sub-pages).
## Customer Status Pages
Customer pages give you the ability to provide your customers with a dedicated, authenticated status page, managed centrally. Customer pages are managed like our [sub-pages](/status-pages/sub-pages), but add a layer of authentication onto each page to limit access to a specific customer.
You may want to use customer pages if only a subset of customers are impacted by an incident. For example, if you run dedicated infrastructure for customers, or maintain components for a small set of high-value customers, you can use customer pages to give those customers a dedicated space, that always shows them when *their* experience of your product is experiencing issues.
Get started [here](/status-pages/customer-overview).
## Internal Status Pages
Designed for internal use, this page keeps all stakeholders within your organization informed about ongoing incidents. It's an effective tool for communicating the status of the entire product suite or specific system components to various teams within the organization.
Get started [here](/status-pages/internal-overview).
# Who on our team can create, manage or post to status pages?
Source: https://docs.incident.io/status-pages/permissions
By default, creating or configuring status pages is an administrative function in [incident.io](http://incident.io/). Typically, **workspace admins or owners** have the permissions to create new status pages, adjust settings (like components, domains, etc.), and delete or archive pages. Regular team members (responders) usually cannot create a new status page without the appropriate role permission.
However, once a page is set up, incident updates to that page can be made by incident responders (for example, an incident commander can publish updates to a public status page during an incident) – you wouldn’t want only admins to be able to post updates, since that would bottleneck communications.
So the model is generally: admins set up and maintain the page configuration, whereas **incident leads or communication leads can publish updates** to the page during an incident.
The specific roles and permissions can be fine-tuned in [incident.io](http://incident.io/) ’s settings (for instance, you may define which user roles are allowed to publish to a status page).
# Control who can publish to your status page
Source: https://docs.incident.io/status-pages/publish-permissions
If you wish to restrict who can publish incidents and updates to your status page, you can achieve this with a custom role.
This lets you manage who can:
* publish new incidents
* publish updates to existing incidents
* schedule maintenance windows
* publish updates to maintenance windows
* modify the impact timeline of incidents and maintenance windows
All of this is managed via the 'Publish to status pages' permission:
By default, the 'responder' role allows anyone in your Slack workspace to update your status page. Learn how to configure this in our [article on customizing permissions](/admin/user-permissions).
# How to publish an incident to your status page
Source: https://docs.incident.io/status-pages/publishing-incidents
During an incident it's important to keep your customers in the loop, so they know you're working on it, and when they can expect things to change. Read more on how to write a great status page update in our [guide to incident management](https://incident.io/guide/response/keeping-your-customers-in-the-loop/).
Publishing an incident to your status page gives your customers a place to check in for the latest information, and can optionally send messages to your subscribers to proactively tell them what's going on.
You can publish a new incident from our dashboard, or via Slack, using the `/incident statuspage` command. Read more about publishing from Slack in [this article](/incidents/customer-updates).
Let's walk through publishing a new incident to your status page from the dashboard.
***
First, navigate to your [status pages list](https://app.incident.io/~/status-pages), and select the status page you want to update.
Click 'Publish incident' in the top-right. You'll see a form like this:
There's four key things here:
1. **The incident name**
What's the headline of this incident in a few words? We'll show this:
* Anywhere there's a link to this incident
* As the subject line for emails to subscribers
* As the heading on the status page for this incident
2. **What's the status right now?**
There's four statuses available:
1. **Investigating** : you're not sure what the issue is yet.
2. **Identified** : you're working on a resolution for this issue.
3. **Monitoring** : your customers should expect things to be back to normal, but your response hasn't wrapped up yet.
4. **Resolved** : everything is back to normal
5. **Message**
This is a longer-form update you can use to communicate in more detail with your customers. We'll show this on your status page while the incident is ongoing, and on the page for this incident.
4. **Components impacted**
Some customers might not use all parts of your product or service. Help them quickly understand what might not be working as normal using component statuses. For example, if only the website is affected by this incident, you might select 'Full outage' for that component:
This will appear in the System Status part of your status page:
If there are multiple incidents ongoing at once, marking a component as `No impact` will not overwrite another incident that has marked it as affected. You should choose the impact levels you set based on **this incident alone**, and we'll aggregate the values across all open incidents when working out the current status.
***
Now it's time to review and publish your incident. Click 'Review incident'.
This is your opportunity to proof-read the details, and make sure everything is ready to go:
You can also choose whether or not to proactively notify subscribers to your status page here.
Once you're ready, click 'Publish incident' and you're all set
# How do I remove subscriptions from a status page?
Source: https://docs.incident.io/status-pages/remove-subscriptions
I am trying to manage my subscription list for my status page on [incident.io](http://incident.io/) but I can't find where in the settings I can remove subscribers from my status page.
## Answer
At the moment, there isn't a way for customers to remove individual subscribers from status pages. Since subscriptions are opt-in from users, a particular user has to choose to unsubscribe from your page.
If you're a user who is looking to remove their subscription from the status page, you can do so by finding any status page related notification/email and clicking "Unsubscribe". If you have any special circumstances, please email [support@incident.io](mailto:support@incident.io) and we can take a look!
# What happens to status page incidents when removing components?
Source: https://docs.incident.io/status-pages/removing-components
## Context
When managing a status page, you may need to remove or reorganize components. This raises questions about what happens to historical incidents that were associated with components that are being removed, and how these incidents will be displayed on the status page afterwards.
## Answer
When you remove a component from your status page:
* The status page incident will remain visible in the incident history
* The link to the removed component will be lost, meaning the status page incident will no longer show any impacted components
* Adding new components as affected to historical incidents will not trigger notifications to subscribers
If you need to reassign historical incidents to different components:
1. First, identify all incidents associated with the components you plan to remove
2. Before removing the old components, manually update the affected status page incidents to include the new replacement components
3. You can then safely remove the old components
# Status Pages incident severity
Source: https://docs.incident.io/status-pages/severity
On your status page, incidents are presented with color-coded icons depending on a few criteria. These appear in the main heads-up banner, the system status section, and the incident calendar:
Scheduled maintenance is always presented with a blue spanner icon.
Unscheduled incidents are presented with a warning triangle that's either grey for "no impact", yellow for "degraded performance", orange for "partial outage", or red for "full outage", depending on the impact of the incident.
1. If an incident is ongoing, we'll show the icon for the worst current impact
2. If an incident is ongoing, but has no impact (for example if impact has been mitigated and you're now in 'monitoring'), we'll show a grey impact icon
3. When an incident is resolved, we show the worst impact it had on each day in the calendar and system status components. For example, if you had a full outage from 11pm until midnight and a partial outage from midnight until 2am, the incident would appear as red on the first day and orange on the second day.
The heads-up banner text (e.g. "We're currently experiencing issues") remains visible while any incident is ongoing,
including during the monitoring stage. The banner is automatically removed once the incident is resolved.
# How are subscribers migrated when switching from Atlassian StatusPage?
Source: https://docs.incident.io/status-pages/statuspage-subscriber-migration
## Context
When migrating from Atlassian StatusPage to incident.io's status page, you'll want to ensure your existing subscribers continue receiving updates. Understanding which subscriber types can be migrated automatically and which require manual intervention is important for planning your migration.
## Answer
During the Atlassian StatusPage migration process, incident.io automatically handles certain types of subscribers while others require manual action:
## Automatically Migrated
* **Email Subscribers:** All email subscribers are automatically migrated when you click "Go Live" in the migration wizard
## Not Supported/Requires Manual Action
* **Webhook Subscribers:** Webhook subscriptions are not currently supported. You may wish to consider exposing the [widget API](/status-pages/api#widget-api) to customers in this case if they want to programatically retrieve the status of your status page.
* **Slack Subscribers:** Slack subscribers cannot be migrated. Slack doesn't allow a new app to take ownership of subscriptions created by another app (in this case, Atlassian Statuspage), so existing Slack channel subscriptions from your old status page won't carry over.
## How to Migrate
1. Enable the status page integration in incident.io
2. Access the Atlassian status page migration wizard
3. Follow the migration steps until you reach the "Go Live" stage
4. Click "Go Live" to automatically migrate supported subscribers
For a detailed walkthrough of the complete migration process, refer to our [migration guide](/status-pages/migrate-from-statuspage).
# Setting up sub-pages
Source: https://docs.incident.io/status-pages/sub-page-setup
Not sure what sub-pages are? [Read our FAQ](/status-pages/sub-pages).
Using sub-pages makes it possible to only share incidents on a status page where it's relevant – if an incident only impacts a system/component used by your customers in North America, you don't want that incident to show up for customers in Europe.
To get started, head over to [Status pages](https://app.incident.io/~/status-pages) hit **Create a new status page** > **Public status page** > **Create with sub-pages**.
## 1. Basic details
The first decision you have to make is what you'll call your status page.
This name will be used as the page heading for both your parent and sub-pages, so we recommend using something sensible, like your company name. Note: you don't need to write "status" or "status page" at the end of your page title - we'll take care of that for you.
## 2. Sub-pages (Catalog)
Sub-pages are powered by [Catalog](https://app.incident.io/~/catalog). This means that most of what you build whilst configuring your sub-pages can be leveraged in other features, like [Workflows](/workflows/getting-started).
The first decision in this section is to choose what your sub-pages represent. This is often Regions that you operate in, or Products that you sell. It could be anything you want though!
As you've already learnt, sub-pages are powered by Catalog. Once you've decided on the type of pages you want, there are two options to choose from:
1. Create a new catalog type
2. Use an existing catalog type
### Catalog Option 1 (default): Create a new catalog type
Under Sub-page components, you should enter all of the different systems, services, components, or features that you want to map to some (or all) of your sub-pages.
Now we can create some pages. Here we've mapped the App component to the UK region:
After you've created your sub-page, these new catalog types will show up [in your Catalog](https://app.incident.io/~/catalog/01H9G0TFFK5VXFN6C3E6QETZWG) as Region and Components.
If you want to add more Regions, feel free to do so from the Catalog UI. Head over to the Region catalog type, hit "Create entry" and choose the relevant components.
### Catalog Option 2: Use existing catalog types
For sub-pages, you'll need two catalog types: one for your sub-pages (e.g. Regions), and one for your components (e.g. Components, Features, or Feature Areas).
If you've already imported catalog types from an external system like Backstage, Cortex, or OpsLevel, or you've just manually created them independently of sub-pages - you can just reuse those in your setup of sub-pages!
If not, you may need to either [Create a new catalog type](/status-pages/sub-page-setup) or adjust your existing catalog types.
At a minimum, your Component catalog type should look like this:
*Feel free to add any additional attributes that better describe the Component, e.g. the Owning Team, a Description, and so on.*
And your Region catalog type should look something like this:
*It's very important that the Region catalog type has an attribute with Resource Type = Component as this is what we'll use to route status page updates to the correct page.*
Ensure that "Multi value" is selected for the Components attribute as this will allow you to associate multiple components to each Region. For example, the UK might rely on both the API and Website components.
Now that you have a "sub-page compatible" Region and Component catalog type, we need to ensure that each Region has a number of Components mapped to it.
An entry for the Region catalog type should look something like this:
The result will look something like this:
You can now complete the sub-page setup wizard with compatible catalog types.
You may optionally configure *grouping* of your components as well. This can be useful if you have a large number of components and want to group them on each of the sub-pages, and will show up as expandable groups on each sub-page's system status.
You can choose to create/not create some pages. If you don't create them during setup, you can always enable them later in the sub-page settings.
In this example, we have *Regions* to represent our different pages, and *Components* to represent our components. In your organization, you might use *Products* instead of *Regions*, and *Features* instead of *Components*. We support any version that works for you!
### Component Ordering
2 options for the ordering of components:
* Alphabetically
* Ranked
more info in this [article](/status-pages/component-ordering).
## 3. Branding
Choose between light and dark mode and add your logo, and you're ready to go!
## → What's next?
You're now ready to **Go live** !
Depending on your configuration, there will be a number of items you'll want to check off before going live. Feel free to do those following the in-app instructions.
Now, the only thing left is to publish incidents. When you publish an incident (from the dashboard, or using `/inc sp` in Slack) and publish to your parent page, the incident will automatically appear on all sub-pages where your impacted components are visible.
If you want to reconfigure anything, or add more sub-pages, head over to the Settings tab.
# Status Pages sub-pages
Source: https://docs.incident.io/status-pages/sub-pages
Want to get started with sub-pages? [Check out this guide](/status-pages/sub-page-setup).
## What are sub-pages and when do I need them?
Sub-pages are useful if you have users that need a more specific view of the health of all of the different services, systems, products, or regions that you offer/operate within.
For example, if you have a product offering with multiple products and the users of those products are independent from each other, you may want a sub-page per product. Another example is that you have a regional separation in your company, and you would like a status page for each of those regions.
## How are they different from status pages?
Sub-pages are powered by [Catalog](/catalog/catalog-setup).
Using catalog, you can build a representation of your business. For example, for each location, you could associate a number of relevant system components.
Some components could be included on every status page, while others are shown or hidden based on need.
To understand how to set up your catalog for sub-pages, [read our guide](/status-pages/sub-page-setup#h_9ff99a6e70).
## Who can see sub-pages?
Your sub-pages are publicly available. Each sub-page will have its own URL, and users will be able to navigate between all of your sub-pages.
## How do I get access to them?
Sub-pages are available on our Enterprise plan.
## How do I publish incidents on my sub-pages?
When you’re publishing an incident to a status page, you will select the components which are impacted, and [incident.io](http://incident.io/) will automatically route updates to the relevant status pages. Alternatively, you can manually select which sub-pages an incident should appear on — this is useful for retrospective incidents or cases where automatic routing doesn’t apply.
## How do I set up my sub-pages?
You can find [a full walkthrough in this guide](/status-pages/sub-page-setup).
## How do I configure my sub-pages?
You can change the configuration of all of your status pages in [Status Pages > \[Your Status Page\] > Settings](https://app.incident.io/~/status-pages/). In the settings you can adjust which sub-pages you have, adjust branding, apply custom domains, and much more.
You can find [a full walkthrough in this guide](/status-pages/sub-page-setup).
## Can users subscribe to them?
Yes! We offer email, Slack, and RSS subscriptions for all of our status pages.
## Can I remove specific sub-pages from showing an incident?
Yes! If an incident is no longer affecting a component, you change the status of that component when providing an update, which will mark things as resolved. However, if you want to remove the incident from the sub-page entirely, you can manually remove a sub-page from an incident in by clicking the "..." > "Delete incident from sub-page" in the right-panel of a status page incident dashboard (not the status page itself).
# Is there a limit on the number of Status Page subscribers?
Source: https://docs.incident.io/status-pages/subscriber-limits
There is no limit on the number of subscribers who can sign up to receive status page updates for your organization. You can have as many email and Slack subscribers as needed.
To view and manage your current status page subscribers:
1. Navigate to your status page settings in the incident.io app
2. Go to the "Subscriptions" tab
3. Here you can view and manage all current subscribers
# Status page subscriptions
Source: https://docs.incident.io/status-pages/subscriptions
People can subscribe to status pages by email, or through our RSS or Atom feeds. When you select "Subscribe to updates", you see a form like this, which allows you to choose whether to subscribe to specific components:
When sending a status page update, you can choose whether to notify subscribers.
If you choose to notify subscribers, updates will still appear in the RSS and Atom feeds for the incident.
# Displaying metrics on your status page
Source: https://docs.incident.io/status-pages/system-metrics
Show visitors real performance data, like response times and uptime, on your public status page.
Metrics let you display live performance charts on your public status page, backed by data from your monitoring provider. Alongside the status of each component, visitors see how your systems are actually performing: response times and uptime, over the last day, week, or month.
You can display two kinds of metric:
* **Latency**: the average response time of a check, in milliseconds
* **Uptime**: the percentage of checks that succeeded
Metrics are currently powered by [Pingdom](https://www.pingdom.com/), reach out to us if you'd like support for another provider.
## Before you start
You'll need:
* Permission to configure status pages
* A plan that includes status page metrics
## Adding a metric
1. Open your status page and go to its **Metrics** settings
2. Click **Add metric** (or **Connect to Pingdom** if you haven't connected it yet)
3. Choose the time series to display: **Latency** or **Uptime**
4. Give the metric a display name, which is what visitors will see on your status page
5. Select the Pingdom check that should back the metric, and click **Add**
When you add a metric, we backfill the last 30 days of data from Pingdom, so charts are populated straight away. After that, we fetch new results automatically in line with the check's own interval in Pingdom.
Visitors to your status page can switch each chart between 1-day, 7-day, and 30-day views.
## Managing metrics
From the **Metrics** settings you can:
* **Reorder** metrics by dragging them, which changes the order they appear on your status page
* **Edit** a metric to rename it, switch between latency and uptime, or point it at a different check
* **Remove** a metric to take it off your status page
Uninstalling the Pingdom integration removes all metrics from your status pages.
## FAQs
Currently Pingdom. If you'd like to see support for another provider, let us know at
[help@incident.io](mailto:help@incident.io).
No, metrics are only available on public status pages.
We fetch new results as often as your check runs in Pingdom. For example, a check with a one-minute resolution
updates roughly every minute.
# Can I manage status pages using Terraform or automation?
Source: https://docs.incident.io/status-pages/terraform
Currently, incident.io status pages cannot be managed through Terraform or configured through code. All status page configuration must be done manually through the incident.io interface.
The status pages API currently enables programmatic management of status page incidents and maintenance windows.
* See [Automatically publishing to your status page via API](/status-pages/api#status-page-v2-api) for more information on how to automate status page incidents and maintenance windows via API.
* Visit the [Status Pages V2 docs](https://docs.incident.io/api-reference/status-pages-v2/) to see a list of available API endpoints.
Support for using Terraform to configure status pages is being tracked as a feature request. If you'd like to add your vote, just let us know at [help@incident.io](mailto:help@incident.io)
# Can I integrate third-party status pages into my status page?
Source: https://docs.incident.io/status-pages/third-party-integration
It's fairly common for folks to display the status of third-party services (like AWS, GitHub, Slack, or Okta) on their incident.io status page to give their users a complete view of service health, including dependencies.
Currently, incident.io status pages do not support direct integration with third-party status pages. This means you cannot automatically display the status of external services like AWS, GitHub, or other vendors' status pages within your incident.io status page.
As a temporary workaround, you can:
1. Use email alert sources to ingest status page subscription emails from third parties
2. Declare incidents based on these alerts
3. Update your status page accordingly (you can also always consider [automating these updates](/status-pages/auto-publishing) )
A third-party status page integration is a frequently requested feature that we're considering for development. If you'd like to add your vote, just let us know at [help@incident.io](mailto:help@incident.io)
# Can I adjust the time window on the status page?
Source: https://docs.incident.io/status-pages/time-window
The status page displays uptime and incident information for services over a default 90-day window. However, you may want to view metrics for different time periods, such as the last 30 days or a specific calendar month, particularly for SLA compliance monitoring.
Currently, it is not possible to adjust the time window on the status page from the default 90-day view. The status page shows a fixed 90-day lookback period for all services and environments.
This feature has been logged as a future enhancement request. While there are no immediate plans to implement adjustable time windows, we understand this functionality would be valuable for SLA monitoring and reporting purposes. If you'd like to add your vote, just let us know at [help@incident.io](mailto:help@incident.io)
# Backfill uptime history on a new status page
Source: https://docs.incident.io/status-pages/uptime-backfill
Remove the empty 'no data' bars on a new status page by backfilling operational history.
When you create a new status page, the uptime chart shows empty "no data" bars for any period before the page started recording data — even if your services were perfectly healthy at the time. You can backfill that history so those bars show as operational instead.
## Why new pages show "no data"
We only show uptime from the point a component first has data to report. Before that, we show "no data" rather than assuming the component was operational, because we have no record of its status either way.
To fill in that earlier period, give the chart a starting point: publish a **retrospective incident** whose earliest update is dated when you want the chart to begin (for example, the day your services went live). From that date onward, each component is shown as operational unless there's a recorded impact.
## Backfill your uptime
Go to your [status pages list](https://app.incident.io/~/status-pages) and select your page. Open the **⋯** menu in the top right and select **Publish retrospective incident**.
Give the incident a name. The most recent update in the timeline must be **Resolved** — set its **Occurred at** to the date you want your uptime chart to start from, and add a short message. This update marks all components operational.
Then select **Add earlier update**.
Set the earlier update's status to **Investigating** and its **Occurred at** to just before the resolved update (a minute earlier is fine). Add a message, then set the affected components to **Degraded performance**.
Setting the components to **Degraded performance** (rather than a partial or full outage) anchors your start date without counting as downtime, so your uptime stays at 100%. See [how we calculate uptime](/status-pages/uptime-calculation) for the statuses we count as "up" and "down".
Select **Save**, then **Publish incident**. Your uptime chart now starts from the date of the earliest update, and the empty "no data" bars before it show as operational.
This creates a resolved retrospective incident, which appears in your page's incident history. Publishing a
retrospective incident does not notify your subscribers by default.
## FAQs
The uptime chart only shows data from the point each component started recording it. Before that, we show "no data"
rather than assuming everything was operational. Publish a retrospective incident dated at your launch to backfill
that period.
Not if you set the anchoring impact to **Degraded performance** — degraded periods don't count as downtime. Only
partial and full outages reduce your uptime percentage. See [how we calculate
uptime](/status-pages/uptime-calculation).
Publishing a retrospective incident is the self-serve option, and it only ever moves your start date earlier. If
you'd prefer to set the date directly without an incident, reach out to our support team.
Not unless you choose to. Retrospective incidents don't notify subscribers by default — leave **Notify subscribers**
unchecked when you publish.
# Status Pages: How we calculate uptime
Source: https://docs.incident.io/status-pages/uptime-calculation
Uptime is the amount of time that a component (ie. API, website) is available and working properly. The possible statuses for components are:
* Full outage
* Partial outage
* Under maintenance
* Degraded performance
* Operational
To calculate uptime, we consider how much time is spent in a status that we consider "down".
Component statuses considered "down":
* Full outage
* Partial outage
Component statuses considered "up"
* Under maintenance
* Degraded performance
* Operational
The uptime percentage is the percentage of a given time period that the component is in a status we consider "up". For example, if a component is operational between 09:00am at 09:10am, then degraded performance from 09:10am to 09:40am, then full outage from 09:40 to 10:00am, its uptime percentage from 9am to 10am would be 66% (40 minutes ‘up’ and 20 minutes ‘down’).
When displaying aggregate uptime for a group, we consider only components in it which are configured to display uptime. A group is only considered "up" if all components in it are in an "up" status.
# Does incident.io integrate with WhatsApp or SMS for sending status page updates?
Source: https://docs.incident.io/status-pages/whatsapp
## Context
Users may want to receive incident updates and notifications through WhatsApp or SMS messaging services to stay informed about ongoing incidents.
## Answer
Currently, incident.io does not have an integration with WhatsApp or SMS for sending incident updates. While we collect product feedback about this potential integration, you can use our existing notification channels:
* Slack
* Email notifications
* Web interface
We track feature requests and will notify customers if WhatsApp integration becomes available in the future.
# Advanced settings
Source: https://docs.incident.io/workflows/advanced
Covers advanced settings, including how to prevent duplicate workflow runs by controlling how often a workflow fires for the same incident, user, or other resource.
## How often should this workflow run?
Many workflow triggers fire repeatedly for the same incident — for example, "an incident is updated" fires every time any field changes. Without deduplication, this could flood channels with duplicate messages or re-run actions that should only happen once.
By default, workflows are configured to run **once** for a given resource, like an incident or a message. This is controlled by the "How often should this workflow run?" setting, which you'll find in the **Advanced** section of the workflow editor.
### How it works
When a workflow fires, incident.io checks whether it has already run for the same combination of values. If it has, the workflow is silently skipped.
For example, if a workflow is set to run once per **Incident**, it will fire the first time its trigger and conditions match for a given incident, but won't fire again for the same incident — even if the trigger fires multiple times.
If you clear the run once setting entirely, the workflow will run **every time** the trigger fires and conditions match, with no deduplication.
### Configuring run frequency
1. Open the workflow you want to edit.
2. Click **Advanced** to open the advanced settings drawer.
3. Under **How often should this workflow run?**, you'll see the current
configuration.
4. Click the edit icon to change which resources the workflow should deduplicate on.
5. Use the dropdown to add or remove resources, then click **Confirm**.
The available resources depend on the trigger you've selected. Common options
include:
| Resource | Meaning |
| ------------- | ------------------------------------------------------------ |
| **Incident** | Run once per incident |
| **User** | Run once per user (combined with other selections) |
| **Message** | Run once per Slack message |
| **Severity** | Run once per severity value (combined with other selections) |
| **Action** | Run once per action item |
| **Follow-up** | Run once per follow-up |
You can select multiple resources. When you do, the workflow runs once for each
**unique combination** of those values.
### Interaction with loops
If your workflow includes a [loop](/workflows/loops), the run once setting applies to non-looped steps as normal. However, looped steps can still "catch up" with new values even after the non-looped steps have been skipped. See [How often will workflow loops run?](/workflows/loops#how-often-will-workflow-loops-run) for a detailed example.
Each trigger has a sensible default. For example, "An incident is updated" defaults to once per incident, while "A
user joins the incident channel" defaults to once per incident and user. You can see the current setting in the
Advanced section and change it at any time.
Yes. Edit the run once setting and remove all resources. The workflow will then run every time its trigger fires and
conditions match.
Run once is scoped to the workflow itself, not to a specific version. If you edit and save a workflow, the
deduplication still considers previous runs of the same workflow.
# How do I set up a workflow trigger for Slack emoji reactions?
Source: https://docs.incident.io/workflows/emoji-triggers
## Context
When setting up workflow triggers for Slack emoji reactions, you'll need to make sure you do it in the correct way to configure the trigger conditions for emoji reactions to messages in Slack channels.
## Answer
To set up a workflow trigger for Slack emoji reactions, follow these guidelines:
1. In the workflow trigger conditions, use the text version of the emoji rather than the emoji symbol itself. For example, use "ticket" instead of " " or ":ticket:"
2. The workflow will only trigger for reactions to regular messages in Slack
3. The workflow will not trigger for reactions to:
* Incident updates
* Messages created via the `/inc update` command
**For example:**
Using the actual emoji symbol (like ) or the emoji code (like :ticket:) in the trigger condition will result in unpredictable behavior. Always use the plain text name of the emoji (e.g., "ticket") for reliable results.
# How to use Workflow Expressions
Source: https://docs.incident.io/workflows/expressions
You can write workflow expressions as a way to vary parts of a workflow based on a set of conditions.
For example, if you want to escalate an incident to the specific on-call engineer for the affected product, Expressions will let you do that. This looks something like this:
* If **Affected Service** is **Payments:**
* **Escalation Team** = **Payments Team**
* Else if **Affected Service** is **Onboarding:**
* **Escalation Team = Onboarding Team**
* Else:
* **Escalation Team** is not set
Later on in your workflow, you can then use `Escalation Team` in any step that expects that type. So, we could pair that with an `Escalate to PagerDuty` step that uses the `Escalation Team`.
## Defining an expression
* Open [Workflows](https://app.incident.io/~/workflows) in your dashboard and create or edit a workflow.
* Navigate to the Workflow step where you want to use an expression, click "Use a variable" and then `Add new expression` to begin creating an expression.
* Choose which type of expression you require.
* In this example, we'll use "If... else...". Give your expression a name. This should be something short that suggests what the expression results in (e.g. Escalation Service, or Mailing Lists).
* Choose a return type. This will decide what *kind* of thing your expression will return (e.g. a Slack Channel or some text).
* Choose whether or not your expression will return multiple values:
* Please note that not all conditions and steps will accept multiple values. For example, the 'Send message to Slack Channel' step expects one single channel. If you choose to return multiple items for a 'Slack Channel' expression, then it won't be available in the 'Send message to Slack Channel' options.
* Define your conditions and the things you want to return when those conditions are met.
* Define what happens when none of your conditions are met. You can either return 'nothing', or a default value. If you return nothing and then use the expression in a step that needs a value, we'll skip running the rest of the workflow from that step.
* Click `Add` to finish creating your expression.
* Continue with creating the rest of your workflow. When you create a condition or add a step that expects something matching the type you've defined, you should see it in the dropdown options.
That's all! Use workflow expressions to consolidate many workflows doing similar things into one general workflow that varies as needed for the incident at hand.
# Getting started with Workflows
Source: https://docs.incident.io/workflows/getting-started
## Quick start
If you're short on time, watch this 3-minute video on how to build a workflow in incident.io:
## Introducing workflows
Workflows allow you to automate certain actions and behaviors based on specific triggers. For example, [incident.io](http://incident.io/) can automatically invite users or user groups to a particular Slack channel when a specific custom field is set on an incident.
## Parts of a Workflow
## Triggers: what should cause the workflow to run
Think of a trigger as something that happens to set off a chain of events. You can choose from the following pre-defined triggers:
* An incident is created or changed
* Someone joins an incident channel
* Someone posts a message in an incident channel
## Conditions: which incidents or users this workflow should run for
Conditions are a set of criteria that control when the workflow should run. If you don't set any conditions, the workflow will apply to **all** incidents/users.
For example, if you choose the "someone posts a message in an incident channel" trigger, and don't add any conditions, the workflow will run for every new message posted in the incident channel.
Depending on the workflow trigger, you can choose from a number of fields such as:
* Incident severity
* Incident role
* Incident status
* User (where applicable)
* Content of a Slack message (where applicable)
* Any [custom fields](/incidents/custom-fields) you've defined
An example condition might be to invite a particular user group to an incident channel only if the severity is high, or the incident is of a certain type (ie, Data Breach).
## Steps: what should happen when the workflow runs
These are the actions or behaviors which happen when the trigger fires and the criteria for the workflow are met.
A workflow can have one or more steps, which will be executed in order. Just a few examples are:
* Send a message to a Slack channel
* Send a direct message to one or more users
* Post an incident announcement in a Slack channel
* Create incident actions
* Create incident follow-ups
* Prompt a Decision Flow
* Invite a user or user group to the incident channel
*Is there a step you'd like to see? Let us know in the* [Community Slack](https://incident.io/community) *!*
## Viewing your workflows
The "Workflows" link on the top menu bar of the Web UI takes you to Workflows Home. This is where you can see - and make changes to - your organization's workflows.
If you don't have any workflows yet, you'll see a list of templates that you can use to get started.
Click the workflow name to open detailed information, or make changes to the workflow directly with the "edit" and "delete" buttons to the right of each list item.
**Getting Started with Workflows**
## Creating a workflow
## Getting started
## From a template
From the Workflows Home page, find the top section with the heading "Templates".
In the template you want to set up, click "Start from this template".
You'll be taken to the "Create a Workflow" page, with the details already filled out.
## From scratch
Create your own workflow from scratch by clicking "New workflow" in the top right-hand corner of Workflows Home.
You'll then be prompted to choose a trigger for the workflow. This is the event that needs to happen for the workflow to run.
Clicking one of these triggers will take you to a form where you can configure the workflow to your liking.
## Configuring your workflow
## Name
Give your workflow a name that describes what it does. We'll use this name in the list of workflows you see when you open Workflows Home, and we'll link back to it when your workflow posts in Slack. If you don't pick a name, we'll create one for you!
## Conditions
Here, you can choose the specific criteria that will control whether or not the workflow runs when the trigger fires. For example, you might want to only run the workflow for incidents with particular severity, or incidents where you're the incident lead.
If you don't add any conditions, the workflow will run for all incidents (and if your trigger involves users, e.g. "when someone joins an incident", it will run for all users).
Click the "Add condition" button to add a new condition.
In the dialog that appears, click the entity you want to filter for this condition.
The options you get will depend on the entity you've selected but might include `is set` / `is not set`, `contains`, or `is one of` / `is not one of`.
Not all operators support values - for example, `is set` or `is not set` is a simple true or false value, so you won't be able to choose a value for that.
`is one of` and `is not one of` operators will give you a list of values to choose from: you can choose as many as you like.
## Steps
Steps are the tasks that the workflow will execute when the conditions are matched. For example, they might include posting a message or inviting a Slack user to a particular Slack channel. You can add multiple steps to a workflow (maximum 20).
You need to add at least one step before you can save your workflow.
Click the "Add a step" button to add a new step to your workflow. In the dialog that appears, choose the step you want to add.
You'll then be asked to configure the step you've chosen. The configuration options differ depending on the step.
For example, you might be able to choose a Slack channel or user, write a message, or select a [Decision Flow](https://app.incident.io/~/settings/decision-flows) to trigger.
## Trigger options
If an option has a "Use variable" button next to it, it's a special dynamic value that depends on the incident - for example, "Incident Slack channel" will be the Slack channel that [incident.io](http://incident.io/) creates for a given incident, and will be unique for each incident.
## Saving your new workflow
Once you've finished adding steps, click the "Save as draft" button at the bottom of the page. If you're ready to set this live, then hit the "Save and set live" button. Once you've set this live, you'll just see a "Save" button.
## Viewing workflow details
When editing a workflow, you can hit the Activity button to view the run history.
A list of runs looks like this:
## Testing a workflow
Testing a workflow will check that your steps work as you expect them to. Due to technical limitations, you can't currently test any workflow conditions.
Click the "Test" button at the top of the workflow.
Choose an incident to test a workflow against, and we'll run the workflow steps you selected. If the trigger involves a user, we'll ask you to select a user for the test as well.
You can use a [test incident](/incidents/sandbox-incidents) for this purpose.
For example, if you have a workflow that sends a direct message to a user who joins an incident channel, selecting a specific Slack user in the `Test workflow` dialog will send your workflow's message to that user once you click "Test". For this reason, we advise that you choose your own name!
We'll then run the workflow, and let you know whether everything worked as expected.
## Team ownership
You can set one or more teams as **Owner** of a workflow. Ownership decides which team the workflow appears under in their team views. If your organization uses [team roles](/admin/team-roles), it also decides who's allowed to manage the workflow.
Set the owner using the **Owned by** control at the top of the workflow editor, or from the **Advanced settings** panel.
Changing which team owns a workflow needs account-level permission to manage workflows. A team-role holder can manage the workflows their team already owns, but can't reassign ownership.
To let a team manage only their own workflows, see [Restrict workflow management to a team](/admin/restrict-workflow-management).
## Make changes to an existing workflow
Click the name of the workflow you want to edit. Here, you can make changes to the name, conditions, and steps.
You can't change the workflow trigger - you'll need to delete the workflow and create a new one with a different trigger.
Click the "Save" button to save your changes. All future workflow runs will use the new configuration.
## Delete a workflow
Click the "Delete workflow" option in the "..." menu to delete the workflow. Note that deleted workflows can't be restored, so make sure you're deleting the right one!
# Using loops in Workflows
Source: https://docs.incident.io/workflows/loops
*If you haven't worked with Workflows before, check out our* [Getting Started with Workflows guide](/workflows/getting-started)
Workflow loops allow you to repeat a step multiple times for all values in a multi-valued custom field or expression.
## Adding a Workflow loop
To add a Workflow loop, simply click "Add a step" and then choose the "Create a loop" option.
Returning to the main workflow screen, you will see a new loop block has appeared in your steps.
## Selecting a resource to loop over
The "Select a variable" dropdown will give you available resources you can loop over. This can be one of:
* A multi-select custom field
* An [expression](/workflows/expressions) that returns a list of values.
## Adding steps to a Workflow loop
Once you've picked what you want to run your steps over, you can add Workflow steps to your loop using the "Add a step to this loop" button.
This works just like adding a regular workflow step, and you can reference the value you are looping over in the step - you'll find these at the top of any relevant menus, prepended by "Each". In this example, we are looping over the custom field "Impacted surface":
You can add as many steps as you would like to a loop and re-order them by dragging and dropping, just like steps. They cannot be moved out of the loop, though.
## How often will workflow loops run?
Workflow loops function slightly differently from regular workflow steps - if the custom field or expression you are looping over changes, the loop will run its steps on any new values.
Let's elucidate this with an example:
Imagine you have set up a workflow to run once per incident when the incident severity is critical or higher. You've got two steps:
* Announce the incident in `#product`
* For each team in the `Affected Teams` custom field:
* Page the relevant escalation policy in PagerDuty
This workflow will function as follows:
1. A critical incident is declared, affecting teams `A` and `B`. The workflow runs, posting the announcement and escalating following `Policy-A` and `Policy-B`.
2. The `Affected Teams` custom field is updated to now include Team `C`
3. The first step, posting the announcement, will *not* be re-run, since it has already been executed for this incident. **However**, the second, looping step will "catch up" with the new `Affected Teams` value by escalating to `Policy-C`.
# How do I mention the Incident Lead in a message or suggestion?
Source: https://docs.incident.io/workflows/mention-lead
## Context
When configuring messages in workflows or [rule-based suggestions](/incidents/rule-based-suggestions) for incidents, you may want to include a mention of the Incident Lead to ensure they are notified. This requires using the correct syntax to properly mention the user in Slack.
## Answer
To mention the Incident Lead in a Slack prompt, simply use `Incident->Incident Lead` in your configuration. The system will automatically handle the proper Slack mention formatting - there's no need to add the `@` symbol before the variable.
**Example:**
# How do I tag a Slack user using their Slack username in a workflow?
Source: https://docs.incident.io/workflows/slack-user-tags
## Context
When creating a workflow that needs to mention or tag a specific user in Slack, they need to have an incident role and you have to reference their incident role in the workflow rather than their full name. This is particularly useful when automating notifications or mentions to role-specific team members, such as a Communications Lead.
## Answer
To properly tag a Slack user in a workflow, simply use the direct role reference without selecting additional user attributes. For example:
1. In your workflow builder, when you need to reference a user, select the role directly (e.g., "Incident → Communications Lead")
2. Do not select additional attributes like "Slack User" and "Name" - this will return their full name instead of their Slack handle
3. The system will automatically convert the role reference into a proper Slack mention (@username) when the workflow executes
Unfortunately, it's also worth mentioning that it's not possible to mention a Slack group at the moment.
# Managing workflows in Terraform
Source: https://docs.incident.io/workflows/terraform
Managing workflows in terraform is useful if you:
* Want to use version control to preview and roll-back changes to a workflow
* Want to apply complex access control (e.g. only members of the SRE team can edit specific core SRE workflows)
* Want to create workflows programmatically based on other data that you store in Terraform
## Building your Terraform
Workflows have a pretty complex structure, so we’d recommend you build your workflow in the UI using our visual builder, and then copy the Terraform that we generate into your repo.
## Making the dashboard ‘Terraform aware’
We want to make sure the dashboard understands that you’re managing a workflow via Terraform, and can adapt accordingly.
You can easily see which workflows are managed via Terraform:
You can tell us where your Terraform code is stored, so it’s easy for your colleagues to find and update it:
We warn you before you make a change that would pull the workflow out of sync with your Terraform state:
You can find out more in our [Terraform provider docs.](https://registry.terraform.io/providers/incident-io/incident/latest/docs/resources/workflow)
## API Key Permissions
As part of the setup you'll need to create an incident.io API Key. To do *all the things* we currently support in Terraform, you'll want to look at giving the key the following permissions. However, you can always refine this if you're only looking to manage certain components.
# Sending a Webhook from a Workflow
Source: https://docs.incident.io/workflows/webhooks
You can configure workflows in incident.io to send HTTP webhooks. This allows you to notify external systems or services when an incident matches your criteria — using a custom payload, headers, and method.
This step is useful for:
* Syncing incident data with third-party tools
* Triggering external automations
* Creating integrations that aren’t yet supported natively
***
## How to Set Up the “Send a webhook” Step
1. **Add the Step:** Add a “Send a webhook” step to any workflow. This step can be placed after any condition you define, like when an incident is created or when the status changes.
2. **Configure the Webhook:**
* **Endpoint URL:** The destination URL where the webhook should be sent. This must be publicly accessible. Example: `https://eok0t15y9atgyjz.m.pipedream.net`
* **HTTP Method:** Choose from `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`. Most webhook consumers expect `POST`.
* **Headers (Optional):** You can include any number of custom headers using key-value pairs. These might be needed for authentication or content type. Example:
```plaintext theme={null}
Authorization: Bearer inc_a23
```
* **Body (Optional):** This is the payload that will be sent in the request body. It supports workflow variable interpolation, so you can include values like the incident name or ID dynamically.
* **Using the dashboard editor**
To add variables to your webhook body in the dashboard:
1. Position your cursor where you want the variable inserted
2. Click the "Insert variable" button in the body field's toolbar
3. Select the variable you need (e.g., `incident → id`) The variable will appear as a highlighted badge in the editor, and will be replaced with the actual value when the webhook is sent.
* **Using the API**
If you're creating workflows via the API, you can use `{{variable.path}}` syntax in your request body and it will be parsed into interpolatable variables. For example:
```plaintext theme={null}
{"incident_id": "{{incident.id}}","incident_name": "{{incident.name}}"}
```
***
## Example Use Cases
Here are a few examples of how you might use the “Send a webhook” step:
* **Notifying an Internal Tool:** Send a webhook to a custom in-house dashboard to update a real-time incident feed with the latest incident status or metadata.
* **Triggering a Runbook in an External System:** Use the webhook to start an automated runbook in systems like RunDeck when an incident enters a particular state (e.g. *Critical* or *Resolved* ).
* **Syncing with a Ticketing System:** Push incident data into a ticketing system to create or update a linked issue whenever an incident is created.
* **Logging to an Audit Service:** Send a record of key incident lifecycle events (e.g. status changed to *Resolved*, or lead updated) to a logging service or data warehouse.
* **Broadcasting to a Notification Bot:** Trigger a message via a custom Slack bot or Discord bot that posts structured incident details in a dedicated alerting channel.
***
## Things to Note
* The request will timeout after 15 seconds if your endpoint doesn’t respond in time.
* Each webhook includes an `Idempotency-Key` header with a value that's unique to that step run. If we retry a delivery, the retry carries the same key, so your endpoint can use it to detect duplicates and process each event only once.
* Make sure your endpoint can handle incoming requests reliably. Use tools like [Pipedream](https://pipedream.com/) or [RequestBin](https://requestbin.com/) for testing.