权限
read — 只读;read write — 读取与管理。API 客户端由已登录用户管理。财务角色可以查看发票和订阅,但看不到员工和网络。
通过公司后台所用的同一套 API 管理公司、成员、VPN 访问权限和路由。
首个版本:当前契约中的 169 个方法——而不是 191 项需求中完成了 169 项。草案使用不同的路径和流程。首个版本完整矩阵:SSO/SCIM、所有权转移、路由器固件部署、配置导出以及发票法律信息不在范围内。notification-channels 仅为旧版清单:其契约以及 email/webhook/in_app 投递不在首个版本中。监控、审计和 API 中提供七种告警类型;通过独立的签名 webhooks API 投递仍在范围内。路由器和资源目前只是清单;billing-profile 只存储元数据,与发票无关联。
基础路径:https://api.meduzavpn.com/api/business/v1。界面使用当前用户会话。如需自动化,请在公司后台创建 API 客户端,并在发放时保存密钥。
curl -X POST https://api.meduzavpn.com/api/business/v1/oauth/token \ -d grant_type=client_credentials \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_SECRET curl https://api.meduzavpn.com/api/business/v1/organizations/ORGANIZATION_ID/members \ -H "Authorization: Bearer TOKEN"
将获得的令牌放在 Authorization: Bearer TOKEN 中传递。令牌有效期为一小时,且仅在发放该客户端的公司内有效。客户端被停用,或创建它的管理员失去权限时,访问即被撤销。
read — 只读;read write — 读取与管理。API 客户端由已登录用户管理。财务角色可以查看发票和订阅,但看不到员工和网络。
修改操作请使用 Idempotency-Key。编辑时请带上对象当前版本的 If-Match: "3"。遇到 412 冲突时请重新读取对象。
POST /organizations 创建公司。subscription/quotes 获取报价:VPN 数量、周期以及 purchase、renewal 或 upgrade 操作。quote_id 和 payment_method: stripe_card 传给 subscription/checkout。invoices,直到出现 payment_url,然后通过该链接付款。catalog/vpn-locations 中的 pricing_id 并附带必填的 Idempotency-Key 创建 VPN。套餐 5 台 VPN 起。每台 VPN 基础价格:每月 $5.99 或每年 $54.99。套餐折扣:5–9 台 — 5%,10–99 台 — 10%,100 台及以上 — 20%。付款后返回浏览器并不会在未核实付款的情况下开通访问。
续费保持数量和周期不变。扩容套餐会按剩余期限计算补差价。要永久删除服务器,请使用 POST /organizations/{organization_id}/vpns/{id}/retire,并附带 confirm: true 和 If-Match。删除确认后名额释放,订阅价格不变。分配给员工时传入 member_id;不传则 VPN 按访问分配供公司使用。
公司 VPN 的可用范围由 PATCH /organizations/{organization_id}/vpns/{id} 中的 access 字段决定,请求需带 If-Match。company 向角色允许连接的所有公司成员开放,member_ids 和 group_ids 列表会被清空。restricted 仅限列出的员工和列出的分组成员;列表为空表示所有人都无法访问。company 与非空列表同时提交会以 422 拒绝。GET 响应和 /me/vpn-grants 始终包含 data.access,字段出现之前创建的 VPN 也不例外。未带 access 但带有 member_ids 或 group_ids 的请求与以前一样,会把 VPN 切换为 restricted。员工专用 VPN 始终为 restricted。模式变更会以 vpn_access_changed 记入审计;收窄访问时,失去访问权限的设备凭据会被吊销。
curl -X PATCH https://api.meduzavpn.com/api/business/v1/organizations/ORGANIZATION_ID/vpns/VPN_ID \
-H "Authorization: Bearer TOKEN" \
-H 'If-Match: "3"' \
-H "Idempotency-Key: vpn-access-1" \
-H "Content-Type: application/json" \
-d '{"access":"company"}'流量集描述网站或网络,规则选择动作:指定 VPN、直连或屏蔽。国家和地区请使用 catalog/traffic-presets 中的值。在 first-match 模式下,规则自上而下检查,最多 128 条;“其余流量”不能设为屏蔽。
保存会生成草稿。先执行校验,再带 If-Match 发布。请检查 policy-deployments:进入队列与设备确认已应用是不同的状态。连接 VPN 由客户端应用完成。
GET /organizations/{id}/roles 返回内置角色和自定义角色、权限定义以及 can_manage 标志。所有者可基于管理员、员工或财务角色创建自定义角色,只保留所需权限。通过 PATCH members/{id} 分配:role 和 custom_role_id。权限变更同样作用于该用户创建的 API 客户端。
角色决定后台中可执行的操作。group_ids 为员工分配 VPN 和路由套餐;加入分组不会获得管理权限。所有者角色不能复制为自定义角色。已分配给员工的角色不能删除。
设备拥有 display_name、所属人和 VPN 信息。PATCH devices/{id} 只修改名称,并校验 If-Match。POST devices/{id}/revocations 请求撤销;最终状态由节点确认。自己的设备可通过 /me/devices 查看。last_api_ip 字段是 API 传输地址,而不是 VPN 连接地址。应用上报的名称和型号不用于授权。
GET /organizations/{id}/employee-analytics 显示观测到的连接、状态变化以及 7 天内的逐小时历史。缺失的测量不会以零代替;会话数量不等于员工的工作时间。
GET /organizations/{id}/activity 返回节点记录的连接请求:请求的域名或 IP、端口、协议、时间、处理结果、设备和员工。筛选:from、to、member_id、action、search;分页:cursor 和 limit。域名来自客户端在连接请求中提交的信息,而非解密 HTTPS 获得。
默认不收集。所有者通过 PATCH 修改 activity-settings,附带 {"enabled": true} 和 If-Match。读取需要 activity.read。开启收集后,应用会向员工显示通知;发放密钥前需核实密钥所属人,并要求最新的 X-Corporate-Activity-Version 确认。旧版客户端在此模式下无法获得密钥。
存储上限为每家公司 7 天、100,000 条事件;节点缓冲最多保存 24 小时。coverage 报告数据新鲜度、不可达设备和缓冲丢失情况。个人 VPN、设备直连流量、到达节点前的本地屏蔽、HTTPS 路径、请求内容和效率评分均不记录。关闭收集不会恢复缺失的历史,也不会立即删除已收集的记录:仍按保存期限处理。
日志响应包含 analysis:按分类、员工和小时的分布、主要目标以及 active_minutes 数量。汇总基于所选时段内保存的全部事件计算,与原始日志的分页无关。使用 category 筛选可查看具体事件。
一个活跃分钟是指节点观测到请求的某位员工的唯一一分钟。它不是浏览网站或工作的时长:后台流量也会计入,且同一分钟内分类可能重叠。总时长单独计算,并非各分类之和。
所有者可在日志设置中定义最多 64 条 classification_rules 规则:域名和分类。规则同样适用于子域名,并优先于内置目录。未知目标归入单独的分类。当前规则会对整个所选时段进行分类;响应中会注明分类版本。
处理的是公司连接的目标,而不是 HTTPS 内容、完整 URL 或个人流量。通知确认在公司内每位员工只保存一次;修改分类、分组或收集模式无需再次确认同一通知。覆盖不完整标志和 truncated 不应被理解为没有活动。
创建 webhooks,使用 443 端口上的公网 HTTPS URL,并订阅 audit.event、* 或 groups.created、members.updated 等资源变更事件。密钥仅在创建或轮换时显示。
Meduza-Signature: t=UNIX_SECONDS,v1=HEX_SIGNATURE Meduza-Event-Id: EVENT_ID Meduza-Delivery-Id: DELIVERY_ID HEX_SIGNATURE = HMAC-SHA256(secret, timestamp + "." + RAW_JSON_BODY)
请基于请求体原始字节校验签名,并检查 timestamp 的允许时长和 event ID 是否重复。轮换期间,请为已入队的事件保留旧密钥。任何 2xx 都视为成功;其他响应会以递增间隔重试,最多八次。历史记录和手动重发可通过 deliveries 使用。成功和已取消的投递最多保存 30 天,每个 webhook 最多 2,000 条。队列和失败记录上限为 1,000 条事件;溢出时丢弃最旧的事件,并由 dropped_deliveries 计数器报告丢失。此时请通过 API 同步状态。
投递保证至少一次。除通过 API 进行的变更外,还会发送已确认的发票变更(invoices.updated)、订阅变更(subscriptions.updated)、VPN 就绪状态(vpns.updated)和告警(alerts.created)。状态未变时重复轮询不会产生新事件。这不是网络流量数据流。禁止使用私有 IP、重定向以及访问内部服务。
正在加载契约…
对于清单类列表,请传入 limit=1..200,再保持其他参数不变,传入 next_cursor 中的 cursor。不带 limit/cursor 时,旧客户端会得到完整列表:数据绝不会被悄悄截断。可用筛选:status、member_id、user_id、vpn_id、search 以及 created_from/created_to(RFC3339,下界包含,上界不包含)。访问权限在筛选前和每一页都会检查。未知或重复的参数返回 422。活动日志列表使用单独的契约。各方法的参数。
管理审计最多保存 90 天,每家公司最多保留最近 10,000 条事件;过期的幂等记录会被清理。此清理不会删除发票和订阅。清单类列表返回 items、total 和 next_cursor;显式传入 limit/cursor 时才会出现后续页。不传时,完整响应与旧客户端保持兼容。activity 日志单独支持游标和文档中列出的筛选。来自幂等缓存的响应不会重复返回密钥。密钥撤销的确认来自 VPN 服务器;停用成员资格会立即禁止新的发放。
监控显示实际的连接和负载。目标历史通过需显式开启的独立日志提供。HTTPS 内容和员工效率评分不包含在这些数据中。SSO/SCIM 以及扩展草案中的其他方法不属于本已实现契约。
管理类错误返回 application/problem+json,包含 status、detail 和 request_id。OAuth 令牌发放错误使用 error 字段。