集体台中的 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 |
✅(不含自己) |
| 统计 | 自己 | 全集体台 | 全集体台 |