{"components":{"securitySchemes":{"accountBearer":{"bearerFormat":"JWT","scheme":"bearer","type":"http"}}},"info":{"title":"WideWired ordinary user API","version":"0.1.0"},"openapi":"3.1.0","paths":{"/account/auth/captcha":{"get":{"description":"查询参数 action=access|login|register|reset。客户端计算一次性 SHA-256 工作量证明；stdio 模式自动处理。","operationId":"account_get_7ccac049b999","responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"GET /account/auth/captcha","tags":["account"]}},"/account/auth/login":{"post":{"description":"国际站请求体 {email,password,captcha?}；中文站为 {identifier,password,captcha}。需要 MFA 时返回临时 mfa_token，再调用 mfa/verify。","operationId":"account_post_053cbd2bfa42","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"国际站请求体 {email,password,captcha?}；中文站为 {identifier,password,captcha}。需要 MFA 时返回临时 mfa_token，再调用 mfa/verify。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/login","tags":["account"]}},"/account/auth/logout":{"post":{"description":"请求体 {refresh_token?}。提供刷新凭据才能撤销对应会话族，仅有 Authorization 不会撤销。revoked=false 表示没有匹配的活跃会话族。stdio 自动提交本地保留的刷新凭据，服务确认后清除本地凭据；已有访问凭据按原到期时间失效。","operationId":"account_post_9a191b224d40","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {refresh_token?}。提供刷新凭据才能撤销对应会话族，仅有 Authorization 不会撤销。revoked=false 表示没有匹配的活跃会话族。stdio 自动提交本地保留的刷新凭据，服务确认后清除本地凭据；已有访问凭据按原到期时间失效。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/logout","tags":["account"]}},"/account/auth/mfa/disable":{"post":{"description":"无请求体。需要普通账号及近期密码/MFA 验证；停用 MFA 前征得用户同意。","operationId":"account_post_a598b116ca67","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/auth/mfa/disable","tags":["account"]}},"/account/auth/mfa/enroll":{"post":{"description":"无请求体。需要近期完成验证的普通账号。返回 otpauth_url、base32_secret 和 recovery_codes，私下交给用户完成绑定，再验证 TOTP 验证码。","operationId":"account_post_6729339a477d","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/auth/mfa/enroll","tags":["account"]}},"/account/auth/mfa/recovery/regenerate":{"post":{"description":"无请求体。需要近期验证；旧恢复码失效，新 recovery_codes 应私下交给用户。","operationId":"account_post_3faf34704fe0","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/auth/mfa/recovery/regenerate","tags":["account"]}},"/account/auth/mfa/recovery/verify":{"post":{"description":"请求体 {code,mfa_token}。使用用户提供的一次性恢复码。","operationId":"account_post_ff88e732a855","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {code,mfa_token}。使用用户提供的一次性恢复码。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/mfa/recovery/verify","tags":["account"]}},"/account/auth/mfa/verify":{"post":{"description":"请求体 {code,mfa_token?}。向用户索取 TOTP 验证码；stdio 自动保留待验证的 mfa_token。","operationId":"account_post_7b1cb4557764","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {code,mfa_token?}。向用户索取 TOTP 验证码；stdio 自动保留待验证的 mfa_token。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/mfa/verify","tags":["account"]}},"/account/auth/password/verify":{"post":{"description":"请求体 {password}。敏感安全操作前，重新验证普通账号密码。密码错误返回原始结果，不自动重试。","operationId":"account_post_1f00c9534c2e","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {password}。敏感安全操作前，重新验证普通账号密码。密码错误返回原始结果，不自动重试。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/auth/password/verify","tags":["account"]}},"/account/auth/refresh":{"post":{"description":"请求体 {refresh_token}。轮换普通账号会话；访问和刷新凭据应安全保存在 MCP 宿主内，不在聊天中复述。","operationId":"account_post_e0dccb4af7e0","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {refresh_token}。轮换普通账号会话；访问和刷新凭据应安全保存在 MCP 宿主内，不在聊天中复述。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/refresh","tags":["account"]}},"/account/auth/register/request-code":{"post":{"description":"中文站注册：请求体 {username,password,phone,referral_code?,captcha}。保留返回的 phone_token，向用户索取短信验证码。","operationId":"account_post_667a0185ff6e","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"中文站注册：请求体 {username,password,phone,referral_code?,captcha}。保留返回的 phone_token，向用户索取短信验证码。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/register/request-code","tags":["account"]}},"/account/auth/register/verify":{"post":{"description":"中文站验证：请求体 {phone_token,phone,code}。激活普通账号，返回会话凭据或 MFA 验证要求。","operationId":"account_post_f90e88bc6c4d","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"中文站验证：请求体 {phone_token,phone,code}。激活普通账号，返回会话凭据或 MFA 验证要求。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/register/verify","tags":["account"]}},"/account/auth/reset-confirm":{"post":{"description":"国际站请求体 {email,code,new_password}，中文站为 {identifier,code,new_password}。现有会话将撤销，之后重新登录。","operationId":"account_post_095c11e8a32e","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"国际站请求体 {email,code,new_password}，中文站为 {identifier,code,new_password}。现有会话将撤销，之后重新登录。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/reset-confirm","tags":["account"]}},"/account/auth/reset-request-sms":{"post":{"description":"请求体 {username,phone,captcha}。向用户索取短信中的密码重置验证码。","operationId":"account_post_a2e5cf29957a","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {username,phone,captcha}。向用户索取短信中的密码重置验证码。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"POST /account/auth/reset-request-sms","tags":["account"]}},"/account/me/password":{"post":{"description":"请求体 {current_password,new_password}。修改普通账号密码，遵守现有重新验证和会话撤销规则；密码错误不自动重试。","operationId":"account_post_5a37f4a54cee","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {current_password,new_password}。修改普通账号密码，遵守现有重新验证和会话撤销规则；密码错误不自动重试。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/me/password","tags":["account"]}},"/account/me/profile":{"get":{"description":"无请求体或查询参数。读取当前普通账号资料、验证和 MFA 状态。","operationId":"account_get_d31dd33e99f8","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /account/me/profile","tags":["account"]}},"/account/me/reward-applications":{"post":{"description":"请求体 {campaign_code,title,scenario,content,article_url?,previous_application_id?}。同一次逻辑提交使用相同的 idempotency_key。","operationId":"account_post_5353657f214c","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"请求体 {campaign_code,title,scenario,content,article_url?,previous_application_id?}。同一次逻辑提交使用相同的 idempotency_key。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/me/reward-applications","tags":["account"]}},"/account/me/reward-applications/{application_id}":{"get":{"description":"路径参数 {application_id}；无请求体。读取当前账号拥有的奖励申请。","operationId":"account_get_f5f3cd44717f","parameters":[{"in":"path","name":"application_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /account/me/reward-applications/{application_id}","tags":["account"]}},"/account/me/reward-applications/{application_id}/withdraw":{"post":{"description":"路径参数 {application_id}；无请求体。经用户确认，撤回当前账号待审核的奖励申请。","operationId":"account_post_9c0fcf67147f","parameters":[{"in":"path","name":"application_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /account/me/reward-applications/{application_id}/withdraw","tags":["account"]}},"/account/me/reward-records":{"get":{"description":"无请求体。查询参数 {cursor?,limit?}，读取当前账号的奖励记录。","operationId":"account_get_b2ed60745c11","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /account/me/reward-records","tags":["account"]}},"/account/me/rewards":{"get":{"description":"无请求体。读取当前账号可见的奖励活动、推荐信息与资格。","operationId":"account_get_ba424bbf9ce5","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /account/me/rewards","tags":["account"]}},"/account/public/capabilities":{"get":{"description":"无请求体或查询参数。注册前读取所选站点的认证方式及能力。","operationId":"account_get_d088f1a870d1","responses":{"default":{"description":"Original service status, response and error codes. "}},"summary":"GET /account/public/capabilities","tags":["account"]}},"/billing/me/credit-ledger":{"get":{"description":"无请求体。查询参数 {kind?,cursor?,limit?}，读取已入账积分流水，并跟随返回的游标分页。","operationId":"billing_get_545272293690","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/credit-ledger","tags":["billing"]}},"/billing/me/credits":{"get":{"description":"无请求体或查询参数。读取当前账号已入账积分和余额。","operationId":"billing_get_20493b6ecb69","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/credits","tags":["billing"]}},"/billing/me/purchases":{"get":{"description":"无请求体。查询参数 {cursor?,limit?}，读取已有购买记录；创建订单与支付仅在网页操作。","operationId":"billing_get_6ce37be3d985","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/purchases","tags":["billing"]}},"/billing/me/purchases/{purchase_id}":{"get":{"description":"路径参数 {purchase_id}；无请求体。读取当前账号拥有的购买记录。","operationId":"billing_get_effa482ea9b2","parameters":[{"in":"path","name":"purchase_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/purchases/{purchase_id}","tags":["billing"]}},"/billing/me/rates":{"get":{"description":"无请求体或查询参数。读取当前账号在所选站点的现行客户费率。","operationId":"billing_get_e4ed01510b7f","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/rates","tags":["billing"]}},"/billing/me/usage":{"get":{"description":"无请求体。查询参数 {network_id?,path_id?,cursor?,limit?}，读取已计费的用量记录。","operationId":"billing_get_c5e8cbd986b4","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/usage","tags":["billing"]}},"/billing/me/usage/daily":{"get":{"description":"无请求体。查询参数 {from,to,tz?,network_id?}，from/to 为 Unix 秒，使用服务允许的有限时间窗口。","operationId":"billing_get_9c0a05bfbc95","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/usage/daily","tags":["billing"]}},"/billing/me/usage/links":{"get":{"description":"无请求体。查询参数 {from,to,network_id?,cursor?,limit?}，from/to 为 Unix 秒。","operationId":"billing_get_dff507b7883b","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /billing/me/usage/links","tags":["billing"]}},"/livechat/me":{"get":{"description":"无请求体或查询参数。读取当前普通账号的客服会话及 last_seq。","operationId":"livechat_get_8502af3d6829","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /livechat/me","tags":["livechat"]}},"/livechat/me/attachments":{"post":{"description":"直接 HTTP：multipart/form-data，必填二进制字段 file。MCP call_operation：使用 file {name,data_base64} 参数，无 JSON 请求体；MCP 单附件上限 8 MiB。","operationId":"livechat_post_b2e2028e0ff2","requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","type":"string"}},"required":["file"],"type":"object"}}},"description":"直接 HTTP：multipart/form-data，必填二进制字段 file。MCP call_operation：使用 file {name,data_base64} 参数，无 JSON 请求体；MCP 单附件上限 8 MiB。","required":true},"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /livechat/me/attachments","tags":["livechat"]}},"/livechat/me/attachments/{attachment_id}":{"get":{"description":"路径参数 {attachment_id}；无请求体。下载当前客服会话拥有的附件，返回 data_base64。","operationId":"livechat_get_c1ecbe29343c","parameters":[{"in":"path","name":"attachment_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /livechat/me/attachments/{attachment_id}","tags":["livechat"]}},"/livechat/me/bind":{"post":{"description":"无请求体。绑定此前的访客会话到当前普通账号，仍须满足原服务凭据要求。","operationId":"livechat_post_2ecdbc14e048","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /livechat/me/bind","tags":["livechat"]}},"/livechat/me/events":{"get":{"description":"无请求体。查询参数 {after_seq?}，可选 last_event_id。每次读取一个 SSE 事件块或心跳，从最后的实际事件序号继续查询。","operationId":"livechat_get_853cf3e9ff66","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /livechat/me/events","tags":["livechat"]}},"/livechat/me/messages":{"get":{"description":"GET 查询参数 {after_seq?,before_seq?,limit?}，两个游标只能选一个；POST 请求体 {client_msg_id,text?,attachment_id?}，重试保持相同的 client_msg_id。","operationId":"livechat_get_7c514b558130","responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"GET /livechat/me/messages","tags":["livechat"]},"post":{"description":"GET 查询参数 {after_seq?,before_seq?,limit?}，两个游标只能选一个；POST 请求体 {client_msg_id,text?,attachment_id?}，重试保持相同的 client_msg_id。","operationId":"livechat_post_dd3779516071","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"GET 查询参数 {after_seq?,before_seq?,limit?}，两个游标只能选一个；POST 请求体 {client_msg_id,text?,attachment_id?}，重试保持相同的 client_msg_id。"},"responses":{"default":{"description":"Original service status, response and error codes. "}},"security":[{"accountBearer":[]}],"summary":"POST /livechat/me/messages","tags":["livechat"]}},"/wwnet/app/networks":{"get":{"description":"无 request body。","operationId":"controller_get_093ecd917327","responses":{"default":{"description":"Original service status, response and error codes. 200 OK：\n\n```json\n{ \"data\": [ { \"id\": \"\u003cnetwork_id 12位短码\u003e\", \"name\": \"...\", \"cidr\": \"10.0.0.0/24\", \"role\": \"owner\", \"client_update_policy\": { \"mode\": \"auto\", \"window\": \"all_day\" } } ], \"next_cursor\": \"\", \"has_more\": false }\n```\n\n每个 network 由单一 account 拥有，`role` 恒为 owner。"}},"security":[{"accountBearer":[]}],"summary":"列出当前账号拥有的网络。","tags":["controller"]},"post":{"description":"JSON：name（必填，显示名称）、cidr（必填，合法 Overlay CIDR）。非法输入返回 400 input.invalid_body。","operationId":"controller_post_0e8322b6df12","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：name（必填，显示名称）、cidr（必填，合法 Overlay CIDR）。非法输入返回 400 input.invalid_body。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：\n\n```json\n{ \"data\": { \"id\": \"\u003cnetwork_id 12位短码\u003e\", \"network_id\": \"\u003c同 id\u003e\", \"name\": \"...\" } }\n```\n\n同时写 audit `network.created`。"}},"security":[{"accountBearer":[]}],"summary":"创建 basic network；调用者成为该 network 的 owner。","tags":["controller"]}},"/wwnet/app/networks/{network_id}":{"delete":{"description":"无 request body。","operationId":"controller_delete_01b8c777d285","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { \"id\": \"\u003cnetwork_id 12位短码\u003e\", \"deleted\": true } }`"}},"security":[{"accountBearer":[]}],"summary":"删除网络并移除其设备；保留审计历史和已有财务记录。","tags":["controller"]},"get":{"description":"无 request body。","operationId":"controller_get_b6eed5e4b2c1","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：\n\n```json\n{ \"data\": { \"id\": \"\u003cnetwork_id 12位短码\u003e\", \"name\": \"...\", \"cidr\": \"...\", \"status\": \"active\", \"role\": \"owner\", \"created_at\": 0, \"updated_at\": 0, \"cloud_relay_tuning\": {}, \"client_update_policy\": { \"mode\": \"auto\", \"window\": \"all_day\" } } }\n```\n\n每个 network 由单一 account 拥有，`role` 恒为 owner。"}},"security":[{"accountBearer":[]}],"summary":"读取当前账号拥有的网络。","tags":["controller"]},"post":{"description":"JSON 至少包含一个字段：name（可选，显示名称）；cloud_relay_tuning（可选对象或 null，POP 探测和切换设置，null 恢复默认）；client_update_policy（可选对象，mode=immediate|auto|off，window=all_day|night|weekend_night，按 UTC+0 解释）；reason（更新 client_update_policy 时必填，去除首尾空白后 1..500 字节）。此接口不接受 cidr，传入返回 400 input.invalid_body；修改网段请使用 CIDR preview/apply 流程。","operationId":"controller_post_a0d1b3ef3c24","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON 至少包含一个字段：name（可选，显示名称）；cloud_relay_tuning（可选对象或 null，POP 探测和切换设置，null 恢复默认）；client_update_policy（可选对象，mode=immediate|auto|off，window=all_day|night|weekend_night，按 UTC+0 解释）；reason（更新 client_update_policy 时必填，去除首尾空白后 1..500 字节）。此接口不接受 cidr，传入返回 400 input.invalid_body；修改网段请使用 CIDR preview/apply 流程。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回更新后的 network，包装为 `{ \"data\": { ... } }`。"}},"security":[{"accountBearer":[]}],"summary":"更新 network 的 name / Cloud Relay POP tuning / client update policy 等字段。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/alerts":{"get":{"description":"Query：`state=active|ended|all`（默认 active）、`component=network|device|link|forward`、`q`、`from`/`to`（Unix 秒，按区间重叠取「窗口内存在过」的告警，缺省不限）。不分页：恒返回最近 500 条，`has_more` 表示还有更多但未返回。","operationId":"controller_get_d53ae2bbc94a","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{data:{items:[{id:\"A-1\",kind,component,target_id,target_name,evidence,state,started_at,last_seen_at,ended_at,duration_seconds,closed_at,closed_display,closed_reason}],has_more}}。状态由时间戳体现；恢复时间是观察到告警条件消失的时间。活跃告警总数见 overview。"}},"security":[{"accountBearer":[]}],"summary":"列出网络告警记录，区分手工关闭和实际恢复。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/alerts/{alert_id}":{"get":{"description":"路径 alert_id 为 A-\u003c序号\u003e；不使用列表筛选或时间窗口。","operationId":"controller_get_b6d85ff0ad29","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"alert_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:{id,state,started_at,last_seen_at,ended_at,closed_at,closed_display,closed_reason,...}}`，字段同告警列表条目。"}},"security":[{"accountBearer":[]}],"summary":"按 ID 读取本网络的一条告警，包含已恢复或手工关闭的记录。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/alerts/{alert_id}/close":{"post":{"description":"JSON：`{\"reason\":\"必填关闭原因，1..1000 bytes\"}`。","operationId":"controller_post_81d5aea3972a","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"alert_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：`{\"reason\":\"必填关闭原因，1..1000 bytes\"}`。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:{id,state,started_at,ended_at,closed_at,closed_display,closed_reason,...}}` 返回更新后告警。"}},"security":[{"accountBearer":[]}],"summary":"手工关闭一条告警。关闭只停止待处理提示，不写 ended_at、不伪造实际恢复；重复请求幂等。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/audit":{"get":{"description":"Query：\n\n| 参数 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `range` 之外不接受 `limit` / `before`：端点不分页，恒返回最近 500 条，`has_more` 表示还有更多但未返回，`next_cursor` 恒空 |\n| `range` | string | 否 | 统一相对时间窗：`live`（180 秒）/ `1h` / `12h` / `24h` / `7d`；缺省 / 非法 → `24h` |\n| `event_kind` | string | 否 | 精确匹配事件类型（高级筛选） |\n| `account_id` | uuid | 否 | 精确匹配操作者（高级筛选） |\n| `target_kind` / `target_id` | string/string | 否 | 精确匹配目标对象（高级筛选） |\n| `q` | string | 否 | 搜索 event_kind / target_kind / payload / actor display（高级筛选） |\n\n高级筛选支持 `event_kind` / `account_id` / `target_kind` / `target_id` / `q`；仅 Network owner 可查询与筛选；跨 Network 请求返回 403 `perm.forbidden`。","operationId":"controller_get_b6815e12ca3a","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：\n\n```json\n{ \"data\": [ { \"id\": \"\u003cuuid\u003e\", \"account_id\": \"\u003cuuid\u003e\", \"actor_display\": \"o***@example.com\", \"event_kind\": \"device.approved\", \"target_kind\": \"device\", \"target_id\": \"\u003cdevice_id\u003e\", \"target_name\": \"edge-router\", \"payload\": { ... }, \"created_at\": 0 } ], \"next_cursor\": \"\", \"has_more\": false }\n```"}},"security":[{"accountBearer":[]}],"summary":"查询 network 的审计事件流（不分页，恒返回最近 500 条，倒序；仅 owner 可读）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/audit/export":{"get":{"description":"Query：format=json（默认，NDJSON）|csv；range=live（180 秒）|1h|12h|24h|7d（缺省或非法取 24h）；可选精确筛选 event_kind、account_id（UUID）、target_kind、target_id；q 搜索事件类型、目标、payload 和操作者显示名；limit 默认 5000，上限 10000。仅 owner 可导出。每客户端 IP 每分钟最多 6 次，超限返回 429 rate_limit.exceeded 及 Retry-After。","operationId":"controller_get_2e86a554eae5","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：\n\n- `format=json`：`Content-Type: application/x-ndjson`，每行一个 audit event 对象（结构同 list 的 events 数组元素）\n- `format=csv`：`Content-Type: text/csv` + `Content-Disposition: attachment`，列序：`id, network_id, account_id, actor_display, event_kind, target_kind, target_id, target_name, payload, created_at`\n\n按 `(created_at, id)` 升序输出。"}},"security":[{"accountBearer":[]}],"summary":"导出 network 的审计事件（NDJSON 或 CSV，流式分批生成，最多 10000 条；owner）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/automation-executions/{execution_id}/output":{"get":{"description":"query `stream=stdout|stderr`；可选 `download=true` 返回附件。","operationId":"controller_get_0f54be72b36d","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：原始输出 bytes；默认 `text/plain; charset=utf-8`，`download=true` 时为 `application/octet-stream` 并携带 `Content-Disposition`；输出范围和截断状态由响应头描述。"}},"security":[{"accountBearer":[]}],"summary":"读取或下载 stdout/stderr 捕获内容","tags":["controller"]}},"/wwnet/app/networks/{network_id}/automation-policies":{"get":{"description":"无请求体。使用说明中的路径和查询参数，遵守现有账号归属与权限规则。","operationId":"controller_get_3418a5d59c9d","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：canonical JSON data envelope。"}},"security":[{"accountBearer":[]}],"summary":"列出 Network 内全部设备的生命周期脚本","tags":["controller"]}},"/wwnet/app/networks/{network_id}/billing-rates":{"get":{"description":"路径参数 network_id；无请求体。","operationId":"controller_get_a7b58cb83d15","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK: {data:{rates,bytes_per_gb}}"}},"security":[{"accountBearer":[]}],"summary":"查询当前网络生效的三档云中继费率，不返回价卡名称。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/cidr/apply":{"post":{"description":"JSON：cidr（必填，合法 IPv4 CIDR）、confirm（必填 true，否则 400）、plan_digest（必填，用户确认的预览原值）。预览过期或已使用时返回 409 conflict.state，配置不变；重新 preview 并再次确认后再试。","operationId":"controller_post_bc7ab5a0a32b","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：cidr（必填，合法 IPv4 CIDR）、confirm（必填 true，否则 400）、plan_digest（必填，用户确认的预览原值）。预览过期或已使用时返回 409 conflict.state，配置不变；重新 preview 并再次确认后再试。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{\"data\":{\"current_cidr\":\"10.1.0.0/24\",\"old_cidr\":\"10.0.0.0/24\",\"affected_count\":3,\"keep_count\":1,\"reassign_count\":2,\"devices\":[...]}}。修改全部生效或保持原配置；相同 CIDR 且无需重分配时返回 200 空操作。地址容量不足返回 400。"}},"security":[{"accountBearer":[]}],"summary":"应用已确认的 Overlay CIDR 修改，更新受影响设备的地址。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/cidr/preview":{"post":{"description":"JSON：cidr（必填，合法 IPv4 CIDR）。地址容量不足返回 400。","operationId":"controller_post_defddf4d8231","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：cidr（必填，合法 IPv4 CIDR）。地址容量不足返回 400。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{\"data\":{\"affected_count\":3,\"keep_count\":1,\"reassign_count\":2,\"devices\":[{\"device_id\":\"\u003cuuid\u003e\",\"hostname\":\"t1\",\"current_ip\":\"10.0.0.10\",\"action\":\"reassign\",\"new_ip\":\"10.1.0.10\"}],\"plan_digest\":\"\u003c不透明预览确认值\u003e\"}}。action 为 keep 或 reassign。用户确认后将 plan_digest 原样传给 apply。"}},"security":[{"accountBearer":[]}],"summary":"预览新 Overlay CIDR 下的设备地址变更，不修改配置。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices":{"get":{"description":"无 body。","operationId":"controller_get_555494791ce0","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：设备列表 envelope，包含 id、hostname、alias、platform、agent_version、overlay_ip、public_ip、ipv6_public_ip、status、online、is_peer_relay、direct_transports、last_seen_at。is_peer_relay 表示设备当前是否参与对等中继。"}},"security":[{"accountBearer":[]}],"summary":"按 created_at 倒序列出可见设备，排除正在移除和已经移除的设备。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}":{"delete":{"description":"无 body。","operationId":"controller_delete_f61fcb08b862","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { \"id\": \"\u003cuuid\u003e\", \"removing\": true } }`"}},"security":[{"accountBearer":[]}],"summary":"移除设备。设备立即从列表隐藏，并在收到移除请求后断开网络。","tags":["controller"]},"post":{"description":"`application/json` body（字段均可选，至少提供一个）：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `hostname` | string | 否 | 去首尾空白后至多 255 字节，超长 400；空串清空 |\n| `alias` | string | 否 | 展示别名，空串清空，\u003c= 64 字符 |\n| `overlay_ip` | string | 否 | 手工指定 Overlay IP，须在当前 Overlay CIDR 内且全网唯一 |\n| `direct_transports` | string[] | 否 | `quic` / `tls` 子集，至少一个；默认 `[\"quic\",\"tls\"]` |","operationId":"controller_post_a282ff2184e6","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body（字段均可选，至少提供一个）：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `hostname` | string | 否 | 去首尾空白后至多 255 字节，超长 400；空串清空 |\n| `alias` | string | 否 | 展示别名，空串清空，\u003c= 64 字符 |\n| `overlay_ip` | string | 否 | 手工指定 Overlay IP，须在当前 Overlay CIDR 内且全网唯一 |\n| `direct_transports` | string[] | 否 | `quic` / `tls` 子集，至少一个；默认 `[\"quic\",\"tls\"]` |"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（结构同 list 元素，含更新后的 hostname/alias/overlay_ip/direct_transports）"}},"security":[{"accountBearer":[]}],"summary":"修改设备 hostname / alias / overlay_ip / direct_transports（任意组合）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/approve":{"post":{"description":"无入参。","operationId":"controller_post_e762b3b0e770","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（结构同 list 元素，status 已变为 active）"}},"security":[{"accountBearer":[]}],"summary":"审批 pending 设备进入 active","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/automation-executions":{"get":{"description":"query 可选 `policy_id`、`stage`、`status`、`limit`；limit 默认 50，最大 200。","operationId":"controller_get_e2376ff1c0c6","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:[...],next_cursor:\"\",has_more:\u003cbool\u003e}`；服务端以 limit+1 判定是否仍有执行记录。"}},"security":[{"accountBearer":[]}],"summary":"列出设备的执行记录（含已删除脚本保留的记录，可按脚本/阶段/状态筛选）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/automation-policies":{"post":{"description":"JSON：`stage`、`order_index`（目标位置，越界落到队尾）、`interpreter`、`content`、`timeout_mode`、`timeout_seconds`、`enabled`；设备取自路径。","operationId":"controller_post_85992b2fc2ea","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：`stage`、`order_index`（目标位置，越界落到队尾）、`interpreter`、`content`、`timeout_mode`、`timeout_seconds`、`enabled`；设备取自路径。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：canonical JSON data envelope。"}},"security":[{"accountBearer":[]}],"summary":"在设备的某个生命周期阶段新建脚本（内容内联）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/automation-policies/reorder":{"post":{"description":"JSON：`stage`、`policy_ids`（该阶段当前全部脚本的新顺序）。","operationId":"controller_post_01f0b563ee50","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：`stage`、`policy_ids`（该阶段当前全部脚本的新顺序）。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：canonical JSON data envelope。"}},"security":[{"accountBearer":[]}],"summary":"原子调整设备某阶段的脚本顺序","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/automation-policies/{policy_id}":{"delete":{"description":"无请求体。使用说明中的路径和查询参数，遵守现有账号归属与权限规则。","operationId":"controller_delete_81f81ab62ef5","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"policy_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：canonical JSON data envelope。"}},"security":[{"accountBearer":[]}],"summary":"删除设备脚本但保留执行快照","tags":["controller"]},"post":{"description":"JSON：`interpreter`、`content`、`timeout_mode`、`timeout_seconds`、`enabled`；顺序走 reorder。","operationId":"controller_post_a9737f4f3b48","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"policy_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：`interpreter`、`content`、`timeout_mode`、`timeout_seconds`、`enabled`；顺序走 reorder。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：canonical JSON data envelope。"}},"security":[{"accountBearer":[]}],"summary":"修改设备脚本的解释器、内容、超时与启停（设备与阶段不可变）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/block":{"post":{"description":"可选 `application/json` body：`{ \"reason\": \"...\" }`；reason 会写入审计事件。","operationId":"controller_post_c4ef8a9d93e2","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"可选 `application/json` body：`{ \"reason\": \"...\" }`；reason 会写入审计事件。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（status 已变为 blocked）"}},"security":[{"accountBearer":[]}],"summary":"阻断设备（status=blocked），停止其网络访问；之后可解除阻断。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/details":{"get":{"description":"无 body。","operationId":"controller_get_157a5f8f28cf","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { \"device\": { ...Device }, \"snapshot\": { collected_at, reported_at, summary, forward_health } } }`；forward_health.checked_at 为服务端观察时间，client_checked_at 仅供终端时钟诊断；设备尚未上报时 snapshot 为空。"}},"security":[{"accountBearer":[]}],"summary":"读取设备最新 CPE 管理详情快照，供设备页详情弹窗展示。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/dynamic-domain":{"delete":{"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。","operationId":"controller_delete_3f575149e454","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。"},"responses":{"default":{"description":"Original service status, response and error codes. 200：{data:{device_id,zone,prefix,fqdn,resolution_mode,version,sync_state,records,synced_at,last_error}}。列表使用 list envelope；可用性检查返回 {data:{available}}。last_error 提供服务失败类别，不返回供应商响应正文。"}},"security":[{"accountBearer":[]}],"summary":"解绑动态域名并报告清理状态。","tags":["controller"]},"get":{"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。","operationId":"controller_get_a9982df16b0d","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200：{data:{device_id,zone,prefix,fqdn,resolution_mode,version,sync_state,records,synced_at,last_error}}。列表使用 list envelope；可用性检查返回 {data:{available}}。last_error 提供服务失败类别，不返回供应商响应正文。"}},"security":[{"accountBearer":[]}],"summary":"读取设备动态域名（未绑定为 unbound）","tags":["controller"]},"put":{"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。","operationId":"controller_put_b32791c65d00","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。"},"responses":{"default":{"description":"Original service status, response and error codes. 200：{data:{device_id,zone,prefix,fqdn,resolution_mode,version,sync_state,records,synced_at,last_error}}。列表使用 list envelope；可用性检查返回 {data:{available}}。last_error 提供服务失败类别，不返回供应商响应正文。"}},"security":[{"accountBearer":[]}],"summary":"绑定域名或保存解析方式；DNS 失败保留同步状态","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/forward-policy":{"get":{"description":"无入参。","operationId":"controller_get_7d80b845ca86","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { device_id, policy_format, policy?, legacy_policy?, dns_hijack_enabled, content_hash, updated_at } }`。管理模型 `{dns:{servers,default_server},l3:{include,exclude},l7:[{id,name?,match:{src_cidr?,dst_cidr?,dst_domain?},dns_server?,action}]}`；`dst_domain` 同时匹配连接域名和 DNS 映射域名（并集），L3 的 `name` 仅作管理标识。L3 `dst_rule_set` 使用自包含 https 来源 URL（`.srs` 或 `.mmdb#\u003c两位国家码\u003e`）。`policy_format=editor-v2` 返回管理 `policy`；旧版非空 DNS/域名策略返回 `policy_format=execution-v1` 与只读 `legacy_policy`，继续按原执行规则下发，保留 AND 条件、AAAA、规则集和凭据绑定。L7 `upstream_socks` 只回 `{addr, username, password_set}`，密码 write-only。"}},"security":[{"accountBearer":[]}],"summary":"读取设备转发策略（从未保存过时返回缺省空策略）","tags":["controller"]},"put":{"description":"`application/json` body：整份 ForwardPolicy，另可带顶层 `expected_content_hash`（乐观并发前提：最近读取的 content_hash，从未保存过为空串；Website 恒带）。管理模型 `{dns:{servers,default_server},l3:{include,exclude},l7:[{id,name?,match:{src_cidr?,dst_cidr?,dst_domain?},dns_server?,action}]}`；`dst_domain` 同时匹配连接域名和 DNS 映射域名（并集），L3 的 `name` 仅作管理标识。L3 `dst_rule_set` 使用自包含 https 来源 URL（`.srs` 或 `.mmdb#\u003c两位国家码\u003e`）。旧版 execution-v1 策略不允许被当前编辑器替换（400，issue code `legacy_read_only`），防止条件丢失。L7 exit 动作的 `upstream_socks.password` 省略=保留同一规则 ID 的原值（addr / username / exit 变化时须重新输入，否则 `password_required`）、显式空串=清除；`addr` 置空=移除上游并清空凭据；可回传读取得到的 `password_set`（忽略）。","operationId":"controller_put_54066c34f816","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：整份 ForwardPolicy，另可带顶层 `expected_content_hash`（乐观并发前提：最近读取的 content_hash，从未保存过为空串；Website 恒带）。管理模型 `{dns:{servers,default_server},l3:{include,exclude},l7:[{id,name?,match:{src_cidr?,dst_cidr?,dst_domain?},dns_server?,action}]}`；`dst_domain` 同时匹配连接域名和 DNS 映射域名（并集），L3 的 `name` 仅作管理标识。L3 `dst_rule_set` 使用自包含 https 来源 URL（`.srs` 或 `.mmdb#\u003c两位国家码\u003e`）。旧版 execution-v1 策略不允许被当前编辑器替换（400，issue code `legacy_read_only`），防止条件丢失。L7 exit 动作的 `upstream_socks.password` 省略=保留同一规则 ID 的原值（addr / username / exit 变化时须重新输入，否则 `password_required`）、显式空串=清除；`addr` 置空=移除上游并清空凭据；可回传读取得到的 `password_set`（忽略）。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：替换后文档，形状同 GET；内容不变时返回原文档。expected_content_hash 过期返回 409 conflict.version，并给出 error.details.current_content_hash。非法输入返回 400 input.invalid_body；配额或配置大小超限返回 429 quota.exceeded。error.details.issues 为 [{path,code,message}]，如 exit_not_found、exit_platform_unsupported、password_required、payload_budget_exceeded；大小超限还提供 error.details.affected_exit_device_ids。"}},"security":[{"accountBearer":[]}],"summary":"整份替换设备转发策略并重算 exit 标志（审计 forward_policy.updated）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/forward-policy/preview":{"post":{"description":"`application/json` body：同整份替换（`expected_content_hash` 被忽略）。","operationId":"controller_post_b4ae40639ab6","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：同整份替换（`expected_content_hash` 被忽略）。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { issues:[{path,code,message}], unreachable_rules:[{rule_id,reason}], site_route_overlaps:[{rule_id,dst_cidr,site_prefix}], dangling_exits:[{path,exit_device_id}], dns_src_not_captured:[{rule_id,src_cidr}], platform_unsupported:[{path,code,message}] } }`；`issues` 非空时整份替换会被拒绝，其余为 warning。"}},"security":[{"accountBearer":[]}],"summary":"干跑设备转发策略：校验问题（含下发预算）、不可达规则、站点前缀重叠、悬空 exit、未捕获的 DNS 源与平台不支持项（不写库）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/peer-relay/disable":{"post":{"description":"`application/json` body：`{ \"reason\": \"\u003c0..500 bytes 的操作原因\u003e\" }`。","operationId":"controller_post_e9471ea30cf8","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：`{ \"reason\": \"\u003c0..500 bytes 的操作原因\u003e\" }`。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（结构同 list 元素；enable=false 后 is_peer_relay = enable AND eligible 必为 false）"}},"security":[{"accountBearer":[]}],"summary":"关闭设备的对等中继参与。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/peer-relay/enable":{"post":{"description":"`application/json` body：`{ \"reason\": \"\u003c0..500 bytes 的操作原因\u003e\" }`。","operationId":"controller_post_3788bdf118f2","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：`{ \"reason\": \"\u003c0..500 bytes 的操作原因\u003e\" }`。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（结构同 list 元素；is_peer_relay = enable AND eligible，即开关已开且控制器派生 eligible 时为 true）"}},"security":[{"accountBearer":[]}],"summary":"在设备符合条件时启用对等中继参与。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/static-routes":{"post":{"description":"JSON：canonical IPv4 prefix、IPv4 next_hop；advertise 可选且默认 true。","operationId":"controller_post_ba47404c3268","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：canonical IPv4 prefix、IPv4 next_hop；advertise 可选且默认 true。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：新建路由；通告在 owner readiness 成功前保持无效。"}},"security":[{"accountBearer":[]}],"summary":"为 active Linux/OpenWrt 设备创建 IPv4 静态站点路由（设备取自路径）","tags":["controller"]},"put":{"description":"JSON：expected_routes 为草稿基于的配置列表（id/prefix/next_hop/advertise）；routes 为完整目标列表，新条目省略 id。两数组均必填，可为空。运行态字段不参与并发校验。","operationId":"controller_put_c11fd08bb7b2","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：expected_routes 为草稿基于的配置列表（id/prefix/next_hop/advertise）；routes 为完整目标列表，新条目省略 id。两数组均必填，可为空。运行态字段不参与并发校验。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：设备路由数组。全部修改一并生效；冲突或失败时保持原路由。"}},"security":[{"accountBearer":[]}],"summary":"原子替换设备的全部静态站点路由","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/static-routes/{route_id}":{"delete":{"description":"无入参。","operationId":"controller_delete_4ad9b8ac5f75","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"route_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：删除确认。"}},"security":[{"accountBearer":[]}],"summary":"软删除设备的静态站点路由并立即撤回有效通告","tags":["controller"]},"post":{"description":"JSON：prefix、next_hop、advertise 至少一项。","operationId":"controller_post_df5578784dc3","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"route_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON：prefix、next_hop、advertise 至少一项。"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：更新后的路由。"}},"security":[{"accountBearer":[]}],"summary":"修改设备的静态站点路由并撤回旧 readiness（归属设备不可变）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/devices/{device_id}/unblock":{"post":{"description":"无入参。","operationId":"controller_post_15df027d7214","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"device_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：返回完整 Device 对象，包装为 `{ \"data\": { ... } }`（status 已变回 active）"}},"security":[{"accountBearer":[]}],"summary":"放行被阻断的设备（status: blocked → active；block 的逆操作）。blocked 不占 device_limit，放行前按 device_limit 门控（active 已满返回 quota.exceeded）。peer relay 能力不自动恢复，需单独再启用。审计 device.unblocked。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/diagnostics/coverage":{"post":{"description":"同query时间与过滤参数，不使用cursor。","operationId":"controller_post_3b6018b33019","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"同query时间与过滤参数，不使用cursor。"},"responses":{"default":{"description":"Original service status, response and error codes. rows,row_limit,truncated；实际报告数、peer方向覆盖、版本及漏报计数。"}},"security":[{"accountBearer":[]}],"summary":"汇总诊断报告覆盖情况。缺少报告不代表健康。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/diagnostics/query":{"post":{"description":"session_id,from/to Unix毫秒(最大24h),可选device_id/peer_device_id/cursor。","operationId":"controller_post_4d9167c2ce86","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"session_id,from/to Unix毫秒(最大24h),可选device_id/peer_device_id/cursor。"},"responses":{"default":{"description":"Original service status, response and error codes. 报告每页最多50条，has_more/next_cursor；payload为专用Snapshot JSON。"}},"security":[{"accountBearer":[]}],"summary":"Agent连通性诊断固定查询，network/session/time范围强制绑定，稳定游标分页。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/diagnostics/sessions":{"get":{"description":"sessions无body。","operationId":"controller_get_d64c9d1f8e5d","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 模式、最近7天最多100个会话及当前设备清单；诊断协议版本null=未知、0=旧客户端，明确inventory_truncated。"}},"security":[{"accountBearer":[]}],"summary":"Agent诊断会话及网络模式，最多最近7天100条。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/dynamic-domains":{"get":{"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。","operationId":"controller_get_80d6989dad34","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200：{data:{device_id,zone,prefix,fqdn,resolution_mode,version,sync_state,records,synced_at,last_error}}。列表使用 list envelope；可用性检查返回 {data:{available}}。last_error 提供服务失败类别，不返回供应商响应正文。"}},"security":[{"accountBearer":[]}],"summary":"列出设备动态域名","tags":["controller"]}},"/wwnet/app/networks/{network_id}/dynamic-domains/check":{"post":{"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。","operationId":"controller_post_7faaf404635c","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"check: {zone,prefix}; PUT: {zone,prefix,resolution_mode,expected_version}; DELETE: {expected_version}。名称固定，换名先解绑。"},"responses":{"default":{"description":"Original service status, response and error codes. 200：{data:{device_id,zone,prefix,fqdn,resolution_mode,version,sync_state,records,synced_at,last_error}}。列表使用 list envelope；可用性检查返回 {data:{available}}。last_error 提供服务失败类别，不返回供应商响应正文。"}},"security":[{"accountBearer":[]}],"summary":"检测域名可用性（不预占）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/events":{"get":{"description":"无 body。使用用户 Bearer JWT；Network owner 可读。","operationId":"controller_get_85eca025e45e","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK text/event-stream：连接后发送 baseline；资源变更时发送 invalidate {resources:[...]}；每 15 秒心跳。不晚于访问凭据过期或 25–30 分钟后发送 bye，使用有效凭据重连。"}},"security":[{"accountBearer":[]}],"summary":"通过 SSE 接收网络变更通知；使用对应 HTTP 接口读取最新业务数据。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/forward-policies":{"get":{"description":"无入参。","operationId":"controller_get_59d715f10684","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:[{device_id,dns_servers,dns_rules,l3_include,l3_exclude,l7_rules,content_hash,updated_at}],next_cursor:\"\",has_more:false}`；从未保存过的设备不出现，等价于全 0 的缺省空策略。"}},"security":[{"accountBearer":[]}],"summary":"列出 Network 内各设备已保存转发策略的条目计数（供转发列表按设备汇总）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/links":{"get":{"description":"无入参。","operationId":"controller_get_3fd7627ce216","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{\"data\":[{\"id\":\"\u003cuuid\u003e\",\"device_a_id\":\"\u003cuuid\u003e\",\"device_b_id\":\"\u003cuuid\u003e\",\"device_a_hostname\":\"...\",\"device_b_hostname\":\"...\",\"path_policy\":{...},\"cloud_relay_schedule\":null}],\"next_cursor\":\"\",\"has_more\":false}。hostname 标识两端设备；链路自动管理，本接口只读。"}},"security":[{"accountBearer":[]}],"summary":"列出 network 的 Device Link（按 created_at、id 倒序；含两端 hostname、路径策略与 Credit 门控状态）","tags":["controller"]}},"/wwnet/app/networks/{network_id}/links/{link_id}/path-policy":{"get":{"description":"无入参。","operationId":"controller_get_427a01582b1d","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"link_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { \"policy\": { \"enabled_transports\": [\"direct\",\"peer_relay\",\"cloud_relay\"], \"strategy\": \"balanced\" }, \"schedule\": null } }`。`schedule=null` 表示云端中继全天可用。Link 不存在、不属于该 Network 或 `link_id` 不是 UUID 返回 404。"}},"security":[{"accountBearer":[]}],"summary":"读取该 Link 独立的传输方式、切换敏感度参数和云端中继工作时段","tags":["controller"]},"post":{"description":"`application/json` body：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `policy` | object | 是 | 至少启用一种 direct/peer_relay/cloud_relay，strategy 选择 conservative/balanced/aggressive |\n| `schedule` | object\\|null | 是 | 云端中继允许窗口；null=全天可用 |\n","operationId":"controller_post_3e12bdac931f","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"link_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `policy` | object | 是 | 至少启用一种 direct/peer_relay/cloud_relay，strategy 选择 conservative/balanced/aggressive |\n| `schedule` | object\\|null | 是 | 云端中继允许窗口；null=全天可用 |\n"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：回显完整策略。非法传输方式、重复方式、非法 strategy、非法时区或窗口返回 400；Link 不存在、不属于该 Network 或 `link_id` 不是 UUID 返回 404。"}},"security":[{"accountBearer":[]}],"summary":"原子设置该 Link 的传输方式、切换敏感度参数和云端中继工作时段","tags":["controller"]}},"/wwnet/app/networks/{network_id}/observe/quality/links/{link_id}":{"get":{"description":"Path `link_id` 必须为当前 network 的 Link UUID。Query `from` / `to` 为 Unix 毫秒，`step` 为秒；最大 7d。","operationId":"controller_get_fcf8e224e76e","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"link_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{data:{trend:[{bucket_micros,src_device_id,dst_device_id,avg_rtt,avg_loss,samples,rtt_samples,loss_samples,last_observed_at_micros,last_rtt_at_micros}],directions:[{src_device_id,dst_device_id,samples,rtt_samples,loss_samples,last_observed_at_micros}],time_range:{from,to,step}}}。历史采样缺失时仍描述两个方向；没有 RTT 时也可显示 100% 丢包。"}},"security":[{"accountBearer":[]}],"summary":"质量诊断单链路趋势：固定返回链路两个方向的采样状态；RTT 与丢包使用各自的可靠样本计数。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/observe/quality/links/{link_id}/transitions":{"get":{"description":"Path `link_id` 必须为当前 network 的 Link UUID。Query `from` / `to` 为 Unix 毫秒，`step` 为聚合秒数；最大 7d。","operationId":"controller_get_a7ac218ff5b6","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"link_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:{events:[...],markers:[...],time_range:{from,to,step},truncated:false,oldest_event_at_micros}}`。events 按事件时间和 transition_id 倒序，markers 覆盖完整 time_range。"}},"security":[{"accountBearer":[]}],"summary":"质量诊断单链路选路事件：返回完整时间范围的聚合标记与最近 100 条事件。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/observe/quality/overview":{"get":{"description":"Query：`from` / `to` 为 Unix 毫秒；最大 7d。省略时默认最近 24h。","operationId":"controller_get_95754efd49f6","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{data:{rows:[{link_id,src_device_id,dst_device_id,avg_rtt,avg_loss,max_loss,samples,last_observed_at_micros,transition_count}],truncated:false}}`。每行保留方向；达到容量上限时返回可用前缀并显式设置 `truncated=true`。"}},"security":[{"accountBearer":[]}],"summary":"质量诊断链路索引：按双向链路汇总质量与路径切换计数。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/observe/traffic":{"post":{"description":"`application/json` body：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `from` / `to` | int64 | 否 | Unix 毫秒，须同时提供；最大跨度 7d |\n| `source` | string | 是 | 站点对的第一端设备 UUID |\n| `destination` | string | 是 | 站点对的第二端设备 UUID；与 source 不得相同 |","operationId":"controller_post_6959df767fad","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"`application/json` body：\n\n| 字段 | 类型 | 必填 | 说明 |\n| --- | --- | --- | --- |\n| `from` / `to` | int64 | 否 | Unix 毫秒，须同时提供；最大跨度 7d |\n| `source` | string | 是 | 站点对的第一端设备 UUID |\n| `destination` | string | 是 | 站点对的第二端设备 UUID；与 source 不得相同 |"},"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：`{ \"data\": { \"bytes_top\": [{ \"src_device_id\", \"src_ip\", \"dst_ip\", \"dst_port\", \"protocol\", \"dst_device_id\", \"path_type\", \"transport\", \"bytes\", \"packets\", \"flow_count\" }], \"trend\": [{ \"bucket_micros\", \"src_device_id\", \"dst_device_id\", \"bps\" }], \"detail\": [{ \"src_device_id\", \"src_ip\", \"src_port\", \"dst_ip\", \"dst_port\", \"protocol\", \"dst_device_id\", \"path_type\", \"transport\", \"bytes\", \"packets\", \"flow_count\" }], \"last_observed_at\", \"time_range\" } }`。\n\n`bytes_top` 先按源设备、源 IP、目的 IP、目的端口与协议合并全部路径，再截取 Top 10；跨路径的 path_type / transport 返回 mixed。`trend.bps` 是两个方向各自的原生一分钟流量增量换算值，不合并双向数据。`detail` 合并双向记录后按流量降序返回最多 100 行且不分页。observe 未启用 / 不可达 → 503 `service.unavailable`。"}},"security":[{"accountBearer":[]}],"summary":"洞察 · 流量查询：按必选站点对返回双方向一分钟带宽趋势、流量 Top 10 与最多 100 条五元组明细。本端不做 DPI / application 识别。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/overview":{"get":{"description":"无 body 或 query。实时数据采用最近 6 分钟内的最新样本，不支持历史 range。","operationId":"controller_get_9f411012ddc4","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：{data:{source_states,network_status,summaries:{links,devices,channels,traffic_24h},topology:{devices,links,total_devices,total_links,returned_links,truncated,mode},alerts:{active_total}}}。配置读取失败返回 5xx；监测数据失败时仍返回 200，对应来源标为 unavailable，并保留配置拓扑。两个方向路径不同时，链路 path_type=mixed。"}},"security":[{"accountBearer":[]}],"summary":"网络运行总览：同一读取时刻下返回控制面摘要、当前链路拓扑、24H 流量与当前告警数量。告警明细由独立告警 API 提供。","tags":["controller"]}},"/wwnet/app/networks/{network_id}/static-routes":{"get":{"description":"无入参。","operationId":"controller_get_f7b7ce85fbea","parameters":[{"in":"path","name":"network_id","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK：路由列表，含配置值、effective_advertise/readiness 原因与 owner routing_health（status/hash/reason/stale）。"}},"security":[{"accountBearer":[]}],"summary":"列出 Network 的 Linux/OpenWrt owner 静态站点路由","tags":["controller"]}},"/wwnet/install/install.ps1":{"get":{"description":"无。","operationId":"controller_get_cb0e9a8fc85a","responses":{"default":{"description":"Original service status, response and error codes. 200 OK 脚本文本；`Cache-Control: no-store`。"}},"summary":"返回 Windows 安装脚本","tags":["controller"]}},"/wwnet/install/install.sh":{"get":{"description":"无。","operationId":"controller_get_2981d72093ac","responses":{"default":{"description":"Original service status, response and error codes. 200 OK 脚本文本；`Cache-Control: no-store`。"}},"summary":"返回 Linux 安装脚本","tags":["controller"]}},"/wwnet/install/join/{artifact}":{"get":{"description":"路径：`/wwnet/install/join/{12-char-network_id}.{sh,ps1}`。 MCP path argument: artifact={network_id}.sh or {network_id}.ps1.","operationId":"controller_get_d9426d2322f8","parameters":[{"in":"path","name":"artifact","required":true,"schema":{"type":"string"}}],"responses":{"default":{"description":"Original service status, response and error codes. 200 OK 脚本文本；network_id 格式不合法返回 404。"}},"summary":"按 network_id 生成入网 one-liner","tags":["controller"]}},"/wwnet/install/uninstall.ps1":{"get":{"description":"无。","operationId":"controller_get_56ef71627dd6","responses":{"default":{"description":"Original service status, response and error codes. 200 OK 脚本文本；`Cache-Control: no-store`。"}},"summary":"返回 Windows 卸载脚本","tags":["controller"]}},"/wwnet/install/uninstall.sh":{"get":{"description":"无。","operationId":"controller_get_0a474a275d58","responses":{"default":{"description":"Original service status, response and error codes. 200 OK 脚本文本；`Cache-Control: no-store`。"}},"summary":"返回 Linux 卸载脚本","tags":["controller"]}}},"servers":[{"url":"https://www-api.widewired.com.cn"}]}
