Use

使用 API Key 调接口

API Key 是长期 Bearer 凭证,无需先换 token。

调用模型

所有业务接口都遵循同一调用模型 —— 把 API Key 直接放在 Authorization 头:

http · request header
Authorization: Bearer kb_xxx
  • 不需要先调 /api/openapi/oauth/token 换 access token。
  • 没有 refresh token;Key 被撤销 / 过期 / 权限不足时,需重新创建或 rotate。
  • 业务接口以 /api/kirby/v1/** 为准,/v1/public/** 已下线。
Rate limits

调用频次限制

API 请求按 clientId 独立统计最近 24 小时的调用次数。

统计窗口请求次数上限
最近 24 小时(按 clientId 独立统计)默认 1,000 次
滚动窗口与额度恢复

24 小时额度采用滚动窗口:每笔计入额度的请求满 24 小时后,释放对应额度。因超限被拒绝的重试不会推迟额度恢复。

达到上限后,需等待窗口内有可用额度再继续请求。建议均匀安排请求,避免立即反复重试。

Examples

选你顺手的语言

所有方式调的都是同一个接口、同一组 Header、同一个 Key —— 建议先用 curl 跑通连通性, 确认 Key 与 scope 没问题后,再切到你工作流里的语言。下面统一以分页查询笔记 POST /api/kirby/v1/note/paging 为例。

bash · curl
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
  }'
json · response
{
  "code": 0,
  "msg": null,
  "data": {
    "data": [],
    "total": 0,
    "page": 1,
    "pageSize": 20
  },
  "success": true
}

把 kb_xxx 通过 stdin 传给 CLI,避免出现在 shell history。

bash · 登录
printf '%s' 'kb_xxx' | kirby \
  --base-url https://openapi-api.comu.com \
  --profile api-key-test \
  login --api-key-stdin
bash · 调用
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。

python · requests
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())
javascript · fetch (Node 18+)
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,零第三方依赖即可调用。

java · HttpClient (JDK 11+)
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());
  }
}
Examples · 用例 2

取出某条笔记的详情

拿到上一例的列表后,挑一个 noteId 调 GET /api/kirby/v1/note/noteDetail。同一把 API Key、同一组 Header, 只是把方法换成 GET、参数走 query string —— 用来佐证"接口换了,调用模式不变"。

bash · curl
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 即可串起整个笔记浏览旅程。 其余接口的入参 / 出参字段,统一在 接口列表 页递归展开查看。

Scopes

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

recordings:read recordings:write note:read note:write summaries:read summaries:write action_items:read action_items:write contacts:read contacts:write mindmaps:read ask:invoke webhooks:read webhooks:write

示例:调用 POST /api/kirby/v1/note/paging 时,按默认规则需要 note:write scope。如对接口的具体 scope 需求有疑问,可联系平台支持团队确认。

Errors

常见错误排查

401 invalid token
  • Authorization 头格式不是 Bearer kb_xxx。
  • API Key 写错、已撤销、已过期。
  • 使用了旧 Key,rotate 后没更新本地配置或 CI Secret。
403 scope insufficient
  • API Key 没有目标 scope。
  • 调用了写请求(POST / PUT / PATCH / DELETE),按默认规则需要 xxx:write。
  • 所调用的接口未对 OpenAPI / API Key 开放。

响应体形如:

json · problem+json (RFC 7807)
{
  "type": "https://kirby.ai/problems/87213",
  "title": "OAUTH_SCOPE_INSUFFICIENT",
  "status": 403,
  "code": 87213,
  "detail": "missing scope: note:write"
}
415 / 请求体解析失败

带 JSON body 的请求必须设置:Content-Type: application/json。 使用 form-encoded 时确认接口是否支持 application/x-www-form-urlencoded。

Security

安全建议

最小权限原则

创建 Key 时显式传 scopes,按实际调用最小化授权; 不需要写权限就别勾 :write。

禁止入库 / 入仓

不要把 API Key 写进前端、移动端或公开仓库。 CI 中使用 Secret 管理,构建日志不打印明文。

定期 rotate

建议每 90 天主动 rotate 一次。POST /openapi/api-keys/{id}/rotate 会返回新明文,旧 Key 立即失效。

泄漏立即 revoke

发现泄漏(推到公开仓库 / 误发到群)后第一时间调 DELETE /openapi/api-keys/{id},再创建新 Key 替换。

页面只展示 hint

线上控制台与日志只展示 hint(末 4 位),不要展示完整 Key。 hint 不可用于鉴权,仅用于识别。

敏感字段写入加密

如果业务数据含敏感字段,配合 Comu 的字段级加密能力, 避免明文落库。