API Key 与外部 API

API Key 用于让外部程序调用 OctoRill 的用户态业务接口,例如读取 feed、Release、通知、日报,或触发同步、翻译与 reaction 刷新。它和网页登录态绑定到同一个用户数据范围,不提供管理员接口、登录接口或 API Key 管理接口本身。

如果只需要展示公开 GitHub 仓库 Releases,不需要登录用户数据,请使用 公开 Release 接入

创建与使用

API Key 在已登录的用户设置页创建,格式以 orill_ak_ 开头。当前管理响应会返回完整 api_keymasked_key,因此这些 session-only 管理接口的响应也必须按敏感数据处理。

所有外部请求都使用 Bearer 认证:

curl "$OCTORILL_ORIGIN/api/feed?scope=mine&limit=20" \
  -H "Authorization: Bearer orill_ak_xxx"

浏览器端程序只有在页面 origin 等于 OctoRill 配置的 public_base_url origin 时,才能通过 CORS 携带 Authorization header 访问;后端允许常见 HTTP method 与 Content-TypeAuthorization header,但不会放开任意第三方 origin。其它外部程序应从服务端、CLI 或同源前端调用。

API Key 被撤销后会立即失效。用户账号被禁用后,即使 API Key 仍存在,也会返回 403 account_disabled

管理接口边界

API Key 管理接口只能用网页登录态调用,不能用 API Key 调用:

接口 说明
GET /api/me/api-keys 列出当前用户的 API Key 摘要。
POST /api/me/api-keys 创建 API Key。body: { "name": "ci" }
DELETE /api/me/api-keys/{api_key_id} 撤销 API Key。

ApiKeySummary 字段:

字段 类型 说明
id string API Key id。
name string 用户填写的名称;未填写时使用默认名称。
api_key string 完整 key;只出现在 session-only 管理响应中。
masked_key string 可展示的脱敏 key。
created_at string 创建时间。
last_used_at string? 最近一次成功使用时间。

可调用接口目录

以下接口都支持 Authorization: Bearer orill_ak_...

分组 接口
读取 GET /api/starredGET /api/releasesGET /api/releases/{release_id}/detailGET /api/repos/{owner}/{repo}/releases/tag/{tag}/detailGET /api/notificationsGET /api/briefsGET /api/briefs/{brief_id}GET /api/feedGET /api/dashboard/updates
Reaction POST /api/feed/reactions/refreshPOST /api/release/reactions/toggle
同步与日报生成 POST /api/sync/starredPOST /api/sync/releasesPOST /api/sync/notificationsPOST /api/sync/allPOST /api/briefs/generateGET /api/tasks/{task_id}/events
翻译 POST /api/translate/requestsGET /api/translate/requests/{request_id}GET /api/translate/requests/{request_id}/streamPOST /api/translate/results
旧版翻译快捷接口 POST /api/translate/releasePOST /api/translate/releases/batchPOST /api/translate/releases/batch/streamPOST /api/translate/release/detailPOST /api/translate/release/detail/batchPOST /api/translate/notificationPOST /api/translate/notifications/batch

这些接口不属于 API Key 可调用范围:/api/me*/api/reaction-token*/api/auth*/api/admin*/auth*

Focus 页面对应的 API

