incidentio-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

incident.io CLI

incident.io CLI

Invoke the
incidentio
binary. Source of truth:
paymog/incidentio-cli
.
Unlike blacksmith's cookie-replay, incident.io has a real public API keyed by Bearer tokens.
incidentio
speaks it directly — no browser, no cookies. Commands are generated from incident.io's official OpenAPI specs (one per resource tag), so every documented endpoint is available. The API base is
https://api.incident.io
.
调用
incidentio
二进制文件。权威来源:
paymog/incidentio-cli
不同于 blacksmith 的 cookie 重放机制,incident.io 拥有真正的公开 API,通过 Bearer 令牌进行鉴权。
incidentio
直接与该 API 通信 —— 无需浏览器,无需 Cookie。命令由 incident.io 的官方 OpenAPI 规范生成(每个资源标签对应一套命令),因此所有已文档化的端点都可用。API 基础地址为
https://api.incident.io

Auth (required before any command)

认证(执行任何命令前必须完成)

A Bearer API key. Create one at Settings → API keys (
app.incident.io/settings/api-keys
); when creating it you choose its scopes (e.g.
incidents.create
), and the scope set is fixed after creation.
sh
incidentio auth set <api-key>     # store it (chmod 600, ~/.config/incidentio/creds.json)
incidentio auth status            # show masked key + last-updated
incidentio auth logout            # clear stored credentials
Resolution order:
--api-key <key>
flag →
$INCIDENT_API_KEY
→ stored credential. For a one-off or CI, export
INCIDENT_API_KEY
and skip
auth set
.
A
401
/
403
means the key is invalid, revoked, or lacks the scope the endpoint needs (e.g. calling
incidents create
with a read-only key). Re-check the key's scopes in the dashboard.
需要一个 Bearer API 密钥。在设置 → API密钥
app.incident.io/settings/api-keys
)创建;创建时需选择其权限范围(例如
incidents.create
),权限范围创建后无法修改。
sh
incidentio auth set <api-key>     # 存储密钥(设置权限chmod 600,路径为~/.config/incidentio/creds.json)
incidentio auth status            # 显示掩码后的密钥及最后更新时间
incidentio auth logout            # 清除存储的凭据
凭据优先级:
--api-key <key>
标志 →
$INCIDENT_API_KEY
环境变量 → 存储的凭据。对于一次性操作或CI环境,导出
INCIDENT_API_KEY
即可,无需执行
auth set
返回
401
/
403
表示密钥无效、已撤销,或缺少端点所需的权限范围(例如使用只读密钥调用
incidents create
)。请在仪表板中重新检查密钥的权限范围。

Usage

使用方法

sh
incidentio list [filter]         # every command (optionally filtered by substring)
incidentio list incidents        # all verbs for the `incidents` resource
incidentio <resource> <verb> [flags]
Commands are two tokens:
<resource> <verb>
. Output is pretty-printed JSON — pipe to
jq
, or pass
--raw
for the unformatted response.
sh
incidentio list [filter]         # 列出所有命令(可通过子串筛选)
incidentio list incidents        # 列出`incidents`资源的所有操作
incidentio <resource> <verb> [flags]
命令由两部分组成:
<resource> <verb>
。输出为格式化后的 JSON —— 可通过管道传递给
jq
,或添加
--raw
参数获取未格式化的响应。

Flags

标志

FlagMeaning
--api-key <key>
API key for this call (else
$INCIDENT_API_KEY
or stored)
--<param> <value>
path params:
--id
,
--user-id
,
--schedule-id
,
--alert-source-config-id
--query key=value
query param, repeatable (incl. bracket filters — see below)
--body-file <path>
JSON request body from file (for POST/PUT)
--body-json '<json>'
inline JSON request body
--set a.b=value
set a body field, repeatable
--raw
print the raw response, no JSON formatting
--auth cookie|bearer
(
raw
only) force the auth mode; otherwise inferred from the path
标志含义
--api-key <key>
当前调用使用的API密钥(若无则使用
$INCIDENT_API_KEY
或存储的凭据)
--<param> <value>
路径参数:
--id
,
--user-id
,
--schedule-id
,
--alert-source-config-id
--query key=value
查询参数,可重复使用(包括括号过滤器 —— 见下文)
--body-file <path>
从文件读取JSON请求体(用于POST/PUT请求)
--body-json '<json>'
内联JSON请求体
--set a.b=value
设置请求体字段,可重复使用
--raw
打印原始响应,不进行JSON格式化
--auth cookie|bearer
(仅
raw
命令可用)强制指定认证模式;否则根据路径自动推断

Bracket query filters

括号查询过滤器

List endpoints use bracket keys (Rails-style). Pass them verbatim to
--query
; repeat for multi-value filters. incident.io's list filters are powerful but the documented param names appear in
incidentio list <resource>
output.
sh
undefined
列表端点使用括号键(Rails风格)。直接传递给
--query
参数即可;多值过滤器可重复传递。incident.io的列表过滤器功能强大,但文档化的参数名称可在
incidentio list <resource>
的输出中查看。
sh
undefined

incidents in the "live" status category, severity rank >= a given severity

筛选处于"live"状态分类、严重程度等级≥指定值的事件

incidentio incidents list --query 'status_category[one_of]=live' --query 'severity[gte]=<sev-id>'
incidentio incidents list --query 'status_category[one_of]=live' --query 'severity[gte]=<sev-id>'

created within a date range (tilde-separated)

筛选指定日期范围内创建的事件(日期用波浪线分隔)

incidentio incidents list --query 'created_at[date_range]=2026-06-01~2026-06-30'
incidentio incidents list --query 'created_at[date_range]=2026-06-01~2026-06-30'

any-of multiple modes

筛选多种模式中的任意一种

incidentio incidents list --query 'mode[one_of]=standard' --query 'mode[one_of]=retrospective'

Dates are ISO-8601 UTC (`2026-06-04T00:00:00.000Z`). For "now" compute it:
`date -u +%FT%T.000Z` (macOS) or `date -u -d '30 days ago' +%FT%T.000Z` (GNU).
incidentio incidents list --query 'mode[one_of]=standard' --query 'mode[one_of]=retrospective'

日期格式为ISO-8601 UTC(`2026-06-04T00:00:00.000Z`)。如需使用「当前时间」,可通过以下命令计算:
`date -u +%FT%T.000Z`(macOS)或 `date -u -d '30 days ago' +%FT%T.000Z`(GNU)。

Command surface

命令范围

Run
incidentio list
for the authoritative set (~324 commands: ~179 public Bearer-API commands across 53 resources, plus ~145 internal/dashboard commands marked 🍪, and the
raw
escape hatch). Grouped highlights (
GET
unless noted):
运行
incidentio list
可查看完整命令集(约324个命令:53个资源对应约179个公开Bearer API命令,加上约145个标记为🍪的内部/仪表板命令,以及
raw
逃生舱口)。以下是分组后的重点命令(未特别说明则为GET请求):

