集体台中的 API v2

集体台中的 API v2(API v2 in Clubstations)

目录

一个集体台可以让多名操作员共用一个集体呼号或特殊呼号。API v2 支持这一点,但在集体台会话中创建的令牌与个人令牌行为不同——它绑定到该成员在集体台中所持有的权限级别。

注意

这些内容都不适用于个人令牌;当实例关闭了集体台功能(special_callsign)时,这些内容也完全不起作用。如果你只使用自己的账户,可以跳过本页。

个人令牌与集体台令牌

每个令牌都会记录两个用户:

个人令牌 集体台令牌
所有者(令牌能访问谁的数据) 你 集体台
创建者(通过令牌行事的人) 你 创建它的那名成员

创建集体台令牌的方法是:在 Web 界面中切换到该集体台,然后像平常一样在 API 页面生成令牌。令牌能访问的一切都属于集体台;它写入的一切都归到该成员名下。

可以用 令牌 资源来区分两者——对于集体台令牌,owner 是集体台的呼号:

curl https://<WAVELOG_URL>/index.php/api/v2/token \
     -H "Authorization: Bearer wl2_your_token_here"

权限级别

级别在集体台的权限页面上按成员设置,并且在每一次 API 请求时都会重新读取——更改会立即生效,无需重新创建令牌。

级别 名称 通过 API
3 集体台成员 记录并管理自己的 QSO;读取台站位置
6 集体台成员 ADIF 与级别 3 相同(额外的 ADIF 权限只是界面上的区分)
9 集体台干事 可无限制访问整个集体台日志

API 对级别 3 和级别 6 的处理完全相同。它们在 Web 界面中的差别在于成员可以打开哪些 ADIF 页面;通过 API 访问时,两者都只是「非干事」。

注意(Wavelog 管理员)

Wavelog 管理员创建的集体台令牌,即使他们本人在该集体台上没有任何权限级别也能使用——他们会被视为干事,就像 Web 界面允许他们管理每个集体台一样。若管理员确实有明确的级别,则按该级别处理,因此把自己设为集体台成员仍然是有意义的。

低于干事级别的成员可以做什么

仅限自己的 QSO

对于级别 3 和 6,每个 QSO 操作都限定在该成员自己的呼号(OPERATOR)范围内:

  • GET /api/v2/qso 只列出他们的 QSO。meta.total 也只统计这些。
  • GET /api/v2/qso?format=adif 导出的正好是同一集合——格式不会扩大结果范围。
  • 对属于其他操作员的 QSO 执行 GET、PATCH 和 DELETE(路径 /api/v2/qso/{id})会返回 404 not_found,而不是 403。令牌看不到的 QSO 会被报告为仿佛并不存在,而不是确认其存在。

干事可以看到并编辑每个操作员的 QSO。

操作员是被指定的,而非可选

当成员创建 QSO 时,operator 始终被设置为其自己的呼号。发送其他值不会有效果——该值会被覆盖,三种创建路径(单条 JSON、批量 qsos[] 和 import_type=adif)都是如此:

# Sent by a level-3 member of HB9CLUB whose own callsign is HB9ABC
curl -X POST https://<WAVELOG_URL>/index.php/api/v2/qso \
     -H "Authorization: Bearer wl2_club_token" \
     -H "Content-Type: application/json" \
     -d '{"station_profile_id": 4, "call": "N9EAT", "band": "20m",
          "mode": "SSB", "qso_date": "2026-06-16", "time_on": "1706",
          "operator": "HB9XYZ"}'
# -> the QSO is stored with OPERATOR = HB9ABC

干事可以自由设置 operator,这正是代其他操作员记录 QSO 的方式。

台站位置仅限干事

台站位置是集体台共享的基础设施,删除其中一个会连同其所有 QSO 一起移除。因此创建、更新和删除台站位置需要级别 9:

请求 级别 3 / 6 级别 9
GET /api/v2/station ✅ ✅
GET /api/v2/station/{id} ✅ ✅
POST /api/v2/station 403 ✅
PATCH /api/v2/station/{id} 403 ✅
DELETE /api/v2/station/{id} 403 ✅

拒绝响应会带上相关的代码和级别:

{
  "error": {
    "code": "insufficient_club_permission",
    "message": "This operation requires clubstation permission level 9",
    "details": { "required_level": 9, "granted_level": 3 }
  }
}

日志仅限干事,读取也包括在内

日志对集体台的台站位置进行分组,因此它同样是共享基础设施——但与台站位置不同,即使只是读取日志也需要级别 9:

请求 级别 3 / 6 级别 9
GET /api/v2/logbook 403 ✅
GET /api/v2/logbook/{id} 403 ✅
POST / PATCH / DELETE 403 ✅

