# Tellagen API Reference

> Generated from the same canonical API contract as the human-readable reference at https://tellagen.com/api-reference.

Documentation contract: `sha256:a5cd8e66988c9c8b615f339b37d49e7572853f4f1e6eb040361a39174365e687`. This fingerprint identifies the generated documentation contract, not the API major version.

## Endpoint index

### Incidents

[Incidents Markdown export](https://tellagen.com/api-reference/incidents/markdown)

- [`GET /api/v1/incidents`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents) — List incidents
- [`POST /api/v1/incidents`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents) — Create incident
- [`GET /api/v1/incidents/archived`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents-archived) — List archived incidents
- [`GET /api/v1/incident-references/{reference}`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incident-references-reference) — Get incident by permanent reference
- [`GET /api/v1/incidents/{id}`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents-id) — Get incident
- [`PATCH /api/v1/incidents/{id}`](https://tellagen.com/api-reference/incidents#incidents-endpoint-patch-api-v1-incidents-id) — Update incident
- [`GET /api/v1/incidents/{id}/actions`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents-id-actions) — List incident actions
- [`POST /api/v1/incidents/{id}/actions`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-actions) — Create incident action
- [`PATCH /api/v1/incident-actions/{id}`](https://tellagen.com/api-reference/incidents#incidents-endpoint-patch-api-v1-incident-actions-id) — Update incident action
- [`POST /api/v1/incidents/{id}/resolve`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-resolve) — Resolve incident
- [`POST /api/v1/incidents/{id}/close`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-close) — Close incident without resolution
- [`POST /api/v1/incidents/{id}/reopen`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-reopen) — Reopen incident
- [`GET /api/v1/incidents/{id}/provisioning`](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents-id-provisioning) — Get incident integration setup
- [`POST /api/v1/incidents/{id}/provisioning/retry`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-provisioning-retry) — Retry incident integration setup
- [`POST /api/v1/incidents/{id}/archive`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-archive) — Archive incident
- [`POST /api/v1/incidents/{id}/restore`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-restore) — Restore incident
- [`POST /api/v1/incidents/{id}/rename-slack-channel`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-rename-slack-channel) — Reapply the Slack channel-name template (deprecated)
- [`POST /api/v1/incidents/{id}/slack/channel-name/preview`](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-slack-channel-name-preview) — Preview an incident Slack channel name
- [`PATCH /api/v1/incidents/{id}/slack/channel-name`](https://tellagen.com/api-reference/incidents#incidents-endpoint-patch-api-v1-incidents-id-slack-channel-name) — Update an incident Slack channel name

## Base URL

`https://{company}.api.tellagen.com/api/v1/`

Replace `{company}` with your company subdomain. Requests and JSON responses use `application/json` unless an endpoint documents an empty response.

## Authentication

Create an API token in **Settings > API keys** and send it as a Bearer token:

`Authorization: Bearer tllg_YOUR_TOKEN`

Tokens are shown only once when created. Grant only the scopes the client needs.

## Integration guides

- [Make your first request](https://tellagen.com/api-reference#first-request)
- [Retries and updates](https://tellagen.com/api-reference#reliable-requests)
- [Rate limits](https://tellagen.com/api-reference/guides/rate-limits)
- [Filter and paginate collections](https://tellagen.com/api-reference/guides/pagination)
- [Create and move an incident through its workflow](https://tellagen.com/api-reference/guides/workflows)
- [Send custom-field values](https://tellagen.com/api-reference/guides/field-values)
- [Receive webhooks (preview)](https://tellagen.com/api-reference/guides/webhooks)

## Versioning

All endpoints in this reference use `/api/v1` and are supported.

**Compatible changes.** Tellagen can add optional response fields or enum values. Ignore response fields that your client does not use.

**Breaking changes.** Tellagen uses a new major version for incompatible changes.

**Deprecated endpoints.** Tellagen marks an endpoint deprecated at least 180 days before removal. Deprecated responses identify the replacement endpoint.

## Scopes

| Scope | Description |
| --- | --- |
| `incidents:read` | List and retrieve incidents, and discover writable workflow statuses and severities |
| `incidents:write` | Create and update incidents and timeline events. Requires an active responder seat for the key owner. |
| `slack_context:read` | Read Slack context collected for incident investigation |
| `services:read` | List and retrieve services, and discover writable service tiers |
| `services:write` | Create, update, and archive services. Requires an active responder seat and the manage_settings role permission. |
| `teams:read` | List and retrieve teams and members |
| `teams:write` | Create, update, and archive teams; manage members. Requires an active responder seat and the manage_teams role permission. |
| `custom_fields:read` | List and retrieve custom field definitions and values |
| `custom_fields:write` | Create, update, and archive custom fields; set incident field values. Definition changes require the manage_settings role permission. Incident value changes require an active responder seat. |
| `webhooks:manage` | Create, pause, resume, revoke, and rotate workspace webhook subscriptions. Requires the manage_settings role permission. |
| `customer_revenue:read` | Read customer revenue and financial impact. Requires the view_customer_revenue role permission and an active key owner membership. |
| `status_updates:email` | Email recorded status updates to the workspace's email groups (never to typed-in addresses). Not granted by default. Requires an active responder seat for the key owner and incidents:write. |

## Prerequisite definitions

- **Active responder seat** (`active_responder`): The API key owner must have an active responder seat.
- **Manage workspace settings** (`manage_settings`): The API key owner must have the manage_settings role permission.
- **Manage teams** (`manage_teams`): The API key owner must have the manage_teams role permission.
- **Incident is not archived** (`mutable_incident`): The incident must not be archived. Workflow-state restrictions are described by each operation.
- **Linked Slack channel** (`slack_channel`): The incident must have a linked Slack channel.

## Errors

Errors always include a stable `code` and a human-readable `message`. They can also include `field`, `details`, and `request_id`.

You can send `X-Request-ID` with a request. If you omit it, the API generates one. The response header and error body return the same value.

### Missing scope (403)

```json
{
  "code": "missing_scope",
  "message": "insufficient scope: incidents:write required",
  "details": {
    "required_scope": "incidents:write"
  },
  "request_id": "01JEXAMPLE8R4N5W6Y7Z"
}
```

### Stale resource version (412)

```json
{
  "code": "precondition_failed",
  "message": "the resource changed; fetch it again and retry with the current resource version",
  "field": "If-Tellagen-Resource-Version",
  "request_id": "01JEXAMPLE8R4N5W6Y7Z"
}
```

### Rate limit (429)

```json
{
  "code": "rate_limited",
  "message": "rate limit exceeded",
  "details": {
    "retry_after_seconds": 1
  },
  "request_id": "01JEXAMPLE8R4N5W6Y7Z"
}
```

When you contact support, include the request ID, method, path, status, and time. Omit tokens and private request bodies.

| Code | Meaning | Next action | Retry |
| --- | --- | --- | --- |
| `authentication_required` | The request has no valid API token or session. | Send an active Bearer token for this workspace. Replace an expired or revoked key. | After correcting authentication. |
| `missing_scope` | The token lacks the scope named in details.required_scope. | Read details.required_scope. Ask a workspace manager for a replacement key with that scope. | After correcting access. |
| `responder_seat_required` | The key owner needs the seat named in details.required_seat. | Ask a workspace manager to review the key owner’s responder seat. | After correcting access. |
| `missing_role_permission` | The key owner lacks details.required_permission or one of details.required_roles. | Ask a workspace manager to review the owner’s role and the permission named in details. | After correcting access. |
| `permission_denied` | Access is denied without exposing private authorization state. | Verify the workspace, key owner, and resource access with a workspace manager. | After correcting access. |
| `invalid_resource_state` | The operation is not valid for the current resource state. | Read the current resource. Restore an archived resource or choose an operation allowed in its current state. | After reconciling state. |
| `invalid_relationship_state` | Restore requires a retained owner or parent relationship to identify an active resource. | Restore the retained parent or owning team before restoring this resource. | After correcting the relationship. |
| `duplicate_slug` | A team already uses the requested slug. | Read the existing team or choose a different slug. | After changing the request. |
| `invalid_json` | The request body is not one valid JSON document. | Send one valid JSON object with Content-Type: application/json. | After correcting the body. |
| `unknown_field` | The request contains an unsupported JSON property named in field. | Remove or correct the property named in field. Use the request schema, not the response schema. | After correcting the body. |
| `request_body_too_large` | The request body is larger than 1 MiB. | Reduce the body to 1 MiB or less. | After reducing the body. |
| `multiple_json_values` | The request body contains more than one JSON document. | Send one JSON document rather than concatenated documents. | After correcting the body. |
| `idempotency_key_reused` | The key was already used with different request content. | Recover the original request for this key. Use a new key only for a different intended operation. | Do not resend changed content with the same key. |
| `idempotency_in_progress` | An equal request with this key is still running. Retry later. | Wait for Retry-After, then resend the identical body with the same key. | After the indicated delay. |
| `idempotency_outcome_unknown` | An earlier request may have completed, but its result could not be stored. Do not retry it automatically. | Read the resource state and contact support with the request ID before deciding whether to create again. | Never retry automatically. |
| `precondition_required` | An API-key PATCH request omitted If-Tellagen-Resource-Version. | Read the resource, then send its Tellagen-Resource-Version as If-Tellagen-Resource-Version. | After adding the current version. |
| `invalid_precondition` | If-Tellagen-Resource-Version is not a positive integer. | Use the positive integer version returned for this resource. Do not use an ETag or a timestamp. | After correcting the header. |
| `precondition_failed` | The resource changed after the client read it. | Read the resource again. Reconcile your intended change with the current state before using its new version. | After reconciling the change. |
| `rate_limited` | Retry after details.retry_after_seconds or the Retry-After header. | Wait for Retry-After or details.retry_after_seconds. Limit concurrency across the workspace. | After the indicated delay, with the original idempotency key where supported. |
| `internal` | The server failed without exposing an internal error. | Keep the request ID. Read current state before retrying a write whose outcome is uncertain. | Retry reads with bounded backoff. Follow operation-specific rules for writes. |
| `invalid_slack_channel_name_request` | The channel-name request is invalid. | Use custom mode with name, or workspace_template mode without name. | After correcting the request. |
| `slack_not_configured` | The workspace has no usable Slack integration. | Ask a workspace manager to connect or repair Slack. | After repairing the integration. |
| `incident_slack_channel_missing` | The incident has no linked Slack channel. | Link a channel through the incident workspace before requesting a rename. | After linking a channel. |
| `slack_channel_not_found` | Slack cannot find the linked channel. | Verify the channel still exists and that the integration can access it. | After repairing channel access. |
| `slack_channel_name_taken` | Another Slack channel uses the requested name. | Choose another custom name or revise the workspace naming template. | After choosing an available name. |
| `invalid_idempotency_key` | The idempotency key has an invalid length or character. | Use 1–128 visible, non-space ASCII characters. A UUID is suitable. | After correcting the key. |

| Status | Meaning |
| --- | --- |
| `400` | Bad Request — invalid input or missing required fields |
| `401` | Unauthorized — missing or invalid token |
| `403` | Forbidden — insufficient scope or responder access |
| `404` | Not Found — resource does not exist |
| `409` | Conflict — resource state prevents the request |
| `412` | Precondition Failed — the supplied resource version is stale |
| `428` | Precondition Required — this operation needs If-Tellagen-Resource-Version |
| `429` | Too Many Requests — rate limit exceeded |
| `500` | Internal Server Error |

Authenticated requests share a workspace limit. Anonymous requests and failed authentication attempts use the trusted client IP. Responses include `X-RateLimit-Limit` and `X-RateLimit-Remaining`. A `429` response also includes `Retry-After`.

## Incidents

Create incidents from alerts, record their progress, and resolve them after recovery.

### `GET /api/v1/incidents`

**List incidents.** Lists incidents that are not archived, newest first by default. The default page size is 50. The maximum is 100.

Repeated values for one filter match either value. Different filters must all match. Filters also apply to restricted_count.

Use the returned cursor with the same filters and sort order. Changes between requests can move incidents between pages.


Required scope: `incidents:read`

Operation ID: `listIncidents`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Query parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | `integer` | No | The maximum number of items in one page. The default is 50, and the maximum is 100. Minimum: 1. Maximum: 100. Default: 50. |
| `cursor` | `string` | No | The next_cursor value from the previous page. Clients treat this value as opaque and do not create, inspect, or change it. Minimum length: 1 characters. Maximum length: 4096 characters. |
| `scope` | `string` | No | Selects all incidents or only postmortems. The default is all. With scope=postmortem, incidents whose postmortem work is missing or in review are listed even when they are older than the workspace history limit, and restricted_count counts only the incidents still hidden. Default: "all". Allowed values: `"all"` \| `"postmortem"` |
| `status` | `string[]` | No | Includes incidents with any supplied workflow status. Repeating status supplies more than one accepted value. |
| `severity` | `string[]` | No | Includes incidents with any supplied severity key. Repeating severity supplies more than one accepted value. |
| `service` | `string[]` | No | Includes incidents with any supplied service slug. Repeating service supplies more than one accepted value. |
| `team_id` | `integer[]` | No | Includes incidents with any supplied owning-team ID. Repeating team_id supplies more than one accepted value. Each ID must be positive. |
| `created_from` | `string (RFC 3339)` | No | Includes incidents created at or after this RFC 3339 timestamp. |
| `created_to` | `string (RFC 3339)` | No | Includes incidents created at or before this RFC 3339 timestamp. |
| `created_before` | `string (RFC 3339)` | No | Includes incidents created strictly before this RFC 3339 timestamp. It cannot be combined with created_to. |
| `region` | `string[]` | No | Includes incidents with any supplied case-insensitive region. Repeating region supplies more than one accepted value. Maximum items: 100. |
| `lifecycle` | `string[]` | No | Includes any supplied incident lifecycle: ticket, incident, postmortem, or alert. Maximum items: 100. Allowed values: `"ticket"` \| `"incident"` \| `"postmortem"` \| `"alert"` |
| `service_tier` | `string[]` | No | Includes incidents whose canonical tenant service has any supplied tier. Maximum items: 100. Allowed values: `"t0"` \| `"t1"` \| `"t2"` \| `"t3"` |
| `effective_team_id` | `integer[]` | No | Includes incidents assigned directly to any supplied team or inheriting it from the canonical service. Repeating the parameter supplies more than one accepted positive ID. Maximum items: 100. |
| `unassigned_team` | `boolean` | No | When true, also includes incidents with no direct or canonical-service team. Default: false. |
| `mine` | `boolean` | No | When true, includes incidents assigned to the authenticated user, or created by that user when no active assignee exists. API-key-only authentication cannot use this filter. Default: false. |
| `active_only` | `boolean` | No | When true, excludes workflow stages configured as terminal. False does not add a status restriction. |
| `status_scope` | `string` | No | Selects all statuses, nonterminal ongoing statuses, or one configured workflow-stage slug. Minimum length: 1 characters. Maximum length: 2048 characters. |
| `diagnosis` | `string[]` | No | Includes incidents in any supplied diagnosis state. Repeating diagnosis supplies more than one accepted value. Maximum items: 100. Allowed values: `"not_run"` \| `"in_progress"` \| `"completed"` \| `"needs_attention"` \| `"unavailable"` |
| `sort` | `string` | No | Selects the collection sort field. Custom requires sort_custom_field. Owner orders by the active incident manager's email; incidents without an incident manager sort last in both directions. Signal orders by priority, with active incidents before resolved ones, then severity rank in the active severity catalog, then latest activity; it defaults to direction=asc, most urgent first. Omission keeps legacy created_at order. Allowed values: `"created_at"` \| `"last_event_at"` \| `"severity"` \| `"service"` \| `"diagnosis"` \| `"case"` \| `"regions"` \| `"team"` \| `"impact"` \| `"status"` \| `"owner"` \| `"events"` \| `"custom"` \| `"signal"` |
| `direction` | `string` | No | Sort direction for both the selected key and incident-ID tiebreaker. Defaults to desc, except asc when sort is signal. Default: "desc". Allowed values: `"asc"` \| `"desc"` |
| `sort_custom_field` | `string` | No | Active custom-field slug used when sort is custom. The server resolves and validates its stored type. Minimum length: 1 characters. Maximum length: 64 characters. |
| `custom_filter` | `string[]` | No | A JSON object with slug, operator, and value. Repeat for up to 32 predicates. Values remain typed JSON; arrays preserve choices containing commas. Supported operators depend on the resolved field type: string is/is_not/contains/starts_with; select is/is_not; boolean is; number and monetary eq/gt/lt/gte/lte/between; date and datetime is/before/after/between/gte/lte; time is/before/after; multiselect includes_any/includes_all/excludes. SQL fragments and client-supplied field types are rejected. Maximum items: 32. |
| `include_counts` | `boolean` | No | When true, returns authoritative matched, all, ongoing, and per-status counts before cursor and limit. Default: false. |
| `impact_status` | `string[]` | No | Includes incidents with any supplied customer-impact status. Allowed values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `affected_customers_op` | `string` | No | Selects the operator for the affected-customer comparison. This parameter and affected_customers_value must appear together. Allowed values: `"<"` \| `">"` \| `"="` |
| `affected_customers_value` | `integer` | No | The non-negative affected-customer count for comparison. This parameter and affected_customers_op must appear together. Minimum: 0. |
| `mrr_op` | `string` | No | Selects the operator for the MRR comparison. This parameter and mrr_value must appear together. Allowed values: `"<"` \| `">"` \| `"="` |
| `mrr_value` | `integer` | No | The non-negative MRR amount for comparison, in minor currency units. This parameter and mrr_op must appear together. Minimum: 0. |
| `mrr_currency` | `string` | No | A three-letter ISO currency code. If mrr_basis is source, this parameter is required. Pattern: ^[A-Z]{3}$. |
| `mrr_basis` | `string` | No | Selects normalized workspace currency values or original source currency values. The default is normalized. Default: "normalized". Allowed values: `"normalized"` \| `"source"` |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incidents` | `object[]` | Always | The incidents in this page. |
| `incidents[].id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incidents[].revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incidents[].company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incidents[].human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incidents[].title` | `string` | Always | The editable display title of the incident. |
| `incidents[].service` | `string` | Always | The service slug associated with the incident. |
| `incidents[].regions` | `string[]` | Always | The affected regions. |
| `incidents[].severity` | `string` | Always | The configured severity key. |
| `incidents[].slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incidents[].meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incidents[].doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incidents[].status` | `string` | Always | The configured workflow-status key. |
| `incidents[].status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incidents[].last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incidents[].last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incidents[].issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incidents[].severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incidents[].impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incidents[].customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incidents[].impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incidents[].first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incidents[].first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incidents[].recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incidents[].duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incidents[].duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incidents[].team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incidents[].event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incidents[].investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incidents[].investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incidents[].investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incidents[].investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incidents[].investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incidents[].investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incidents[].status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incidents[].status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incidents[].status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incidents[].status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incidents[].status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incidents[].status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incidents[].postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incidents[].postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incidents[].postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incidents[].postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incidents[].postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incidents[].postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incidents[].created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incidents[].created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incidents[].custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incidents[].archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incidents[].archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incidents[].incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incidents[].incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incidents[].has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `has_more` | `boolean` | Always | Deprecated top-level alias for pagination.has_more. |
| `next_cursor` | `string` | Optional | Deprecated top-level alias for pagination.next_cursor. |
| `pagination` | `object` | Always | Pagination details for a collection response. |
| `pagination.limit` | `integer` | Always | The maximum number of items requested for this page. Minimum: 1. Maximum: 100. |
| `pagination.has_more` | `boolean` | Always | Indicates whether another page is available. |
| `pagination.next_cursor` | `string` | Optional | The opaque cursor for the next page. This field is absent on the final page. |
| `restricted_count` | `integer` | Optional | The number of matching incidents excluded by the workspace history limit. Minimum: 0. |
| `history_limited` | `boolean` | Optional | Indicates whether the workspace history limit applies to this response. |
| `mrr_currency` | `string` | Optional | The workspace reporting currency used for normalized MRR values. |
| `mrr_conversion_mode` | `string` | Optional | The workspace mode for MRR currency conversion. Possible values: `"normalized"` \| `"source_only"` |
| `mrr_projection_state` | `string` | Optional | The MRR projection state. Possible values: `"ready"` \| `"stale"` \| `"unavailable"` |
| `supported_mrr_currencies` | `string[]` | Optional | The ISO currency codes supported by MRR filters. |
| `collection_counts` | `object` | Optional | Complete collection counts before cursor and limit when include_counts is true. |
| `collection_counts.matched` | `integer` | Always | Count after every predicate, including status selection. Minimum: 0. |
| `collection_counts.all` | `integer` | Always | Count after non-status predicates, excluding status, status_scope, and active_only. Minimum: 0. |
| `collection_counts.ongoing` | `integer` | Always | Nonterminal count after non-status predicates. Minimum: 0. |
| `collection_counts.by_status` | `object` | Always | Exact counts by normalized stored status after non-status predicates. |

Returns incidents and pagination fields. If has_more is true, next_cursor is the cursor for the next request. When include_counts is true, collection_counts describes the complete filtered collection before cursor and limit. Nullable fields are always present. Empty arrays and empty custom_fields objects are also present.

```json
{
  "incidents": [
    {
      "id": 1,
      "revision": 7,
      "company_id": 7,
      "human_id": "INC-2025-001",
      "title": "Payments API requests timing out",
      "service": "payments",
      "regions": [
        "us-east-1"
      ],
      "severity": "sev1",
      "slack_channel_id": "C08ABC123",
      "meet_url": "https://meet.google.com/abc-defg-hij",
      "doc_url": "https://docs.google.com/d/1abc",
      "status": "active",
      "status_changed_at": "2025-01-30T12:05:00Z",
      "last_event_at": "2025-01-30T12:10:00Z",
      "last_event_summary": "Investigating root cause",
      "issue_type": "incident",
      "severity_mode": "manual",
      "impact_summary": "Payment processing delayed for EU customers",
      "customer_impact_status": "confirmed",
      "impact_started_at": "2025-01-30T11:55:00Z",
      "first_reported_at": "2025-01-30T11:58:00Z",
      "first_responded_at": "2025-01-30T12:00:00Z",
      "recovered_at": null,
      "duration_seconds": 900,
      "duration_anchor": "impact_started_at",
      "team_id": 42,
      "event_count": 5,
      "investigation_summary": null,
      "status_update_summary": {
        "latest_recorded_at": "2025-01-30T12:05:00Z",
        "next_update_at": "2025-01-30T12:35:00Z",
        "latest_excerpt": "Rolling back the payments deploy"
      },
      "postmortem_summary": {
        "has_work": false,
        "has_working_draft": false,
        "latest_version_id": null,
        "latest_version_kind": null,
        "work_state": "none"
      },
      "created_at": "2025-01-30T12:00:00Z",
      "created_by": "oncall@example.com",
      "custom_fields": {},
      "archived_at": null,
      "archived_by": null,
      "incident_manager": "oncall@example.com",
      "incident_responders": [
        "responder@example.com"
      ],
      "has_assignees": true
    }
  ],
  "has_more": true,
  "next_cursor": "opaque-server-cursor",
  "pagination": {
    "limit": 50,
    "has_more": true,
    "next_cursor": "opaque-server-cursor"
  },
  "collection_counts": {
    "matched": 12,
    "all": 20,
    "ongoing": 8,
    "by_status": {
      "active": 8,
      "resolved": 12
    }
  }
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents`

**Create incident.** Creates an incident from an alert or another tool. The API validates all fields before it saves the incident and its declaration event.

If Slack is configured and create_slack_channel is true, Tellagen creates the channel after it saves the incident. The getIncidentProvisioning endpoint shows progress. The retryIncidentProvisioning endpoint retries failed steps.


Required scope: `incidents:write`

Operation ID: `createIncident`
Contract: `supported`
Retry guidance: Within 24 hours, retry with the original Idempotency-Key and identical body. If the result is unknown, do not retry automatically. Check whether the resource exists.
Prerequisites: None

#### Request headers

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | `string` | No | A key for safe retries of a create request. It must contain 1–128 visible, non-space ASCII characters. The same key applies only to an identical request. Minimum length: 1 characters. Maximum length: 128 characters. Pattern: ^[\x21-\x7E]+$. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

For `<idempotency-key>`, choose a unique key on the first attempt. Reuse it only when retrying the identical request.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents' \
  --header 'Authorization: Bearer <token>' \
  --header 'Idempotency-Key: <idempotency-key>' \
  --header 'Content-Type: application/json' \
  --data '{
  "title": "Payments API requests timing out",
  "impact_summary": "EU customers cannot complete payment authorization",
  "create_slack_channel": false
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | No | The incident display title. The maximum length is 160 characters. If title is omitted, the API derives it from impact_summary or service. Maximum length: 160 characters. |
| `service` | `string` | No | The service slug. The maximum length is 128 characters. Maximum length: 128 characters. |
| `regions` | `string[]` | No | The affected regions. The API trims each value and removes duplicates. |
| `severity` | `string` | No | A severity key from the workspace configuration. If severity is omitted, the API uses the configured default severity. |
| `short_title` | `string` | Conditional | A short slug for the incident reference and Slack channel name. The API normalizes it and limits it to 12 characters. If short_title_required is true, this field is required. This field is not the incident title. Required when: Required when the workspace configuration enables short titles. Maximum length: 12 characters. |
| `impact_summary` | `string` | No | The customer or operational impact summary. This field is separate from title and can change independently. |
| `declaration_evidence` | `string` | No | Alert or log text for the incident_declared timeline event. This field records responder evidence and does not set customer_impact_status. |
| `doc_url` | `string` | No | An absolute HTTP or HTTPS URL stored as an incident reference. The API can import a supported initial report as a separate timeline event. |
| `import_source_timeline_event` | `boolean` | Conditional | If this value is true, the API imports a supported Slack or PagerDuty doc_url as a timeline event. This value requires doc_url. A signed Slack declaration can require import regardless of this value. Required when: This field may be true only when doc_url is provided. |
| `team_id` | `integer` | No | A positive owning-team ID. If the team does not exist, the API returns 404. If the team is archived, the API returns 400. If the request omits team_id, the API uses the service owner. Minimum: 1. |
| `issue_type` | `string` | No | The work type. If the request omits issue_type, the API uses incident. Allowed values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `status` | `string` | No | An initial workflow-status key from the workspace configuration. If the request omits status, the API uses the configured default status. |
| `severity_mode` | `string` | No | The severity selection mode. If the request omits severity_mode, the API uses auto. Allowed values: `"auto"` \| `"manual"` |
| `create_slack_channel` | `boolean` | No | Controls Slack channel creation. If the request omits create_slack_channel, the API uses the workspace Slack configuration. Slack must be configured before the API can create a channel. |
| `invite_usergroups` | `string[]` | No | The Slack user-group IDs to invite. If the request omits invite_usergroups, the API uses the workspace Slack configuration. |
| `custom_field_values` | `object[]` | No | Custom-field values for the new incident. The API validates every value and each required_on_creation field before Slack work. It saves these values and the incident in one database transaction. |
| `custom_field_values[].field_id` | `integer` | Yes | The positive ID of the custom-field definition. Minimum: 1. |
| `custom_field_values[].value` | `any` | Yes | The value for the custom field. The accepted type depends on field_type. |

Request JSON:

```json
{
  "title": "Payments API requests timing out",
  "impact_summary": "EU customers cannot complete payment authorization",
  "create_slack_channel": false
}
```

#### Success response

Status: `201 Created`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |
| `source_timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `source_timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `source_timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `source_timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `source_timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `source_timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `source_timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `source_timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `source_timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `source_timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `source_timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `source_timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `source_timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `source_timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `source_timeline_event.title` | `string` | Always | The optional display title of the event. |
| `source_timeline_event.body` | `string` | Always | The event description. |
| `source_timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `source_timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `source_timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `source_timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `source_timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `source_timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `source_timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `source_timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `source_timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `source_timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `source_timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `source_timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `source_timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `source_timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `source_timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `source_timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `source_timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `source_timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `source_timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `source_timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `source_timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `source_timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `source_timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `source_timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `source_timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `source_timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `source_timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `source_timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `source_timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `source_timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `source_timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `source_timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `source_timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `source_timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `source_timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |
| `source_timeline_import` | `object` | Optional | The result of importing an initial report as a timeline event. |
| `source_timeline_import.status` | `string` | Always | The import result. Possible values: `"imported"` \| `"failed"` \| `"unavailable"` \| `"invalid"` \| `"unsupported"` |
| `source_timeline_import.provider` | `string` | Optional | The detected source provider. When the provider is unavailable, this field is absent. |
| `slack_declaration_attachment` | `object` | Optional | The result of attaching Slack declaration context to the incident. |
| `slack_declaration_attachment.status` | `string` | Always | The attachment result. Possible values: `"attached"` \| `"failed"` |
| `slack_declaration_images` | `object` | Optional | The result of copying images from a Slack declaration. |
| `slack_declaration_images.status` | `string` | Always | The image-copy result. Possible values: `"attached"` \| `"partial"` \| `"failed"` |
| `slack_declaration_images.total` | `integer` | Always | The total number of Slack images considered. Minimum: 0. |
| `slack_declaration_images.attached` | `integer` | Always | The number of images copied successfully. Minimum: 0. |
| `slack_declaration_images.failed` | `integer` | Always | The number of images that the API did not copy. Minimum: 0. |
| `declaration_next` | `string` | Optional | The next incident workspace section requested by a signed Slack declaration. |
| `custom_field_values` | `object[]` | Optional | The custom-field values saved in the same transaction as the incident. |
| `custom_field_values[].id` | `integer` | Always | The positive numeric ID of the stored value. Minimum: 1. |
| `custom_field_values[].incident_id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `custom_field_values[].custom_field_id` | `integer` | Always | The positive numeric ID of the custom-field definition. Minimum: 1. |
| `custom_field_values[].value` | `any` | Optional | The stored field value. Its type depends on field_type. |
| `custom_field_values[].created_at` | `string (RFC 3339)` | Always | The initial value storage time. |
| `custom_field_values[].updated_at` | `string (RFC 3339)` | Always | The time of the latest value change. |

The incident field contains the saved incident. custom_field_values contains values saved in the same database transaction. timeline_event contains the incident_declared event. source_timeline_event contains the imported source event. A 201 response does not guarantee a successful evidence import. source_timeline_import identifies the provider and reports the import result.

```json
{
  "incident": {
    "id": 1,
    "revision": 1,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev2",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://acme.pagerduty.com/incidents/PXYZ123",
    "status": "active",
    "status_changed_at": "2025-01-30T12:00:00Z",
    "last_event_at": null,
    "last_event_summary": "",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "EU customers cannot complete payment authorization",
    "customer_impact_status": "unknown",
    "impact_started_at": null,
    "first_reported_at": null,
    "first_responded_at": null,
    "recovered_at": null,
    "duration_seconds": 0,
    "duration_anchor": "created_at",
    "team_id": 42,
    "event_count": 0,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "",
    "incident_responders": [],
    "has_assignees": false
  },
  "timeline_event": {
    "id": 101,
    "revision": 1,
    "incident_id": 1,
    "started_at": "2025-01-30T12:00:00Z",
    "at": "2025-01-30T12:00:00Z",
    "ended_at": null,
    "is_ongoing": false,
    "group_id": null,
    "is_key": false,
    "source": "system",
    "source_ref": "",
    "type": "incident_declared",
    "icon": "🚨",
    "title": "Incident declared",
    "body": "PagerDuty reports elevated payment authorization latency.",
    "collaboration_generation": 1,
    "tags": [],
    "ai_context": "",
    "created_by": "oncall@example.com",
    "comment_count": 0,
    "attachments": [],
    "source_window_started_at": null,
    "source_window_ended_at": null,
    "evidence_links": []
  },
  "source_timeline_event": {
    "id": 102,
    "revision": 1,
    "incident_id": 1,
    "started_at": "2025-01-30T12:00:00.000001Z",
    "at": "2025-01-30T12:00:00.000001Z",
    "ended_at": null,
    "is_ongoing": false,
    "group_id": null,
    "is_key": false,
    "source": "pagerduty",
    "source_ref": "pagerduty:PXYZ123",
    "type": "alert",
    "icon": "🚨",
    "title": "Payment authorization latency",
    "body": "PagerDuty incident PXYZ123 is triggered.",
    "collaboration_generation": 1,
    "tags": [],
    "ai_context": "",
    "created_by": "oncall@example.com",
    "comment_count": 0,
    "attachments": [],
    "source_window_started_at": null,
    "source_window_ended_at": null,
    "evidence_links": []
  },
  "source_timeline_import": {
    "provider": "pagerduty",
    "status": "imported"
  },
  "custom_field_values": [
    {
      "id": 1,
      "incident_id": 1,
      "custom_field_id": 50,
      "value": 1500,
      "created_at": "2025-01-30T12:00:00Z",
      "updated_at": "2025-01-30T12:00:00Z"
    }
  ]
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

Endpoint-specific codes: `idempotency_key_reused`, `idempotency_in_progress`, `idempotency_outcome_unknown`

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [List available workflow statuses](https://tellagen.com/api-reference/configuration#configuration-endpoint-get-api-v1-configuration-workflow-statuses) (`GET /api/v1/configuration/workflow-statuses`)
- [List available severities](https://tellagen.com/api-reference/configuration#configuration-endpoint-get-api-v1-configuration-severities) (`GET /api/v1/configuration/severities`)
- [List services](https://tellagen.com/api-reference/services#services-endpoint-get-api-v1-services) (`GET /api/v1/services`)

### `GET /api/v1/incidents/archived`

**List archived incidents.** Returns one page of archived incidents. The default page size is 50, and the maximum is 100. Results are ordered by archived_at and incident ID. The workspace history limit can exclude older incidents.

Required scope: `incidents:read`

Operation ID: `listArchivedIncidents`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Query parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | `integer` | No | The maximum number of items in one page. The default is 50, and the maximum is 100. Minimum: 1. Maximum: 100. Default: 50. |
| `cursor` | `string` | No | The next_cursor value from the previous page. Clients treat this value as opaque and do not create, inspect, or change it. Minimum length: 1 characters. Maximum length: 4096 characters. |
| `scope` | `string` | No | Selects all incidents or only postmortems. The default is all. With scope=postmortem, incidents whose postmortem work is missing or in review are listed even when they are older than the workspace history limit, and restricted_count counts only the incidents still hidden. Default: "all". Allowed values: `"all"` \| `"postmortem"` |
| `status` | `string[]` | No | Includes incidents with any supplied workflow status. Repeating status supplies more than one accepted value. |
| `severity` | `string[]` | No | Includes incidents with any supplied severity key. Repeating severity supplies more than one accepted value. |
| `service` | `string[]` | No | Includes incidents with any supplied service slug. Repeating service supplies more than one accepted value. |
| `team_id` | `integer[]` | No | Includes incidents with any supplied owning-team ID. Repeating team_id supplies more than one accepted value. Each ID must be positive. |
| `created_from` | `string (RFC 3339)` | No | Includes incidents created at or after this RFC 3339 timestamp. |
| `created_to` | `string (RFC 3339)` | No | Includes incidents created at or before this RFC 3339 timestamp. |
| `created_before` | `string (RFC 3339)` | No | Includes incidents created strictly before this RFC 3339 timestamp. It cannot be combined with created_to. |
| `region` | `string[]` | No | Includes incidents with any supplied case-insensitive region. Repeating region supplies more than one accepted value. Maximum items: 100. |
| `lifecycle` | `string[]` | No | Includes any supplied incident lifecycle: ticket, incident, postmortem, or alert. Maximum items: 100. Allowed values: `"ticket"` \| `"incident"` \| `"postmortem"` \| `"alert"` |
| `service_tier` | `string[]` | No | Includes incidents whose canonical tenant service has any supplied tier. Maximum items: 100. Allowed values: `"t0"` \| `"t1"` \| `"t2"` \| `"t3"` |
| `effective_team_id` | `integer[]` | No | Includes incidents assigned directly to any supplied team or inheriting it from the canonical service. Repeating the parameter supplies more than one accepted positive ID. Maximum items: 100. |
| `unassigned_team` | `boolean` | No | When true, also includes incidents with no direct or canonical-service team. Default: false. |
| `mine` | `boolean` | No | When true, includes incidents assigned to the authenticated user, or created by that user when no active assignee exists. API-key-only authentication cannot use this filter. Default: false. |
| `active_only` | `boolean` | No | When true, excludes workflow stages configured as terminal. False does not add a status restriction. |
| `status_scope` | `string` | No | Selects all statuses, nonterminal ongoing statuses, or one configured workflow-stage slug. Minimum length: 1 characters. Maximum length: 2048 characters. |
| `diagnosis` | `string[]` | No | Includes incidents in any supplied diagnosis state. Repeating diagnosis supplies more than one accepted value. Maximum items: 100. Allowed values: `"not_run"` \| `"in_progress"` \| `"completed"` \| `"needs_attention"` \| `"unavailable"` |
| `sort` | `string` | No | Selects the collection sort field. Custom requires sort_custom_field. Owner orders by the active incident manager's email; incidents without an incident manager sort last in both directions. Signal orders by priority, with active incidents before resolved ones, then severity rank in the active severity catalog, then latest activity; it defaults to direction=asc, most urgent first. Omission keeps legacy created_at order. Allowed values: `"created_at"` \| `"last_event_at"` \| `"severity"` \| `"service"` \| `"diagnosis"` \| `"case"` \| `"regions"` \| `"team"` \| `"impact"` \| `"status"` \| `"owner"` \| `"events"` \| `"custom"` \| `"signal"` |
| `direction` | `string` | No | Sort direction for both the selected key and incident-ID tiebreaker. Defaults to desc, except asc when sort is signal. Default: "desc". Allowed values: `"asc"` \| `"desc"` |
| `sort_custom_field` | `string` | No | Active custom-field slug used when sort is custom. The server resolves and validates its stored type. Minimum length: 1 characters. Maximum length: 64 characters. |
| `custom_filter` | `string[]` | No | A JSON object with slug, operator, and value. Repeat for up to 32 predicates. Values remain typed JSON; arrays preserve choices containing commas. Supported operators depend on the resolved field type: string is/is_not/contains/starts_with; select is/is_not; boolean is; number and monetary eq/gt/lt/gte/lte/between; date and datetime is/before/after/between/gte/lte; time is/before/after; multiselect includes_any/includes_all/excludes. SQL fragments and client-supplied field types are rejected. Maximum items: 32. |
| `include_counts` | `boolean` | No | When true, returns authoritative matched, all, ongoing, and per-status counts before cursor and limit. Default: false. |
| `impact_status` | `string[]` | No | Includes incidents with any supplied customer-impact status. Allowed values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `affected_customers_op` | `string` | No | Selects the operator for the affected-customer comparison. This parameter and affected_customers_value must appear together. Allowed values: `"<"` \| `">"` \| `"="` |
| `affected_customers_value` | `integer` | No | The non-negative affected-customer count for comparison. This parameter and affected_customers_op must appear together. Minimum: 0. |
| `mrr_op` | `string` | No | Selects the operator for the MRR comparison. This parameter and mrr_value must appear together. Allowed values: `"<"` \| `">"` \| `"="` |
| `mrr_value` | `integer` | No | The non-negative MRR amount for comparison, in minor currency units. This parameter and mrr_op must appear together. Minimum: 0. |
| `mrr_currency` | `string` | No | A three-letter ISO currency code. If mrr_basis is source, this parameter is required. Pattern: ^[A-Z]{3}$. |
| `mrr_basis` | `string` | No | Selects normalized workspace currency values or original source currency values. The default is normalized. Default: "normalized". Allowed values: `"normalized"` \| `"source"` |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/archived' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incidents` | `object[]` | Always | The incidents in this page. |
| `incidents[].id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incidents[].revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incidents[].company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incidents[].human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incidents[].title` | `string` | Always | The editable display title of the incident. |
| `incidents[].service` | `string` | Always | The service slug associated with the incident. |
| `incidents[].regions` | `string[]` | Always | The affected regions. |
| `incidents[].severity` | `string` | Always | The configured severity key. |
| `incidents[].slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incidents[].meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incidents[].doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incidents[].status` | `string` | Always | The configured workflow-status key. |
| `incidents[].status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incidents[].last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incidents[].last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incidents[].issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incidents[].severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incidents[].impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incidents[].customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incidents[].impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incidents[].first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incidents[].first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incidents[].recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incidents[].duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incidents[].duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incidents[].team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incidents[].event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incidents[].investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incidents[].investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incidents[].investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incidents[].investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incidents[].investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incidents[].investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incidents[].status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incidents[].status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incidents[].status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incidents[].status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incidents[].status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incidents[].status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incidents[].status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incidents[].postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incidents[].postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incidents[].postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incidents[].postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incidents[].postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incidents[].postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incidents[].created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incidents[].created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incidents[].custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incidents[].archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incidents[].archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incidents[].incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incidents[].incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incidents[].has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `has_more` | `boolean` | Always | Deprecated top-level alias for pagination.has_more. |
| `next_cursor` | `string` | Optional | Deprecated top-level alias for pagination.next_cursor. |
| `pagination` | `object` | Always | Pagination details for a collection response. |
| `pagination.limit` | `integer` | Always | The maximum number of items requested for this page. Minimum: 1. Maximum: 100. |
| `pagination.has_more` | `boolean` | Always | Indicates whether another page is available. |
| `pagination.next_cursor` | `string` | Optional | The opaque cursor for the next page. This field is absent on the final page. |
| `restricted_count` | `integer` | Optional | The number of matching incidents excluded by the workspace history limit. Minimum: 0. |
| `history_limited` | `boolean` | Optional | Indicates whether the workspace history limit applies to this response. |
| `mrr_currency` | `string` | Optional | The workspace reporting currency used for normalized MRR values. |
| `mrr_conversion_mode` | `string` | Optional | The workspace mode for MRR currency conversion. Possible values: `"normalized"` \| `"source_only"` |
| `mrr_projection_state` | `string` | Optional | The MRR projection state. Possible values: `"ready"` \| `"stale"` \| `"unavailable"` |
| `supported_mrr_currencies` | `string[]` | Optional | The ISO currency codes supported by MRR filters. |
| `collection_counts` | `object` | Optional | Complete collection counts before cursor and limit when include_counts is true. |
| `collection_counts.matched` | `integer` | Always | Count after every predicate, including status selection. Minimum: 0. |
| `collection_counts.all` | `integer` | Always | Count after non-status predicates, excluding status, status_scope, and active_only. Minimum: 0. |
| `collection_counts.ongoing` | `integer` | Always | Nonterminal count after non-status predicates. Minimum: 0. |
| `collection_counts.by_status` | `object` | Always | Exact counts by normalized stored status after non-status predicates. |

Returns archived incidents, pagination fields, and workspace history-limit details. The filters also apply to restricted_count.

```json
{
  "incidents": [
    {
      "id": 1,
      "revision": 7,
      "company_id": 7,
      "human_id": "INC-2025-001",
      "title": "Payments API requests timing out",
      "service": "payments",
      "regions": [
        "us-east-1"
      ],
      "severity": "sev1",
      "slack_channel_id": "C08ABC123",
      "meet_url": "https://meet.google.com/abc-defg-hij",
      "doc_url": "https://docs.google.com/d/1abc",
      "status": "active",
      "status_changed_at": "2025-01-30T12:05:00Z",
      "last_event_at": "2025-01-30T12:10:00Z",
      "last_event_summary": "Investigating root cause",
      "issue_type": "incident",
      "severity_mode": "manual",
      "impact_summary": "Payment processing delayed for EU customers",
      "customer_impact_status": "confirmed",
      "impact_started_at": "2025-01-30T11:55:00Z",
      "first_reported_at": "2025-01-30T11:58:00Z",
      "first_responded_at": "2025-01-30T12:00:00Z",
      "recovered_at": null,
      "duration_seconds": 900,
      "duration_anchor": "impact_started_at",
      "team_id": 42,
      "event_count": 5,
      "investigation_summary": null,
      "status_update_summary": {
        "latest_recorded_at": null,
        "next_update_at": null,
        "latest_excerpt": null
      },
      "postmortem_summary": {
        "has_work": false,
        "has_working_draft": false,
        "latest_version_id": null,
        "latest_version_kind": null,
        "work_state": "none"
      },
      "created_at": "2025-01-30T12:00:00Z",
      "created_by": "oncall@example.com",
      "custom_fields": {},
      "archived_at": "2025-02-07T09:30:00Z",
      "archived_by": 42,
      "incident_manager": "oncall@example.com",
      "incident_responders": [
        "responder@example.com"
      ],
      "has_assignees": true
    }
  ],
  "restricted_count": 3,
  "history_limited": true,
  "has_more": false,
  "pagination": {
    "limit": 50,
    "has_more": false
  }
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `GET /api/v1/incident-references/{reference}`

**Get incident by permanent reference.** Returns an incident from its permanent, opaque reference. This endpoint is suitable for stored references and links in other systems. The numeric-ID endpoint accepts only a positive ID returned by this API.

Required scope: `incidents:read`

Operation ID: `getIncidentByReference`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `reference` | `string` | Yes | A permanent, opaque reference from Tellagen incident links and messages. This parameter does not accept a numeric incident ID. Minimum length: 1 characters. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incident-references/{reference}' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete incident record. The reference continues to identify the same incident after editable fields change.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "active",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": null,
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [Get incident](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incidents-id) (`GET /api/v1/incidents/{id}`)

### `GET /api/v1/incidents/{id}`

**Get incident.** Returns one incident by its positive numeric ID. The permanent-reference endpoint is suitable for stored references, external links, and workflows in other systems.

Required scope: `incidents:read`

Operation ID: `getIncident`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete incident record. Nullable timestamps, team details, archive details, and investigation_summary are always present. These fields can be null. Arrays and custom_fields are never null.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "active",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": null,
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [Get incident by permanent reference](https://tellagen.com/api-reference/incidents#incidents-endpoint-get-api-v1-incident-references-reference) (`GET /api/v1/incident-references/{reference}`)

### `PATCH /api/v1/incidents/{id}`

**Update incident.** Updates only the fields that you send. Other fields keep their current values. The response contains the complete incident.

Use resolve, close, or reopen to change the workflow status. This endpoint still accepts status changes for existing API v1 clients. The API checks new timestamps against existing timestamps. Field changes can also change automatic severity.


Required scope: `incidents:write`

Operation ID: `updateIncident`
Contract: `supported`
Retry guidance: If the API returns 412, read the resource again. Compare the latest changes before you retry with the new version.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Request headers

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `If-Tellagen-Resource-Version` | `integer` | Yes | The current positive resource version from the latest response. API-key PATCH requests must send this value. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

Use the Tellagen-Resource-Version header from a GET of this resource for `<resource-version>`.

```bash
curl --request PATCH \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}' \
  --header 'Authorization: Bearer <token>' \
  --header 'If-Tellagen-Resource-Version: <resource-version>' \
  --header 'Content-Type: application/json' \
  --data '{
  "title": "Payments API recovered; monitoring authorization backlog",
  "impact_summary": "Full payment outage in EU region"
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | No | The incident display title. The maximum length is 160 characters. This field is separate from impact_summary. Maximum length: 160 characters. |
| `service` | `string` | No | The service slug. The maximum length is 128 characters. Maximum length: 128 characters. |
| `regions` | `string[]` | No | The complete replacement list of affected regions. An empty array removes all regions. |
| `severity` | `string` | No | A severity key from the workspace configuration. |
| `slack_channel_id` | `string` | No | The stored Slack channel ID. |
| `meet_url` | `string` | No | The absolute HTTP or HTTPS meeting URL. |
| `doc_url` | `string` | No | An absolute HTTP or HTTPS URL for an incident document or source. |
| `status` | `string` | No | A workflow-status key from the workspace configuration. New clients use the resolve, close, and reopen operations for lifecycle changes. |
| `issue_type` | `string` | No | The work type. Existing alert records remain available for compatibility. Allowed values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `team_id` | `integer \| null` | No | The positive ID of an active owning team. A null value removes the current team assignment. |
| `severity_mode` | `string` | No | The severity selection mode. Allowed values: `"auto"` \| `"manual"` |
| `impact_summary` | `string` | No | The customer or operational impact summary. |
| `customer_impact_status` | `string` | No | The customer-impact assessment. Allowed values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `impact_started_at` | `string (RFC 3339)` | No | The RFC 3339 impact start time. |
| `first_reported_at` | `string (RFC 3339)` | No | The RFC 3339 time of the first incident report. |
| `first_responded_at` | `string (RFC 3339)` | No | The RFC 3339 time of the first response. |
| `recovered_at` | `string (RFC 3339)` | No | The RFC 3339 service recovery time. |

Request JSON:

```json
{
  "title": "Payments API recovered; monitoring authorization backlog",
  "impact_summary": "Full payment outage in EU region"
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete updated incident. A transition to resolved changes issue_type to postmortem. A transition from resolved to active changes issue_type to incident.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API recovered; monitoring authorization backlog",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "active",
    "status_changed_at": "2025-01-30T12:00:00Z",
    "last_event_at": "2025-01-30T13:30:00Z",
    "last_event_summary": "Service fully recovered",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Full payment outage in EU region",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": "2025-01-30T13:30:00Z",
    "duration_seconds": 5700,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 12,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `412` | The resource changed after the client obtained its If-Tellagen-Resource-Version value. |
| `428` | An API-key PATCH request did not include the required If-Tellagen-Resource-Version header. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [Resolve incident](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-resolve) (`POST /api/v1/incidents/{id}/resolve`)
- [Close incident without resolution](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-close) (`POST /api/v1/incidents/{id}/close`)
- [Reopen incident](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-reopen) (`POST /api/v1/incidents/{id}/reopen`)

### `GET /api/v1/incidents/{id}/actions`

**List incident actions.** Returns the incident actions that match the repeated status filters. If status is omitted, the API returns open, in_progress, blocked, and waiting actions. The response is ordered by priority, due time, and creation time. The total field equals the number of returned actions.

Required scope: `incidents:read`

Operation ID: `listIncidentActions`
Contract: `preview`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Query parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | `string[]` | No | Repeated action statuses to include. The default is open, in_progress, blocked, and waiting. Allowed values: `"open"` \| `"in_progress"` \| `"blocked"` \| `"waiting"` \| `"completed"` \| `"canceled"` |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/actions' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `actions` | `object[]` | Always | The incident actions matching the requested statuses. |
| `actions[].id` | `integer` | Always | The positive numeric ID of the action. Minimum: 1. |
| `actions[].incident_id` | `integer` | Always | The positive numeric ID of the incident that owns the action. Minimum: 1. |
| `actions[].title` | `string` | Always | The action title after trimming. The maximum length is 160 Unicode characters. Minimum length: 1 characters. Maximum length: 160 characters. |
| `actions[].description` | `string` | Always | The action details after trimming. The maximum length is 2 Maximum length: 2000 characters. |
| `actions[].status` | `string` | Always | The response-work state of an incident action. Possible values: `"open"` \| `"in_progress"` \| `"blocked"` \| `"waiting"` \| `"completed"` \| `"canceled"` |
| `actions[].priority` | `string` | Always | The urgency assigned to an incident action. Possible values: `"critical"` \| `"high"` \| `"medium"` \| `"low"` |
| `actions[].category` | `string` | Always | The response-work category assigned to an incident action. Possible values: `"immediate"` \| `"prevent_recurrence"` \| `"investigate"` \| `"monitor"` \| `"unspecified"` |
| `actions[].operational_caveat` | `string` | Optional | The diagnostic guidance caveat for the action. This is separate from blocker_reason and is omitted when empty. |
| `actions[].blocker_reason` | `string` | Optional | The human dependency explanation. It is present and nonempty for blocked or waiting actions and omitted after leaving those states. Maximum length: 2000 characters. |
| `actions[].unblock_owner_user_id` | `integer \| null` | Optional | The active incident manager or responder responsible for clearing the dependency. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `actions[].source` | `string` | Always | The source that created an incident action. Possible values: `"custom"` \| `"diagnostic"` \| `"suggestion"` |
| `actions[].source_suggestion_id` | `integer \| null` | Optional | The source suggestion ID when the action was accepted from a diagnostic suggestion. This field is omitted for other sources. Minimum: 1. |
| `actions[].assignee_user_id` | `integer \| null` | Optional | The active incident participant responsible for carrying out the action. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `actions[].due_at` | `string (RFC 3339) \| null` | Optional | The action due time in RFC 3339 format. A null value means no due time and this field may be omitted from responses. |
| `actions[].completed_at` | `string (RFC 3339) \| null` | Optional | The completion time in RFC 3339 format. It is null or omitted while the action is not completed. |
| `actions[].created_by` | `string` | Always | The identifier of the user who created the action. |
| `actions[].created_at` | `string (RFC 3339)` | Always | The action creation time. |
| `actions[].updated_at` | `string (RFC 3339)` | Always | The time of the latest action change. |
| `actions[].supporting_evidence` | `object[]` | Always | Evidence references attached to the action. |
| `actions[].supporting_evidence[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `actions[].supporting_evidence[].url` | `string` | Always | The absolute URL of the evidence. |
| `actions[].supporting_evidence[].label` | `string` | Optional | A short display name for the evidence. |
| `actions[].supporting_evidence[].summary` | `string` | Optional | A short summary of the evidence. |
| `actions[].supporting_evidence[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `actions[].supporting_evidence[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `actions[].supporting_evidence[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `actions[].supporting_evidence[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `total` | `integer` | Always | The number of actions in the actions array. Minimum: 0. |

Returns the matching action records and their count. Blocker fields are present for blocked or waiting actions; an unassigned unblock owner is represented by a null value or an omitted response field.

```json
{
  "actions": [
    {
      "id": 301,
      "incident_id": 1,
      "title": "Confirm provider recovery",
      "description": "Confirm the provider has restored the payment path.",
      "status": "blocked",
      "priority": "high",
      "category": "immediate",
      "operational_caveat": "",
      "blocker_reason": "Waiting for provider confirmation",
      "unblock_owner_user_id": 42,
      "source": "custom",
      "assignee_user_id": 7,
      "due_at": "2026-08-31T13:00:00Z",
      "created_by": "oncall@example.com",
      "completed_at": null,
      "created_at": "2026-08-31T12:15:00Z",
      "updated_at": "2026-08-31T12:20:00Z",
      "supporting_evidence": []
    }
  ],
  "total": 1
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/actions`

**Create incident action.** Creates an open action on an active incident. The API validates the title, description, priority, assignee, and due time before saving. New actions do not accept blocker fields; use the update operation to move an action to blocked or waiting with a required blocker reason.

Required scope: `incidents:write`

Operation ID: `createIncidentAction`
Contract: `preview`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/actions' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "title": "Confirm provider recovery",
  "description": "Confirm the provider has restored the payment path.",
  "priority": "high",
  "assignee_user_id": 7,
  "due_at": "2026-08-31T13:00:00Z"
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | Yes | The action title. Leading and trailing whitespace is removed before the maximum of 160 Unicode characters is enforced. Minimum length: 1 characters. Maximum length: 160 characters. |
| `description` | `string` | No | Optional action details. Leading and trailing whitespace is removed before the maximum of 2 Maximum length: 2000 characters. |
| `priority` | `string` | No | The urgency assigned to an incident action. Allowed values: `"critical"` \| `"high"` \| `"medium"` \| `"low"` |
| `assignee_user_id` | `integer \| null` | No | The positive ID of an active incident manager or responder. A null value leaves the action unassigned. Minimum: 1. |
| `due_at` | `string (RFC 3339) \| null` | No | The due time in RFC 3339 format |

Request JSON:

```json
{
  "title": "Confirm provider recovery",
  "description": "Confirm the provider has restored the payment path.",
  "priority": "high",
  "assignee_user_id": 7,
  "due_at": "2026-08-31T13:00:00Z"
}
```

#### Success response

Status: `201 Created`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `action` | `object` | Always | The complete public record for an incident action. A blocker reason is required for blocked and waiting actions. Blocker fields are omitted when they are empty or unassigned. |
| `action.id` | `integer` | Always | The positive numeric ID of the action. Minimum: 1. |
| `action.incident_id` | `integer` | Always | The positive numeric ID of the incident that owns the action. Minimum: 1. |
| `action.title` | `string` | Always | The action title after trimming. The maximum length is 160 Unicode characters. Minimum length: 1 characters. Maximum length: 160 characters. |
| `action.description` | `string` | Always | The action details after trimming. The maximum length is 2 Maximum length: 2000 characters. |
| `action.status` | `string` | Always | The response-work state of an incident action. Possible values: `"open"` \| `"in_progress"` \| `"blocked"` \| `"waiting"` \| `"completed"` \| `"canceled"` |
| `action.priority` | `string` | Always | The urgency assigned to an incident action. Possible values: `"critical"` \| `"high"` \| `"medium"` \| `"low"` |
| `action.category` | `string` | Always | The response-work category assigned to an incident action. Possible values: `"immediate"` \| `"prevent_recurrence"` \| `"investigate"` \| `"monitor"` \| `"unspecified"` |
| `action.operational_caveat` | `string` | Optional | The diagnostic guidance caveat for the action. This is separate from blocker_reason and is omitted when empty. |
| `action.blocker_reason` | `string` | Optional | The human dependency explanation. It is present and nonempty for blocked or waiting actions and omitted after leaving those states. Maximum length: 2000 characters. |
| `action.unblock_owner_user_id` | `integer \| null` | Optional | The active incident manager or responder responsible for clearing the dependency. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `action.source` | `string` | Always | The source that created an incident action. Possible values: `"custom"` \| `"diagnostic"` \| `"suggestion"` |
| `action.source_suggestion_id` | `integer \| null` | Optional | The source suggestion ID when the action was accepted from a diagnostic suggestion. This field is omitted for other sources. Minimum: 1. |
| `action.assignee_user_id` | `integer \| null` | Optional | The active incident participant responsible for carrying out the action. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `action.due_at` | `string (RFC 3339) \| null` | Optional | The action due time in RFC 3339 format. A null value means no due time and this field may be omitted from responses. |
| `action.completed_at` | `string (RFC 3339) \| null` | Optional | The completion time in RFC 3339 format. It is null or omitted while the action is not completed. |
| `action.created_by` | `string` | Always | The identifier of the user who created the action. |
| `action.created_at` | `string (RFC 3339)` | Always | The action creation time. |
| `action.updated_at` | `string (RFC 3339)` | Always | The time of the latest action change. |
| `action.supporting_evidence` | `object[]` | Always | Evidence references attached to the action. |
| `action.supporting_evidence[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `action.supporting_evidence[].url` | `string` | Always | The absolute URL of the evidence. |
| `action.supporting_evidence[].label` | `string` | Optional | A short display name for the evidence. |
| `action.supporting_evidence[].summary` | `string` | Optional | A short summary of the evidence. |
| `action.supporting_evidence[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `action.supporting_evidence[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `action.supporting_evidence[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `action.supporting_evidence[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |

Returns the created open action.

```json
{
  "action": {
    "id": 301,
    "incident_id": 1,
    "title": "Confirm provider recovery",
    "description": "Confirm the provider has restored the payment path.",
    "status": "open",
    "priority": "high",
    "category": "unspecified",
    "operational_caveat": "",
    "source": "custom",
    "assignee_user_id": 7,
    "due_at": "2026-08-31T13:00:00Z",
    "created_by": "oncall@example.com",
    "completed_at": null,
    "created_at": "2026-08-31T12:15:00Z",
    "updated_at": "2026-08-31T12:15:00Z",
    "supporting_evidence": []
  }
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `PATCH /api/v1/incident-actions/{id}`

**Update incident action.** Updates the supplied action fields after validating the merged result. Omitted fields stay unchanged. Set status to blocked or waiting only with a nonempty trimmed blocker_reason of at most 2,000 Unicode characters; an unblock_owner_user_id, when supplied, must identify an active incident manager or responder. A null blocker_reason or unblock_owner_user_id clears that field when the resulting status is not blocked or waiting. Leaving a blocked or waiting status clears both blocker fields. The update is serialized with other action changes so a stale read cannot persist an invalid status and blocker combination.

Required scope: `incidents:write`

Operation ID: `updateIncidentAction`
Contract: `preview`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident-action ID returned by this API. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request PATCH \
  --url 'https://{company}.api.tellagen.com/api/v1/incident-actions/{id}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "status": "waiting",
  "blocker_reason": "Waiting for the maintenance window.",
  "unblock_owner_user_id": null
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | No | The replacement action title after trimming. The maximum length is 160 Unicode characters. Minimum length: 1 characters. Maximum length: 160 characters. |
| `description` | `string` | No | The replacement action details after trimming. The maximum length is 2 Maximum length: 2000 characters. |
| `status` | `string` | No | The response-work state of an incident action. Allowed values: `"open"` \| `"in_progress"` \| `"blocked"` \| `"waiting"` \| `"completed"` \| `"canceled"` |
| `priority` | `string` | No | The urgency assigned to an incident action. Allowed values: `"critical"` \| `"high"` \| `"medium"` \| `"low"` |
| `assignee_user_id` | `integer \| null` | No | The positive ID of an active incident manager or responder Minimum: 1. |
| `due_at` | `string (RFC 3339) \| null` | No | The replacement due time in RFC 3339 format |
| `blocker_reason` | `string \| null` | No | The trimmed dependency explanation Maximum length: 2000 characters. |
| `unblock_owner_user_id` | `integer \| null` | No | The active incident manager or responder responsible for clearing the dependency, or null to clear the owner while the merged status remains blocked or waiting. Both blocker fields are cleared automatically when the merged status is another state. Minimum: 1. |

Request JSON:

```json
{
  "status": "waiting",
  "blocker_reason": "Waiting for the maintenance window.",
  "unblock_owner_user_id": null
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `action` | `object` | Always | The complete public record for an incident action. A blocker reason is required for blocked and waiting actions. Blocker fields are omitted when they are empty or unassigned. |
| `action.id` | `integer` | Always | The positive numeric ID of the action. Minimum: 1. |
| `action.incident_id` | `integer` | Always | The positive numeric ID of the incident that owns the action. Minimum: 1. |
| `action.title` | `string` | Always | The action title after trimming. The maximum length is 160 Unicode characters. Minimum length: 1 characters. Maximum length: 160 characters. |
| `action.description` | `string` | Always | The action details after trimming. The maximum length is 2 Maximum length: 2000 characters. |
| `action.status` | `string` | Always | The response-work state of an incident action. Possible values: `"open"` \| `"in_progress"` \| `"blocked"` \| `"waiting"` \| `"completed"` \| `"canceled"` |
| `action.priority` | `string` | Always | The urgency assigned to an incident action. Possible values: `"critical"` \| `"high"` \| `"medium"` \| `"low"` |
| `action.category` | `string` | Always | The response-work category assigned to an incident action. Possible values: `"immediate"` \| `"prevent_recurrence"` \| `"investigate"` \| `"monitor"` \| `"unspecified"` |
| `action.operational_caveat` | `string` | Optional | The diagnostic guidance caveat for the action. This is separate from blocker_reason and is omitted when empty. |
| `action.blocker_reason` | `string` | Optional | The human dependency explanation. It is present and nonempty for blocked or waiting actions and omitted after leaving those states. Maximum length: 2000 characters. |
| `action.unblock_owner_user_id` | `integer \| null` | Optional | The active incident manager or responder responsible for clearing the dependency. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `action.source` | `string` | Always | The source that created an incident action. Possible values: `"custom"` \| `"diagnostic"` \| `"suggestion"` |
| `action.source_suggestion_id` | `integer \| null` | Optional | The source suggestion ID when the action was accepted from a diagnostic suggestion. This field is omitted for other sources. Minimum: 1. |
| `action.assignee_user_id` | `integer \| null` | Optional | The active incident participant responsible for carrying out the action. A null value means unassigned and this field may be omitted from responses. Minimum: 1. |
| `action.due_at` | `string (RFC 3339) \| null` | Optional | The action due time in RFC 3339 format. A null value means no due time and this field may be omitted from responses. |
| `action.completed_at` | `string (RFC 3339) \| null` | Optional | The completion time in RFC 3339 format. It is null or omitted while the action is not completed. |
| `action.created_by` | `string` | Always | The identifier of the user who created the action. |
| `action.created_at` | `string (RFC 3339)` | Always | The action creation time. |
| `action.updated_at` | `string (RFC 3339)` | Always | The time of the latest action change. |
| `action.supporting_evidence` | `object[]` | Always | Evidence references attached to the action. |
| `action.supporting_evidence[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `action.supporting_evidence[].url` | `string` | Always | The absolute URL of the evidence. |
| `action.supporting_evidence[].label` | `string` | Optional | A short display name for the evidence. |
| `action.supporting_evidence[].summary` | `string` | Optional | A short summary of the evidence. |
| `action.supporting_evidence[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `action.supporting_evidence[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `action.supporting_evidence[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `action.supporting_evidence[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |

Returns the updated action. Blocker fields are present only while the action is blocked or waiting; an unassigned unblock owner is represented by a null value or an omitted response field.

```json
{
  "action": {
    "id": 301,
    "incident_id": 1,
    "title": "Confirm provider recovery",
    "description": "Confirm the provider has restored the payment path.",
    "status": "waiting",
    "priority": "high",
    "category": "immediate",
    "operational_caveat": "",
    "blocker_reason": "Waiting for the maintenance window.",
    "unblock_owner_user_id": null,
    "source": "custom",
    "assignee_user_id": 7,
    "due_at": "2026-08-31T13:00:00Z",
    "created_by": "oncall@example.com",
    "completed_at": null,
    "created_at": "2026-08-31T12:15:00Z",
    "updated_at": "2026-08-31T12:25:00Z",
    "supporting_evidence": []
  }
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/resolve`

**Resolve incident.** Marks the incident resolved and changes issue_type to postmortem. Tellagen saves the status, recovery time, and resolution note together. Existing postmortem drafts and versions stay unchanged.

The request body is optional. An outdated expected_revision returns 412. If the incident is already resolved, an empty request succeeds without another event. A repeated request with a note or recovery edit returns 412.


Required scope: `incidents:write`

Operation ID: `resolveIncident`
Contract: `supported`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/resolve' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "resolution_note": "Rolled back the deployment and verified payment processing.",
  "recovered_at": "2025-01-30T12:04:00Z",
  "expected_revision": 6
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `resolution_note` | `string` | No | An optional note stored in the resolution timeline event. Leading and trailing whitespace is removed before enforcing the 1000 Unicode character limit. |
| `recovered_at` | `string` | No | The recovery timestamp in RFC 3339 format. Omit to preserve the current value. An empty string clears it. The timestamp must follow recorded impact, report, and response times and must not be in the future. |
| `expected_revision` | `integer` | No | The incident revision displayed to the responder. A mismatch returns 412 without saving any changes. |

Request JSON:

```json
{
  "resolution_note": "Rolled back the deployment and verified payment processing.",
  "recovered_at": "2025-01-30T12:04:00Z",
  "expected_revision": 6
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete incident and the committed resolution timeline event.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "resolved",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "postmortem",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": "2025-01-30T13:30:00Z",
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/close`

**Close incident without resolution.** Closes an incident from a non-terminal workflow status without marking it resolved. The API records the reason and comment in a lifecycle event.

Required scope: `incidents:write`

Operation ID: `closeIncident`
Contract: `supported`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/close' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "reason": "duplicate",
  "comment": "Tracked by the primary payment incident.",
  "related_incident_id": 99
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `reason` | `string` | Yes | The closure reason. Allowed values: `"duplicate"` \| `"false_alarm"` \| `"test_or_accidental"` \| `"not_an_incident"` \| `"other"` |
| `comment` | `string` | Yes | The explanation for the closure. The maximum length is 1000 characters. Minimum length: 1 characters. Maximum length: 1000 characters. |
| `related_incident_id` | `integer` | Conditional | The positive ID of the primary incident. If reason is duplicate, this field is required. Required when: Required when reason is "duplicate". Minimum: 1. |

Request JSON:

```json
{
  "reason": "duplicate",
  "comment": "Tracked by the primary payment incident.",
  "related_incident_id": 99
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete incident after closure.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "closed",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": null,
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/reopen`

**Reopen incident.** Changes a resolved or closed incident to active. A closed incident requires a comment. A comment is optional for a resolved incident. If issue_type is postmortem, the API changes it to incident.

Required scope: `incidents:write`

Operation ID: `reopenIncident`
Contract: `supported`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/reopen' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "comment": "Customer-visible errors returned."
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `comment` | `string` | Conditional | The reason for reopening. A closed incident requires this field. The maximum length is 500 characters. Required when: Required when reopening a closed incident. Maximum length: 500 characters. |

Request JSON:

```json
{
  "comment": "Customer-visible errors returned."
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete incident after it becomes active.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "active",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": null,
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `GET /api/v1/incidents/{id}/provisioning`

**Get incident integration setup.** Shows progress for integration tasks, such as Slack channel creation. Pending tasks resume after a server restart. Failed tasks retry automatically. The completed state means that all saved tasks finished.


Required scope: `incidents:read`

Operation ID: `getIncidentProvisioning`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: None

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request GET \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/provisioning' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `status` | `string` | Always | Aggregate state of persisted incident integration steps. Possible values: `"pending"` \| `"failed"` \| `"completed"` |
| `retryable` | `boolean` | Always | True when a failed step can be made eligible for immediate retry. |

Current setup state. Retryable indicates whether failed steps can be retried manually.

```json
{
  "status": "pending",
  "retryable": false
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/provisioning/retry`

**Retry incident integration setup.** Makes failed setup steps eligible to run again. Completed steps and incident history are not repeated. The caller must have an active responder seat. Demo workspaces cannot retry external setup.

Required scope: `incidents:write`

Operation ID: `retryIncidentProvisioning`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: Active responder seat

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/provisioning/retry' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `status` | `string` | Always | Aggregate state of persisted incident integration steps. Possible values: `"pending"` \| `"failed"` \| `"completed"` |
| `retryable` | `boolean` | Always | True when a failed step can be made eligible for immediate retry. |

Current setup state. Retryable indicates whether failed steps can be retried manually.

```json
{
  "status": "pending",
  "retryable": false
}
```

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/archive`

**Archive incident.** Removes the incident from default lists without changing its workflow status. The incident and its related records remain available as read-only data.

A repeated request returns 204 without changes to archive details, revision, changelog, or audit records. The API key owner needs an active responder seat.


Required scope: `incidents:write`

Operation ID: `archiveIncident`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: Active responder seat

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/archive' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `204 No Content`

No response body.

#### Endpoint error responses

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/restore`

**Restore incident.** Returns an archived incident to default lists without changing its workflow status. If the incident has a team_id, that team must be active.

A repeated request returns the incident without changes to its revision, changelog, or audit records. The API key owner needs an active responder seat.


Required scope: `incidents:write`

Operation ID: `restoreIncident`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: Active responder seat

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/restore' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `incident` | `object` | Always | The complete public record for an incident. |
| `incident.id` | `integer` | Always | The positive numeric ID of the incident. Minimum: 1. |
| `incident.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `incident.company_id` | `integer` | Always | The ID of the workspace that owns the incident. Minimum: 1. |
| `incident.human_id` | `string` | Always | The permanent incident reference shown to users. |
| `incident.title` | `string` | Always | The editable display title of the incident. |
| `incident.service` | `string` | Always | The service slug associated with the incident. |
| `incident.regions` | `string[]` | Always | The affected regions. |
| `incident.severity` | `string` | Always | The configured severity key. |
| `incident.slack_channel_id` | `string` | Always | The linked Slack channel ID. An empty string means that no channel is linked. |
| `incident.meet_url` | `string` | Always | The incident meeting URL. An empty string means that no meeting is linked. |
| `incident.doc_url` | `string` | Always | The incident document or source URL. An empty string means that no URL is stored. |
| `incident.status` | `string` | Always | The configured workflow-status key. |
| `incident.status_changed_at` | `string (RFC 3339) \| null` | Always | The time of the latest workflow-status change. A null value means that this time is unavailable. |
| `incident.last_event_at` | `string (RFC 3339) \| null` | Always | The start time of the latest timeline event. A null value means that no event exists. |
| `incident.last_event_summary` | `string` | Always | A summary of the latest timeline event. |
| `incident.issue_type` | `string` | Always | The work type. Possible values: `"ticket"` \| `"incident"` \| `"postmortem"` |
| `incident.severity_mode` | `string` | Always | The severity selection mode. Possible values: `"auto"` \| `"manual"` |
| `incident.impact_summary` | `string` | Always | The current customer or operational impact summary. |
| `incident.customer_impact_status` | `string` | Always | The customer-impact assessment. Possible values: `"unknown"` \| `"none"` \| `"confirmed"` |
| `incident.impact_started_at` | `string (RFC 3339) \| null` | Always | The impact start time. A null value means that the time is unknown. |
| `incident.first_reported_at` | `string (RFC 3339) \| null` | Always | The time of the first incident report. A null value means that the time is unknown. |
| `incident.first_responded_at` | `string (RFC 3339) \| null` | Always | The time of the first response. A null value means that the time is unknown. |
| `incident.recovered_at` | `string (RFC 3339) \| null` | Always | The service recovery time. A null value means that recovery is not recorded. |
| `incident.duration_seconds` | `integer` | Always | The calculated incident duration in whole seconds. Minimum: 0. |
| `incident.duration_anchor` | `string` | Always | The timestamp field from which the API calculates duration. |
| `incident.team_id` | `integer \| null` | Always | The owning-team ID. A null value means that the incident has no owning team. |
| `incident.event_count` | `integer` | Always | The number of timeline events for the incident. Minimum: 0. |
| `incident.investigation_summary` | `object \| null` | Always | A summary of investigation runs. A null value means that no investigation data exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.run_count` | `integer` | Always | The total number of investigation runs. Minimum: 0. |
| `incident.investigation_summary.latest_run` | `object \| null` | Always | The most recent investigation run. A null value means that no run exists. Must match exactly one of 2 schema variants. |
| `incident.investigation_summary.latest_run.status` | `string` | Always | The current investigation-run status. |
| `incident.investigation_summary.latest_run.started_at` | `string (RFC 3339)` | Always | The investigation-run start time. |
| `incident.investigation_summary.latest_run.completed_at` | `string (RFC 3339)` | Optional | The investigation-run completion time. |
| `incident.status_update_summary` | `object \| null` | Always | The latest recorded status update and the next update time that it set. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load status-update data. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_recorded_at` | `string (RFC 3339) \| null` | Always | The time of the latest status update. A null value means that no status update has been recorded. |
| `incident.status_update_summary.next_update_at` | `string (RFC 3339) \| null` | Always | The next update time set by the latest status update. A null value means that no time was set. |
| `incident.status_update_summary.latest_excerpt` | `string \| null` | Always | One line from the latest status update: its current action, or its current impact when the action is blank, trimmed. Text longer than 120 characters keeps its first 117 characters and ends with an ellipsis (…). A null value means that no status update has been recorded. Only incident collection responses load this field; single-incident and mutation responses return status_update_summary as null. Maximum length: 120 characters. |
| `incident.status_update_summary.latest_delivery` | `object \| null` | Optional | How the latest status update was posted to Slack. A null value means that the update was recorded without sharing, that no status update has been recorded, or that the workspace does not have status update delivery turned on. Must match exactly one of 2 schema variants. |
| `incident.status_update_summary.latest_delivery.sent` | `integer` | Always | Delivered. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.pending` | `integer` | Always | Queued or being posted. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.failed` | `integer` | Always | Failed or stopped without reaching Slack; a person can retry these. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.unconfirmed` | `integer` | Always | Slack did not confirm these posts and may have accepted them. Check the channel before retrying. Minimum: 0. |
| `incident.status_update_summary.latest_delivery.skipped` | `integer` | Always | Never attempted. Minimum: 0. |
| `incident.postmortem_summary` | `object \| null` | Always | The postmortem work recorded for the incident and whether the incident still needs it. Incident collection responses always include this object. Single-incident and mutation responses return null because they do not load postmortem data. Must match exactly one of 2 schema variants. |
| `incident.postmortem_summary.has_work` | `boolean` | Always | Indicates whether a postmortem draft with content, a postmortem version, or a revision request exists. |
| `incident.postmortem_summary.has_working_draft` | `boolean` | Always | Indicates whether the working postmortem draft has content or prepared evidence. |
| `incident.postmortem_summary.latest_version_id` | `integer \| null` | Always | The ID of the latest postmortem version. A null value means that no version exists. |
| `incident.postmortem_summary.latest_version_kind` | `string \| null` | Always | The kind of the latest postmortem version. submitted is a human submission. draft, llm, and legacy need human review before submission. A null value means that no version exists. Possible values: `"submitted"` \| `"draft"` \| `"llm"` \| `"legacy"` \| `null` |
| `incident.postmortem_summary.work_state` | `string` | Always | Whether the incident still needs postmortem work. none means that no postmortem is due: the incident is not resolved or closed, or it is archived without a submitted postmortem. missing means that a resolved or closed incident has no postmortem version. in_review means that the latest version needs human submission. complete means that the latest version is a human submission. missing and in_review need work; the postmortem queue (scope=postmortem) shows those incidents even when the plan's history window hides other finished incidents. Only incident collection responses load this field; single-incident and mutation responses return postmortem_summary as null. Possible values: `"none"` \| `"missing"` \| `"in_review"` \| `"complete"` |
| `incident.created_at` | `string (RFC 3339)` | Always | The incident creation time. |
| `incident.created_by` | `string` | Always | The identifier of the user who created the incident. |
| `incident.custom_fields` | `object` | Always | The incident values keyed by custom-field slug. |
| `incident.archived_at` | `string (RFC 3339) \| null` | Always | The incident archive time. A null value means that the incident is active. |
| `incident.archived_by` | `integer \| null` | Always | The user ID that archived the incident. A null value means that the incident is active. |
| `incident.incident_manager` | `string` | Always | The user identifier of the incident manager. An empty string means that no manager is assigned. |
| `incident.incident_responders` | `string[]` | Always | The user identifiers of assigned responders. |
| `incident.has_assignees` | `boolean` | Always | Indicates whether the incident has a manager or at least one responder. |
| `timeline_event` | `object` | Optional | The complete public record for a timeline event. |
| `timeline_event.id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.revision` | `integer` | Always | The resource version for concurrency control. Minimum: 1. |
| `timeline_event.incident_id` | `integer` | Always | The positive numeric ID of the incident. |
| `timeline_event.started_at` | `string (RFC 3339)` | Always | The event start time. |
| `timeline_event.at` | `string (RFC 3339)` | Always | A deprecated response alias for started_at. Both fields contain the same value. |
| `timeline_event.ended_at` | `string (RFC 3339) \| null` | Always | The event end time. A null value means that the event has no end time. |
| `timeline_event.is_ongoing` | `boolean` | Always | Indicates whether the event is still in progress. |
| `timeline_event.group_id` | `integer \| null` | Always | The timeline-group ID. A null value means that the event has no group. |
| `timeline_event.is_key` | `boolean` | Always | Indicates whether responders marked this as a key incident event. |
| `timeline_event.source` | `string` | Always | The system or actor that created the event. |
| `timeline_event.source_ref` | `string` | Always | The source-specific reference for the event. |
| `timeline_event.type` | `string` | Always | The event type used for grouping and display. |
| `timeline_event.icon` | `string` | Always | The event icon. The maximum length is 8 Unicode characters. Maximum length: 8 characters. |
| `timeline_event.title` | `string` | Always | The optional display title of the event. |
| `timeline_event.body` | `string` | Always | The event description. |
| `timeline_event.collaboration_generation` | `integer` | Always | The version of collaborative content associated with the event. |
| `timeline_event.tags` | `string[]` | Always | The normalized event tags. |
| `timeline_event.ai_context` | `string` | Always | The saved AI context for a generated event. An empty string means that no context is stored. |
| `timeline_event.created_by` | `string` | Always | The identifier of the user or system that created the event. |
| `timeline_event.comment_count` | `integer` | Always | The number of comments on the event. |
| `timeline_event.attachments` | `object[]` | Always | The files attached to the event. |
| `timeline_event.attachments[].id` | `integer` | Always | The positive numeric ID of the attachment. |
| `timeline_event.attachments[].timeline_event_id` | `integer` | Always | The positive numeric ID of the timeline event. |
| `timeline_event.attachments[].filename` | `string` | Always | The original file name. |
| `timeline_event.attachments[].url` | `string` | Always | A temporary download URL. An empty string means that no URL is currently available. |
| `timeline_event.attachments[].url_available` | `boolean` | Always | Indicates whether url contains an available download URL. |
| `timeline_event.attachments[].content_type` | `string` | Always | The media type of the attached file. |
| `timeline_event.attachments[].size_bytes` | `integer` | Always | The file size in bytes. |
| `timeline_event.attachments[].created_at` | `string (RFC 3339)` | Always | The attachment creation time. |
| `timeline_event.attachments[].created_by` | `string` | Always | The identifier of the user who attached the file. |
| `timeline_event.source_window_started_at` | `string (RFC 3339) \| null` | Always | The start of the source-data window. A null value means that no window is recorded. |
| `timeline_event.source_window_ended_at` | `string (RFC 3339) \| null` | Always | The end of the source-data window. A null value means that no window is recorded. |
| `timeline_event.evidence_links` | `object[]` | Always | The evidence references associated with the event. |
| `timeline_event.evidence_links[].source` | `string` | Always | The system or provider that supplied the evidence. |
| `timeline_event.evidence_links[].url` | `string` | Always | The absolute URL of the evidence. |
| `timeline_event.evidence_links[].label` | `string` | Optional | A short display name for the evidence. |
| `timeline_event.evidence_links[].summary` | `string` | Optional | A short summary of the evidence. |
| `timeline_event.evidence_links[].artifact_id` | `string` | Optional | The identifier of a stored evidence artifact. |
| `timeline_event.evidence_links[].artifact_digest` | `string` | Optional | The digest used to make sure that the artifact content did not change. |
| `timeline_event.evidence_links[].result_bytes` | `integer` | Optional | The original evidence result size in bytes. |
| `timeline_event.evidence_links[].truncated` | `boolean` | Optional | Indicates whether the stored evidence omits part of the original result. |
| `timeline_event.operational_update` | `object \| null` | Optional | The validated operational status payload. Null or absent for ordinary and legacy timeline events. Must match exactly one of 2 schema variants. |
| `timeline_event.operational_update.current_impact` | `string` | Always | The current customer or system impact in human-authored text. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.current_action` | `string` | Always | The response work currently in progress. Leading and trailing whitespace is removed before the Unicode length limit is enforced. Minimum length: 1 characters. Maximum length: 2000 characters. |
| `timeline_event.operational_update.next_update_at` | `string (RFC 3339) \| null` | Always | The planned next update time as RFC 3339 |
| `timeline_event.operational_update.audience` | `string` | Always | The intended audience for the status update. Possible values: `"responders"` \| `"stakeholders"` \| `"customers"` |
| `timeline_event.operational_update.channel` | `string` | Always | Records the destination workflow. manual_external means the caller must deliver the copied message themselves. Possible values: `"incident_record"` \| `"manual_external"` |
| `timeline_event.operational_update.destination` | `string` | Always | The human-readable external destination for manual_external Maximum length: 200 characters. |
| `timeline_event.operational_update.communications_owner_user_id` | `integer \| null` | Always | The active incident participant responsible for coordinating manual delivery |
| `timeline_event.operational_update.delivery_state` | `string` | Always | The server-derived delivery state. Tellagen does not claim that a manual external message was sent. Possible values: `"recorded"` \| `"pending_manual_delivery"` |

Returns the complete active incident. If its saved team is not active, the API returns 409 invalid_relationship_state.

```json
{
  "incident": {
    "id": 1,
    "revision": 7,
    "company_id": 7,
    "human_id": "INC-2025-001",
    "title": "Payments API requests timing out",
    "service": "payments",
    "regions": [
      "us-east-1"
    ],
    "severity": "sev1",
    "slack_channel_id": "C08ABC123",
    "meet_url": "https://meet.google.com/abc-defg-hij",
    "doc_url": "https://docs.google.com/d/1abc",
    "status": "active",
    "status_changed_at": "2025-01-30T12:05:00Z",
    "last_event_at": "2025-01-30T12:10:00Z",
    "last_event_summary": "Investigating root cause",
    "issue_type": "incident",
    "severity_mode": "manual",
    "impact_summary": "Payment processing delayed for EU customers",
    "customer_impact_status": "confirmed",
    "impact_started_at": "2025-01-30T11:55:00Z",
    "first_reported_at": "2025-01-30T11:58:00Z",
    "first_responded_at": "2025-01-30T12:00:00Z",
    "recovered_at": null,
    "duration_seconds": 900,
    "duration_anchor": "impact_started_at",
    "team_id": 42,
    "event_count": 5,
    "investigation_summary": null,
    "status_update_summary": null,
    "postmortem_summary": null,
    "created_at": "2025-01-30T12:00:00Z",
    "created_by": "oncall@example.com",
    "custom_fields": {},
    "archived_at": null,
    "archived_by": null,
    "incident_manager": "oncall@example.com",
    "incident_responders": [
      "responder@example.com"
    ],
    "has_assignees": true
  }
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Tellagen-Resource-Version` | `integer` | Always | The positive resource version for If-Tellagen-Resource-Version in the next API-key PATCH request. Minimum: 1. |

#### Endpoint error responses

Endpoint-specific codes: `invalid_relationship_state`

| Status | Meaning |
| --- | --- |
| `400` | The API rejected the request because its syntax or one of its values is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | The request conflicts with the current resource state. idempotency_key_reused means that the key belongs to different request content. idempotency_in_progress means that an identical request is still in progress. idempotency_outcome_unknown means that an earlier request may have completed, but its result could not be stored and must not be retried automatically. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/rename-slack-channel`

**Reapply the Slack channel-name template (deprecated).** This operation is deprecated. It reapplies the workspace channel-name template. It rejects every request body, including whitespace. The replacement is PATCH /api/v1/incidents/{id}/slack/channel-name with mode workspace_template. Every response includes the RFC 9745 Deprecation date and a link to the replacement operation. The Sunset header is absent because Tellagen has not set an end date.

Required scope: `incidents:write`

Operation ID: `syncIncidentSlackChannelName`
Contract: `supported`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived, Linked Slack channel

**Deprecated.**
Announced: `2026-08-31`. Sunset review: `2027-03-01`.
Successor: `PATCH /api/v1/incidents/{id}/slack/channel-name`

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/rename-slack-channel' \
  --header 'Authorization: Bearer <token>'
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `channel_name` | `string` | Always | The new Slack channel name. |

Returns the new Slack channel name.

```json
{
  "channel_name": "inc-2025-001-payments"
}
```

#### Response headers

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `Deprecation` | `string` | Always | The date of the deprecation announcement in RFC 9745 format. Pattern: ^@[0-9]+$. |
| `Link` | `string` | Always | A link to the replacement operation with rel="successor-version". |

#### Endpoint error responses

Endpoint-specific codes: `invalid_slack_channel_name_request`, `slack_not_configured`, `incident_slack_channel_missing`, `slack_channel_not_found`, `slack_channel_name_taken`, `invalid_resource_state`

| Status | Meaning |
| --- | --- |
| `400` | The compatibility action received a non-empty request body. |
| `401` | Authentication failed. |
| `403` | The API key lacks access or an active responder seat. |
| `404` | The incident does not exist. |
| `409` | Slack is not configured, the linked channel is missing, the incident is immutable, or the resolved name is already used. |
| `429` | The workspace rate limit is exceeded. |
| `500` | An internal server error prevented completion of the request. |

### `POST /api/v1/incidents/{id}/slack/channel-name/preview`

**Preview an incident Slack channel name.** Calculates and validates the channel name without renaming the Slack channel or creating an audit record. The workspace_template mode must omit name. The custom mode requires name.

Required scope: `incidents:write`

Operation ID: `previewIncidentSlackChannelName`
Contract: `supported`
Retry guidance: You can repeat this request. If the API returns 429, wait for Retry-After. Set a maximum number of attempts.
Prerequisites: Active responder seat, Incident is not archived, Linked Slack channel

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request POST \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/slack/channel-name/preview' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "mode": "custom",
  "name": "Payments War Room"
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `mode` | `string` | Yes | Selects how the API creates the Slack channel name. Must match exactly one of 2 schema variants. Allowed values: `"workspace_template"` \| `"custom"` |
| `name` | `string` | Conditional | The proposed channel name for custom mode. It must contain an ASCII letter or digit. The preview and update operations normalize it identically. Required when: Required when mode is "custom". Minimum length: 1 characters. Pattern: .*[A-Za-z0-9].*. |

Request JSON:

```json
{
  "mode": "custom",
  "name": "Payments War Room"
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `channel_id` | `string` | Always | The Slack channel ID. |
| `previous_name` | `string` | Always | The channel name before the request. |
| `new_name` | `string` | Always | The validated channel name. The maximum length is 80 characters. Minimum length: 1 characters. Maximum length: 80 characters. |
| `mode` | `string` | Always | The naming mode. Possible values: `"workspace_template"` \| `"custom"` |

Returns the current and proposed channel names. A 409 response uses slack_not_configured, incident_slack_channel_missing, slack_channel_not_found, or slack_channel_name_taken.

```json
{
  "channel_id": "C08ABC123",
  "previous_name": "inc-2025-001-payments",
  "new_name": "payments-war-room",
  "mode": "custom"
}
```

#### Endpoint error responses

Endpoint-specific codes: `invalid_slack_channel_name_request`, `slack_not_configured`, `incident_slack_channel_missing`, `slack_channel_not_found`, `slack_channel_name_taken`, `invalid_resource_state`

| Status | Meaning |
| --- | --- |
| `400` | The naming request is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | Slack is not configured, the linked channel is missing, or the resolved name is already used. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [Update an incident Slack channel name](https://tellagen.com/api-reference/incidents#incidents-endpoint-patch-api-v1-incidents-id-slack-channel-name) (`PATCH /api/v1/incidents/{id}/slack/channel-name`)

### `PATCH /api/v1/incidents/{id}/slack/channel-name`

**Update an incident Slack channel name.** Renames the linked Slack channel with workspace_template or custom mode. The audit log records the old name, new name, mode, person, and time. Tellagen also publishes the audit entry as an incident event.

If the audit save fails, Tellagen attempts to restore the old channel name and returns an error.


Required scope: `incidents:write`

Operation ID: `updateIncidentSlackChannelName`
Contract: `supported`
Retry guidance: If the result is unknown, read the resource before another attempt. The error details explain the next step.
Prerequisites: Active responder seat, Incident is not archived, Linked Slack channel

#### Path parameters

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `integer` | Yes | A positive numeric incident ID returned by this API. The permanent incident reference is suitable for stored references and external links. Minimum: 1. |

#### Example request

Replace `{company}`, `<token>`, and any other placeholders with your values.

```bash
curl --request PATCH \
  --url 'https://{company}.api.tellagen.com/api/v1/incidents/{id}/slack/channel-name' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "mode": "custom",
  "name": "Payments War Room"
}'
```

#### Request body

Required nested fields apply when their parent object is present. Optional does not imply nullable.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `mode` | `string` | Yes | Selects how the API creates the Slack channel name. Must match exactly one of 2 schema variants. Allowed values: `"workspace_template"` \| `"custom"` |
| `name` | `string` | Conditional | The proposed channel name for custom mode. It must contain an ASCII letter or digit. The preview and update operations normalize it identically. Required when: Required when mode is "custom". Minimum length: 1 characters. Pattern: .*[A-Za-z0-9].*. |

Request JSON:

```json
{
  "mode": "custom",
  "name": "Payments War Room"
}
```

#### Success response

Status: `200 OK`

#### Response fields

Returned means the field is present when its parent object is present. A nullable field can contain null.

| Name | Type | Returned | Description |
| --- | --- | --- | --- |
| `channel_id` | `string` | Always | The Slack channel ID. |
| `previous_name` | `string` | Always | The channel name before the request. |
| `new_name` | `string` | Always | The validated channel name. The maximum length is 80 characters. Minimum length: 1 characters. Maximum length: 80 characters. |
| `mode` | `string` | Always | The naming mode. Possible values: `"workspace_template"` \| `"custom"` |

Returns the renamed channel. The preview operation validates the same request without changing the channel. A 409 response uses slack_not_configured, incident_slack_channel_missing, slack_channel_not_found, or slack_channel_name_taken.

```json
{
  "channel_id": "C08ABC123",
  "previous_name": "inc-2025-001-payments",
  "new_name": "payments-war-room",
  "mode": "custom"
}
```

#### Endpoint error responses

Endpoint-specific codes: `invalid_slack_channel_name_request`, `slack_not_configured`, `incident_slack_channel_missing`, `slack_channel_not_found`, `slack_channel_name_taken`, `invalid_resource_state`

| Status | Meaning |
| --- | --- |
| `400` | The naming request is invalid. |
| `401` | The request does not contain valid authentication. |
| `403` | Authentication succeeded, but the caller lacks the required API scope or workspace permission. |
| `404` | The requested resource does not exist or is not available to the caller. |
| `409` | Slack is not configured, the linked channel is missing, or the resolved name is already used. |
| `429` | The request exceeded an applicable sliding limit. Free API keys allow 20 requests per second and 600 requests per 60 seconds. Team API keys allow 100 requests per second and 3,000 requests per 60 seconds. Browser users allow 100 requests per second. Browser company allows 500 requests per second and 5,000 requests per 10 seconds. Browser company means the sum of user traffic for one company. Anonymous client IPs allow 20 requests per second and 200 requests per 10 seconds. The rate limiter does not count requests that it rejects. |
| `500` | An internal server error prevented completion of the request. |

#### Related operations

- [Preview an incident Slack channel name](https://tellagen.com/api-reference/incidents#incidents-endpoint-post-api-v1-incidents-id-slack-channel-name-preview) (`POST /api/v1/incidents/{id}/slack/channel-name/preview`)
