公共 API 为组织管理员提供对你所在组织的实时数据的直接 HTTP 访问——任何能够发出 HTTP 请求的网站、应用、机器人或自动化流程都可以接入。这是 Business 方案 的一项功能。

公共 API 页面:生成组织 API 密钥,并启用使用 Ludoya 登录

该密钥的作用域限定为你的组织——所有端点都会自动作用于该组织。基础 URL:https://api.ludoya.com/public/v1。认证请求头:X-Api-Key: YOUR_KEY。速率限制:每分钟 100 次请求,超过后你将收到 429

密钥以 ldy_ 开头,长度为 36 个字符,因此在配置文件中很容易发现——若它出现在不该出现的地方也便于扫描检出。请将其视为密码:仅限服务器端使用;若发生泄露,可在同一页面撤销。

可访问的内容

  • 地点 — 你的组织可用的地点及其位置;在创建活动时用作输入
  • 活动(读取) — 即将到来和过往的活动,包含标题、描述、日期/时间、时区、容量、参与者数量和状态
  • 活动(写入) — 通过 POST 和 PUT 创建与更新活动,可完全控制地点、容量、权限、可见性和图片
  • 子活动 — 列出嵌套在父活动内的活动
  • 参与者 — 将某人加入活动、更改其出席状态或将其移除
  • 成员 — 含用户资料与角色(所有者、管理员、成员)的成员列表,支持分页
  • 邀请 — 邀请某人加入你的组织
  • 搜索 — 查找 Ludoya 用户和桌游目录,以便在写入前将名称解析为 ID
  • 收藏 — 桌游收藏,可按拥有情况、名称、玩家人数和列表筛选;可排序并分页;每个桌游都包含 BGG 元数据
  • 统计 — 任意时间段的对局统计:总计、平均值、含胜场与得分的顶尖玩家、按玩家人数细分、按地点、按桌游
  • 战役(读取) — 列出组织的战役及成员数和场次数;获取完整战役详情,包括成员、过往场次和已安排的活动
  • 战役(写入) — 为组织创建战役,并更新其名称、描述、状态与可见性
  • 战役成员 — 在战役中添加、更新和移除人员

端点

GET /locations

返回组织的可用地点。每个地点包含 idname、可选的 addresscapacity、一个 isDefault 标志,以及一个 spots 数组(每个位置都有自己的 idnamecapacity)。创建活动时请使用地点和位置的 ID。

使用 Ludoya 登录

保存你 API 密钥的同一页面也会将你的组织变成一个登录提供方。让人们使用他们的 Ludoya 账户登录你自己的网站、论坛或社区平台——他们无需再记另一套密码,你也无需运行用户数据库。

为什么值得

当有人批准登录时,他们会与你的组织关联:根据你们群组的加入策略,他们要么(开放)立即成为成员,要么(申请加入)提交加入请求供管理员批准,或(仅限邀请)仅登录而不加入。无论哪种情况,他们都会像其他人一样出现在 /members 端点中——因此你的网站登录与 Ludoya 成员列表会自动保持同步。

设置方法

这是标准的 OpenID Connect,因此大多数平台只需要一个发行者 URL,再加上客户端 ID 和密钥。从 Public API 页面注册你的应用以获取这些凭据,并列出你的网站将使用的重定向 URI——你可以注册多个,每一个都必须与网站发送的 redirect_uri 逐字符完全匹配,包括末尾的斜杠。轻微的不匹配是首次登录尝试失败的最常见原因。

  • Discourse —— 安装 OpenID Connect 插件,粘贴发现 URL,添加凭据
  • WordPress —— 任何通用的 OpenID Connect 插件,使用其 "auto discover" 选项
  • 其他任何平台 —— 如果支持 OIDC,指向发行者 URL 即可自动完成配置

每次登录都会返回该用户的永久标识符、用户名、显示名和头像,以及其电子邮件地址。包含手动流程在内的完整设置说明,位于应用内的开发者指南:开发者 → 使用 Ludoya 登录

给正在登录的用户

任何曾使用 Ludoya 在某处登录过的人,都可以在 设置 → 已连接的应用 下查看这些连接,查看每个连接的连接时间与上次使用时间,并可随时断开任意连接。断开会立即切断该网站的访问权限,但不会将他们从你的群组中移除。

GET /events

以两个彼此独立的分页列表返回未来和过去的活动。

参数 类型 默认值 描述
onlyFuture 布尔值 true 将其设为 false 以同时返回过去的活动

每个活动包含: type(MEETUP 或 PLANNED_PLAY)、titledescriptionstartsAtendsAttimeZoneimageUrlcapacityparticipantCountcanceledteacher(用户对象或 null)、master(用户对象或 null)。用户对象包含 idusernamenameavatarUrl

POST /events

在群组中创建一个活动。必填字段:typetitle。如果省略 locationId,将使用群组的默认地点;如果不存在,则返回 400。

可选字段包括:descriptionlocationIdspotIdgameIdparentEventId(用于子活动),startsAtendsAtrestrictedAttendancecapacityminParticipantsestimatedDurationMinutesmaxReservationsPerUsertakeGamesPermissionorganizePlaysPermissionteacherUserIdmasterUserIdvisibilityimage

