使用 API Key 调接口
API Key 是长期 Bearer 凭证,无需先换 token。
调用模型
所有业务接口都遵循同一调用模型 —— 把 API Key 直接放在 Authorization 头:
Authorization: Bearer kb_xxx
- 不需要先调
/api/openapi/oauth/token换 access token。 - 没有 refresh token;Key 被撤销 / 过期 / 权限不足时,需重新创建或 rotate。
- 业务接口以
/api/kirby/v1/**为准,/v1/public/**已下线。
调用频次限制
API 请求按 clientId 独立统计最近 24 小时的调用次数。
| 统计窗口 | 请求次数上限 |
|---|---|
最近 24 小时(按 clientId 独立统计) | 默认 1,000 次 |
24 小时额度采用滚动窗口:每笔计入额度的请求满 24 小时后,释放对应额度。因超限被拒绝的重试不会推迟额度恢复。
达到上限后,需等待窗口内有可用额度再继续请求。建议均匀安排请求,避免立即反复重试。
选你顺手的语言
所有方式调的都是同一个接口、同一组 Header、同一个 Key —— 建议先用 curl 跑通连通性,
确认 Key 与 scope 没问题后,再切到你工作流里的语言。下面统一以分页查询笔记
POST /api/kirby/v1/note/paging 为例。
curl --location 'https://openapi-api.comu.com/api/kirby/v1/note/paging' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer kb_xxx' \
--data '{
"page": 1,
"pageSize": 20
}'
{
"code": 0,
"msg": null,
"data": {
"data": [],
"total": 0,
"page": 1,
"pageSize": 20
},
"success": true
}
把 kb_xxx 通过 stdin 传给 CLI,避免出现在 shell history。
printf '%s' 'kb_xxx' | kirby \
--base-url https://openapi-api.comu.com \
--profile api-key-test \
login --api-key-stdin
kirby --base-url https://openapi-api.comu.com \
--profile api-key-test \
--output json \
api POST /api/kirby/v1/note/paging \
--body '{"page":1,"pageSize":20}'
API Key 模式下 CLI 收到 401 不会自动 refresh,也不会重试换 token; 需要重新登录或更换 Key。
import os
import requests
BASE_URL = "https://openapi-api.comu.com"
API_KEY = os.environ["KIRBY_API_KEY"]
resp = requests.post(
f"{BASE_URL}/api/kirby/v1/note/paging",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={"page": 1, "pageSize": 20},
timeout=10,
)
resp.raise_for_status()
print(resp.json())
const BASE_URL = "https://openapi-api.comu.com";
const API_KEY = process.env.KIRBY_API_KEY;
const resp = await fetch(`${BASE_URL}/api/kirby/v1/note/paging`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ page: 1, pageSize: 20 }),
});
if (!resp.ok) {
throw new Error(`HTTP ${resp.status}`);
}
const data = await resp.json();
console.log(data);
JDK 11+ 自带 java.net.http.HttpClient,零第三方依赖即可调用。
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class ComuDemo {
static final String BASE_URL = "https://openapi-api.comu.com";
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("KIRBY_API_KEY");
String body = "{\"page\":1,\"pageSize\":20}";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/api/kirby/v1/note/paging"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(10))
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() / 100 != 2) {
throw new RuntimeException("HTTP " + resp.statusCode() + " - " + resp.body());
}
System.out.println(resp.body());
}
}
取出某条笔记的详情
拿到上一例的列表后,挑一个 noteId 调
GET /api/kirby/v1/note/noteDetail。同一把 API Key、同一组 Header,
只是把方法换成 GET、参数走 query string —— 用来佐证"接口换了,调用模式不变"。
curl --location \
'https://openapi-api.comu.com/api/kirby/v1/note/noteDetail?noteId=NOTE_ID' \
--header 'Authorization: Bearer kb_xxx'
这条接口要求 note:read scope;用例 1 也是同一个 scope —— 一把 Key 即可串起整个笔记浏览旅程。
其余接口的入参 / 出参字段,统一在
接口列表 页递归展开查看。
Scope 校验规则
通过 OpenAPI / CLI / API Key 调用业务接口时,平台会按以下规则校验 scope。
| 条件 | 结果 |
|---|---|
| 接口已对外开放 | 允许通过 OpenAPI / API Key 调用;否则一律返回 403 |
HTTP 方法是 GET / HEAD / OPTIONS |
默认匹配 resource:read |
HTTP 方法是 POST / PUT / PATCH / DELETE |
默认匹配 resource:write |
接口声明了精细化 scope(例如 ask:invoke) |
以接口声明为准,覆盖默认匹配 |
常见 scope
示例:调用 POST /api/kirby/v1/note/paging 时,按默认规则需要
note:write scope。如对接口的具体 scope 需求有疑问,可联系平台支持团队确认。
常见错误排查
Authorization头格式不是Bearer kb_xxx。- API Key 写错、已撤销、已过期。
- 使用了旧 Key,rotate 后没更新本地配置或 CI Secret。
- API Key 没有目标 scope。
- 调用了写请求(POST / PUT / PATCH / DELETE),按默认规则需要
xxx:write。 - 所调用的接口未对 OpenAPI / API Key 开放。
响应体形如:
{
"type": "https://kirby.ai/problems/87213",
"title": "OAUTH_SCOPE_INSUFFICIENT",
"status": 403,
"code": 87213,
"detail": "missing scope: note:write"
}
带 JSON body 的请求必须设置:Content-Type: application/json。
使用 form-encoded 时确认接口是否支持 application/x-www-form-urlencoded。
安全建议
创建 Key 时显式传 scopes,按实际调用最小化授权;
不需要写权限就别勾 :write。
不要把 API Key 写进前端、移动端或公开仓库。 CI 中使用 Secret 管理,构建日志不打印明文。
建议每 90 天主动 rotate 一次。POST /openapi/api-keys/{id}/rotate
会返回新明文,旧 Key 立即失效。
发现泄漏(推到公开仓库 / 误发到群)后第一时间调
DELETE /openapi/api-keys/{id},再创建新 Key 替换。
线上控制台与日志只展示 hint(末 4 位),不要展示完整 Key。
hint 不可用于鉴权,仅用于识别。
如果业务数据含敏感字段,配合 Comu 的字段级加密能力, 避免明文落库。