---
title: "Link or unlink an incident to/from an issue"
method: POST
path: "/issues/{id}/external-incidents"
tags: ["issues"]
---

# Link or unlink an incident to/from an issue

`POST /issues/{id}/external-incidents`

## Request

- Base URL: `https://api.usepylon.com`
- URL: `https://api.usepylon.com/issues/{id}/external-incidents`
- Auth: HTTP bearer

Links an incident from one of the organization's connected incident systems (incident.io or Rootly). An issue can have several linked incidents, and linking one that is already linked has no effect. To unlink, set the operation field to "unlink".

**Rate limit:** 120 requests per minute

## Path parameters

- `id` string, required

## Request body

- LinkExternalIncidentRequestBody
  - `incident_id` string, required: The incident's reference (such as INC-123 or ROOT-123) or its ID in the incident system.
  - `operation` string: Operation to perform. Use "link" to link the incident (default) or "unlink" to unlink it.
  - `source` 'incident_io' | 'rootly', required: The incident system the incident belongs to. It must be connected to the organization. Valid values: "incident_io", "rootly"

## Response `200`

- LinkExternalIncidentResponseBody
  - `data` Issue, required
    - `account` MiniAccount
      - `external_ids` ExternalID[], nullable: External IDs associated with the account.
        - `external_id` string: The external ID. Must be unique per object type (ex. account).
        - `label` string: The label of the external ID. Must be unique per object.
      - `id` string, required: The ID of the account.
    - `active_time_by_user` ActiveTimeByUser[]: Active time spent on the issue broken down per user, if any.
      - `active_time_seconds` integer, required: The user's active time on the issue in seconds.
      - `business_hours_active_time_seconds` integer, required: The user's business-hours active time on the issue in seconds.
      - `user_id` string, required: The ID of the user who spent the time.
    - `active_time_seconds` integer: The total active time spent on the issue in seconds, if any. Equals the sum of the per-user active time.
    - `assignee` MiniUser
      - `email` string: The email of the user.
      - `id` string, required: The ID of the user.
    - `attachment_urls` string[]: The attachment URLs attached to this issue, if any. Signed download URLs. Fetch with a plain GET, no Authorization header.
    - `author_unverified` boolean: Whether any message on the issue has an unverified author identity. True if any message author's identity has NOT been verified (e.g., from public forms).
    - `body_html` string, required: The body of the issue in HTML format.
    - `business_hours_active_time_seconds` integer: The total business-hours active time spent on the issue in seconds, if any. Equals the sum of the per-user business-hours active time.
    - `business_hours_first_response_seconds` integer: The business hours time in seconds it took for the first response to the issue, if any.
    - `business_hours_resolution_seconds` integer: The business hours time in seconds it took for the issue to be resolved, if any.
    - `business_hours_time_in_status_seconds` object: A map of status slug to the business hours time in seconds the issue has spent in that status. Includes both base statuses (e.g. "new", "waiting_on_you") and custom statuses.
    - `chat_widget_info` IssueChatWidgetInfo
      - `page_url` string, required: The URL of the page that the user was on when they started the chat widget issue.
    - `child_issues` MiniIssue[]: The child issues in this group, if this issue is an issue group.
      - `id` string, required: The ID of the issue.
      - `number` integer, required: The number of the issue.
      - `title` string, required: The title of the issue.
    - `created_at` string, date-time, required: The time the issue was created.
    - `csat_responses` CSATResponse[]: The CSAT responses of the issue, if any.
      - `comment` string, nullable: The comment of the CSAT response.
      - `score` integer, required: The score of the CSAT response.
    - `custom_fields` object, nullable: Custom field values associated with the issue.
    - `customer_portal_visible` boolean, required: Whether the issue is visible in the customer portal.
    - `external_incidents` ExternalIncident[]: Incidents from incident.io or Rootly linked to this issue.
      - `external_id` string: The incident system's own ID for the incident, when known.
      - `link` string: Link to the incident, when known.
      - `reference` string, required: The incident's reference in the incident system, such as INC-123 or ROOT-123.
      - `source` string, required: The incident system the incident belongs to. Known values: `incident_io`, `rootly`. This list is not exhaustive.
    - `external_issues` ExternalIssue[]: The external issues associated with the issue, if any.
      - `external_id` string, required: The external ID of the external issue. Jira: ID of the issue (autoincrementing number from 10000). GitHub: Owner/Repo/IssueID. Linear: ID of the issue (UUID). Asana: ID of the task (Long number).
      - `key` string: The human-readable key of the external issue, such as ENG-123 for Linear or Jira.
      - `link` string, required: Link to the product issue.
      - `source` string, required: The source of the external issue.
      - `state` string: Whether the external issue is open, closed (done), or canceled, as last synced from the source. Known values: `open`, `closed`, `canceled`. This list is not exhaustive.
    - `first_resolution_time` string, date-time, nullable: The time of the first resolution of the issue, if any. Frozen at the issue's first resolution and never updated on reopen/re-resolve.
    - `first_response_assignee_id_at_breach` string: The ID of the user the issue was assigned to when its first response SLA breached, if it breached.
    - `first_response_breach_time` string, date-time: The time by which the issue's first response SLA will breach, if any. Only present for issues with an active first response SLA.
    - `first_response_resolving_user_id` string: The ID of the user whose action resolved the issue's first response SLA. Absent when resolved by a contact or automation.
    - `first_response_seconds` integer: The time in seconds it took for the first response to the issue, if any.
    - `first_response_time` string, date-time, nullable: The time of the first response to the issue, if any.
    - `follow_up` SLATimes
      - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
      - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
      - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
      - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
      - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
      - `time` string, date-time, nullable: The time it was reached, if any.
    - `id` string, required: The ID of the issue.
    - `is_issue_group` boolean, required: Whether this issue is an issue group.
    - `latest_message_time` string, date-time, nullable: The time of the latest message in the issue, if any.
    - `link` string, required: The link to the issue in Pylon.
    - `next_reply` SLATimes
      - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
      - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
      - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
      - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
      - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
      - `time` string, date-time, nullable: The time it was reached, if any.
    - `number` integer, required: The number of the issue.
    - `number_of_touches` integer, required: The number of times the issue has been touched.
    - `parent_issue_group` MiniIssue
      - `id` string, required: The ID of the issue.
      - `number` integer, required: The number of the issue.
      - `title` string, required: The title of the issue.
    - `requester` MiniContact
      - `email` string: The email of the contact.
      - `id` string, required: The ID of the contact.
    - `resolution_assignee_id_at_breach` string: The ID of the user the issue was assigned to when its resolution SLA breached, if it breached.
    - `resolution_breach_time` string, date-time: The time by which the issue's resolution SLA will breach, if any. Only present for open issues with an active resolution SLA.
    - `resolution_resolving_user_id` string: The ID of the user whose action resolved the issue's resolution SLA. Absent when resolved by a contact or automation.
    - `resolution_seconds` integer: The time in seconds it took for the issue to be resolved, if any.
    - `resolution_time` string, date-time, nullable: The time of the resolution of the issue, if any.
    - `slack` SlackInfo
      - `channel_id` string, required: The Slack channel ID associated with the issue.
      - `message_ts` string, required: The root message ID of slack message that started issue.
      - `workspace_id` string, required: The Slack workspace ID associated with the issue.
    - `snoozed_until_time` string, date-time: The time the issue was snoozed until in RFC3339 format, if any.
    - `source` string, required: The source of the issue. Known values: `slack`, `microsoft_teams`, `microsoft_teams_chat`, `chat_widget`, `customer_portal`, `email`, `manual`, `form`, `discord`, `google_chat`, `whatsapp`, `sms`, `telegram`, `phone`. This list is not exhaustive.
    - `state` string, required: The state of the issue. Standard values are `new`, `waiting_on_you`, `waiting_on_customer`, `on_hold`, and `closed`; custom status slugs are also supported.
    - `tags` string[], nullable: Tags associated with the issue.
    - `team` MiniTeam
      - `id` string, required: The ID of the team.
    - `team_slas` TeamSLA[]: The team-scoped SLAs on the issue, if any. One entry per team, mirroring the issue-level first response and resolution SLA fields.
      - `first_resolution` SLATimes
        - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
        - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
        - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
        - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
        - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
        - `time` string, date-time, nullable: The time it was reached, if any.
      - `first_response` SLATimes
        - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
        - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
        - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
        - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
        - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
        - `time` string, date-time, nullable: The time it was reached, if any.
      - `follow_up` SLATimes
        - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
        - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
        - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
        - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
        - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
        - `time` string, date-time, nullable: The time it was reached, if any.
      - `next_reply` SLATimes
        - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
        - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
        - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
        - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
        - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
        - `time` string, date-time, nullable: The time it was reached, if any.
      - `resolution` SLATimes
        - `assignee_id_at_breach` string: The ID of the user the issue was assigned to when the breach was detected, if it breached.
        - `breach_time` string, date-time: The time at which it breaches (or has breached), if any.
        - `business_hours_seconds` integer: The part of `seconds` that falls within support hours, if any.
        - `resolving_user_id` string: The ID of the user whose action resolved it, if any. Absent when it was resolved by a contact or automation.
        - `seconds` integer: The elapsed time in seconds, counting only time the issue spent in states that count toward this SLA. May be less than the time between the SLA's start and `time`.
        - `time` string, date-time, nullable: The time it was reached, if any.
      - `team_id` string, required: The ID of the team these are scoped to.
    - `time_in_status_seconds` object: A map of status slug to the time in seconds the issue has spent in that status. Includes both base statuses (e.g. "new", "waiting_on_you") and custom statuses.
    - `title` string, required: The title of the issue.
    - `type` string, required: The type of the issue. Known values: `conversation`, `ticket`. This list is not exhaustive.
    - `updated_at` string, date-time, required: The time the issue was last updated.
    - `workspace_email` string: The email address connected to the Pylon workspace through which the issue's email conversation is routed. For inbound issues, this is the address that received the original email.
    - `workspace_phone_number` string: The WhatsApp, SMS, or voice phone number connected to the Pylon workspace through which the issue's conversation is routed. For inbound issues, this is the number the customer messaged or called.
  - `request_id` string, required: The request ID for tracking.