Incidents

事件管理

sh
incidentio incidents list [--query status[one_of]=<id>] [--query page_size=50]
incidentio incidents show --id <id>
incidentio incidents create --body-json '{"name":"...","severity_id":"...","visibility":"public"}'
incidentio incidents edit --id <id>            # edit fields/status of an incident
incidentio incidents import-postmortem-document --id <id>
sh
incidentio incidents list [--query status[one_of]=<id>] [--query page_size=50]
incidentio incidents show --id <id>
incidentio incidents create --body-json '{"name":"...","severity_id":"...","visibility":"public"}'
incidentio incidents edit --id <id>            # 编辑事件的字段/状态
incidentio incidents import-postmortem-document --id <id>

Actions, follow-ups, attachments

操作、跟进事项、附件

sh
incidentio actions list --query incident_id=<id>
incidentio follow-ups list --query incident_id=<id>
incidentio follow-ups create --body-json '{"incident_id":"...","content":"..."}'
incidentio follow-ups connect-external-issue --id <id> --body-json '{...}'
incidentio incident-attachments list --query incident_id=<id>
sh
incidentio actions list --query incident_id=<id>
incidentio follow-ups list --query incident_id=<id>
incidentio follow-ups create --body-json '{"incident_id":"...","content":"..."}'
incidentio follow-ups connect-external-issue --id <id> --body-json '{...}'
incidentio incident-attachments list --query incident_id=<id>

Alerts & alert sources

警报与警报源

sh
incidentio alerts list
incidentio alerts show --id <id>
incidentio alerts resolve --id <id>
incidentio alert-sources list
incidentio alert-routes list
incidentio alert-routes show --id <id>
incidentio alert-routes update --id <id> --body-json '{...}'   # public API, no version field
incidentio alert-events create-http --alert-source-config-id <id> --body-json '{...}'
incidentio heartbeat ping --alert-source-config-id <id>   # GET ping
sh
incidentio alerts list
incidentio alerts show --id <id>
incidentio alerts resolve --id <id>
incidentio alert-sources list
incidentio alert-routes list
incidentio alert-routes show --id <id>
incidentio alert-routes update --id <id> --body-json '{...}'   # 公开API,无需版本字段
incidentio alert-events create-http --alert-source-config-id <id> --body-json '{...}'
incidentio heartbeat ping --alert-source-config-id <id>   # GET请求的ping检测

Alert route with incident-template custom-field binding (🍪 dashboard API)

绑定事件模板自定义字段的警报路由(🍪 仪表板API)

Rules:

规则:

1. version = current_version + 1 (optimistic concurrency — GET it first).

1. version = 当前版本 + 1(乐观并发控制 —— 需先GET获取当前版本)。

2. OMIT the
users
key from every escalation_config.escalation_targets entry;

2. 省略每个escalation_config.escalation_targets条目中的
users
键;

the GET payload carries an invalid users binding that PUT rejects. API restores it.

GET返回的payload包含无效的users绑定,PUT请求会拒绝该字段,API会在PUT后自动恢复。

3. Custom-field bindings: static option OR navigation-expression reference.

3. 自定义字段绑定:静态选项或导航表达式引用。

Static: array_value:[{reference:"",value:"<opt-id>",label:"<label>",sort_key:0}]

静态选项:array_value:[{reference:"",value:"<opt-id>",label:"<label>",sort_key:0}]

Expression: array_value:[{reference:"expressions["<expr-ref>"]"}]

表达式:array_value:[{reference:"expressions["<expr-ref>"]"}]

4. Navigation expressions (derive component array from Service catalog attribute):

4. 导航表达式(从服务目录属性派生组件数组):

Declare in top-level
expressions
array; bind by reference in custom_fields.

在顶层
expressions
数组中声明;在custom_fields中通过引用绑定。

merge_strategy: "first-wins" | "last-wins" | "append"

merge_strategy: "first-wins" | "last-wins" | "append"

incidentio alert-routes show-route --id <route-id> incidentio alert-routes update-route --id <route-id> --body-json '{ "version":4, "escalation_config":{"escalation_targets":[ {"type":"schedule","id":"<sched-id>"} ]}, "incident_template":{ "custom_fields":[{ "custom_field_id":"<field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"","value":"<option-id>","label":"<label>","sort_key":0}]} }] }}'
incidentio alert-routes show-route --id <route-id> incidentio alert-routes update-route --id <route-id> --body-json '{ "version":4, "escalation_config":{"escalation_targets":[ {"type":"schedule","id":"<sched-id>"} ]}, "incident_template":{ "custom_fields":[{ "custom_field_id":"<field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"","value":"<option-id>","label":"<label>","sort_key":0}]} }] }}'

With a catalog navigation expression (auto-derive Affected Components from alert Service):

使用目录导航表达式(从警报中的服务自动派生受影响组件):

incidentio alert-routes update-route-expr --id <route-id> --body-json '{ "version":5, "expressions":[{ "id":"01EXPR001","label":"Affected Components","reference":"affected_components", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "root_reference":"alert.attributes.<service-alert-attr-id>", "operations":[{"operation_type":"navigate", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "navigate":{"reference":"catalog_attribute["components"]","reference_label":"Components"}}] }], "incident_template":{ "custom_fields":[{ "custom_field_id":"<affected-components-field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"expressions["affected_components"]"}]} }] }}'
undefined
incidentio alert-routes update-route-expr --id <route-id> --body-json '{ "version":5, "expressions":[{ "id":"01EXPR001","label":"Affected Components","reference":"affected_components", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "root_reference":"alert.attributes.<service-alert-attr-id>", "operations":[{"operation_type":"navigate", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "navigate":{"reference":"catalog_attribute["components"]","reference_label":"Components"}}] }], "incident_template":{ "custom_fields":[{ "custom_field_id":"<affected-components-field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"expressions["affected_components"]"}]} }] }}'
undefined

Escalations & on-call schedules

升级流程与值班计划

sh
incidentio escalations list [--query status=active]
incidentio escalations create --body-json '{...}'
incidentio escalations cancel-escalation --id <id>
incidentio escalation-paths list
incidentio schedules list
incidentio schedules show --id <id>
incidentio schedule-entries list --schedule-id <id>
incidentio schedule-overrides list --schedule-id <id>
incidentio schedule-replicas list --schedule-id <id>
sh
incidentio escalations list [--query status=active]
incidentio escalations create --body-json '{...}'
incidentio escalations cancel-escalation --id <id>
incidentio escalation-paths list
incidentio schedules list
incidentio schedules show --id <id>
incidentio schedule-entries list --schedule-id <id>
incidentio schedule-overrides list --schedule-id <id>
incidentio schedule-replicas list --schedule-id <id>

Catalog (service catalog as code)

目录(即服务目录即代码)

sh
undefined
sh
undefined

