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

# Update alert status

`POST /api/alerts/{alertId}/status`

## Request

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

Update an alert lifecycle status and append a status-change timeline entry when the status changes. Optional feedback is appended as a comment in the same transaction. Duplicate status requires a canonical alert target.

## Path parameters

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

## Request body

- object
  - `status` 'open' | 'in_progress' | 'escalated' | 'closed_true_positive' | 'closed_false_positive' | 'closed_true_positive_benign' | 'dismissed' | 'duplicate', required: New alert lifecycle status. `expired` is set only by the alert inactivity job and is rejected here.
  - `reason` string: Optional reason for the status change
  - `commentBodyMarkdown` string: Optional human feedback appended to the alert timeline as a comment
  - `duplicateOfAlertId` string: Required canonical alert identifier when marking an alert as duplicate. A target that is itself a duplicate resolves to its canonical alert, and any duplicates of the alert being marked move to that canonical alert.
  - `confirmedAlternativeExplanationId` string, uuid: Alternative explanation from the latest escalation that this close confirms. Only valid with closed_false_positive or closed_true_positive_benign; the explanation is recorded on the status change and, when no reason is given, becomes the reason.

## 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
  - `entry` union, required: Timeline entry created for a status transition, or null when the requested status was already set
    - 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
            - `messageTs` string, required
            - `userId` string, required: The author's Slack user ID, or the bot ID of an app that posted without a user
            - `userName` string
            - `text` string, required
            - `textTruncated` boolean
            - `permalink` string, uri
            - `editedAt` string, date-time: When the author last edited the reply in Slack
    - 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
  - `commentEntry` union: Optional feedback comment appended with the status transition
    - 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
            - `messageTs` string, required
            - `userId` string, required: The author's Slack user ID, or the bot ID of an app that posted without a user
            - `userName` string
            - `text` string, required
            - `textTruncated` boolean
            - `permalink` string, uri
            - `editedAt` string, date-time: When the author last edited the reply in Slack
    - 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
  - `commentAdded` boolean: Whether optional feedback was appended as a comment with the status transition
  - `statusChanged` boolean, required: Whether the alert status changed and a timeline entry was recorded

## 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
- `409`: The alert cannot be reopened because a newer open hit exists for the same entity.
- `500`: Internal server error

## Changes

- **2026-11-05** `f5abe0add203`: 2 info
  - the `commentEntry/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`
  - the `entry/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/status/post.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)