## Other responses

- `400`: The request was invalid or could not be completed.
- `401`: The request could not be authenticated for this API.
- `403`: The authenticated caller or organization is not allowed to access this endpoint or operation.
- `404`
- `429`: The request exceeded the applicable rate limit.
- `500`: An unexpected internal error occurred.

## Changes

- **2026-10-31** `05e40342a893`: 2 info
  - added the optional property `data/external_issues/items/key` to the response with the `200` status
  - added the optional property `data/external_issues/items/state` to the response with the `200` status
- **2026-10-21** `b64ce6c1bce3`: 1 info
  - added the optional property `data/workspace_phone_number` to the response with the `200` status
- **2026-10-15** `1ecc216f2835`: 14 info
  - added the optional property `data/first_response_assignee_id_at_breach` to the response with the `200` status
  - added the optional property `data/first_response_resolving_user_id` to the response with the `200` status
  - added the optional property `data/follow_up` to the response with the `200` status
  - added the optional property `data/next_reply` to the response with the `200` status
  - …10 more
- **2026-10-12** `40bf3229d58f`: 1 info
  - the response property `data` became required for the status `200`
- **2026-10-11** `dfb481067e5a`: 18 breaking, 7 warning, 142 info
  - the response property `data/account` became nullable for the status `200`
  - the response property `data/assignee` became nullable for the status `200`
  - the response property `data/csat_responses/items/comment` became nullable for the status `200`
  - the response property `data/custom_fields` became nullable for the status `200`
  - …163 more

[Operation history](https://skmtc.dev/usepylon/apis/pylon-api/changes/issues/:id/external-incidents/post.md)

---

[API](https://skmtc.dev/usepylon/apis/pylon-api.md) - [All operations](https://skmtc.dev/usepylon/apis/pylon-api/llms.txt) - [OpenAPI document](https://skmtc.dev/usepylon/apis/pylon-api/revisions/7d018a2a6265?raw)