Public API (Bearer)

公开API(Bearer鉴权)

incidentio catalog-types list incidentio catalog-types show --id <type-id> # includes .schema.attributes[].id incidentio catalog-types create --body-json '{...}' incidentio catalog-types update-type-schema --id <id> --body-json '{...}' incidentio catalog-entries list --query catalog_type_id=<id> incidentio catalog-entries create --body-json '{...}' # simple entries incidentio catalog-entries update --id <id> --body-json '{...}' incidentio catalog-entries bulk-update-entries --body-json '{...}' incidentio catalog-resources list
incidentio catalog-types list incidentio catalog-types show --id <type-id> # 包含.schema.attributes[].id incidentio catalog-types create --body-json '{...}' incidentio catalog-types update-type-schema --id <id> --body-json '{...}' incidentio catalog-entries list --query catalog_type_id=<id> incidentio catalog-entries create --body-json '{...}' # 创建简单条目 incidentio catalog-entries update --id <id> --body-json '{...}' incidentio catalog-entries bulk-update-entries --body-json '{...}' incidentio catalog-resources list

Catalog entries with attribute_values (🍪 dashboard API — verified contract)

带attribute_values的目录条目(🍪 仪表板API —— 已验证契约)

Required body: catalog_type_id, name, external_id, attribute_values (pass {} when none)

必填请求体:catalog_type_id, name, external_id, attribute_values(无属性时传{})

Attribute shapes:

属性格式:

plain text: {"<attr-id>":{"value":"some text"}}

纯文本: {"<attr-id>":{"value":"some text"}}

catalog-relation: {"<attr-id>":{"array_value":["<entry-id>",...]}}

目录关联: {"<attr-id>":{"array_value":["<entry-id>",...]}}

intentional clear (create only): {"<attr-id>":{"value":null}}

主动清空(仅创建时可用):{"<attr-id>":{"value":null}}

Get attribute IDs: incidentio catalog-types show --id <type-id> | jq '.catalog_type.schema.attributes[].id'

获取属性ID:incidentio catalog-types show --id <type-id> | jq '.catalog_type.schema.attributes[].id'

incidentio catalog-entries create-entry --body-json '{ "catalog_type_id":"<type-id>", "name":"My Service", "external_id":"my-service", "attribute_values":{ "<attr-id>":{"value":"production"}, "<rel-attr-id>":{"array_value":["<related-entry-id>"]} }}' incidentio catalog-entries update-entry --id <entry-id> --body-json '{ "name":"My Service", "attribute_values":{"<attr-id>":{"value":"staging"}}}'
undefined
incidentio catalog-entries create-entry --body-json '{ "catalog_type_id":"<type-id>", "name":"My Service", "external_id":"my-service", "attribute_values":{ "<attr-id>":{"value":"production"}, "<rel-attr-id>":{"array_value":["<related-entry-id>"]} }}' incidentio catalog-entries update-entry --id <entry-id> --body-json '{ "name":"My Service", "attribute_values":{"<attr-id>":{"value":"staging"}}}'
undefined

Config (custom fields, severities, types, roles, statuses, timestamps)

配置(自定义字段、严重程度、类型、角色、状态、时间戳)

sh
undefined
sh
undefined

Public API (Bearer)

公开API(Bearer鉴权)

incidentio custom-fields list incidentio custom-fields create --body-json '{...}' # basic fields incidentio custom-field-options list --query custom_field_id=<id> incidentio severities list incidentio incident-types list incidentio incident-roles list incidentio incident-statuses list incidentio incident-timestamps list
incidentio custom-fields list incidentio custom-fields create --body-json '{...}' # 创建基础字段 incidentio custom-field-options list --query custom_field_id=<id> incidentio severities list incidentio incident-types list incidentio incident-roles list incidentio incident-statuses list incidentio incident-timestamps list

Catalog-backed multi-select custom field (🍪 dashboard API — supports catalog_type_id,

基于目录的多选自定义字段(🍪 仪表板API —— 支持公开API中没有的catalog_type_id、

field_mode, condition_groups not available in the public API)

field_mode、condition_groups参数)

Required body: name, description, field_type:"multi_select", catalog_type_id, field_mode,

必填请求体:name, description, field_type:"multi_select", catalog_type_id, field_mode,

dynamic_options, cannot_be_unset, options, condition_groups

dynamic_options, cannot_be_unset, options, condition_groups

incidentio custom-fields create-catalog-backed --body-json '{ "name":"Affected Services", "description":"Which services are affected by this incident", "field_type":"multi_select", "catalog_type_id":"<catalog-type-id>", "field_mode":"dashboard", "dynamic_options":true, "cannot_be_unset":false, "options":[], "condition_groups":[]}'
undefined
incidentio custom-fields create-catalog-backed --body-json '{ "name":"Affected Services", "description":"Which services are affected by this incident", "field_type":"multi_select", "catalog_type_id":"<catalog-type-id>", "field_mode":"dashboard", "dynamic_options":true, "cannot_be_unset":false, "options":[], "condition_groups":[]}'
undefined

Status pages

状态页

sh
undefined
sh
undefined

Read (Bearer public API)

读取操作(Bearer公开API)

incidentio status-pages list incidentio status-pages show --status-page-id <id> # includes current_structure incidentio status-page-incidents list --query status_page_id=<id> incidentio status-page-maintenances list --query status_page_id=<id>
incidentio status-pages list incidentio status-pages show --status-page-id <id> # 包含current_structure incidentio status-page-incidents list --query status_page_id=<id> incidentio status-page-maintenances list --query status_page_id=<id>

Manage the page itself (🍪 internal — the public API cannot create pages/components)

管理页面本身(🍪 内部API —— 公开API无法创建页面/组件)

Simple page:

创建简单页面:

incidentio status-pages create --body-json '{"name":"Acme","subpath":"acme","theme":"light"}'
incidentio status-pages create --body-json '{"name":"Acme","subpath":"acme","theme":"light"}'

Catalog-backed parent page with auto-generated sub-pages per catalog entry:

创建基于目录的父页面,并为每个目录条目自动生成子页面:

incidentio status-pages create --body-json '{ "name":"Acme","subpath":"acme","theme":"light", "parent_page_options":{ "page_type":"parent", "split_by_catalog_type_id":"<catalog-type-id>", "split_by_component_attribute_id":"<component-attr-id>", "sub_pages":[ {"defined_by_catalog_entry_id":"<entry-id>","name":"Team A","subpath":"team-a"} ] }}'
incidentio status-pages create --body-json '{ "name":"Acme","subpath":"acme","theme":"light", "parent_page_options":{ "page_type":"parent", "split_by_catalog_type_id":"<catalog-type-id>", "split_by_component_attribute_id":"<component-attr-id>", "sub_pages":[ {"defined_by_catalog_entry_id":"<entry-id>","name":"Team A","subpath":"team-a"} ] }}'