/focus/* 页面对应同一个 feed API,通过 query 参数表达 scope:

页面 API
/focus/repo/:owner/:repo GET /api/feed?scope=repo&items=owner/repo
/focus/repos?items=owner/a,owner/b GET /api/feed?scope=repos&items=owner/a,owner/b
/focus/org/:org GET /api/feed?scope=org&org=org
/focus/mine GET /api/feed?scope=mine
任一 /releases 子页 追加 types=releases

示例:

curl "$OCTORILL_ORIGIN/api/feed?scope=repo&items=IvanLi-CN/octo-rill&types=releases&limit=30" \
  -H "Authorization: Bearer orill_ak_xxx"

curl "$OCTORILL_ORIGIN/api/feed?scope=repos&items=owner/a,owner/b&cursor=$CURSOR" \
  -H "Authorization: Bearer orill_ak_xxx"

curl "$OCTORILL_ORIGIN/api/feed?scope=org&org=IvanLi-CN" \
  -H "Authorization: Bearer orill_ak_xxx"

curl "$OCTORILL_ORIGIN/api/feed?scope=mine" \
  -H "Authorization: Bearer orill_ak_xxx"

scope=repos 最多接受 12 个仓库,重复项会按大小写无关规则去重。limit 默认 30,范围会被限制在 1..100;响应里的 next_cursor 可作为下一页 cursor

types 可选 allreleasesstarsfollowers。scoped focus feed 不返回 follower-only 内容。

Feed

GET /api/feed

Query:

参数 说明
cursor 上一页响应的 next_cursor
limit 默认 30,限制到 1..100
types allreleasesstarsfollowers
scope 空、reporeposorgmine
items scope=repo 时为 owner/reposcope=repos 时为逗号分隔仓库列表。
org scope=org 时必填。

响应 FeedResponse

字段 类型 说明
items FeedItem[] 当前页条目。
next_cursor string? 下一页游标;为空表示没有下一页。

FeedItem 是按 kind 区分的 union:

字段 类型 说明
kind string releaserepo_star_receivedfollower_receivedannouncementrelease_updaterepo_forked
ts string 排序时间。
id string 条目 id。
repo_full_name string? 相关仓库。
repo_visual RepoVisual? 仓库头像与 Open Graph 图。
title string? 标题。
body string? 正文或摘要。
body_truncated boolean body 是否被截断。
subtitle string? 副标题。
reason string? 通知或事件原因。
subject_type string? 通知 subject 类型。
html_url string? GitHub 页面。
unread integer? 通知未读标记。
actor FeedActor? 事件 actor。
translated TranslatedItem? 中文翻译状态。
smart SmartItem? 阅读润色状态。
reactions ReleaseReactions? Release reaction 缓存。

Release、通知、日报

读取接口:

接口 响应
GET /api/starred StarredRepoItem[],最多 2000 条。
GET /api/releases ReleaseItem[],最多 200 条。
GET /api/releases/{release_id}/detail ReleaseDetailResponse
GET /api/repos/{owner}/{repo}/releases/tag/{tag}/detail ReleaseDetailResponse
GET /api/notifications NotificationItem[],最多 200 条。
GET /api/briefs BriefSummaryItem[]
GET /api/briefs/{brief_id} BriefDetailItem

主要字段:

类型 字段
StarredRepoItem repo_idfull_namedescriptionhtml_urlstargazed_atis_private
ReleaseItem full_nametag_namenamepublished_athtml_urlis_prereleaseis_draft
ReleaseDetailResponse release_idrepo_full_namerepo_visualtag_nameprevious_tag_namenamebodyhtml_urlpublished_atis_prereleaseis_drafttranslatedsmart
NotificationItem thread_idrepo_full_namesubject_titlesubject_typereasonupdated_atunreadhtml_url
BriefSummaryItem iddatewindow_startwindow_endeffective_time_zoneeffective_local_boundaryrelease_countrelease_idspreview_markdowncovers_repo_starscovers_followerscreated_atupdated_at
BriefDetailItem BriefSummaryItem 的全部字段,加 content_markdown

Dashboard updates

GET /api/dashboard/updates

用于外部程序轮询“列表是否变化”,不会返回完整列表内容。

Query:

参数 说明
token 上次响应的 token;首次请求省略。
include 逗号分隔:feedbriefsnotificationsinbox。省略表示全部。
feed_type allreleasesstarsfollowers
scopeitemsorg GET /api/feed 相同。

响应:

字段 类型 说明
token string 下次轮询使用。
generated_at string 生成时间。
lists object 按 include 返回 feedbriefsnotifications
lists.*.changed boolean 与上次 token 相比是否有新增变化。
lists.*.new_count number 新增 key 数量。
lists.*.latest_keys string[] 变化 key。首次请求通常为空。

Reaction

POST /api/feed/reactions/refresh

{ "release_ids": ["123", "456"] }

release_ids 最多 100 个,必须是当前用户可见 Release。响应:

{
  "items": [
    {
      "release_id": "123",
      "reactions": {
        "counts": { "plus1": 0, "laugh": 0, "heart": 0, "hooray": 0, "rocket": 0, "eyes": 0 },
        "viewer": { "plus1": false, "laugh": false, "heart": false, "hooray": false, "rocket": false, "eyes": false },
        "status": "ready"
      }
    }
  ]
}

POST /api/release/reactions/toggle

{ "release_id": "123", "content": "heart" }

content 可选 plus1laughhearthoorayrocketeyes。该接口需要用户配置有效 GitHub PAT;未配置时返回 403 pat_required

同步、日报生成与任务流

这些接口支持 query 参数 return_mode

说明
sync 默认值;请求内同步执行并返回结果。
task_id 入队后台任务,返回 TaskAcceptedResponse
sse 入队后台任务,并直接返回 Server-Sent Events。

TaskAcceptedResponse

字段 类型 说明
mode string 固定为 task_id
task_id string 任务 id。
task_type string 后台任务类型。
status string 初始任务状态。

可调用接口:

接口 sync 响应
POST /api/sync/starred { "repos": number }
POST /api/sync/releases { "repos": number, "releases": number }
POST /api/sync/notifications { "notifications": number, "since": string? }
POST /api/sync/all { "starred": ..., "releases": ..., "social": ..., "notifications": ..., "social_error"?: string }
POST /api/briefs/generate BriefGenerateResponse

POST /api/briefs/generate body 可省略;如指定日期:

{ "date": "2026-07-06" }

BriefGenerateResponse 字段:iddatewindow_startwindow_endeffective_time_zoneeffective_local_boundaryrelease_countrelease_idscontent_markdown

任务 SSE 可通过 GET /api/tasks/{task_id}/events 读取。这个接口同样支持 API Key,适合配合 return_mode=task_id 使用。

翻译接口

推荐使用通用翻译请求接口。

POST /api/translate/requests

Body:

字段 类型 说明
mode string asyncwaitstream
item TranslationRequestItemInput? 单个请求。
items TranslationRequestItemInput[]? 批量请求,仅支持 mode=async

itemitems 互斥。kind 只支持 release_summaryrelease_smartrelease_detailnotificationtarget_lang 只支持 zh-CN

TranslationRequestItemInput

字段 类型 说明
producer_ref string 调用方自定义引用。
kind string 翻译类型。
variant string 调用方变体标识。
entity_id string Release id 或 notification thread id。
target_lang string zh-CN
max_wait_ms number 等待模式的最大等待时间,会按服务端上下限 clamp。
source_blocks { slot, text }[] slot 可为 titleexcerptbody_markdownmetadata
target_slots string[] 可为 title_zhsummary_mdbody_md

单个请求响应 TranslationRequestResponse

字段 类型 说明
request_id string 翻译请求 id。
status string queuedrunningcompletedfailed 等。
result PublicTranslationResultItem 当前结果或占位结果。

批量提交响应:

字段 类型 说明
requests object[] 每项包含 request_idstatusproducer_refentity_idkindvariant

结果查询:

接口 说明
GET /api/translate/requests/{request_id} 读取单个请求当前状态。
GET /api/translate/requests/{request_id}/stream SSE stream;事件字段包含 eventrequest_idstatusbatch_idresulterror
POST /api/translate/results body: { "items": [...], "retry_on_error": false };返回 { "items": PublicTranslationResultItem[] }

PublicTranslationResultItem 字段:producer_refentity_idkindvariantstatustitle_zhsummary_mdbody_mderrorwork_item_idbatch_iderror_codeerror_summaryerror_detail

旧版快捷接口仍可调用:

接口 Body 响应
POST /api/translate/release { "release_id": "123" } TranslateResponse 或任务响应,支持 return_mode
POST /api/translate/release/detail { "release_id": "123" } TranslateResponse 或任务响应,支持 return_mode
POST /api/translate/notification { "thread_id": "..." } TranslateResponse 或任务响应,支持 return_mode
POST /api/translate/releases/batch { "release_ids": ["123"] } TranslateBatchResponse
POST /api/translate/release/detail/batch { "release_ids": ["123"] } TranslateBatchResponse
POST /api/translate/notifications/batch { "thread_ids": ["..."] } TranslateBatchResponse
POST /api/translate/releases/batch/stream { "release_ids": ["123"] } NDJSON stream,事件为 itemdoneerror

TranslateResponse 字段:langstatustitlesummaryTranslateBatchResponse 字段:items;每个 item 包含 idlangstatustitlesummaryerror

通用字段

RepoVisual

字段 类型
owner_avatar_url string?
open_graph_image_url string?
uses_custom_open_graph_image boolean

TranslatedItemSmartItem

字段 类型 说明
lang string 当前为 zh-CN
status string readymissingdisablederrorsmart 还可能是 insufficient
title string? 中文标题或润色标题。
summary string? 中文摘要或润色摘要。
error_code string? 错误分类。
error_summary string? 面向用户的错误摘要。
error_detail string? 详细错误。
auto_translate boolean? 是否自动翻译产生。

ReleaseReactions

字段 类型 说明
counts object plus1laughhearthoorayrocketeyes 数量。
viewer object 当前用户是否已点对应 reaction。
status string readysync_required

错误码

错误响应通常包含 codemessage。常见状态:

HTTP code 说明
400 bad_request 参数、body 或 mode 不合法。
401 unauthorized 未提供可用 session,且请求没有携带 Authorization
401 invalid_api_key Bearer API Key 格式错误、已撤销或不存在。
403 account_disabled API Key 所属用户已禁用。
403 pat_required reaction toggle 需要 GitHub PAT。
404 not_found 资源不存在或不属于当前用户范围。
500 internal 服务端内部错误。