---
title: "Update alert details"
method: PATCH
path: "/api/alerts/{alertId}"
tags: ["Alerts"]
---

# Update alert details

`PATCH /api/alerts/{alertId}`

## Request

- Base URL: `https://app.cotool.ai`
- URL: `https://app.cotool.ai/api/alerts/{alertId}`
- Auth: HTTP bearer

Update an alert title and/or description and append matching timeline entries.

## Path parameters

- `alertId` string, required: Alert UUID or human-readable display ID

## Request body

- object
  - `title` string: Updated human-readable alert title
  - `description` string, nullable: Updated markdown description, or null to clear it

## Response `200`

Successful response

- object
  - `alert` object, required
    - `id` string, uuid, required: Internal alert identifier
    - `displayId` string, required: Human-readable alert identifier
    - `organizationId` string, uuid, required: Organization that owns the alert
    - `organizationName` string, required: URL-safe organization name used in durable alert paths
    - `title` string, required: Human-readable alert title
    - `description` string, nullable, required: Markdown summary or details for the alert
    - `severity` 'low' | 'medium' | 'high' | 'critical' | 'null', nullable, required: Alert severity when known
    - `status` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired', required: Lifecycle status for a first-class alert. Terminal closed statuses include final disposition. Dismissed, duplicate, and expired alerts are archived and hidden from alert lists.
    - `duplicateOfAlertId` string, uuid, nullable: Canonical alert this alert duplicates, when status is duplicate
    - `duplicateCount` integer, required: Number of alerts archived as duplicates of this alert. A high count means the same finding keeps recurring.
    - `source` object, required: Filter-oriented source attribution for an alert.
      - `category` 'detection' | 'trigger' | 'hunt' | 'api' | 'agent', required: Broad alert source category. Hunt covers threat-intel exposure alerts minted by the Hunt surface; api covers alerts submitted through an API source; agent covers alerts deliberately created by an agent.
      - `name` 'cotool_detection' | 'cotool_code' | 'cotool_signal' | 'hunt' | 'hunt_v2' | 'api' | 'agent' | 'jira' | 'jira-automation' | 'slack' | 'linear' | 'cron' | 'webhook' | 'email' | 'bugcrowd' | 'hackerone' | 'zscaler' | 'darktrace' | 'seon', required: Filter-oriented alert source name. Trigger-created alerts use the trigger type.
      - `triggerType` 'jira' | 'jira-automation' | 'slack' | 'linear' | 'cron' | 'webhook' | 'email' | 'bugcrowd' | 'hackerone' | 'zscaler' | 'darktrace' | 'seon' | 'null', nullable, required: Trigger source when category is trigger
    - `detection` object, nullable, required: Detection attribution for the alert, when known.
      - `id` string, uuid, nullable, required: Cotool detection identifier when known
      - `agentId` string, uuid, nullable, required: Cotool detection agent identifier when known
      - `codeDetectionId` string, uuid, nullable: Code detection identifier when this alert came from Code Mode
      - `ruleId` string, uuid, nullable, required: Platform detection rule identifier (detection_rules inventory) when an external detection was matched to a synced rule
      - `name` string, required: Detection display name
      - `kind` 'cotool' | 'cotool_code' | 'cotool_signal' | 'external', required: Whether this detection attribution is internal or extracted. `cotool_signal` alerts were promoted from a signal; their name is the signal type, and `codeDetectionId` is the streaming detection that emitted it.
      - `origin` 'user' | 'orchestrator' | 'null', nullable: Origin of the Cotool detection agent when known. `orchestrator` marks a detection created by the retired Auto Detect feature.
    - `createdBy` 'agent' | 'trigger' | 'system', required: Actor class that created the alert.
    - `originAgentId` string, uuid, nullable, required: Agent that produced or owns the source flow
    - `originTriggerId` string, uuid, nullable, required: Trigger that created this alert, when source is an external trigger
    - `originRunId` string, uuid, nullable, required: Run that minted the alert, stored as chats.id
    - `originDetectionHitId` string, uuid, nullable, required: Detection hit that produced this alert, when applicable
    - `codeDetectionId` string, uuid, nullable, required: Code detection that produced this alert, when applicable
    - `originCodeDetectionHitId` string, uuid, nullable, required: Code-detection hit that produced this alert, when applicable
    - `externalProvider` 'jira' | 'jira-automation' | 'slack' | 'linear' | 'cron' | 'webhook' | 'email' | 'bugcrowd' | 'hackerone' | 'zscaler' | 'darktrace' | 'seon' | 'null', nullable, required: External trigger provider such as jira, linear, email, or webhook
    - `externalRef` string, nullable, required: Provider-native event, ticket, message, or alert identifier
    - `externalUrl` string, uri, nullable, required: Provider-native URL for the originating object
    - `assignedAgentId` string, uuid, nullable, required: Response agent currently assigned to triage this alert
    - `triageRunId` string, uuid, nullable, required: Latest response-agent triage run for this alert, stored as chats.id
    - `dedupeKey` string, nullable, required: Stable key used for idempotent alert creation
    - `createdAt` string, required: ISO timestamp when the alert was created
    - `updatedAt` string, required: ISO timestamp when the alert was last updated
    - `firstTriagedAt` string, nullable, required: ISO timestamp when triage first started
    - `resolvedAt` string, nullable, required: ISO timestamp when the alert reached a terminal closed status
  - `entries` union[], required: Timeline entries recorded for changed title/description fields
    - union
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'created', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert creation timeline entries.
          - `source` object: Filter-oriented source attribution for an alert.
            - `category` 'detection' | 'trigger' | 'hunt' | 'api' | 'agent', required: Broad alert source category. Hunt covers threat-intel exposure alerts minted by the Hunt surface; api covers alerts submitted through an API source; agent covers alerts deliberately created by an agent.
            - `name` 'cotool_detection' | 'cotool_code' | 'cotool_signal' | 'hunt' | 'hunt_v2' | 'api' | 'agent' | 'jira' | 'jira-automation' | 'slack' | 'linear' | 'cron' | 'webhook' | 'email' | 'bugcrowd' | 'hackerone' | 'zscaler' | 'darktrace' | 'seon', required: Filter-oriented alert source name. Trigger-created alerts use the trigger type.
            - `triggerType` 'jira' | 'jira-automation' | 'slack' | 'linear' | 'cron' | 'webhook' | 'email' | 'bugcrowd' | 'hackerone' | 'zscaler' | 'darktrace' | 'seon' | 'null', nullable, required: Trigger source when category is trigger
          - `originDetectionHitId` string, uuid, nullable
          - `originTriggerId` string, uuid, nullable
          - `sourcePayloadId` string, uuid
          - `notifications` object[]: New Alert posts, as the alert-created delivery sends them. A top-level Slack post is the alert's thread in its channel.
            - `destinationId` string, uuid, required: Output destination ID
            - `destinationType` 'webhook' | 'teams' | 'slack' | 'pagerduty' | 'linear' | 'tines' | 'incidentio', required
            - `destinationName` string, required: Name of the output destination when it was sent
            - `label` string, nullable, required: What the destination created, e.g. "SEC-412"
            - `url` string, uri, nullable, required: Link to the message, issue, or case
            - `externalId` string, required: Destination-side identifier (Slack channel and message ts, Linear issue id, ...); with the destination, identifies the notification
            - `sentAt` string, date-time, required: When the notification was sent
            - `threadTs` string: Slack only: the thread root the post replied in; absent for a top-level post
            - `routeId` string, uuid: Escalation route that sent the notification; absent when it went to the default destinations
            - `routeName` string: Name of the escalation route when it was sent
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'comment', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert comment timeline entries.
          - `slackSource` unknown
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'status_change', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert status-change timeline entries.
          - `reason` string, nullable
          - `agentId` string, uuid
          - `runId` string, uuid
          - `outcome` 'completed' | 'failed' | 'canceled': How an alert triage run ended. `completed` means the run finished without setting a final disposition; `failed` means the agent run errored; `canceled` means the run was interrupted.
          - `duplicateOfAlertId` string, uuid
          - `duplicateOfDisplayId` string: Human-readable alert identifier
          - `duplicateOfTitle` string
          - `notifications` object[]: For an escalation, where its notifications landed, as the delivery jobs send them
            - `destinationId` string, uuid, required: Output destination ID
            - `destinationType` 'webhook' | 'teams' | 'slack' | 'pagerduty' | 'linear' | 'tines' | 'incidentio', required
            - `destinationName` string, required: Name of the output destination when it was sent
            - `label` string, nullable, required: What the destination created, e.g. "SEC-412"
            - `url` string, uri, nullable, required: Link to the message, issue, or case
            - `externalId` string, required: Destination-side identifier (Slack channel and message ts, Linear issue id, ...); with the destination, identifies the notification
            - `sentAt` string, date-time, required: When the notification was sent
            - `threadTs` string: Slack only: the thread root the post replied in; absent for a top-level post
            - `routeId` string, uuid: Escalation route that sent the notification; absent when it went to the default destinations
            - `routeName` string: Name of the escalation route when it was sent
          - `alternativeExplanations` object[]: For an agent escalation, explanations the agent could not rule out that a reviewer can confirm to close the alert. Recorded by the generation job after the escalation; absent until then or when none apply.
            - `id` string, uuid, required
            - `statement` string, required: One present-tense sentence a reviewer can confirm, e.g. "ClickUp is an approved Gmail integration".
            - `disposition` 'false_positive' | 'true_positive_benign', required: How the alert closes when a reviewer confirms this explanation: the activity happened but is expected (benign), or the detection claim is wrong (false positive).
            - `basis` string, required: The cue in the evidence that makes the explanation plausible and the gap in the escalation it would fill.
          - `confirmedAlternativeExplanation` object: For a close, the alternative explanation the reviewer confirmed, when the close came from confirming one
            - `id` string, uuid, required
            - `statement` string, required: One present-tense sentence a reviewer can confirm, e.g. "ClickUp is an approved Gmail integration".
            - `disposition` 'false_positive' | 'true_positive_benign', required: How the alert closes when a reviewer confirms this explanation: the activity happened but is expected (benign), or the detection claim is wrong (false positive).
            - `basis` string, required: The cue in the evidence that makes the explanation plausible and the gap in the escalation it would fill.
            - `escalationTimelineEntryId` string, uuid, required: The escalation entry the explanation was offered on
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'title_change', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert title-change timeline entries.
          - `beforeTitle` string, nullable
          - `afterTitle` string, nullable
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'description_change', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert description-change timeline entries.
          - `beforeDescription` string, nullable
          - `afterDescription` string, nullable
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'severity_change', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert severity-change timeline entries.
          - `beforeSeverity` 'low' | 'medium' | 'high' | 'critical' | 'null', nullable
          - `afterSeverity` 'low' | 'medium' | 'high' | 'critical' | 'null', nullable
          - `reason` string, nullable
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'assignment_change', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert assignment-change timeline entries.
          - `reason` string, nullable
          - `assignedAgentId` string, uuid, nullable
          - `runId` string, uuid, nullable
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'triage_run', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for alert triage-run timeline entries.
          - `reason` string, nullable
          - `agentId` string, uuid
          - `runId` string, uuid
          - `outcome` 'completed' | 'failed' | 'canceled': How an alert triage run ended. `completed` means the run finished without setting a final disposition; `failed` means the agent run errored; `canceled` means the run was interrupted.
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'duplicate_linked', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for an alert marked as a duplicate of this alert.
          - `duplicateAlertId` string, uuid, required
          - `duplicateAlertDisplayId` string, required: Human-readable alert identifier
          - `duplicateAlertTitle` string, required
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'external_event', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata for externally mirrored alert timeline entries.
          - `slackThread` object: Replies people and apps posted in one of the alert's Slack threads, mirrored from Slack
            - `teamId` string, required
            - `channelId` string, required
            - `threadTs` string, required
            - `url` string, uri, nullable, required: Link to the thread root
            - `replies` object[], required: Replies oldest first, by Slack message timestamp
              - …
      - object
        - `id` string, uuid, required: Timeline entry identifier
        - `organizationId` string, uuid, required: Organization that owns the timeline entry
        - `alertId` string, uuid, required: Alert this entry belongs to
        - `createdAt` string, required: ISO timestamp when the entry was created
        - `actorType` 'human' | 'agent' | 'system', required: Actor class responsible for a timeline entry.
        - `actorUserId` string, uuid, nullable, required: Human actor user id, when actorType is human
        - `actorAgentId` string, uuid, nullable, required: Agent actor id, when actorType is agent
        - `actorRunId` string, uuid, nullable, required: Run responsible for this entry, stored as chats.id
        - `actorUserName` string, nullable, required: Resolved display name for a human actor, hydrated for rendering
        - `actorUserImageUrl` string, nullable, required: Resolved avatar image URL for a human actor, when one is available
        - `actorAgentName` string, nullable: Resolved display name for an agent actor or referenced assigned agent
        - `kind` 'detection_tuned', required
        - `bodyMarkdown` string, nullable, required: Timeline body, when this entry has prose content
        - `beforeStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status before a status transition
        - `afterStatus` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate' | 'expired' | 'null', nullable, required: Status after a status transition
        - `metadata` object, required: Metadata recorded on cited alerts when a tuning proposal built on this alert's feedback is approved and published.
          - `detectionId` string, uuid, required
          - `detectionName` string, nullable, required
          - `versionId` string, uuid, required
          - `version` integer, nullable, required
          - `proposalId` string, uuid, required
          - `chatId` string, uuid, nullable, required
          - `role` 'fp_eliminated' | 'benign_eliminated' | 'tp_retained', required: How this alert's label figured in the approved tuning proposal: its false-positive or benign label was eliminated by the change, or it was a true positive the backtest verified the new version still catches.
          - `windowStart` string, date-time, required
          - `windowEnd` string, date-time, required

## Other responses

- `400`: Bad request — input validation failed or the request was malformed
- `401`: Unauthorized — missing or invalid API key / session
- `403`: Forbidden — the authenticated user lacks the required permissions
- `500`: Internal server error

## Changes

- **2026-11-05** `f5abe0add203`: 1 info
  - the `entries/items/oneOf[subschema #10]/metadata/slackThread/replies/items/userId` response's property pattern was changed from `^[UW][A-Z0-9]+$` to `^[UWB][A-Z0-9]+$` for the status `200`

[Operation history](https://skmtc.dev/cotool/apis/cotool-api/changes/api/alerts/:alertId/patch.md)

---

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