Update — name, subpath, support_label are ALL required even for a single-field change:

更新页面 —— 即使只修改单个字段,name、subpath、support_label也必须全部传入:

incidentio status-pages update --status-page-id <id> --body-json '{"name":"Acme","subpath":"acme","support_label":"Report a problem","allow_search_engine_indexing":false}' incidentio status-page-components create --body-json '{"name":"API","status_page_id":"<id>"}' incidentio status-page-components delete --id <component-id> incidentio status-page-structures create --body-json '{"status_page_id":"<id>","items":[ {"group":{"name":"Core","display_aggregated_uptime":true,"hidden":false,"components":[ {"component_id":"<id>","display_uptime":true,"hidden":false}]}}, {"component":{"component_id":"<id>","display_uptime":true,"hidden":false}}]}'
incidentio status-pages update --status-page-id <id> --body-json '{"name":"Acme","subpath":"acme","support_label":"Report a problem","allow_search_engine_indexing":false}' incidentio status-page-components create --body-json '{"name":"API","status_page_id":"<id>"}' incidentio status-page-components delete --id <component-id> incidentio status-page-structures create --body-json '{"status_page_id":"<id>","items":[ {"group":{"name":"Core","display_aggregated_uptime":true,"hidden":false,"components":[ {"component_id":"<id>","display_uptime":true,"hidden":false}]}}, {"component":{"component_id":"<id>","display_uptime":true,"hidden":false}}]}'

Audit subscribers / templates (🍪)

审核订阅者/模板(🍪)

incidentio status-page-subscriptions --query status_page_id=<id> incidentio status-page-templates --query status_page_id=<id>
incidentio status-page-subscriptions --query status_page_id=<id> incidentio status-page-templates --query status_page_id=<id>

Retrospective status-page incident (Bearer) — bulk-import historical incidents

回顾性状态页事件(Bearer)—— 批量导入历史事件

incidentio status-page-incidents create-status-page-retrospective-incident --body-json '{ "status_page_id":"<id>", "name":"Elevated API latency", "idempotency_key":"historical-2021-08-17", "updates":[ {"incident_status":"investigating","message":"Looking into it.","published_at":"2021-08-17T13:28:57Z"}, {"incident_status":"resolved","message":"Fixed.","published_at":"2021-08-17T14:00:00Z", "component_statuses":[{"component_id":"<id>","component_status":"operational"}]} ]}'

Notes: creating/branding a page and defining its components/layout is **internal-only** (cookie
session); the public Bearer API only lists/shows and publishes incidents/maintenance. Public-page
components are page-native objects (create them, then place them with `status-page-structures`),
not a custom field (that model is for *internal* pages). `theme` is `light`|`dark`. Team plan allows
**one** public page (a second `create` returns `422 exceeded your allowance`). Logo/favicon/brand
color are uploads done in the dashboard.

For catalog-backed parent pages: `split_by_catalog_type_id` and `split_by_component_attribute_id`
identify which catalog type backs the sub-pages and which attribute on that type points to
components; each `sub_pages` entry maps a catalog entry to a sub-page slug.
incidentio status-page-incidents create-status-page-retrospective-incident --body-json '{ "status_page_id":"<id>", "name":"Elevated API latency", "idempotency_key":"historical-2021-08-17", "updates":[ {"incident_status":"investigating","message":"Looking into it.","published_at":"2021-08-17T13:28:57Z"}, {"incident_status":"resolved","message":"Fixed.","published_at":"2021-08-17T14:00:00Z", "component_statuses":[{"component_id":"<id>","component_status":"operational"}]} ]}'

注意:创建/品牌化页面以及定义组件/布局是**内部专属操作**(需要Cookie会话);公开Bearer API仅支持列表/查看以及发布事件/维护信息。公开页面的组件是页面原生对象(先创建组件,再通过`status-page-structures`放置),而非自定义字段(自定义字段模型用于*内部*页面)。`theme`可选值为`light`|`dark`。团队计划仅允许创建**一个**公开页面(第二次调用`create`会返回`422 exceeded your allowance`)。Logo/图标/品牌颜色需在仪表板中上传设置。

对于基于目录的父页面:`split_by_catalog_type_id`和`split_by_component_attribute_id`分别指定支撑子页面的目录类型,以及该类型中指向组件的属性;每个`sub_pages`条目将目录条目映射到子页面的slug。

Users, teams, API keys, workflows, secrets

用户、团队、API密钥、工作流、密钥存储

sh
incidentio users list --query email=<email>
incidentio users show --id <id>
incidentio teams list
incidentio api-keys list
incidentio api-keys rotate --id <id>
sh
incidentio users list --query email=<email>
incidentio users show --id <id>
incidentio teams list
incidentio api-keys list
incidentio api-keys rotate --id <id>

api-keys create/update accept optional
comments
string

api-keys create/update支持可选的
comments
字符串参数

Workflows (public Bearer CRUD)

工作流(公开Bearer CRUD)

incidentio workflows list incidentio workflows show --id <id> incidentio workflows create --body-json '{...}' # public shape — see OpenAPI incidentio workflows update --id <id> --body-json '{...}'
incidentio workflows list incidentio workflows show --id <id> incidentio workflows create --body-json '{...}' # 公开格式 —— 参考OpenAPI文档 incidentio workflows update --id <id> --body-json '{...}'

Secrets store (public Bearer — prefer this for scripting)

密钥存储(公开Bearer —— 脚本编写优先使用)

Create: {name, value, description?, owning_team_ids?}

创建:{name, value, description?, owning_team_ids?}

Rotate: {value} — bumps version; value never returned (only last_four_chars)

轮换:{value} —— 版本号递增;value不会返回(仅返回last_four_chars)

incidentio secrets list [--query team_ids=<id>] incidentio secrets show --id <id> # includes versions[] history incidentio secrets create --body-json '{"name":"pagerduty_token","value":"..."}' incidentio secrets rotate --id <id> --body-json '{"value":"new-secret"}' incidentio secrets update --id <id> --body-json '{"name":"pagerduty_token"}' incidentio secrets delete --id <id>
undefined
incidentio secrets list [--query team_ids=<id>] incidentio secrets show --id <id> # 包含versions[]历史记录 incidentio secrets create --body-json '{"name":"pagerduty_token","value":"..."}' incidentio secrets rotate --id <id> --body-json '{"value":"new-secret"}' incidentio secrets update --id <id> --body-json '{"name":"pagerduty_token"}' incidentio secrets delete --id <id>
undefined

Housekeeping

运维管理

sh
incidentio utilities identity              # validate the key + show the identity
incidentio maintenancewindows list
incidentio ipallowlists show
incidentio telemetry update --id <id> --body-json '{...}'
sh
incidentio utilities identity              # 验证密钥并显示身份信息
incidentio maintenancewindows list
incidentio ipallowlists show
incidentio telemetry update --id <id> --body-json '{...}'