Web 界面也划了同样的界线——它的整个日志管理界面都仅限干事——因此当低于该级别的成员创建令牌时,连 logbook:* 作用域都不会提供。

电台归属于其操作员

每名成员把自己的设备注册到共享的集体台账户中,因此 电台 的限定方式相同:低于干事级别的成员只能列出、读取和删除自己注册的电台。其他成员的电台会返回 404 not_found。

查询遵循同样的边界

查询会从日志中回答「我之前是否通联过这个台」,因此它遵守同样的限制——否则它就会返回成员无权列出的 QSO 中所记录的姓名、QTH 和网格定位:

  • 当唯一匹配的 QSO 属于其他操作员时,?callsign= 会报告 workedBefore: false(在 detail=full 时为 call_worked: false)。
  • ?grid= 和 ?grid=all 只考虑该成员自己的 QSO。

集体台成员资格仅限干事

整个 集体台 资源都仅限干事——既包括读取成员列表(不向非干事披露成员信息),也包括管理权限:

请求 级别 3 / 6 级别 9
GET /api/v2/club 403 ✅
GET /api/v2/club/{user_id} 403 ✅
POST /api/v2/club 403 ✅
PATCH /api/v2/club/{user_id} 403 ✅
DELETE /api/v2/club/{user_id} 403 ✅

此处拒绝时返回的是普通的 forbidden,而不是其他地方使用的 insufficient_club_permission:该资源会拒绝一切既不是干事也不是 Wavelog 管理员的对象,而个人令牌会得到同样的代码,只是消息中会指出另一个缺失的角色。

{
  "error": {
    "code": "forbidden",
    "message": "Token is not a club officer"
  }
}

干事无法通过 API 更改或移除自己的成员资格,因此他们无法让集体台失去权限管理。参见集体台。

Wavelog 管理员可以从外部使用个人令牌和 ?club_id= 访问同一资源,且不受该规则约束——参见 Wavelog 管理员。club:* 作用域只提供给符合这两种角色之一的会话,因此普通用户根本看不到它们。

统计数据是全集体台范围的

有一个刻意的例外:统计 对每名成员都报告全集体台范围的数字,与级别无关。这些计数器是聚合值而非 QSO 数据,并且与仪表盘共享。

这意味着这些数字完全可能与该令牌从 QSO 资源得到的结果不一致:

GET /api/v2/statistic?profile=qso   ->  total: 412   (the whole club)
GET /api/v2/qso                     ->  total: 57    (this member's QSOs)

不要用统计总数来对 QSO 列表分页或做核对。

失去成员资格

从集体台中移除成员会删除其为该集体台创建的每一个集体台令牌——包括被设为永不过期的令牌。这与 v1 API 密钥一直以来的清理方式相同,并且立即生效。此后用这类令牌发起的任何调用都会被拒绝:

{
  "error": {
    "code": "invalid_token",
    "message": "Invalid or revoked API token"
  }
}

状态码是 401:令牌已不再存在。重新添加该成员会恢复其权限,但不会恢复令牌——他们必须创建新的令牌。

有两件事不受影响:

  • 该成员的个人令牌(owner == creator)。它们属于其自己的账户,而不属于集体台。
  • 其他成员为同一集体台创建的令牌。清理是按成员进行的。

提示:在客户端中处理这种情况

把 401 invalid_token 视为永久性错误并停止重试——与 rate_limited 不同,它不会自行恢复。请把这一情况呈现给用户:他们需要新令牌,而只有集体台才能授予其背后的成员资格。

注意(club_access_revoked 仍然存在)

还有一项独立的检查会在每次请求时重新读取成员资格。它覆盖上述清理无法触及的情况——例如直接在数据库中删除的成员资格——并返回 403 club_access_revoked,同时令牌保持完好。客户端应同时处理这两种代码;日常使用中它见到的会是 401。

汇总

个人 级别 3 / 6 级别 9
读取自己的 QSO ✅ ✅ ✅
读取其他操作员的 QSO — 404 ✅
选择 operator 字段 ✅ 被覆盖 ✅
读取台站位置 ✅ ✅ ✅
写入/删除台站位置 ✅ 403 ✅
日志(读取和写入) ✅ 403 ✅
自己的电台 ✅ ✅ ✅
其他操作员的电台 — 404 ✅
跨所有操作员的查询 ✅ 仅自己 ✅
集体台成员列表 — 403 ✅
管理集体台权限 — 403 ✅(不含自己)
统计 自己 全集体台 全集体台
Wavelog 手册(中文版) / 集体台中的 API v2 0 字 0 行 bg8lng
2026-10-21T12:42:36.416837579Z 2026-10-21T12:44:05.502056342Z