image 字段接受 {"base64": "data:image/jpeg;base64,..."} or {"url": "https://..."}。最大 5 MB。

返回 {"id": "string"},状态码 201。

PUT /events/{eventId}

更新现有的活动。请求体结构与 POST 相同——只需包含你想更改的字段。调用方必须是该活动的组织者(群组账号)。返回 202,响应体为空。

GET /events/{eventId}

根据 ID 获取单个活动,返回的数据结构与 GET /events 中的条目相同。

GET /events/{eventId}/children

列出嵌套在父级活动内的子活动——更大型聚会的各个专题或场次。每个子活动与常规活动具有相同的结构。

参与者管理

三个端点让你在 Ludoya 之外管理活动的参与者名单——当报名发生在你自己的网站上,或你正在导入现有名单时,这非常方便。

方法 路径 作用
POST `/events/

GET /members

返回分页的成员列表。

参数 类型 默认值
pagination.size int 50
pagination.offset int 0

每个成员包含: idusernamenameavatarUrlrole(OWNER、ADMIN 或 MEMBER)。

POST /members/invite

将某人邀请加入你的群组。此接口可直接接收一个 username —— 无需查找 ID —— 因此你可以直接从你自己的网站或管理工具添加成员。

GET /collection

返回你的桌游收藏,并支持筛选、排序和分页。

参数 类型 默认值 说明
filter string 用分号分隔的 key=value 对。键:ownership (OWNED, PREVIOUSLY_OWNED, PREORDERED, WISHLISTED)、played (boolean)、listIdnameFilterplayerCountFilterType (OFFICIAL, GOOD, BEST)、playerCountFilter (number)
groupExpansions boolean true 将扩展归类到其基础桌游下
sort string 格式:property,direction — 例如 name,asc
pagination string 格式:size,pageIndex — 例如 20,0

响应: totalGamestotalExpansionsgames[] — 每个包含:idslugnameimageUrlisExpansionyearPublishedminPlayerCountmaxPlayerCount

GET /stats

返回可配置时间窗口的对局统计数据。

参数 类型 默认值 描述
period 字符串 ALL_TIME 格式:PERIOD,date,index。取值:ALL_TIMEONE_YEARONE_MONTHTHIRTY_DAYSSEVEN_DAYSONE_DAYCUSTOMindex 将窗口向后偏移(0 = 当前,1 = 上一段)。自定义:CUSTOM,startDate,0,endDate

响应包括:

  • 摘要 — 总对局数、总/平均对局时长、唯一桌游、玩家和地点数量
  • 按玩家 — 每人对局数、胜场、平均分和最佳分
  • 按玩家人数 — 2 人、3 人、4 人等对局的细分
  • 按地点 — 对局次数及每个场地的唯一桌游数量
  • 按桌游 — 对局次数、总/平均对局时长,以及每个桌游标题的唯一玩家数

GET /campaigns

返回属于该群组的分页战役列表。

参数 类型 默认值 说明
status string 按状态筛选:ACTIVECOMPLETEDARCHIVED
pagination.size int 50 每页条目数
pagination.offset int 0 偏移量

每个战役包含: id, game (id, name, imageUrl), name, image, status, visibility, createdAt, updatedAt, memberCount, sessionCount.

GET /campaigns/{campaignId}

返回属于该群组的战役的完整详细信息。

响应包含: 所有列表字段,以及 templatedescriptionglobalNotesglobalStatemembers[](每个包含 userrolecharacterNotescharacterState)、sessions[]events[]

POST /campaigns

为该群组创建一个战役。必填字段:gameIdname。若省略,可见性默认为仅群组成员(ONLY_GROUP)。

可选字段:templateIddescriptionvisibilityPUBLICONLY_GROUPONLY_FRIENDSPRIVATE)。

返回 {"id": "string"},状态码为 201。

PUT /campaigns/{campaignId}

更新现有战役。所有字段均为可选——只需包含你想更改的内容。

可选字段:namedescriptionstatusACTIVECOMPLETEDARCHIVED)、visibility

返回 202,响应体为空。

战役成员

以与管理活动参与者相同的方式管理战役中的成员。

方法 路径 执行的操作
POST `/campaigns/

错误代码

状态 何时
400 验证失败(缺少必填字段,未找到地点,图片无效)
401 缺少或无效的 API 密钥
403 操作不被允许,或群组未使用 Business 方案
404 未找到资源
429 已超出速率限制

开始使用

1. 生成 API 密钥

新生成的 API 密钥,仅显示一次,带有复制按钮和“撤销”操作

  1. 前往你的组织资料页面
  2. 点击菜单()→ 公共 API
  3. 点击 生成密钥
  4. 立即复制你的密钥 — 它只会显示一次,之后无法再次找回

该密钥与你的组织绑定。请妥善保密:任何持有该密钥的人都可以读写以上所有数据。

2. 撤销或重新生成

要撤销现有密钥,返回 公共 API 页面并点击 撤销。在对话框中确认。任何使用旧密钥的系统将立即开始收到 401 错误。要生成新的密钥,请再次点击 生成密钥

相关:

  • 组织 — 组织账户和高级功能
  • Premium — Business 计划定价
  • 集成 — 将 Ludoya 与外部工具连接的其他方式