Dashboard / internal API (🍪 — needs a browser session)

仪表板/内部API(🍪 —— 需要浏览器会话)

These hit
app.incident.io/api/*
, which rejects API keys ("Cannot use API keys to authenticate to internal APIs"). They replay a logged-in browser session. Import one first:
sh
undefined
这些命令调用
app.incident.io/api/*
,该接口拒绝API密钥(提示"Cannot use API keys to authenticate to internal APIs")。它们会重放已登录的浏览器会话。需先导入会话:
sh
undefined

devtools → Network → right-click any /api/ request → Copy as cURL

开发者工具 → 网络 → 右键点击任意/api/请求 → 复制为cURL

incidentio auth import '<paste curl>' # or: pbpaste | incidentio auth import incidentio auth set-org 01G9XY4BZ7YGBPJ3K50NB30YXS # x-incident-organisation-id (auto-captured from the curl if present)

Then commands marked 🍪 in `list` work. Highlights — things the public API can't do:

```sh
incidentio saved-views --query context=incidents     # saved filter views
incidentio insights trends --query start_date=2026-06-01 --query end_date=2026-06-30
incidentio insights custom-dashboards
incidentio policies                                 # policy list
incidentio policies update --id <id> --body-json '{...}'  # flip run_on_private_incidents etc.
incidentio secrets list-internal                  # cookie twin of public secrets.*
incidentio workflows triggers                     # alert.updated|attached, scheduled, ...
incidentio workflows show-internal --id <id>      # expands webhook.send signing params
incidentio workflows create-internal --body-json '{
  "trigger":"alert.updated",
  "workflow":{"name":"...","once_for":["alert"],"condition_groups":[],"steps":[],"expressions":[],
    "runs_on_incident_modes":["standard"],"continue_on_step_error":false,
    "runs_on_incidents":"newly_created","state":"draft","private_incident_scope":"none"}}'
incidentio policy-violations
incidentio incident-timelines timeline --incident-timeline <id>            # full timeline
incidentio incident-timelines activity-log --incident-timeline <id>        # activity log
incidentio debriefs incident-debriefs --query incident_id=<id>
incidentio incident-suggestions for-incident --query incident_id=<id>      # AI suggestions
incidentio postmortems templates --query incident_id=<id>
incidentio schedule-reports
incidentio user-preferences
incidentio identity self                  # who am I + scopes (dashboard identity)
A
401 "No authorization material"
on a 🍪 command means the session cookie isn't being recognized (wrong/expired) — re-import a fresh Copy-as-cURL. Org id resolves
--org
$INCIDENT_ORG_ID
→ stored.
incidentio auth import '<paste curl>' # 或:pbpaste | incidentio auth import incidentio auth set-org 01G9XY4BZ7YGBPJ3K50NB30YXS # x-incident-organisation-id(若cURL中包含会自动捕获)

之后`list`命令中标记为🍪的命令即可使用。以下是公开API无法实现的重点操作:

```sh
incidentio saved-views --query context=incidents     # 已保存的筛选视图
incidentio insights trends --query start_date=2026-06-01 --query end_date=2026-06-30
incidentio insights custom-dashboards
incidentio policies                                 # 策略列表
incidentio policies update --id <id> --body-json '{...}'  # 切换run_on_private_incidents等设置
incidentio secrets list-internal                  # 公开secrets.*命令的Cookie版本
incidentio workflows triggers                     # 触发器:alert.updated|attached、定时触发等
incidentio workflows show-internal --id <id>      # 展开webhook.send的签名参数
incidentio workflows create-internal --body-json '{
  "trigger":"alert.updated",
  "workflow":{"name":"...","once_for":["alert"],"condition_groups":[],"steps":[],"expressions":[],
    "runs_on_incident_modes":["standard"],"continue_on_step_error":false,
    "runs_on_incidents":"newly_created","state":"draft","private_incident_scope":"none"}}'
incidentio policy-violations
incidentio incident-timelines timeline --incident-timeline <id>            # 完整时间线
incidentio incident-timelines activity-log --incident-timeline <id>        # 活动日志
incidentio debriefs incident-debriefs --query incident_id=<id>
incidentio incident-suggestions for-incident --query incident_id=<id>      # AI建议
incidentio postmortems templates --query incident_id=<id>
incidentio schedule-reports
incidentio user-preferences
incidentio identity self                  # 查看当前身份及权限范围(仪表板身份)
执行🍪命令时返回
401 "No authorization material"
表示会话Cookie未被识别(错误/已过期)—— 重新从app.incident.io复制cURL并导入。组织ID优先级:
--org
$INCIDENT_ORG_ID
→ 存储的凭据。

Raw requests & reverse-engineering new endpoints

原始请求与逆向工程新端点

Not every endpoint is codified.
incidentio raw <METHOD> </path>
hits any endpoint with your stored creds — the fast path for probing and reverse-engineering internal routes:
sh
incidentio raw GET  /api/status_pages                    # cookie inferred (/api/*)
incidentio raw GET  /v2/incidents --query page_size=1    # bearer inferred (else)
incidentio raw POST /api/status_pages --body-json '{}'   # probe: 422 names required fields
incidentio raw PUT  /api/settings/self --body-json '{...}'   # tune a setting
incidentio raw DELETE /api/status_pages/<id> --auth cookie
Auth is inferred (
/api/*
→ cookie, otherwise bearer); override with
--auth cookie|bearer
. Inline any IDs directly in the path (
raw
does no
:param
substitution).
Codify a new endpoint (recipe):
  1. Probe with an empty/partial body:
    incidentio raw POST /api/<thing> --body-json '{}'
    .
  2. Read the
    422 validation_error
    — the
    source.field
    / message names the required fields; retry with an intentionally invalid enum value to learn allowed values.
  3. Add a
    Command
    to
    src/commands/manual-internal.ts
    (it's merged at load time and survives HAR regeneration), then
    bun run build
    .
并非所有端点都已编码到命令集中。
incidentio raw <METHOD> </path>
可使用存储的凭据调用任意端点 —— 是探测和逆向工程内部路由的快捷方式:
sh
incidentio raw GET  /api/status_pages                    # 自动推断为Cookie鉴权(/api/*路径)
incidentio raw GET  /v2/incidents --query page_size=1    # 自动推断为Bearer鉴权(其他路径)
incidentio raw POST /api/status_pages --body-json '{}'   # 探测:422错误会返回必填字段
incidentio raw PUT  /api/settings/self --body-json '{...}'   # 修改设置
incidentio raw DELETE /api/status_pages/<id> --auth cookie
鉴权模式自动推断(
/api/*
→ Cookie,其他 → Bearer);可通过
--auth cookie|bearer
强制指定。路径中可直接包含ID(
raw
命令不进行
:param
替换)。
编码新端点步骤:
  1. 使用空/部分请求体探测:
    incidentio raw POST /api/<thing> --body-json '{}'
  2. 查看
    422 validation_error
    ——
    source.field
    /消息会指明必填字段;可传入故意无效的枚举值来获取允许的取值。
  3. src/commands/manual-internal.ts
    中添加
    Command
    (加载时会合并,且HAR重新生成后仍保留),然后执行
    bun run build

Recipes

使用示例

Validate your API key

验证API密钥

sh
incidentio utilities identity | jq '.identity'
sh
incidentio utilities identity | jq '.identity'

Open incidents, newest first

查看未关闭的事件(按最新排序)

sh
incidentio incidents list --query 'status_category[one_of]=live' \
  | jq '.incidents[] | {id, name, severity: .severity.name, status: .incident_status.name}'
sh
incidentio incidents list --query 'status_category[one_of]=live' \
  | jq '.incidents[] | {id, name, severity: .severity.name, status: .incident_status.name}'

Page through a list (cursor pagination)

分页获取列表(游标分页)

list
responses include a
pagination_meta.after
cursor; pass it back as
--query after=<cursor>
:
sh
incidentio incidents list --query page_size=250 > first.json
AFTER=$(jq -r '.pagination_meta.after // empty' first.json)
[ -n "$AFTER" ] && incidentio incidents list --query page_size=250 --query "after=$AFTER" > second.json
list
响应包含
pagination_meta.after
游标;将其作为
--query after=<cursor>
参数传入即可获取下一页:
sh
incidentio incidents list --query page_size=250 > first.json
AFTER=$(jq -r '.pagination_meta.after // empty' first.json)
[ -n "$AFTER" ] && incidentio incidents list --query page_size=250 --query "after=$AFTER" > second.json

Declare an incident

创建事件

sh
incidentio incidents create --body-json '{
  "name": "API 5xx spike",
  "severity_id": "<sev-id>",
  "summary": "Elevated 5xx from the edge.",
  "visibility": "public"
}' | jq '.incident.id'
Need the severity/status IDs first?
incidentio severities list
/
incidentio incident-statuses list
.
sh
incidentio incidents create --body-json '{
  "name": "API 5xx spike",
  "severity_id": "<sev-id>",
  "summary": "Elevated 5xx from the edge.",
  "visibility": "public"
}' | jq '.incident.id'
需要先获取严重程度/状态ID?执行
incidentio severities list
/
incidentio incident-statuses list

Which verbs does a resource have?

查看资源支持的操作

sh
incidentio list schedules      # shows list/create/show/update/delete + nested schedule-entries/overrides/replicas
incidentio list catalog-entries   # shows create/create-entry (🍪)/update/update-entry (🍪)/...
sh
incidentio list schedules      # 显示list/create/show/update/delete以及嵌套的schedule-entries/overrides/replicas
incidentio list catalog-entries   # 显示create/create-entry (🍪)/update/update-entry (🍪)/...

Create a catalog entry with component relations (🍪)

创建带组件关联的目录条目(🍪)

sh
undefined
sh
undefined

1. Get the catalog type's attribute IDs

1. 获取目录类型的属性ID

incidentio catalog-types show --id <type-id> | jq '.catalog_type.schema.attributes[] | {id, name}'
incidentio catalog-types show --id <type-id> | jq '.catalog_type.schema.attributes[] | {id, name}'

2. Create an entry with attribute values

2. 创建带属性值的条目

incidentio catalog-entries create-entry --body-json '{ "catalog_type_id":"<type-id>", "name":"payments-service", "external_id":"payments-service", "attribute_values":{ "<team-attr-id>":{"array_value":["<team-catalog-entry-id>"]}, "<tier-attr-id>":{"value":"tier-1"} }}'
undefined
incidentio catalog-entries create-entry --body-json '{ "catalog_type_id":"<type-id>", "name":"payments-service", "external_id":"payments-service", "attribute_values":{ "<team-attr-id>":{"array_value":["<team-catalog-entry-id>"]}, "<tier-attr-id>":{"value":"tier-1"} }}'
undefined

Update an alert route to bind a custom field (🍪)

更新警报路由以绑定自定义字段(🍪)

sh
undefined
sh
undefined

1. GET current route — capture version and escalation_targets (you'll need to strip
users
)

1. 获取当前路由 —— 捕获version和escalation_targets(需要移除
users
字段)

VERSION=$(incidentio alert-routes show-route --id <route-id> | jq '.version')
VERSION=$(incidentio alert-routes show-route --id <route-id> | jq '.version')

2. PUT with version+1. Two critical rules:

2. 传入version+1进行PUT请求。两个关键规则:

a) version = $VERSION + 1 (optimistic concurrency)

a) version = $VERSION + 1(乐观并发控制)

b) omit
users
from every escalation_config.escalation_targets entry

b) 省略escalation_config.escalation_targets条目中的
users
字段

(the GET payload has an invalid users binding the PUT rejects; API restores it after PUT)

(GET返回的payload包含无效的users绑定,PUT请求会拒绝该字段;API会在PUT后自动恢复)

incidentio alert-routes update-route --id <route-id> --body-json '{ "version":'$((VERSION+1))', "name":"My Route", "escalation_config":{"escalation_targets":[ {"type":"schedule","id":"<sched-id>"} ]}, "incident_template":{ "custom_fields":[{ "custom_field_id":"<field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"","value":"<option-id>","label":"P1 - Critical","sort_key":0}]} }] }}'
undefined
incidentio alert-routes update-route --id <route-id> --body-json '{ "version":'$((VERSION+1))', "name":"My Route", "escalation_config":{"escalation_targets":[ {"type":"schedule","id":"<sched-id>"} ]}, "incident_template":{ "custom_fields":[{ "custom_field_id":"<field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"","value":"<option-id>","label":"P1 - Critical","sort_key":0}]} }] }}'
undefined

Derive Affected Components from alert Service via catalog navigation expression (🍪)

通过目录导航表达式从警报服务派生受影响组件(🍪)

A navigation expression lets an alert route auto-populate a catalog-backed custom field by navigating from an alert attribute (e.g. Service) through a catalog relationship (e.g. Components).
sh
undefined
导航表达式可让警报路由通过从警报属性(例如服务)遍历目录关系(例如组件),自动填充基于目录的自定义字段。
sh
undefined

1. Find the IDs you need:

1. 获取所需的ID:

- service-alert-attr-id: the alert source attribute ID for the Service field

- service-alert-attr-id:警报源中服务字段的属性ID

- component-type-id: catalog type ID for Components (incidentio catalog-types list)

- component-type-id:组件的目录类型ID(执行incidentio catalog-types list查看)

- affected-components-field-id: the incident custom field ID (incidentio custom-fields list)

- affected-components-field-id:事件自定义字段ID(执行incidentio custom-fields list查看)

VERSION=$(incidentio alert-routes show-route --id <route-id> | jq '.version')
VERSION=$(incidentio alert-routes show-route --id <route-id> | jq '.version')

2. PUT the route with an expression + expression-reference binding.

2. 传入表达式+表达式引用绑定更新路由。

Same rules: version+1, omit users from escalation_targets.

同样遵循规则:version+1,省略escalation_targets中的users字段。

incidentio alert-routes update-route-expr --id <route-id> --body-json '{ "version":'$((VERSION+1))', "escalation_config":{"escalation_targets":[{"type":"schedule","id":"<sched-id>"}]}, "expressions":[{ "id":"<expr-id>", "label":"Affected Components", "reference":"affected_components", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "root_reference":"alert.attributes.<service-alert-attr-id>", "operations":[{ "operation_type":"navigate", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "navigate":{"reference":"catalog_attribute["components"]","reference_label":"Components"} }] }], "incident_template":{ "custom_fields":[{ "custom_field_id":"<affected-components-field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"expressions["affected_components"]"}]} }] }}'
incidentio alert-routes update-route-expr --id <route-id> --body-json '{ "version":'$((VERSION+1))', "escalation_config":{"escalation_targets":[{"type":"schedule","id":"<sched-id>"}]}, "expressions":[{ "id":"<expr-id>", "label":"Affected Components", "reference":"affected_components", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "root_reference":"alert.attributes.<service-alert-attr-id>", "operations":[{ "operation_type":"navigate", "returns":{"type":"CatalogEntry["<component-type-id>"]","array":true}, "navigate":{"reference":"catalog_attribute["components"]","reference_label":"Components"} }] }], "incident_template":{ "custom_fields":[{ "custom_field_id":"<affected-components-field-id>", "merge_strategy":"first-wins", "binding":{"array_value":[{"reference":"expressions["affected_components"]"}]} }] }}'

After a successful PUT the API echoes the expressions array back intact.

PUT请求成功后,API会完整返回expressions数组。


Notes:
- `root_reference` points at the alert source attribute that holds a Service catalog entry.
- `operations[0].navigate.reference` is the catalog attribute name on the Service type that
  holds its component entries (verify via `incidentio catalog-types show --id <service-type-id>`).
- The expression `reference` value becomes the key in `expressions["<reference>"]` binding.
- The Affected Components custom field must be a catalog-backed `multi_select` created via
  `custom-fields create-catalog-backed` (dashboard internal API) targeting the Component catalog type.

注意:
- `root_reference`指向警报源中存储服务目录条目的属性。
- `operations[0].navigate.reference`是服务类型中存储其组件条目的目录属性名称(可通过`incidentio catalog-types show --id <service-type-id>`验证)。
- 表达式的`reference`值会成为`expressions["<reference>"]`绑定中的键。
- 受影响组件自定义字段必须是通过`custom-fields create-catalog-backed`(仪表板内部API)创建的、针对组件目录类型的基于目录的`multi_select`字段。

Secrets, signed webhooks, alert-triggered workflows

密钥、签名Webhook、警报触发的工作流

sh
undefined
sh
undefined

List triggers (🍪) — includes alert.updated, alert.attached, scheduled

查看触发器(🍪)—— 包括alert.updated、alert.attached、定时触发等

incidentio workflows triggers | jq '.triggers[] | select(.name|test("alert|scheduled"))'
incidentio workflows triggers | jq '.triggers[] | select(.name|test("alert|scheduled"))'

Create an alert-triggered workflow (🍪). NOTE the split body: top-level
trigger

创建警报触发的工作流(🍪)。注意请求体分为两部分:顶层的
trigger

string + nested
workflow
object. Public
workflows create
uses a flatter shape.

字符串 + 嵌套的
workflow
对象。公开的
workflows create
使用更扁平的格式。

incidentio workflows create-internal --body-json '{ "trigger":"alert.updated", "workflow":{ "name":"Alert resolved webhook", "once_for":["alert"], "condition_groups":[], "steps":[{ "id":"step1", "name":"webhook.send", "param_bindings":[ {"value":{"literal":"https://example.com/hook"}}, {"value":{"literal":"POST"}}, {"array_value":[{"literal":"Authorization: Bearer {{secrets.my_token}}"}]}, {"value":{"literal":"{"ok":true}"}}, {"value":{"literal":"<secret-id>"}}, {"value":{"literal":""}}, {"value":{"literal":"X-Signature"}} ] }], "expressions":[], "runs_on_incident_modes":["standard"], "continue_on_step_error":false, "runs_on_incidents":"newly_created", "state":"draft", "private_incident_scope":"none" }}'
incidentio workflows create-internal --body-json '{ "trigger":"alert.updated", "workflow":{ "name":"Alert resolved webhook", "once_for":["alert"], "condition_groups":[], "steps":[{ "id":"step1", "name":"webhook.send", "param_bindings":[ {"value":{"literal":"https://example.com/hook"}}, {"value":{"literal":"POST"}}, {"array_value":[{"literal":"Authorization: Bearer {{secrets.my_token}}"}]}, {"value":{"literal":"{"ok":true}"}}, {"value":{"literal":"<secret-id>"}}, {"value":{"literal":""}}, {"value":{"literal":"X-Signature"}} ] }], "expressions":[], "runs_on_incident_modes":["standard"], "continue_on_step_error":false, "runs_on_incidents":"newly_created", "state":"draft", "private_incident_scope":"none" }}'

webhook.send param order (from show-internal): endpoint, method, headers

webhook.send的参数顺序(来自show-internal):endpoint, method, headers

(TemplatedText plain_single_line_with_secrets), body, signing_secret (type Secret),

(TemplatedText plain_single_line_with_secrets), body, signing_secret(类型为Secret),

generated_signing_secret, signature_header_name (HMAC-SHA256).

generated_signing_secret, signature_header_name(HMAC-SHA256)。

Prefer public
secrets create
for the signing secret when you have a Bearer key.

若拥有Bearer密钥,优先使用公开的
secrets create
创建签名密钥。

undefined
undefined

Opt a policy into private incidents (🍪)

让策略支持私有事件(🍪)

sh
undefined
sh
undefined

GET first — subjects/operations come back as expanded objects

先GET获取策略 —— subjects/operations会以展开对象形式返回

incidentio policies | jq '.policies[] | {id,name,run_on_private_incidents}'
incidentio policies | jq '.policies[] | {id,name,run_on_private_incidents}'

PUT write shape differs: subject/operation are bare strings; follow_up needs due_date_config

PUT请求的格式不同:subject/operation为纯字符串;follow_up需要due_date_config

incidentio policies update --id <id> --body-json '{ "enabled":true, "name":"...", "description":"...", "policy_type":"follow_up", "conditions":[{"conditions":[{"subject":"incident.severity","operation":"gte", "param_bindings":[{"value":{"literal":"<sev-id>"}}]}]}], "requirements":{"conditions":[{"conditions":[{"subject":"follow_up.status","operation":"not_one_of", "param_bindings":[{"array_value":[{"literal":"outstanding"}]}]}]}]}, "run_on_private_incidents":true, "due_date_config":{"incident_timestamp_id":"<ts-id>","days":{"value":{"literal":"30"}}, "calculation_type":"seven_days"} }'
undefined
incidentio policies update --id <id> --body-json '{ "enabled":true, "name":"...", "description":"...", "policy_type":"follow_up", "conditions":[{"conditions":[{"subject":"incident.severity","operation":"gte", "param_bindings":[{"value":{"literal":"<sev-id>"}}]}]}], "requirements":{"conditions":[{"conditions":[{"subject":"follow_up.status","operation":"not_one_of", "param_bindings":[{"array_value":[{"literal":"outstanding"}]}]}]}]}, "run_on_private_incidents":true, "due_date_config":{"incident_timestamp_id":"<ts-id>","days":{"value":{"literal":"30"}}, "calculation_type":"seven_days"} }'
undefined

Regenerate the command catalog

重新生成命令目录

Commands live in
src/commands/generated.ts
, generated from incident.io's per-tag OpenAPI specs (fetched live from
docs.incident.io
):
sh
bun run codegen
The generator discovers the REST tag set from
docs.incident.io/llms.txt
, fetches each
/openapi/tags/<tag>.json
, derives a
<resource> <verb>
name per operation, and resolves collisions (e.g.
catalog-types update-type
vs
update-type-schema
;
heartbeat ping
vs
ping-post
). After regenerating, rebuild (
bun run build
).
Dashboard/internal commands are generated from captured browser HAR(s) via
bun run codegen:har <a.har> [b.har ...]
. It harvests GET and write endpoints (POST→
create
, PUT/PATCH→
update
, DELETE→
delete
), templates ULID/Slack IDs to
:param
, drops anything the public Bearer API already covers, and overwrites
generated-internal.ts
— so pass every HAR you want represented in a single invocation (e.g.
app.incident.io.har app.incident.io2.har app.incident.io3.har
). Hand-verified internal endpoints that appear in no HAR (e.g. status-page create/update/components/structures) live in
src/commands/manual-internal.ts
and are merged at load time, so they survive regeneration.
命令存储在
src/commands/generated.ts
中,由incident.io的每个标签对应的OpenAPI规范生成(从
docs.incident.io
实时获取):
sh
bun run codegen
生成器从
docs.incident.io/llms.txt
发现REST标签集,获取每个
/openapi/tags/<tag>.json
,为每个操作生成
<resource> <verb>
名称,并解决冲突(例如
catalog-types update-type
vs
update-type-schema
heartbeat ping
vs
ping-post
)。重新生成后,需执行
bun run build
重新构建。
仪表板/内部命令通过捕获的浏览器HAR文件生成,执行
bun run codegen:har <a.har> [b.har ...]
即可。该命令会提取GET和写入端点(POST→
create
,PUT/PATCH→
update
,DELETE→
delete
),将ULID/Slack ID替换为
:param
,移除公开Bearer API已覆盖的端点,并覆盖
generated-internal.ts
—— 因此需在单次调用中传入所有需要包含的HAR文件(例如
app.incident.io.har app.incident.io2.har app.incident.io3.har
)。未出现在任何HAR文件中的手动验证内部端点(例如status-page create/update/components/structures)存储在
src/commands/manual-internal.ts
中,加载时会合并,因此重新生成后仍会保留。

Common issues

常见问题

not authenticated

not authenticated

No key found via flag, env, or store. Run
incidentio auth set <key>
or
export INCIDENT_API_KEY=<key>
.
未通过标志、环境变量或存储找到密钥。执行
incidentio auth set <key>
export INCIDENT_API_KEY=<key>

HTTP 401
/
HTTP 403
(public/Bearer commands)

HTTP 401
/
HTTP 403
(公开/Bearer命令)

The key is invalid/expired, or lacks the scope the endpoint requires (e.g. a read-only key calling a write verb). Check the key's scopes in Settings → API keys; scopes are fixed at creation — rotate or create a new key if you need more.
密钥无效/已过期,或缺少端点所需的权限范围(例如使用只读密钥调用写入操作)。在设置 → API密钥中检查密钥的权限范围;权限范围创建后无法修改 —— 若需要更多权限,可轮换或创建新密钥。

needs a browser session
/
401 "No authorization material"
(🍪 dashboard commands)

needs a browser session
/
401 "No authorization material"
(🍪 仪表板命令)

Dashboard commands (
app.incident.io/api/*
) reject API keys. They need a logged-in browser session: re-import via
incidentio auth import <curl>
(Copy-as-cURL from app.incident.io), and ensure the org id is set (
auth set-org
or
--org
). HARs from Chrome/Brave usually strip cookies — use Copy-as-cURL.
仪表板命令(
app.incident.io/api/*
)拒绝API密钥。需要已登录的浏览器会话:通过
incidentio auth import <curl>
重新导入(从app.incident.io复制为cURL),并确保组织ID已设置(
auth set-org
--org
)。Chrome/Brave的HAR文件通常会剥离Cookie —— 请使用复制为cURL功能。

HTTP 422
with a validation message

HTTP 422
并附带验证消息

The body/query is the wrong shape (missing required field, bad enum, wrong type). The error body names the offending
source.field
— fix the
--body-json
/
--query
/
--set
value.
请求体/查询参数格式错误(缺少必填字段、枚举值无效、类型错误)。错误响应体中会指明
source.field
—— 修改
--body-json
/
--query
/
--set
的值即可。

HTTP 429

HTTP 429

Rate limit (default 1200 req/min/key). The error body includes
rate_limit.retry_after
. Back off and retry; don't hammer.
触发速率限制(默认1200请求/分钟/密钥)。错误响应体包含
rate_limit.retry_after
。请等待后重试,不要频繁请求。

unknown command

unknown command

Commands are
<resource> <verb>
. Run
incidentio list <resource>
to see the exact verbs. If you typed just the resource, the CLI suggests its verbs. CRUD verbs are collapsed (
incidents list/create/show/update/delete
); non-CRUD actions keep their name (
incidents edit
,
escalations cancel-escalation
,
catalog-entries bulk-update-entries
).
命令格式为
<resource> <verb>
。执行
incidentio list <resource>
查看该资源支持的具体操作。若仅输入资源名称,CLI会提示支持的操作。CRUD操作会被合并显示(
incidents list/create/show/update/delete
);非CRUD操作保留原名称(
incidents edit
,
escalations cancel-escalation
,
catalog-entries bulk-update-entries
)。

Missing endpoint

缺少端点

The endpoint isn't in the generated catalog. Re-run
bun run codegen
to pick up newly published incident.io endpoints, then rebuild.
该端点未包含在生成的命令目录中。重新执行
bun run codegen
以获取incidentio新发布的端点,然后重新构建。