Origin API
Origin 目前处于早期 beta 版,可能会发生变更。更新集成时,请查阅 OpenAPI 规范。
Origin 是 Cherri Code 的代码托管平台。其公开的 REST API 可让应用和工具与 Origin 仓库、提交、检查、PR 和应用安装协同工作。
- Origin 应用使用应用 JWT 和安装访问令牌进行身份验证。请参阅身份验证。
- 查看完整的 OpenAPI 规范,了解详细的架构和示例。
- 智能体可以加载 llms.txt 索引,或在 llms-full.txt 中以 Markdown 格式加载完整参考。
概述
Origin 应用采用 OAuth 风格的安装授权流程和 GitHub App 风格的身份验证模型:
- 应用使用其 Ed25519 私钥为短期有效的 EdDSA JWT 签名。
- 应用使用该 JWT 和安装 ID 换取短期有效的安装访问令牌 (
oit_…) 。 - 安装令牌可在该安装已获批准的仓库和权限范围内调用代码仓库 API,并通过 HTTPS 对 Git 进行身份验证。
- Origin 会向应用注册的 webhook URL 发送已签名的 webhook 投递记录。
基础 URL
https://api.cursor.com/v1/origin参考中的端点路径均包含完整的 /v1/origin 前缀。
协议约定
请求和响应均使用 application/json。JSON 字段名采用 camelCase。时间戳采用 RFC 3339 格式的 string。Protobuf 64 位整数 (包括 PR 编号和版本号) 在 JSON 中表示为 string。
响应会保留处于默认值的字段,而不会将其丢弃,因此 false 布尔值、0 数值、空字符串和空数组都会出现在响应体中。请直接读取字段值本身,而不要把缺失的 key 当作默认值。文档中标注为不出现或被省略的字段在合约中是可选的,未设置时不会出现在响应体中。
预览版
部分 API 接口以预览版形式发布。这些接口会出现在本参考文档和规范中,但在正式发布前,其结构可能会发生变化。OpenAPI 规范会将其标记为 x-cursor-visibility: PREVIEW。该标记可以出现在操作、参数、schema 或单个字段上,因此即使是稳定的操作,也可能返回预览版字段。处于预览阶段的端点在本参考文档中会带有 预览版 badge。请将预览版字段视为可选字段,不要对其结构形成硬性依赖。
入门
访问 Origin
- 前往 cursor.com/codebase 浏览 Origin。
- 前往 cursor.com/codebase/settings/apps 管理应用设置。
- 生成应用签名密钥,且仅注册公钥。
Origin CLI
安装 Origin CLI 并登录:
curl -fsSL https://downloads.cursor.com/origin/install.sh | shorigin auth login克隆已有代码仓库:
origin repo clone '{ownerSlug}/{repoName}'# 或直接使用 gitgit clone 'https://origin.cursor.com/{ownerSlug}/{repoName}.git'应用通过 Git HTTPS 身份验证 使用安装访问令牌克隆,而非使用用户登录。
安装
将以下内容发送给客户工作区管理员:
/codebase/apps/install ?client_id=APP_ID &scope=SPACE_SEPARATED_SCOPES &redirect_uri=REGISTERED_CALLBACK &state=RANDOM_ANTI_FORGERY_VALUE &summary=SHORT_REASON_FOR_ACCESS &include_granted_scopes=true| 参数 | 必填 | 描述 |
|---|---|---|
client_id | 是 | Origin 应用 ID。 |
scope | 是 | 以空格分隔的权限范围。会自动添加 repository:metadata:read。 |
redirect_uri | 合作伙伴发起安装时必填 | 已注册的准确回调 URI。 |
state | 强烈建议 | 作为安装回执的 state 声明回显的随机防伪值。重定向前生成,并在回调时验证该声明。 |
summary | 否 | 同意授权时显示的简短说明。 |
include_granted_scopes | 否 | 当值为 true 时,保留现有授权,仅请求新增权限范围。 |
工作区管理员选择目标所有者、批准的权限范围,以及所有仓库或选定的仓库。仓库访问权限由客户而非应用控制。
批准后,Origin 会重定向到已注册的回调地址:
https://ci.example.com/origin/callback?installation_receipt=RECEIPT_JWT验证安装回执,然后存储其 sub 声明中的安装 ID。签发安装访问令牌时需要用到它。
安装有以下两种仓库选择模式:
all:该安装可访问所选目标拥有的所有仓库。selected:该安装只能访问工作区管理员选择的仓库。
两种模式均涵盖镜像仓库和原生 Origin 仓库,因此镜像会显示在 GET /installation/repos 中,并且可以被选中。镜像在成为稳定的出站镜像之前为只读:请参阅镜像仓库。
使用安装令牌调用 GET /installation/repos,即可查看该安装可访问的仓库。应用 JWT 端点可列出、查看和删除该 App 的安装。删除安装后将无法再签发新 token。
安装回执
installation_receipt 是由 Origin 签名的短期有效紧凑型 JWT,用于证明安装批准来自 Origin,而非伪造的重定向,并携带回调所需的全部信息。Cherri Code 不会在缺少此凭据时进行重定向,因此外部回调始终会携带它。
JOSE 请求头:
{ "alg": "EdDSA", "kid": "origin-key-id", "typ": "origin-installation-receipt+jwt"}声明:
{ "iss": "https://api.cursor.com/v1/origin", "aud": "app_01...", "sub": "i_01...", "namespace_id": "ns_01...", "iat": 1786465200, "exp": 1786465500, "jti": "RECEIPT_UUID", "installedBy": { "id": "user_01...", "email": "[email protected]", "displayName": "Jane Doe" }, "state": "ORIGINAL_VALUE"}aud是您的应用 ID,sub是签发安装访问令牌时使用的安装 ID。namespace_id是 app 所安装 namespace 的稳定 ID。installedBy用于标识执行此次安装或重新同意的用户。它描述当前操作,因此在重新同意时,可能与 获取 App Installation 中持久的installedBy不同。当账户设有名称时,它会携带displayName,但绝不会携带handle;请改为从 REST 响应或 webhook 负载中读取handle。- 回执在签发五分钟后过期。每份回执的
jti均唯一。 - 仅当安装 URL 携带非空
state时,才会包含state,其值与该state相同。请将其与重定向前生成的防伪值进行匹配。
信任回调前,请先验证回执:根据 kid 请求头从 JWKS 获取签名密钥,要求 alg 为 EdDSA、typ 为 origin-installation-receipt+jwt,并验证签名、iss、aud 和 exp。验证失败时,拒绝该回调。
该回执不是安装访问令牌。切勿将其作为 Bearer 凭据发送;请改为通过 创建安装访问令牌 签发安装令牌。
身份验证
使用 Bearer 方案发送 REST 凭据。每个端点 的 Auth badge 列出了其接受的凭据类型:
curl --request GET \ --url https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME \ --header "Authorization: Bearer $ORIGIN_BEARER_TOKEN"Cherri Code API 密钥不是 Origin Bearer token。对于用户认证的请求,请使用 Origin CLI,它会用个人用户 API 密钥换取 Origin 所接受的短期 访问令牌。请勿将 Cherri Code API 密钥直接放入 Authorization 请求头中。
生成应用签名密钥
Origin 应用使用 Ed25519 密钥对进行认证。在本地生成密钥对,然后仅将公钥注册到 cursor.com/codebase/settings/apps。每个应用最多可拥有 10 个当前有效的签名密钥。
私钥必须严格保密。请勿上传、粘贴到应用设置中、提交到代码仓库或分享给他人。请将其存储在机密信息管理器中。Cherri Code 仅存储公钥。
使用 OpenSSL 创建 PKCS#8 私钥和 PEM SPKI 公钥:
openssl genpkey -algorithm ED25519 -out origin-app-private.pemopenssl pkey -in origin-app-private.pem -pubout -out origin-app-public.pem公钥文件以 -----BEGIN PUBLIC KEY----- 开头。添加签名密钥时,请粘贴该 PEM。请仅使用对应的私钥签署应用 JWT。
应用 JWT
使用与应用的一个当前有效的签名密钥配对的 Ed25519 私钥签署短期有效的 JWT。按照生成应用签名密钥中的说明生成该密钥对。
JOSE 请求头:
{ "alg": "EdDSA", "kid": "app_01...", "typ": "JWT"}声明:
{ "iss": "app_01...", "aud": "origin-apps", "iat": 1782928800, "exp": 1782929100}将 iss 和 kid 设为应用 ID,并将有效期设为约五分钟。
Authorization: Bearer APP_JWT使用应用 JWT 执行应用级操作,例如读取应用元数据、管理安装、签发安装令牌,以及恢复 Webhook 投递记录。
安装访问令牌
使用应用 JWT 调用 POST /app/installations/{installationId}/access_tokens。安装访问令牌以 oit_ 开头。
Authorization: Bearer oit_...响应中包含 expiresAt。请按需签发 token,在到期前刷新,将其视为密码,切勿记录到日志中。
令牌最长在创建后 15 分钟过期,且不会晚于请求它的应用 JWT,因此上文推荐的五分钟 JWT 最多只能签发出有效期五分钟的令牌。请读取 expiresAt,在其过期后签发新令牌,而不要假定某个固定时长:源站令牌的有效期比 GitHub App 安装访问令牌更短,若集成按 GitHub 的周期复用令牌,会在令牌过期后失败。当某个作业需要完整的 15 分钟时,请在签名 JWT 时设置更晚的 exp,参见 CloneKit CI 方案。
移除该安装或删除应用会使其安装访问令牌在 expiresAt 前失效。REST API 和 Git over HTTPS 随后会以 401 拒绝该令牌。请勿使用同一令牌重试;必须重新安装应用后才能签发可用令牌。
安装访问令牌的权限不得超出该安装获批的权限范围或仓库访问权限。你可以将安装访问令牌限制为更少的 scopes 或 repositoryIds。空数组或省略数组将继承完整的安装授权。
对限定在仓库范围内的操作使用安装访问令牌,包括 PR、check-run 写入操作以及Git over HTTPS。
若要以该安装所属命名空间的成员身份 (而非应用身份) 执行操作,请签发安装用户令牌。参见代表用户执行操作。
Git HTTPS 身份验证
安装访问令牌用于通过 HTTPS 验证 Git 身份。Git 端点使用 HTTP Basic 认证:密码为安装令牌,用户名为 x-access-token。Bearer 凭据应仅用于 REST API;Git HTTPS 会拒绝此类凭据。
请在执行 Git 操作前立即通过 创建安装访问令牌 签发令牌。令牌最长有效期为 15 分钟。
克隆、获取和拉取需要 repository:contents:read。推送需要 repository:contents:write。令牌的授权范围必须包含目标代码仓库。
推送还要求代码仓库所有者有资格向 Origin 写入,这与创建代码仓库的要求相同。用户所有者必须使用 Pro、Pro Student、Pro+、Ultra 或 Start 方案。团队所有者必须拥有有效的付费团队方案、未使用隐私模式 (旧版) ,且 Origin 未被团队管理员关闭。向所有者不符合条件的代码仓库推送会返回 403。克隆、获取和拉取不受此要求限制。
从 Get Repo 或 列出应用安装可访问的仓库 获取 cloneUrl。GitHub 风格的路径 (https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git) 和旧版 /git/ 路径均可用于克隆。
git clone "https://x-access-token:${INSTALLATION_TOKEN}@origin.cursor.com/OWNER_SLUG/REPO_NAME.git"将令牌嵌入 URL 会使其存储在 .git/config 中。克隆成功后,重写远程地址,避免后续命令重复使用已过期的机密信息:
git remote set-url origin "https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git"为避免令牌出现在远程 URL 中,请通过 Git's 凭据助手传入令牌:
git -c credential.helper="!f() { echo username=x-access-token; echo password=${INSTALLATION_TOKEN}; }; f" \ clone "https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git"Origin CLI 凭据助手用于用户登录。应用集成会按此处所示传递安装令牌。请将令牌视为密码,切勿将其写入日志;如果作业仍需访问 Git,请在 expiresAt 到期前签发新的令牌。
Git over HTTPS 有独立的预算计量,与 限额 中的 REST 预算相互独立。计费的 Git 响应会带有相同的 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Used 请求头,其中 X-RateLimit-Resource 为 git 而非 core。超出预算的 Git 请求会返回 429,并附带 Retry-After 和 X-RateLimit-Reset。请读取请求头来控制作业节奏,而不要假定某个具体数值;不计量的请求不会带有限额相关请求头。
对于镜像仓库,安装令牌可用于克隆、获取和拉取;在镜像成为稳定的出站镜像前,Origin 会拒绝 git push 并返回 403。请参阅镜像仓库。
用户认证的 CLI 请求
使用 origin api 发起用户认证的请求。若需交互式会话,请通过浏览器登录:
origin auth loginorigin api /repos/OWNER_SLUG/REPO_NAME/pulls对于非交互式会话,请在 Cherri Code Dashboard → API Keys 中获取个人用户 API 密钥并提供:
export CURSOR_API_KEY="YOUR_PERSONAL_USER_API_KEY"origin api /repos/OWNER_SLUG/REPO_NAME/pullsCLI 会用个人 API 密钥换取一个短期有效的用户访问令牌,然后在 Authorization 请求头中发送该令牌。请勿将 API 密钥本身发送到 Origin 端点。应用集成应改用应用 JWT 和安装访问令牌。
发现和签名密钥
Origin 会发布无需认证的发现元数据及其当前有效的签名密钥。这些密钥也用于签署 webhook 投递记录和安装回执。
发现元数据中包含颁发方和 jwks_uri:
curl https://api.cursor.com/v1/origin/.well-known/openid-configuration{ "issuer": "https://api.cursor.com/v1/origin", "jwks_uri": "https://api.cursor.com/v1/origin/keys", "response_types_supported": ["id_token"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["EdDSA"]}/keys 返回有效的 Ed25519 JWK:
curl https://api.cursor.com/v1/origin/keys{ "keys": [ { "kty": "OKP", "crv": "Ed25519", "use": "sig", "alg": "EdDSA", "kid": "origin-key-id", "x": "PUBLIC_KEY_MATERIAL" } ]}缓存 JWKS。/keys 会发送 Cache-Control: public, max-age=600, stale-if-error=600,因此可复用缓存的响应 10 分钟,然后刷新;如果刷新失败,最多可再继续使用上一次有效的密钥 10 分钟,之后验证失败。此外,遇到没有任何密钥能验证的签名时也应刷新,这会移除已退役的密钥 ID。密钥每周轮换。
Webhook 签名不含密钥 ID,因此验证时应依次尝试所有有效的 Ed25519 密钥。安装回执会在其 JOSE 请求头中携带签名密钥的 kid,因此可直接解析用于验证回执的密钥。
权限范围
仅请求应用所需的最低权限范围。repository:metadata:read 以及应用或安装元数据访问权限会自动授予,无需单独添加到安装 URL。
| 权限范围 | 允许的操作 |
|---|---|
repository:metadata:read | 读取代码仓库元数据。自动添加。 |
repository:contents:read | 读取提交、分支、内容、比较文件和底层 Git 对象。搜索文件文本。下载代码仓库归档文件。通过 Git HTTPS 克隆、获取和拉取。将镜像代码仓库与其上游源同步。 |
repository:contents:write | 通过 Git HTTPS 推送。合并 PR。通过 Git 数据端点创建分支并提交文件更改。重新请求检查运行。 |
repository:pull_requests:read | 读取 PR、修改的文件、PR 提交、已分配的标签和合并资格。 |
repository:pull_requests:write | 创建和更新 PR。分配和移除 PR 标签。 |
repository:pull_requests:reviews:read | 读取 PR 评论、评论线程、已提交的评审和请求的审阅人。 |
repository:pull_requests:reviews:write | 创建和更新评论;解决和重新打开评论线程;创建、更新和撤销评审;请求和移除审阅人。 |
repository:checks:read | 读取检查套件、运行和检查运行注释。 |
repository:checks:write | 创建和更新检查套件和运行。追加检查运行注释。 |
repository:labels:read | 读取代码仓库拥有的标签定义。 |
repository:labels:write | 创建、更新和删除代码仓库标签定义。 |
repository:rulesets:read | 读取代码仓库规则集。 |
repository:rulesets:write | 创建、更新和删除代码仓库规则集。 |
repository:settings:read | 读取直接在代码仓库上持有的授权。 |
repository:settings:write | 更新代码仓库设置:默认分支、可见性、合并方式以及自动删除头分支。更新或插入以及删除代码仓库上的授权。 |
namespace:settings:read | 读取直接在所有者上持有的授权。读取所有者信任的 SSH 证书颁发机构,以及该所有者是否要求使用证书。 |
namespace:settings:write | 更新或插入以及删除所有者上的授权。添加和移除 SSH 证书颁发机构,并设置所有者是否要求使用证书;这些写入操作由 Cherri Code 用户凭据携带。 |
namespace:user_tokens:write | 签发安装用户令牌,以安装所属命名空间成员的身份执行操作。令牌本身不能携带此权限范围。请参阅代表用户操作。 |
请求 :write 权限范围也会授予对应的 :read 权限范围,因此 repository:labels:write 包含 repository:labels:read,无需同时列出两者。反之则不成立:读取权限范围绝不会授予写入权限。
安装令牌只能进一步缩小这些已授予的权限,不能添加工作区管理员未批准的权限范围或代码仓库。
镜像状态更改不在此表范围内。转换代码仓库镜像、强制代码仓库镜像切换 和 Detach Repo Mirror 需要 repository:mirror:write 或 repository:mirror:delete,应用无法在安装时请求这些权限:它们由 Cherri Code 用户凭据携带,且调用方还必须在镜像的上游源上拥有该代码仓库的管理权限。
安装管理同样不在此表范围内。Add App Installation Repositories 需要 namespace:installations:write,应用无法在安装时请求该权限:它由命名空间管理员在 Cherri Code 用户凭据上持有,且只有与同意该安装时相同类型的凭据才能扩展它。
出于同样的原因,应用管理也不在此表范围内。创建应用 需要 namespace:apps:create,List Namespace Apps 和 Get App 需要 namespace:apps:read,而 Update App、添加应用签名密钥 和 撤销应用签名密钥 需要 app:settings:write。发布者在 Cherri Code 用户凭据上持有这些权限;应用无法为自身请求它们。
该表涵盖应用在安装时请求的权限范围。要查找单个操作所需的权限范围,请参阅其在 OpenAPI 规范中的 x-origin-scopes 扩展。该扩展涵盖所有操作,包括凭据本身附带而非来自安装授权的 app、installation 和 namespace 权限范围。若某个操作所需的权限范围全部随凭据附带,其扩展会标记为 ambient: true:无需为其请求任何权限,出示正确的凭据即可。
镜像仓库
安装对原生 Origin 代码仓库和稳定出站镜像拥有的所有权限范围均有效。对于处于其他任何镜像状态的代码仓库,仅以下两个权限范围有效:
repository:metadata:readrepository:contents:read
无论工作区管理员批准了哪些权限,该代码仓库上的其他所有权限范围都会返回 403。通过 REST API,仍可读取代码仓库和内容、比较 commit 以及使用 Sync Mirror,而 Origin 会拒绝 PR、评审、评论、检查、规则集及所有写入操作。通过 Git HTTPS,clone、fetch、pull 和下载 LFS 文件仍可正常进行,而 Origin 会拒绝 push 和上传 LFS 文件。
将代码仓库移出该状态需要使用用户凭据执行,而非安装可执行的操作:转换代码仓库镜像 可推进镜像方向,强制代码仓库镜像切换 可切换至上游源,而无需将有差异的 refs 推送回去,Detach Repo Mirror 则会永久断开镜像。
代码仓库上的 mirror object 并不能表明是否允许写入。正在过渡中的镜像可能会将 mirror.status 报告为 outbound,但仍处于只读状态,因此应以 403 为准,而不要根据 mirror.status 进行分支判断。
速率限制
Origin API 对每个主体采用共享的积分预算,并按滚动的一分钟窗口重置。每种已认证主体类型都有各自的预算:
| 主体 | 默认预算 |
|---|---|
| 安装访问令牌 | 3,000 点数/分钟 |
| 应用 JWT | 6,000 点数/分钟 |
| Cherri Code 用户或服务账户 | 600 点数/分钟 |
每个端点都会在处理程序运行前从该预算中扣除固定点数。身份验证或授权失败不扣除点数。
| 成本 | 操作 |
|---|---|
| 0 | 获取速率限制。仅返回状态;不消耗点数。 |
| 1 | 大多数读取端点,以及创建安装访问令牌 |
| 5 | 常规写入操作,以及以下开销较大的读取操作:获取提交、列出提交文件、列出比较文件、列出 PR 文件、获取代码仓库 Tarball 和 搜索内容 |
| 10 | 创建应用、创建代码仓库、从文件创建提交、合并 PR、获取 PR 可合并性、转换代码仓库镜像 和 强制代码仓库镜像切换 |
Cherri Code 可为设计合作伙伴提高每个应用的每分钟预算。如果您的集成需要更高的限额,请联系 Cherri Code。
响应头
计费响应和 获取速率限制包含以下请求头:
| 请求头 | 描述 |
|---|---|
X-RateLimit-Limit | 当前窗口中此主体可用的点数 |
X-RateLimit-Remaining | 当前窗口中剩余的点数 |
X-RateLimit-Used | 当前窗口中已消耗的点数 |
X-RateLimit-Reset | 窗口重置时的 Unix 时间戳 (UTC 秒) |
X-RateLimit-Resource | 共享公共 API 预算始终为 core |
X-RateLimit-Reset 表示从响应时间起算的完整 60 秒窗口。计数窗口从一连串请求中的第一个计费请求开始,而非按自然分钟边界划分。
超出限额
当请求会超出预算时,API 会返回 HTTP 429,并包含:
Retry-After:重试前需等待的秒数 (60)- 相同的
X-RateLimit-*请求头,其中X-RateLimit-Remaining设为0
{ "code": 8, "message": "Rate limit exceeded: 3000 points per minute for this installation. Retry after 60s.", "details": []}重试前,请等待 Retry-After 指定的时间,或等到 X-RateLimit-Reset。当多个调用方共用一个安装令牌时,请使用带抖动的退避策略。
查看剩余配额
调用 获取速率限制 可在不消耗点数的情况下获取当前配额。响应体与共享 core 资源的 X-RateLimit-* 请求头相对应。
通用约定
分页
分页端点接受:
pageSize:默认值为 30,最大值为 100。pageToken:由上一页返回的不透明 token。请勿解析或自行构造。
响应使用 resource 特定的集合字段和 nextPageToken。没有下一页时,该字段为空。公开列表响应不包含总数。页面 token 与其来源 resource 和筛选条件绑定。筛选条件变更后,请重新开始分页。无效或不匹配的非空 token 将返回 400。
在同一请求序列中 (包括后续请求) ,每次请求都应发送相同的 pageSize。大多数列表端点会将与页面 token 一同发送的 pageSize 应用于该页;若省略 pageSize,则沿用上一页的大小。这些端点的 pageToken 条目中会注明这一点。其余端点的页面 token 所记录的信息各不相同,因此保持 pageSize 不变,即可在所有端点获得一致的页面大小。
错误
错误响应采用 Google RPC 风格的响应体:
{ "code": 5, "message": "resource not found", "details": []}常见的 HTTP 状态码包括 400、401、403、404、429、500 和 503。部分 Git 数据库操作在代码仓库状态冲突时还会返回 409。有关 429 请求头和重试行为,请参阅速率限制。
根据 HTTP 状态码和 code 对错误进行分支处理。将 message 视为面向开发者的文本。
404 永远不会区分资源不存在和应用无法访问资源这两种情况。应将其理解为 "此安装不可用",而非资源不存在的证明。
details 包含具有明确类型的条目:参数无效时的 google.rpc.BadRequest 字段违规,以及每个错误中的 google.rpc.RequestInfo 条目。Origin 可随时添加详细信息类型,因此请忽略集成无法识别的条目。
每个错误响应都会在两个位置携带请求 ID:X-Request-ID 响应请求头中,以及 details 中的 google.rpc.RequestInfo 条目。Origin 会回显你发送的 x-request-id,若未发送则会生成一个。即使 message 是不透明的内部错误,也会提供 RequestInfo 条目,因此就失败的调用联系 Cherri Code 时,请提供请求 ID。
/v1/origin 下未匹配的路径,以及在已知路径上使用错误 method 的请求,会返回相同的响应体,而非通用 router 错误。消息会注明 method 和路径,且绝不会回显 query string。
ID
Resource ID 是带有类型前缀的不透明 string,例如应用 ID 以 app_… 开头,安装 ID 以 i_… 开头。请将其作为完整的 string 进行存储和比较。不要解析 ID,不要从其字符推断含义,也不要依赖其排序顺序。
ID 在其 resource 的整个生命周期内保持不变,而名称和 slug 则可能变化。代码仓库重命名后仍保留原有 ID,因此缓存数据时应以 ID 而非 {ownerSlug}/{repoName} 作为键,并按照代码仓库路径中的说明,通过 ID 引用代码仓库。
代码仓库路径
代码仓库范围内的路径使用 {ownerSlug}/{repoName} 格式,包含所有者 slug 和代码仓库名称。两个部分的解析均不区分大小写,因此无论使用何种大小写都可定位到该代码仓库。响应返回的是存储的名称和 slug,而非你发送时使用的大小写;Git HTTPS URL 也以相同方式解析。比较代码仓库名称时应忽略大小写,并从 Get Repo 获取规范的大小写形式。
每个代码仓库范围内的路径也可以使用代码仓库的稳定 ID 来代替这一组合:将 _ 作为所有者 slug,并将 ID 作为代码仓库名称,例如 GET /v1/origin/repos/_/REPO_ID。从 Get Repo 的 id 字段读取 ID。保留值 _ 不能被声明为所有者 slug,因此这两种形式永远不会冲突。在 Connect 或 JSON 请求中,将 ownerSlug 设为 _,并将 name 设为 ID。
ID 形式在重命名后仍然有效,因此是定位代码仓库的稳定方式。它本身不授予任何权限:Origin 将 ID 解析为代码仓库后,你的 app 仍需要在该代码仓库上具有相同的 scope。你的 app 无法访问的 ID 会返回与不存在的 ID 相同的 404 响应体,因此响应绝不会确认某个代码仓库是否存在。格式错误的 ID 返回 400。创建代码仓库 仅接受所有者 slug,并拒绝 _。
资源引用
资源快照包含资源当前的字段。容器上下文使用紧凑引用,避免重复完整的资源:
RepositoryReference用于标识代码仓库。PullRequestReference用于标识 PR,并嵌套其代码仓库引用。ThreadReference用于标识包含 PR 评论的线程。OriginActor将公共操作人标识为user、app或serviceAccount之一。仅存在一个变体;请从该变体中读取身份信息。
Check runs
应用通过 Post Check Run 和 Batch Upsert Check Runs 将 CI 结果以 check suite 和 check run 的形式上报到某个提交,再通过 Checks 端点读回这些结果。本节定义这些端点共用的概念:哪一次尝试为当前尝试、源站如何对写入操作排序并上报,以及 timestamp 和截止时间的行为。
尝试与当前尝试
针对某个提交上报的每个 (actor, key, externalId) 都是一次 suite 尝试,其中每个 (suite, key, externalId) 都是一次 run 尝试。复用同一个 externalId 会就地更新该次尝试;使用新的 externalId 则会开启一次新尝试,并把此前的尝试保留为历史。被取代的尝试仍可通过 获取检查套件 和 获取检查 run 按 id 读取。
在 API 展示某个提交的当前检查的位置,即 List Check Suites For Commit、List Check Runs For Commit,以及 PR 的 CI 状态和必需检查中,源站会通过两步收敛这些尝试:
- 每个
(actor, key)的当前 suite 尝试,是其当前 run (按第二步选出) 携带最新externalUpdatedAt的那一次;没有 run 的 suite 则按自身的createdAt排序。若相同,则依次按 suite 的createdAt、id排序,最新在前。 - 在该 suite 尝试内,某个
key的当前 run 是externalUpdatedAt最新的那一次。若相同,则依次按createdAt、id排序,最新在前。
List Check Runs For Suite 只对你指定的 suite 应用第二步。只有当某个 run 所属的 suite 是该提交的当前 suite 尝试时,它才是该提交的当前 run。由于第一步是对整个 suite 尝试排序,只要另一次尝试的 externalUpdatedAt 更新,在已被取代的 suite 尝试下提交的 run 就不会出现在该提交的检查中;而一旦它的时间戳成为最新,其 suite 尝试就成为当前尝试,转而隐藏另一次尝试的 run。
已取消的尝试不会取代已通过的尝试。在任一步中,如果某个 key 最新的未取消尝试已通过,则已取消的尝试会排在该 key 的其他尝试之后。当 run 状态为 completed 且结论为 success、neutral 或 skipped 时,该 run 视为已通过。当 suite 尝试的所有当前 run 都已通过时,该 suite 尝试视为已通过;当其当前 run 均为 completed,且至少一个结论为 cancelled、其余均已通过时,该 suite 尝试视为已取消。当请求重新运行已通过的尝试时,externalUpdatedAt 等于或晚于该请求时间的已取消尝试会重新按时间戳排序。较新的已取消 suite 尝试仍会取代未完全通过的较早尝试。
已被请求重新运行的 run,仍会保持其 key 的当前尝试地位,并在所属应用作出响应前显示为待处理:参见 Rerequest Check Run。
写入排序
对于同一 suite 中 externalId 和 key 相同的同一个 run,源站按 checkRun.externalUpdatedAt 以毫秒精度对提交排序。只有当提交的值等于或晚于该 run 已存储的 externalUpdatedAt 时才会生效;若存在尚未完成的重新请求,该基准会提升为 rerequestedAt。值相等时同样生效,因此后提交者胜出,但有两种例外也被视为过时:queued 或 in_progress 的提交不能在相同时间戳上重新打开已 completed 的 run;以及在设置了 rerequestedAt 时,时间戳与存储值完全相同的提交会被忽略。更新的值会生效,包括重新打开已 completed 的 run,但有一种例外:无论时间戳如何,结论为 cancelled 的 completed 提交都不能替换结论为 success、neutral 或 skipped 的 completed run;此类提交会被视为过时。
过时的提交仍会返回成功。响应为 HTTP 200,其中返回的是已存储的 suite 和 run,而非提交的值,且该 run 的 updatedAt 不会变化。每个提交的 run 都会以一对值返回:checkRun 是调用后已存储的 run,outcome 是本次写入对它所做的操作。Post Check Run 在响应顶层返回这对值,与 checkSuite 并列。Batch Upsert Check Runs 在 results[] 中按请求顺序为每个提交的 run 返回一对值,因此批处理中每个元素携带的单个 run 结果,与单次调用内联返回的结果一致。读取 outcome 或各个 results[].outcome,即可了解本次写入的行为:
outcome | 含义 |
|---|---|
created | 该 suite 中不存在与 (externalId, key) 对应的 run;已创建一个。 |
updated | 已有的 run 被提交的值替换。 |
unchanged | 提交的值 (包括 externalUpdatedAt) 与已存储的 run 相同;未写入任何内容。 |
ignored_stale | 该提交因过时被忽略;checkRun 携带的是已存储的 run,而非提交的值。 |
unchanged 与 ignored_stale 两种提交都不会推进 updatedAt,因此无法据此区分二者,只能依靠 outcome。遇到无法识别的值时,应理解为“响应中是已存储的 run;是否发生写入未知”。在批处理中,源站会对每个 run 分别应用该规则:某个 run 过时不会导致整个批处理失败,results[] 会在该 run 对应的位置携带已存储的 run,并将 outcome 设为 ignored_stale。
在 Batch Upsert Check Runs 中,顶层的 checkRuns[] 已弃用,应改用 results[]。它仍会以相同顺序填充相同的已存储 run,但不携带 outcome;请改为读取 results[]。这仅适用于批处理:在 Post Check Run 中,应读取的顶层字段是 checkRun 和 outcome。
时间戳与截止时间
若某次提交的 externalUpdatedAt、startedAt 或 completedAt 比当前时间超前 60 秒以上,则返回 InvalidArgument (HTTP 400) 。当同一次提交中同时包含两者时,completedAt 不得早于 startedAt。deadlineAt 距当前时间不得超过 24 小时。
只有 in_progress 状态的运行会过期。一旦其 deadlineAt 已过,定期清理任务会以 timed_out 结论将其标记为完成;若该运行尚无 completedAt,则为其设置该值,并清除 deadlineAt,同时投递 repository.check_run.completed。过期处理发生在截止时间之后的若干分钟,而非恰好在截止时刻:清理任务默认约每 30 分钟运行一次,这属于可能调整的运维设置,因此请勿依赖该间隔。queued 状态的运行永不过期,没有 deadlineAt 的运行同样不会过期。completed 的提交会清除截止时间。源站将运行判定为超时时不会改动 externalUpdatedAt,因此后续携带更新的 externalUpdatedAt 的提交仍可作用于已超时的运行。
当前限制
- 合作伙伴 API 不支持在命名空间范围内列出或创建代码仓库。请通过安装来发现代码仓库。
- 提交 比较返回摘要数据,而不是嵌入式 提交 列表。修改的文件有自己的分页端点,列出比较文件。
- 线程仅能在解决操作中被引用。没有直接列出线程的端点;请从其包含的评论中读取它们。
- 推送 Webhook 不包含完整的 提交 列表。
- PR 合并支持原生 Origin 仓库,不支持镜像代码仓库。
- 镜像代码仓库在成为稳定的出站镜像之前,对安装为只读。参阅镜像代码仓库。
实施检查清单
- 将 Ed25519 私钥存储在机密信息管理服务中,并有计划地轮换密钥。请参阅生成应用签名密钥。
- 验证安装回调中的安装回执,并从其声明中读取安装 ID 和
state。 - 使用短期有效的 应用 JWT,并在需要时签发安装令牌。
- 对代码仓库范围的 API、check-run 写入操作和 Git HTTPS 使用安装令牌,而非 应用 JWT。
- 仅请求最低限度的 作用域 和代码仓库访问权限。
- 将 页面 token 视为 不透明,并在筛选条件变更时重新开始分页。
- 保持 check
key值稳定且易读。每次 retry 均使用新的不可变externalId,更新时使用递增的externalUpdatedAt值。 - 在每个 Post Check Run 响应中读取
outcome,并在每个 Batch Upsert Check Runs 响应中读取每一项results[].outcome;过期的提交会返回200及已存储的 run。请参阅 Check runs。 - 解析前,使用原始请求体验证 webhook 签名。
- 使用
webhook-id对投递进行去重,并在返回2xx后异步处理。 - 忽略未知的 JSON 字段,以实现前向兼容。
- 遵守
Retry-After和X-RateLimit-*请求头。使用 获取速率限制 在不消耗点数的情况下监控剩余点数。
端点参考
下载OpenAPI 规范,查看完整的组件架构。该文档将 https://api.cursor.com 声明为服务器,并定义了 bearerAuth HTTP Bearer 安全方案;每个操作都会列出该操作可能返回的响应代码,以及请求和响应示例。每个操作还带有 x-origin-scopes 扩展:scopes 表示该操作所需的作用域,tokenTypes 表示它接受的凭据类型。每个 webhook 负载架构都带有 x-origin-webhook-events 扩展,列出投递该负载的事件;预览版接口则带有 x-cursor-visibility: PREVIEW。路径参数与 URL 中使用的名称相同,即 ownerSlug 和 repoName。每个操作都带有唯一的 operationId;当一个操作对应两种 URL 形式时,第二种形式的 id 会带上 _2 后缀,例如 OriginService_GetRepoTarball_2。
JSON 代码段展示与架构相符的占位符值。响应字段描述反映 OpenAPI 架构和当前平台契约。
应用和安装
获取速率限制
/v1/origin/rate_limit返回已认证主体当前的公共 API 速率限制状态。
访问此端点不会消耗速率限制点数。响应包含该主体与其他公共 API 端点共用的每分钟点数预算。请参阅速率限制。
响应字段
resources object
resources.core object
resources.core.limit integer
resources.core.remaining integer
resources.core.reset integer
resources.core.used integer
rate object
resources.core 的别名。新客户端应优先使用 resources.core。curl --request GET \ --url 'https://api.cursor.com/v1/origin/rate_limit' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "resources": { "core": { "limit": 6000, "remaining": 5994, "reset": 1785682800, "used": 6 } }, "rate": { "limit": 6000, "remaining": 5994, "reset": 1785682800, "used": 6 }}获取已认证应用
/v1/origin/app返回已认证应用的元数据。
响应字段
id string
displayName string
webhookUrl string
events array
installation.* 事件始终会投递,且不会出现在此处。createdAt string
updatedAt string
installationRedirectUris array
namespaceSlug string
description string
websiteUrl string
defaultScopes array
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}列出应用安装
/v1/origin/app/installations列出已认证应用的安装。
查询参数
pageSize integer
pageToken string
next_page_token 返回的不透明游标。第一页为空。响应字段
installations array
installations[].id string
installations[].appId string
installations[].target object
installations[].target.slug string
installations[].target.id string
installations[].target.type string
team、user。未知时省略。installations[].createdAt string
installations[].updatedAt string
installations[].repoSelectionMode string
installations[].scopes array
installations[].installedBy object
installations[].installedBy.id string
user_。installations[].installedBy.email string
installations[].installedBy.displayName string
installations[].installedBy.handle string
@ 前缀。仅在该资料公开可见时提供;否则省略。installations[].suspendedAt string
installations[].deletedAt string
installation.deleted webhook 快照中携带;已删除的安装无法再通过 API 解析,因此该端点不会返回该字段。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/installations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "installations": [ { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "repoSelectionMode": "selected", "scopes": [ "repository:contents:read", "repository:pull_requests:read" ] } ]}获取应用安装
/v1/origin/app/installations/{installationId}返回已认证应用的单个安装。
repoSelectionMode 为 all 或 selected。
路径参数
installationId string 必填
响应字段
id string
appId string
target object
target.slug string
target.id string
target.type string
team、user。未知时省略。createdAt string
updatedAt string
repoSelectionMode string
scopes array
installedBy object
installedBy.id string
user_ 为前缀。installedBy.email string
installedBy.displayName string
installedBy.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。suspendedAt string
deletedAt string
installation.deleted webhook 快照中携带;已删除的安装无法再通过 API 解析,因此此端点永远不会返回该字段。curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "repoSelectionMode": "selected", "scopes": [ "repository:contents:read", "repository:pull_requests:read" ]}删除应用安装
/v1/origin/app/installations/{installationId}删除属于已认证应用的安装,并阻止签发新的安装令牌。已签发的短期令牌在过期前可能仍然有效 (最长 15 分钟) 。响应体为空。
路径参数
installationId string 必填
响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content创建安装访问令牌
/v1/origin/app/installations/{installationId}/access_tokens为已认证应用创建安装访问令牌。
需要使用应用 signing-JWT 身份验证,与 GetAuthenticatedApp 相同。令牌仅适用于指定的安装,该安装必须属于已认证应用。调用方可将令牌权限缩小为该安装所接受权限范围和可访问代码仓库的子集。
repositoryIds 可以指定镜像代码仓库。生成的令牌携带该安装的权限范围,Origin 仍会对每个请求应用镜像限制:请参阅镜像代码仓库。
路径参数
installationId string 必填
请求体
scopes array
repositoryIds array
响应字段
token string
expiresAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID/access_tokens' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoryIds": [ "repo_01k2ja2000e0080000000000q4" ]}'响应结构:
{ "token": "oit_2v8xkq4m1c7p9t3w5y0z6r4b", "expiresAt": "2026-08-01T10:30:00Z"}创建安装用户 token
/v1/origin/app/installations/{installationId}/user_access_tokens创建一个安装用户 token,以该安装所属命名空间中的一位成员的身份操作。
该安装必须属于已认证应用,且已接受 namespace:user_tokens:write。必须通过 userId 或 userEmail 指定用户,且只能使用其中一个。如果用户不存在、无法唯一确定或不符合使用条件,API 将返回 PermissionDenied (HTTP 403) ,且不会透露具体原因。
该 token 的访问权限仅限于安装和用户共同拥有的权限。如果同时设置了 scopes 和 repositoryIds,安装和用户都必须对列出的每个代码仓库拥有所请求的每项作用域权限,否则请求将返回 PermissionDenied (HTTP 403) 。完整流程请参阅代表用户操作。
路径参数
installationId string 必填
请求体
userId string
user_… ID,由 actor 负载返回。必须设置 userId 或 userEmail,且只能设置其中一个。userEmail string
scopes array
namespace:user_tokens:write 会返回 InvalidArgument (HTTP 400) ;该作用域用于授权签发 token,不能委托给 token。留空或省略则不限制作用域。repositoryIds array
响应字段
token string
expiresAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID/user_access_tokens' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "userId": "user_01k2ja2000e0080000000000c3", "scopes": [ "repository:pull_requests:reviews:write" ], "repositoryIds": [ "repo_01k2ja2000e0080000000000q4" ]}'响应结构:
{ "token": "YOUR_INSTALLATION_USER_TOKEN", "expiresAt": "2026-08-01T10:30:00Z"}列出应用安装可访问的代码仓库
/v1/origin/installation/repos列出已认证应用安装可访问的代码仓库。
需要由 CreateInstallationAccessToken 签发的安装访问令牌 (oit_) 。
合作伙伴可通过此端点发现其仓库。列表条目为简要的仓库摘要;如需完整的时间戳,请使用 Get Repo。Get Repo 包含仅供输出的 cloneUrl。
结果中包含镜像仓库。镜像在成为稳定的出站镜像之前为只读:参见镜像仓库。
查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页时为空。请求后续页面时必须使用相同的过滤条件。后续请求中的 pageSize 仅作用于该页;省略此参数则沿用上一页的页面大小。filter string
owner/repo 值会将两部分分别与对应字段匹配。开头和结尾的空白字符将被忽略;值为空时不应用任何筛选。响应字段
repositories array
repositories[].id string
repositories[].name string
repositories[].fullName string
repositories[].owner object
repositories[].owner.slug string
repositories[].owner.id string
repositories[].owner.type string
team、user。未知时省略。repositories[].defaultBranch string
repositories[].mirror 对象
repositories[].mirror.source string
github。repositories[].mirror.sourceId string
repositories[].mirror.status string
inbound、outbound。repositories[].visibility string
internal、private。repositories[].allowMergeCommit boolean
repositories[].allowSquashMerge boolean
repositories[].deleteBranchOnMerge boolean
nextPageToken string
repoSelectionMode string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/installation/repos' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" } ], "repoSelectionMode": "selected"}列出 Webhook 投递记录
/v1/origin/app/webhook/deliveries列出已认证应用的 Webhook 投递记录,按最新优先排序。
一次投递是欠某个应用的一次事件;其 id 是接收方看到的 webhook-id 请求头的值。delivered=false 是恢复谓词:它会选择所有从未收到 2xx 的投递,包括在故障期间其重试阶梯耗尽的投递。
投递在创建后七天内可列出,且仅在您的应用在该投递所属命名空间中有活动安装时可见。面向应用的生命周期事件 (例如 installation.deleted) 在其所描述的卸载发生后仍然可见。
查询参数
delivered 布尔值
delivered_at 进行比较。delivered=false 是恢复谓词:它在服务器端评估,因此不会像调用方提供的时间窗口那样,在故障期间重试阶梯耗尽时悄然漏掉某次投递。eventType string
pull_request.created。installationId string
WebhookDelivery.installation.id) 。createdAfter string
createdBefore string
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页为空。响应字段
deliveries 数组
deliveries[].id 字符串
webhook-id 值;将其用作幂等键。deliveries[].event 对象
deliveries[].event.id string
deliveries[].event.type string
deliveries[].installation 对象
id 是目标所有者当前的活动安装;如果不存在则不设置 (仅在卸载后的面向应用的生命周期事件中可能出现) 。deliveries[].installation.id string
deliveries[].installation.target 对象
deliveries[].installation.target.slug string
deliveries[].installation.target.id string
deliveries[].installation.target.type string
team、user。未知时省略。deliveries[].createdAt string
deliveries[].deliveredAt string
deliveries[].lastAttempt 对象
deliveries[].lastAttempt.id 字符串
deliveries[].lastAttempt.deliveryId string
deliveries[].lastAttempt.trigger string
automatic、manual。deliveries[].lastAttempt.responseStatusCode 整数
deliveries[].lastAttempt.latencyMs integer
deliveries[].lastAttempt.errorMessage string
deliveries[].lastAttempt.attemptedAt string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/webhook/deliveries' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "deliveries": [ { "id": "whd_01k2ja2000e0080000000000j9", "event": { "id": "evt_01k2ja2000e0080000000000r5", "type": "pull_request.created" }, "installation": { "id": "inst_01k2ja2000e0080000000000b2", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "createdAt": "2026-08-01T09:30:00Z", "deliveredAt": "2026-08-02T14:45:05Z", "lastAttempt": { "id": "wha_01k2ja2000e0080000000000k0", "deliveryId": "whd_01k2ja2000e0080000000000j9", "trigger": "automatic", "responseStatusCode": 200, "latencyMs": 182, "attemptedAt": "2026-08-02T14:45:05Z" } } ]}批量重新投递 Webhook 投递记录
/v1/origin/app/webhook/deliveries:batchRedeliver请求 Origin 重新发送投递记录。
该请求表示“确保这些记录中的每条都有一次发送正在进行”,而非“新增一次发送”。它会为每个唯一输入返回一个结果,不会因某个无效条目而使整个批次失败,因此单个过期 ID 不会阻塞恢复页中的其余记录。202 表示发送已排队;投递本身是异步的,因此请轮询 列出 Webhook 投递记录 查看结果。
请求体
deliveryIds array 必填
pageSize 上限一致。重复项会被移除,并保留首次出现的顺序。空列表或超过 100 个唯一条目将返回 InvalidArgument (HTTP 400)。响应字段
results array
results[].deliveryId string
results[].outcome string
queued,已有发送正在进行时为 already_in_flight,否则为 not_found。already_in_flight 表示成功,而非错误。not_found 包括未知 ID、早于七天保留期的 ID,以及未再安装您的应用的命名空间。curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/webhook/deliveries:batchRedeliver' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "deliveryIds": [ "whd_01k2ja2000e0080000000000j9" ]}'响应结构:
{ "results": [ { "deliveryId": "whd_01k2ja2000e0080000000000j9", "outcome": "queued" } ]}Ping Webhook
/v1/origin/app/webhook/pings向已认证应用的 webhook URL 发送测试投递,并返回接收方的响应情况。
配置应用时,可使用此操作验证接收方,无需等待真实事件。与 获取已认证应用 一样,需要使用应用 signing-JWT 进行身份验证。
接收方将收到生产环境格式的数据:相同的请求头和 v1ed 签名,可通过签名密钥验证;webhook-event-type 设为 ping,负载中会标明应用名称。ping 不关联任何安装,因此不包含 webhook-installation-id 请求头和信封中的 installationId。
Origin 会同步发送一次 ping,并在响应中返回结果。不会重试,且 ping 不属于域名事件:它不会出现在 列出 Webhook 投递记录 中,也无法重新投递。接收方处理失败会在响应中体现,而不会返回错误。未配置 webhook URL 的应用会返回 FailedPrecondition (HTTP 400) 。
请求体
请求不接受任何字段。请发送空 JSON 对象。
响应字段
deliveryId string
webhook-id,与接收方收到的请求头中的值一致。eventId string
event.id 的值相同。delivered boolean
2xx 状态时为 true。始终存在。responseStatusCode integer
0。始终存在。curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/webhook/pings' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{}'响应结构:
{ "deliveryId": "whd_01k2ja2000e0080000000000j9", "eventId": "evt_01k2ja2000e0080000000000r5", "delivered": true, "responseStatusCode": 200}获取应用
/v1/origin/apps/{appId}按标识符返回单个应用。这是供应用发布者使用的管理读取接口;Get Authenticated App 则是使用应用自身 JWT 凭据的等效自读取接口。
Path Parameters
appId string 必填
app_。Response Fields
id string
app_。displayName string
webhookUrl string
events array
installation.* 事件始终会投递,且不会出现在此处。createdAt string
updatedAt string
installationRedirectUris array
namespaceSlug string
description string
websiteUrl string
defaultScopes array
curl --request GET \ --url 'https://api.cursor.com/v1/origin/apps/{appId}' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}更新应用
/v1/origin/apps/{appId}更新应用的设置。省略的字段保持不变,且至少需提供一个可设置的字段。通过发送空字符串清除 webhookUrl 会禁用对外的 webhook 投递,并取消该应用待处理的投递;之后重新设置 URL 也不会恢复已取消的投递。
路径参数
appId string 必填
app_ 为前缀。请求体
displayName string
webhookUrl string
events object
events.events 数组
installation.* 事件始终会投递,无法在此列出。description string
websiteUrl string
installationRedirectUris object
installationRedirectUris.installationRedirectUris 数组
defaultScopes object
defaultScopes.scopes 数组
响应字段
id string
app_ 为前缀。displayName string
webhookUrl string
events array
installation.* 事件始终会投递,不会在此列出。createdAt string
updatedAt string
installationRedirectUris 数组
namespaceSlug string
description string
websiteUrl string
defaultScopes 数组
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/apps/APP_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "webhookUrl": "https://ci.acme.dev/webhooks/origin-v2", "events": { "events": [ "pull_request.created", "pull_request.merged", "repository.pushed" ] }}'响应结构:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin-v2", "events": [ "pull_request.created", "pull_request.merged", "repository.pushed" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}添加应用签名密钥
/v1/origin/apps/{appId}/signing_keys向应用添加一个签名密钥。应用可持有的当前有效的签名密钥数量有上限;超出上限后再添加密钥会返回 FailedPrecondition (HTTP 400) ,直到吊销其他密钥为止。若密钥已注册,则返回 AlreadyExists (HTTP 409 Conflict) 。
路径参数
appId string 必填
app_。请求体
publicKey string 必填
响应字段
kid string
kid 请求头,也可用于吊销该密钥。createdAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/apps/APP_ID/signing_keys' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "publicKey": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAq9zTf3hL6wXe1cVj0bYs5mKR8uDnG2oAaPp4NiEkKlM=\n-----END PUBLIC KEY-----"}'响应结构:
{ "kid": "3q2xW9dK5fJm8vB1nY6cT0aZrQpLh4eGkVsN7uMxOdI", "createdAt": "2026-08-02T14:45:00Z"}吊销应用签名密钥
/v1/origin/apps/{appId}/signing_keys/{kid}按密钥 ID 吊销应用签名密钥。使用已吊销密钥签名的应用 JWT 将无法再通过认证。最后一个当前有效的签名密钥无法吊销,此类请求会返回 FailedPrecondition (HTTP 400) 。响应体为空。
路径参数
appId string 必填
app_。kid string 必填
响应字段
请求成功时不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/apps/{appId}/signing_keys/{kid}' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content列出 命名空间 应用
/v1/origin/namespaces/{namespaceSlug}/apps列出某个命名空间拥有的应用,最新的排在前面。响应仅包含用于展示的 metadata;如需读取某个应用的 webhook 配置,请使用 Get App。
路径参数
namespaceSlug string 必填
Query Parameters
pageSize integer
pageToken string
next_page_token 返回的不透明游标。首页时为空。响应字段
apps array
apps[].id string
app_。apps[].displayName string
apps[].description string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/namespaces/{namespaceSlug}/apps' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "apps": [ { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "description": "Posts CI status on pull requests." }, { "id": "app_01k2ja2000e0080000000000a2", "displayName": "Deploy Bot", "description": "" } ], "nextPageToken": ""}创建应用
/v1/origin/namespaces/{namespaceSlug}/apps创建一个归属于某个 namespace 的 app。新建的 app 默认为私有。请在本地生成 Ed25519 key pair,并且只发送 public key;Origin 会将其存储,用于验证该 app 的 JWT。若 webhook URL、event type、重定向 URI 或 scope 无效,则返回 InvalidArgument (HTTP 400) 。
发起请求时,namespace 所有者必须具备向 Origin 写入的资格,这与创建代码仓库的要求相同。个人所有者必须使用 Pro、Pro Student、Pro+、Ultra 或 Start 方案。团队所有者必须拥有有效的付费团队方案,不得启用隐私模式 (旧版) ,且未被团队管理员关闭 Origin。若所有者不符合资格,则返回 FailedPrecondition (HTTP 400) 。Origin 读取的是 namespace 所有者的资格,而非调用方用户的资格。
路径参数
namespaceSlug string 必填
请求体
displayName string 必填
publicKey string 必填
webhookUrl string
events array
installation.* 事件。description string
websiteUrl string
installationRedirectUris 数组
defaultScopes 数组
repository:contents:read。安装时仍可显式指定作用域。响应字段
id string
app_ 为前缀。displayName string
webhookUrl string
events array
installation.* 事件始终都会投递,因此不会出现在此处。createdAt string
updatedAt string
installationRedirectUris 数组
namespaceSlug string
description string
websiteUrl string
defaultScopes 数组
curl --request POST \ --url 'https://api.cursor.com/v1/origin/namespaces/NAMESPACE_SLUG/apps' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "displayName": "CI Status Bot", "publicKey": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAv7wFoV1bC9yKq3nZ8dQmXh5uJb2tR4sEwG6aP0iN8kY=\n-----END PUBLIC KEY-----", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}'响应结构:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-01T09:30:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}添加应用安装的仓库
/v1/origin/namespaces/{namespaceSlug}/installations/{installationId}/repos将仓库添加到某个安装的代码仓库选择范围中,并返回更新后的安装。该写入操作为增量操作:列出的仓库会并入当前选择;如果请求中列出的仓库已全部被授予,则请求成功但不作任何更改;安装的作用域始终不会改变。
列出的每个代码仓库都必须属于目标命名空间,否则请求将返回 FailedPrecondition (HTTP 400) 且不会授予任何权限。以下情况同样返回该错误:安装已覆盖该命名空间中的所有仓库 (repoSelectionMode 为 all)、安装处于挂起状态,以及安装早于支持按安装设置作用域的版本。若安装不存在或属于其他命名空间,则返回 404;当该应用从未在此命名空间中安装过时,错误消息会指明需要打开的授权页面,因为此端点无法执行首次安装。
调用方必须使用拥有该命名空间安装管理权限的 Cherri Code 用户凭据。应用令牌、安装令牌和服务账户无法更改安装的仓库。
路径参数
namespaceSlug string 必填
installationId string 必填
请求体
repoIds array 必填
响应字段
id string
appId string
target object
target.slug string
target.id string
target.type string
team、user。未知时省略。createdAt string
updatedAt string
repoSelectionMode string
scopes 数组
installedBy object
installedBy.id string
user_ 为前缀。installedBy.email string
installedBy.displayName string
installedBy.handle string
@ 前缀。仅当该配置文件公开可见时提供,否则省略。suspendedAt string
deletedAt string
installation.deleted Webhook 的快照中;已删除的安装不再可通过 API 解析,因此此端点不会返回该安装。curl --request POST \ --url 'https://api.cursor.com/v1/origin/namespaces/NAMESPACE_SLUG/installations/INSTALLATION_ID/repos' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "repoIds": [ "repo_01k2ja2000e0080000000000q4", "repo_01k2ja2000e0080000000000q5" ]}'响应结构:
{ "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "repoSelectionMode": "selected", "scopes": [ "repository:contents:read", "repository:pull_requests:read", "repository:metadata:read" ]}代码仓库
cloneUrl 是仅输出的 HTTPS 克隆 URL。Get Repo 会返回 cloneUrl。
合作伙伴可通过 列出应用安装可访问的代码仓库 查找其代码仓库。合作伙伴 API 不支持按命名空间列出或创建代码仓库。
列出命名空间
/v1/origin/namespaces列出你可在其中列出仓库的命名空间,按 slug 排序。
候选范围包括你所在团队的命名空间、你的个人命名空间,以及包含已授权给你的仓库的命名空间。仅返回你拥有 namespace:repositories:read 权限的命名空间,因此每个结果都可作为 列出仓库 的有效 ownerSlug。
调用方必须使用 Cherri Code 用户凭据;此调用本身无需任何作用域。应用 token、安装令牌和服务账户调用时会收到 PermissionDenied (HTTP 403) 。
查询参数
pageSize integer
pageToken string
next_page_token 返回的不透明游标。请求首页时留空。后续请求中的 pageSize 仅作用于该页;省略则沿用上一页的分页大小。响应字段
namespaces array
namespaces[].namespace object
namespaces[].namespace.slug string
ownerSlug 传入。namespaces[].namespace.id string
namespaces[].namespace.type string
team、user。类型未知时省略。namespaces[].viewerCanCreateRepositories boolean
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/namespaces' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "namespaces": [ { "namespace": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "viewerCanCreateRepositories": true }, { "namespace": { "slug": "jane", "id": "ns_01k2ja2000e0080000000000p4", "type": "user" }, "viewerCanCreateRepositories": false } ]}列出仓库
/v1/origin/repos/{ownerSlug}列出指定所有者实体下的仓库。
路径参数
ownerSlug string 必填
查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页为空。后续请求中的 pageSize 作用于所请求的该页;省略则沿用上一页的页面大小。filter string
响应字段
repositories array
repositories[].id string
repositories[].name string
repositories[].fullName string
repositories[].owner object
repositories[].owner.slug string
repositories[].owner.id string
repositories[].owner.type string
team、user。未知时省略。repositories[].defaultBranch string
repositories[].createdAt string
repositories[].updatedAt string
repositories[].pushedAt string
repositories[].cloneUrl string
repositories[].mirror 对象
repositories[].mirror.source string
github。repositories[].mirror.sourceId string
repositories[].mirror.status string
inbound, outbound.repositories[].visibility string
internal、private。repositories[].allowMergeCommit boolean
repositories[].allowSquashMerge boolean
repositories[].deleteBranchOnMerge boolean
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" } ]}Get Repo
/v1/origin/repos/{ownerSlug}/{repoName}根据 (owner_id, name) 标识符返回单个仓库。
cloneUrl 是仅输出的 HTTPS 克隆 URL。Get repository 会包含 cloneUrl。
路径参数
ownerSlug 字符串 必填
repoName string 必填
响应字段
id string
name string
fullName string
owner object
owner.slug string
owner.id string
owner.type string
team、user。未知时省略。defaultBranch string
createdAt string
updatedAt string
pushedAt string
cloneUrl string
mirror 对象
mirror.source string
github。mirror.sourceId string
mirror.status string
inbound、outbound。visibility string
internal、private。allowMergeCommit boolean
allowSquashMerge boolean
deleteBranchOnMerge boolean
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git"}更新仓库
/v1/origin/repos/{ownerSlug}/{repoName}更新代码仓库设置。省略的字段保持不变,且至少须提供一个可设置的字段。
设置按固定顺序以独立群组的形式生效:默认分支、自动删除 head 分支、可见性,最后是合并方式。跨群组的更新不是原子操作。当某个群组被拒绝时,排在它之前的群组已经生效且会保持生效,因此请修正被拒绝的群组后重试,以收敛到你期望的状态。响应返回的代码仓库状态为最后一个成功生效的群组应用之后的状态。
未设置任何字段的请求将返回 InvalidArgument (HTTP 400) 。对默认分支的并发修改将返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
defaultBranch string
FailedPrecondition (HTTP 400) 。allowMergeCommit boolean
allowSquashMerge 一同发送,且两者中至少有一个必须为 true。若只发送其中一个,将返回 InvalidArgument (HTTP 400) 。allowSquashMerge boolean
allowMergeCommit 一同发送,且两者中至少有一个为 true。仅发送其中一个会返回 InvalidArgument (HTTP 400) 。deleteBranchOnMerge boolean
FailedPrecondition (HTTP 400) 。visibility string
internal、private。省略此项则保持可见性不变。响应字段
id string
name string
fullName string
owner 对象
owner.slug string
owner.id string
owner.type string
team、user。未知时省略。defaultBranch string
createdAt string
updatedAt string
pushedAt string
cloneUrl string
mirror 对象
mirror.source string
github。mirror.sourceId string
mirror.status string
inbound、outbound。visibility string
internal、private。allowMergeCommit boolean
allowSquashMerge boolean
deleteBranchOnMerge boolean
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "defaultBranch": "main", "allowMergeCommit": false, "allowSquashMerge": true, "deleteBranchOnMerge": true, "visibility": "private"}'响应结构:
{ "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git", "visibility": "private", "allowMergeCommit": false, "allowSquashMerge": true, "deleteBranchOnMerge": true}创建仓库
/v1/origin/repos/{ownerSlug}为指定所有者创建仓库。
发起请求时,所有者必须具备向 Origin 写入的资格。用户所有者必须使用 Pro、Pro Student、Pro+、Ultra 或 Start 方案。团队所有者必须拥有生效的付费团队方案,且不得处于隐私模式 (旧版) ,也不得被团队管理员关闭 Origin。若所有者不具备资格,则返回 FailedPrecondition (HTTP 400) 。读取已有仓库不受此要求限制。
代码仓库名称以不区分大小写的方式被占用。若某个名称仅在大小写上与该所有者已有的仓库不同,则会被拒绝,因此 widgets 和 Widgets 不能共存于同一命名空间。你提交的名称将按原样存储。
向新仓库的首次推送可能会重新指定其默认分支。当该次推送仅创建分支且这些分支中没有任何一个是仓库已存储的默认分支时,Origin 会将默认分支设为所创建的分支;如果该推送创建了多个分支且其中包含 main 或 master,则设为 main 或 master。其他情况下默认分支保持不变。可通过 Get Repo 读取当前值。
路径参数
ownerSlug string 必填
请求体
name string 必填
defaultBranch string
响应字段
id string
name string
fullName string
owner object
owner.slug string
owner.id string
owner.type string
team、user。未知时省略。defaultBranch string
createdAt string
updatedAt string
pushedAt string
cloneUrl string
mirror object
mirror.source string
github。mirror.sourceId string
mirror.status string
inbound、outbound。visibility string
internal、private。allowMergeCommit boolean
allowSquashMerge boolean
deleteBranchOnMerge boolean
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "rocket", "defaultBranch": "main"}'响应结构:
{ "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git"}列出分支
/v1/origin/repos/{ownerSlug}/{repoName}/branches按名称升序列出仓库的分支及其最新提交,使用 page_size 和 page_token 分页。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页为空。该值编码了续取位置。后续请求中的 pageSize 仅作用于该页;若省略,则沿用上一页的页面大小。响应字段
branches array
branches[].name string
branches[].commit object
branches[].commit.sha string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/branches' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "branches": [ { "name": "main", "commit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" } } ]}获取代码仓库 Tarball
/v1/origin/repos/{ownerSlug}/{repoName}/tarball/{ref}下载代码仓库在 ref 对应树的 gzip 压缩 tar 包。
Origin 按代码仓库和 ref 解析到的提交索引归档文件。针对某个提交的首次请求会返回 200,Content-Type: application/gzip,并将归档文件作为响应体流式传输。后续针对同一提交的请求会返回 302,响应体为空,且 Location 中包含有效期为 15 分钟的签名下载 URL;请跟随重定向获取数据。归档文件包含一个名为 {ownerSlug}-{repoName}-{shortSha}/ 的顶层目录,其中 shortSha 是解析后提交的前 7 个十六进制字符,与 GitHub 的 tarball 端点布局一致。空代码仓库返回 ABORTED (HTTP 409 Conflict) ,无法解析的引用返回 404。
如果引用包含 "/",请将其作为查询参数而非路径段发送:GET /v1/origin/repos/{ownerSlug}/{repoName}/tarball?ref=refs/heads/main。省略该参数将归档代码仓库的默认分支。
路径参数
ownerSlug string 必填
repoName string 必填
ref string 必填
refs/heads/... 或 refs/tags/...,或符号引用 HEAD。不支持 glob 或 revspec,因此会拒绝 <rev>~3。为空时使用代码仓库默认分支。响应字段
sha string
downloadUrl string
302 的 Location 请求头发送。curl --request GET --location --output repo.tar.gz \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/tarball/HEAD' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "downloadUrl": "https://artifacts.origin.cursor.com/tarballs/0192f7a4-6c1e-7b3a-9f21-3d54c9a7e6b0/9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4.tar.gz?Expires=1767225600&Signature=EXAMPLE&Key-Pair-Id=KEXAMPLE123", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}同步镜像
/v1/origin/repos/{ownerSlug}/{repoName}:syncMirror将镜像代码仓库的一个引用与其上游源同步。同步目标达成时返回 HTTP 200,同步仍在进行时返回 HTTP 202。wait=false (默认值) 会安排同步,通常返回 202;如果可从 ref 访问到 sha,则会立即返回 200。wait=true 会阻塞至同步完成或等待时限 (约 2 分钟) 到期;到期后仍会返回 202,同步将在后台继续。不从上游源拉取的代码仓库将被拒绝。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
ref string 必填
refs/ 开头,且该前缀后必须指定引用,例如 refs/heads/main 或 refs/tags/v1。main 等短名称会被拒绝,并返回 INVALID_ARGUMENT。wait boolean
sha string
ref 的最新提交。设置后,如果可从 ref 访问到该值,调用会提前返回,无需等待其他镜像任务完成。其他值会被拒绝,并返回 INVALID_ARGUMENT。响应字段
synced boolean
200,false 时为 202。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME:syncMirror' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "refs/heads/main", "wait": true}'响应结构:
{ "synced": true}镜像转换端点的文档位于 Origin Migration API。同步镜像 仍保留在本页面。
分离代码仓库镜像
参见 Detach 代码仓库镜像。
获取镜像转换作业
参见 获取镜像转换作业。
获取活跃的镜像转换作业
强制代码仓库镜像切换
参见强制代码仓库镜像切换。
转换代码仓库镜像
参见转换代码仓库镜像。
检查
- 首次执行更新或插入操作时,会自动创建相应的检查套件。
- 必需检查会与安装该应用的应用以及套件
key匹配,也可选择与 runkey匹配。name仅用于显示,不参与匹配。 - 请在多次尝试中保持
key值稳定且易于用户理解,因为必需检查的配置以它们为键。 - 重用
externalId可更新一次尝试,这会丢弃该尝试之前的结果;重试时请使用新的externalId,以便将较早的尝试保留为历史记录。 - 使用
checkRun.output提供用户可读的结果:title:简短的结果标题,最多 255 个字符。summary:主要的 Markdown 摘要,最多 65,535 个 UTF-8 字节。text:扩展的 Markdown 详细信息,最多 65,535 个 UTF-8 字节。
- 使用
detailsUrl链接到提供方的外部结果页面。
Check runs 定义了哪次尝试为当前尝试、externalUpdatedAt 如何为写入操作排序、outcome 报告哪些内容,以及这些端点共用的时间戳与截止时间规则。
创建检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs使用具有 repository:checks:write 权限的安装访问令牌对检查套件和检查运行执行 upsert 操作。写入操作归属于拥有已认证安装的应用。使用相同的 (repo, head_sha, suite.key, check.key) 重复调用时,会就地更新现有的检查运行,而不会创建重复项。
该端点以原子方式查找或创建套件尝试,并对一次运行尝试执行 upsert (更新或插入) 。externalUpdatedAt 用于确定同一运行标识的更新顺序;过期重试不会覆盖较新的状态,且 cancelled 状态的完成结果不能替换已存储的通过结果;参见写入顺序。被忽略的过期提交和重复已存储值的提交,都会返回 200 以及已存储的套件和运行,因此应读取 outcome,以区分 ignored_stale 和 unchanged 与 created 和 updated。这两种情况下 updatedAt 都不会变化,因此无法据此区分。
在同一个 suite 内,某个运行 key 的当前尝试是 externalUpdatedAt 最新的那次运行;若相同,则依次按 createdAt、id 排序,最新者优先。针对某个提交上报的每个 (actor, key, externalId) 即为一次 suite 尝试;每个 (actor, key) 的当前尝试是其运行带有最新 externalUpdatedAt 的那次,而没有任何运行的 suite 则按其自身的 createdAt 排序。只有当某次运行所属的 suite 是该提交的当前尝试时,该运行才是该提交的当前运行;因此,只要同一 suite 的另一次尝试有更新的活动,以较早的 suite externalId 提交的运行就不会出现在以提交为作用域的列表中。在这两个层级上,已取消的尝试都不会取代已通过的尝试,具体规则参见尝试与当前尝试。被取代的尝试仍可按 id 读取。
deadlineAt 记录运行的可选截止时间。Origin 会存储该值、在读取时返回,并在运行变为 completed 时将其清除。超过当前时间 24 小时的截止时间会被以 InvalidArgument (HTTP 400) 拒绝,而不是被截断。
当某个仍处于 in_progress 的运行超过截止时间时,Origin 会自行以 timed_out 结论完成该运行,若该运行尚无 completedAt 则为其设置该值,并发送 repository.check_run.completed。过期处理作为周期性扫描运行,而不是基于每个运行的定时器,因此过期会在截止时间之后数分钟才生效,而非恰好在截止时间生效。该扫描默认约每 30 分钟运行一次,这是一项可能变更的运维设置。处于 queued 状态的运行永不过期,未包含 deadlineAt 的运行也不会过期。在截止时间之前自行完成该运行即可清除其截止状态。Origin 在将运行判定为超时时不会更改该运行的 externalUpdatedAt,因此来自你的提供者的后续完成仍然可以覆盖 timed_out 结论。
路径参数
ownerSlug 字符串 必填
repoName string 必填
请求体
headSha string 必填
checkSuite 对象 必填
checkSuite.key 字符串 必填
checkSuite.name string 必填
checkSuite.detailsUrl string
checkSuite.externalId string 必填
checkRun 对象 必填
checkRun.key string 必填
checkRun.name string 必填
checkRun.status string 必填
CHECK_RUN_LIFECYCLE_STATUS_UNSPECIFIED、queued、in_progress、completed。模式还列出了 rerequested,该值仅在重新请求时由 Origin 设置;携带该值的请求会返回 InvalidArgument (HTTP 400) 。checkRun.conclusion string
status == completed 时为必填。允许的值:CHECK_RUN_CONCLUSION_UNSPECIFIED、success、failure、neutral、cancelled、skipped、timed_out、action_required、stale。checkRun.externalUpdatedAt string 必填
checkRun.startedAt string
InvalidArgument (HTTP 400)。checkRun.completedAt string
InvalidArgument (HTTP 400);如果与 startedAt 一并提交且早于 startedAt,同样会返回该错误。checkRun.detailsUrl string
checkRun.externalId string 必填
checkRun.output 对象
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
InvalidArgument (HTTP 400) 拒绝。创建时省略此字段表示不记录截止时间;更新时省略此字段表示保留已存储的截止时间不变。checkRun.isRerequestable boolean
true 即表示你的应用承诺订阅 repository.check_run.rerequested,并在每次投递时作出响应,方法是为相同的 head SHA 和 key 发布一条新的运行:要么使用新的 externalId 创建新运行,将旧的尝试保留为历史记录;要么使用相同的 externalId 更新被重新请求的运行,就地刷新该运行。在该新发布到达之前,被重新请求的运行在提交的最新检查状态中将显示为待处理,因此必需的检查会阻止合并,PR 会显示该运行正等待其重运行;声明可重新请求但不作出响应会使该检查处于搁置状态。你发布时,Origin 不会验证该订阅。省略此字段可保留已存储的值 (新运行默认为 false) ;发送 false 可撤回该声明。响应字段
checkSuite 对象
checkSuite.id string
checkSuite.repository 对象
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner 对象
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team、user。未知时省略。checkSuite.sha string
checkSuite.key string
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId string
checkSuite.actor 对象
checkSuite.actor.user 对象
checkSuite.actor.user.id string
checkSuite.actor.user.email string
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
@ 前缀。仅在该资料公开可见时存在;否则省略。checkSuite.actor.app 对象
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount 对象
checkSuite.actor.serviceAccount.id string
checkRun 对象
checkRun.id string
checkRun.repository 对象
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner 对象
checkRun.repository.owner.slug string
checkRun.repository.owner.id string
checkRun.repository.owner.type string
team、user。未知时省略。checkRun.checkSuite 对象
checkRun.checkSuite.id string
checkRun.sha string
checkRun.key string
checkRun.name string
checkRun.status string
checkRun.conclusion string
status 为 completed 时才读取。checkRun.detailsUrl string
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
checkRun.externalId string
checkRun.actor object
actor。checkRun.actor.user 对象
checkRun.actor.user.id string
checkRun.actor.user.email string
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
@ 前缀。仅在该资料公开可见时存在;否则省略。checkRun.actor.app 对象
checkRun.actor.app.id string
checkRun.actor.app.displayName string
checkRun.actor.serviceAccount 对象
checkRun.actor.serviceAccount.id string
checkRun.output 对象
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
checkRun.isRerequestable boolean
checkRun.rerequestedAt string
status 就为 rerequested,该运行将保留在该提交的最新检查状态并显示为待处理,而 conclusion 和计时仍保留被取代的结果;因此在该应用作出响应之前,必需的检查会阻止合并。checkRun.rerequestedBy 对象
actor 相同的 actor 变体。只要设置了 rerequestedAt 就会存在,并随其一同清除。outcome string
checkRun 执行的操作。允许的值:created、updated、unchanged、ignored_stale。因数据过时而被忽略的提交,以及重复已存储值的提交,都会返回已存储的运行;此字段是区分二者的唯一方式。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "checkSuite": { "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "build-8842" }, "checkRun": { "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "run-8842", "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }}'响应结构:
{ "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }, "outcome": "created"}批量更新或插入检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs:batchUpsert以原子方式对属于同一测试套件的多个检查运行执行 upsert 操作。该请求最多接受 10 个运行,并拒绝重复的 (external_id, key) 标识。要么所有运行全部提交,要么整个请求回滚。
每个运行均接受与 Post Check Run 相同的可选 deadlineAt。
Origin 会分别对每个运行应用 externalUpdatedAt 排序规则。被判为过时而被忽略的运行不会导致批处理失败:响应会在其位置返回已存储的运行,且 results[].outcome 会按请求顺序报告每个运行的裁决。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
headSha string 必填
checkSuite 对象 必填
checkSuite.key string 必填
checkSuite.name string 必填
checkSuite.detailsUrl string
checkSuite.externalId string 必填
checkRuns 数组 必填
(external_id, key) 的组合唯一。checkRuns[0].key string 必填
checkRuns[0].name string 必填
checkRuns[0].status string 必填
CHECK_RUN_LIFECYCLE_STATUS_UNSPECIFIED、queued、in_progress、completed。schema 中还列出了 rerequested,该值仅由 Origin 在重新请求时设置;携带该值的请求会返回 InvalidArgument (HTTP 400) 。checkRuns[0].conclusion string
status == completed 时必填。允许的值:CHECK_RUN_CONCLUSION_UNSPECIFIED、success、failure、neutral、cancelled、skipped、timed_out、action_required、stale。checkRuns[0].externalUpdatedAt string 必填
checkRuns[0].startedAt string
InvalidArgument (HTTP 400) 。checkRuns[0].completedAt string
InvalidArgument (HTTP 400) ;如果与 startedAt 一并提交且早于 startedAt 的值也会返回该错误。checkRuns[0].detailsUrl string
checkRuns[0].externalId string 必填
checkRuns[0].output 对象
checkRuns[0].output.title string
checkRuns[0].output.summary string
checkRuns[0].output.text string
checkRuns[0].deadlineAt string
InvalidArgument (HTTP 400) 被拒绝,而不是被截断。创建时省略表示不记录截止时间;更新时省略表示保持已存储的截止时间不变。checkRuns[0].isRerequestable boolean
true 即表示你的应用承诺订阅 repository.check_run.rerequested,并在每次投递时通过为相同的 head SHA 和 key 发布新的运行来响应:要么使用新的 externalId 创建新运行,将旧尝试保留为历史;要么使用相同的 externalId 更新被重新请求的运行,从而就地刷新它。在新的发布到达之前,被重新请求的运行在该提交的最新检查状态中会显示为待处理,因此必需的检查会阻止合并,拉取请求会显示该运行正在等待重新运行;声明可重新请求但不予响应会使该检查陷入搁置。发布时 Origin 不会验证该订阅。省略此字段以保留已存储的值 (新运行默认为 false) ;发送 false 可撤回该声明。响应字段
checkSuite 对象
checkSuite.id string
checkSuite.repository 对象
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner 对象
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team、user。未知时省略。checkSuite.sha string
checkSuite.key string
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId string
checkSuite.actor 对象
checkSuite.actor.user 对象
checkSuite.actor.user.id string
checkSuite.actor.user.email string
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。checkSuite.actor.app 对象
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount 对象
checkSuite.actor.serviceAccount.id string
checkRuns 数组
results[].checkRun。该字段仍会按请求顺序填充。checkRuns[].id string
checkRuns[].repository 对象
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner 对象
checkRuns[].repository.owner.slug string
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type string
team、user。未知时省略。checkRuns[].checkSuite 对象
checkRuns[].checkSuite.id string
checkRuns[].sha string
checkRuns[].key string
checkRuns[].name string
checkRuns[].status string
checkRuns[].conclusion string
status 为 completed 时读取。checkRuns[].detailsUrl string
checkRuns[].externalUpdatedAt string
checkRuns[].startedAt string
checkRuns[].completedAt string
checkRuns[].createdAt string
checkRuns[].updatedAt string
checkRuns[].externalId string
checkRuns[].actor 对象
actor。checkRuns[].actor.user 对象
checkRuns[].actor.user.id string
checkRuns[].actor.user.email string
checkRuns[].actor.user.displayName string
checkRuns[].actor.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。checkRuns[].actor.app 对象
checkRuns[].actor.app.id string
checkRuns[].actor.app.displayName string
checkRuns[].actor.serviceAccount 对象
checkRuns[].actor.serviceAccount.id string
checkRuns[].output 对象
checkRuns[].output.title string
checkRuns[].output.summary string
checkRuns[].output.text string
checkRuns[].deadlineAt string
checkRuns[].isRerequestable boolean
checkRuns[].rerequestedAt string
status 为 rerequested,该运行会保留在该提交的最新检查状态并显示为“待处理”,而 conclusion 和时间信息仍保留被取代的结果,因此在应用回应之前,必需的检查会阻止合并。checkRuns[].rerequestedBy 对象
actor 相同的参与者变体。只要设置了 rerequestedAt 就会存在,并会与其一同被清除。results 数组
results[].checkRun 对象
outcome 为 created 或 updated 时,使用已提交的值;否则保持该运行原有的值。字段与 checkRuns[] 相同。results[].outcome string
results[].checkRun 所做的操作。允许的值:created、updated、unchanged、ignored_stale。因过时而被忽略的运行与返回已存储值的重复运行都会返回已存储的运行,因此只能通过此字段将它们区分开来。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs:batchUpsert' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "checkSuite": { "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "build-8842" }, "checkRuns": [ { "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "run-8842", "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}'响应结构:
{ "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ], "results": [ { "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }, "outcome": "created" } ]}获取检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}按服务器分配的 ID (cr_...) 返回单个检查运行。
路径参数
ownerSlug 字符串 必填
repoName string 必填
checkRunId string 必填
cr_...) 。响应字段
id string
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team、user。未知时省略。checkSuite 对象
checkSuite.id 字符串
sha string
key string
name string
status string
conclusion string
status 为 completed 时读取。detailsUrl string
externalUpdatedAt string
startedAt string
completedAt string
createdAt string
updatedAt string
externalId string
actor 对象
actor。actor.user 对象
actor.user.id string
actor.user.email string
actor.user.displayName string
actor.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。actor.app 对象
actor.app.id string
actor.app.displayName string
actor.serviceAccount 对象
actor.serviceAccount.id string
output 对象
output.title string
output.summary string
output.text string
deadlineAt string
isRerequestable boolean
rerequestedAt string
status 为 rerequested,该运行保持在该提交的最新检查状态并显示为待处理,conclusion 和各时间字段仍保留被取代的结果,因此在该应用响应之前,必需的检查会阻止合并。rerequestedBy 对象
actor 相同的 actor 变体。只要设置了 rerequestedAt 即存在,并随其一起清除。curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." }}列表检查运行注解
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/annotations按 ID 升序列出检查运行的注释。
注释 ID 可按时间排序,因此 ID 升序即为创建顺序。page token 会为后续整个序列固定范围。
路径参数
ownerSlug string 必填
repoName string 必填
checkRunId string 必填
查询参数
pageSize 整数
pageToken string
nextPageToken 的不透明游标。第一页可省略。后续请求中的 pageSize 仅对该页生效;省略则沿用上一页的分页大小。响应字段
annotations array
annotations[].id string
annotations[].checkRunId string
annotations[].annotationLevel string
notice、warning、failure。annotations[].message string
annotations[].title string
annotations[].rawDetails string
annotations[].createdAt string
annotations[].updatedAt string
annotations[].location object
annotations[].location.path string
annotations[].location.startLine 整数
annotations[].location.endLine 整数
annotations[].location.columns 对象
annotations[].location.columns.startColumn 整数
annotations[].location.columns.endColumn 整数
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/annotations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "annotations": [ { "id": "cra_01k2ja2000e0080000000000v1", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}创建检查运行注解
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/annotations以单个原子批次向一次检查运行添加 1 至 25 条注释。
单次检查运行最多包含 100 条注释。若某个批次会使其超过此限制,则该批次会被拒绝并返回 ResourceExhausted (HTTP 429) ,且不会写入任何内容;批次大小若不在 1 到 25 的范围内,则会被拒绝并返回 InvalidArgument (HTTP 400) 。此操作仅支持追加且不具备幂等性,因此在发生不明确的传输故障后重试可能会追加重复项并消耗容量。允许完全相同的内容。
路径参数
ownerSlug string 必填
repoName string 必填
checkRunId string 必填
请求体
annotations array 必填
annotations[].annotationLevel string 必填
notice、warning、failure。annotations[].message string 必填
annotations[].title string
annotations[].rawDetails string
annotations[].location object
annotations[].location.path string 必填
annotations[].location.startLine integer 必填
annotations[].location.endLine integer 必填
startLine 之后。annotations[].location.columns 对象
startLine 与 endLine 为同一行时才受支持,且两列必须一起发送。annotations[].location.columns.startColumn 整数
annotations[].location.columns.endColumn 整数
startColumn。响应字段
annotations array
annotations[].id string
annotations[].checkRunId string
annotations[].annotationLevel string
notice、warning、failure。annotations[].message string
annotations[].title string
annotations[].rawDetails string
annotations[].createdAt string
annotations[].updatedAt string
annotations[].location object
annotations[].location.path string
annotations[].location.startLine 整数
annotations[].location.endLine integer
annotations[].location.columns 对象
annotations[].location.columns.startColumn 整数
annotations[].location.columns.endColumn 整数
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/annotations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "annotations": [ { "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}'响应结构:
{ "annotations": [ { "id": "cra_01k2ja2000e0080000000000v1", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}重新请求检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/rerequest请求发起该检查运行的应用重新运行该检查。Origin 在该运行上将请求记录为 rerequestedAt,并通过 repository.check_run.rerequested 通知所属应用。该应用通过为相同的 head SHA 和 key 发布新的运行 (可以是新建的运行或对该运行的更新) 来响应,从而清除 rerequestedAt 并保存所发布的状态。在请求尚未完成期间,该运行的 status 为 rerequested;其 conclusion 和计时仍描述被取代的尝试。该调用返回的运行将设置 rerequestedAt,且 status 为 rerequested。
该运行必须为 completed,必须带有 isRerequestable,必须是其 key 的当前尝试,并且必须位于开放 PR 的当前 head 上。否则将返回 FailedPrecondition (HTTP 400) 。
每次运行同时只能有一个未完成的重新请求。当 rerequestedAt 已设置时再次请求会返回 AlreadyExists (HTTP 409 Conflict) ;在拥有该运行的应用作出响应后,该运行将再次变为可重新请求。任何持有 repository:contents:write 权限的主体都可以重新请求任何可重新请求的运行,无论是哪一个应用上报的。若 checkRunId 未知或属于其他仓库,则返回 404。
路径参数
ownerSlug 字符串 必填
repoName string 必填
checkRunId string 必填
cr_...) 。请求体
该请求不接受任何字段。请发送空 JSON 对象。
响应字段
id string
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team、user。未知时省略。checkSuite 对象
checkSuite.id 字符串
sha string
key string
name string
status string
conclusion string
status 为 completed 时读取。detailsUrl string
externalUpdatedAt string
startedAt string
completedAt string
createdAt string
updatedAt string
externalId string
actor 对象
actor。actor.user 对象
actor.user.id string
actor.user.email string
actor.user.displayName string
actor.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。actor.app 对象
actor.app.id string
actor.app.displayName string
actor.serviceAccount 对象
actor.serviceAccount.id string
output 对象
output.title string
output.summary string
output.text string
deadlineAt string
isRerequestable boolean
rerequestedAt string
status 为 rerequested,该运行保持在提交的最新检查状态并显示为待处理,conclusion 和时间信息仍保留被取代的结果;因此必需的检查会阻止合并,直到该应用作出响应。rerequestedBy 对象
actor 相同的主体变体。只要设置了 rerequestedAt 就会存在,并会随之一并清除。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/rerequest' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{}'响应结构:
{ "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "rerequested", "conclusion": "failure", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:02:10Z", "externalId": "run-8842", "actor": { "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "Acme CI" } }, "output": { "title": "Unit tests", "summary": "3 of 128 tests failed." }, "isRerequestable": true, "rerequestedAt": "2026-08-02T15:02:10Z", "rerequestedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}获取检查套件
/v1/origin/repos/{ownerSlug}/{repoName}/check-suites/{checkSuiteId}按服务器分配的 id (crg_...) 返回 check suite 元数据。不内嵌 check runs;如需获取该 suite 的 runs,请使用 ListCheckRunsForSuite。
路径参数
ownerSlug 字符串 必填
repoName string 必填
checkSuiteId string 必填
crg_...) 。响应字段
id string
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team、user。未知时省略。sha string
key string
name string
detailsUrl string
createdAt string
updatedAt string
externalId string
actor 对象
actor.user 对象
actor.user.id string
actor.user.email string
actor.user.displayName string
actor.user.handle 字符串
@ 前缀。仅在该个人资料公开可见时提供;否则省略。actor.app 对象
actor.app.id string
actor.app.displayName string
actor.serviceAccount 对象
actor.serviceAccount.id 字符串
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-suites/CHECK_SUITE_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}列出套件的检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/check-suites/{checkSuiteId}/check-runs列出某个 suite 当前的检查运行。若在该 suite 中某个 run key 被报告多次,则仅返回该 key 的最新一次尝试;被取代的尝试会被省略。Post Check Run 定义了哪次尝试是最新的。已重新请求的运行仍会保留在列表中并显示为待处理,其 status 为 rerequested 且 rerequestedAt 已设置,其被取代的 conclusion 与时间信息保持不变,直到拥有该运行的应用作出响应。可通过 Get Check Run 使用被取代尝试自身的 id 来读取该尝试。支持分页。
路径参数
ownerSlug 字符串 必填
repoName string 必填
checkSuiteId 字符串 必填
crg_...) 。查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。第一页时为空。对该套件范围内最后看到的 check-run id 进行编码。后续请求中的 pageSize 适用于该页;省略则沿用先前的每页大小。响应字段
checkRuns 数组
checkRuns[].id string
checkRuns[].repository 对象
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner 对象
checkRuns[].repository.owner.slug string
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type string
team、user。未知时省略。checkRuns[].checkSuite 对象
checkRuns[].checkSuite.id string
checkRuns[].sha string
checkRuns[].key string
checkRuns[].name string
checkRuns[].status string
checkRuns[].conclusion string
status 为 completed 时读取。checkRuns[].detailsUrl string
checkRuns[].externalUpdatedAt string
checkRuns[].startedAt string
checkRuns[].completedAt string
checkRuns[].createdAt string
checkRuns[].updatedAt string
checkRuns[].externalId string
checkRuns[].actor 对象
actor。checkRuns[].actor.user 对象
checkRuns[].actor.user.id string
checkRuns[].actor.user.email string
checkRuns[].actor.user.displayName string
checkRuns[].actor.user.handle string
@ 前缀。仅在该资料公开可见时提供;否则省略。checkRuns[].actor.app 对象
checkRuns[].actor.app.id string
checkRuns[].actor.app.displayName string
checkRuns[].actor.serviceAccount 对象
checkRuns[].actor.serviceAccount.id string
checkRuns[].output 对象
checkRuns[].output.title string
checkRuns[].output.summary string
checkRuns[].output.text string
checkRuns[].deadlineAt string
checkRuns[].isRerequestable boolean
checkRuns[].rerequestedAt string
status 为 rerequested,该运行保持在提交的最新检查状态并显示为待处理,conclusion 和计时仍保留被取代的结果,因此在该应用响应之前,必需的检查会阻止合并。checkRuns[].rerequestedBy 对象
actor 相同的 actor 变体。只要设置了 rerequestedAt 就会存在,并与其一并清除。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-suites/CHECK_SUITE_ID/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}列出提交的检查运行
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/check-runs列出某个提交在所有 suite 中当前的检查运行:仅包含每个 suite 最新一次尝试中的运行,且在每个 suite 内,每个运行键只保留最新一次尝试。 已被取代的尝试将被省略;提交检查运行 定义哪次尝试是最新的。 被重新请求的运行会保留在列表中并显示为待处理:其 status 为 rerequested,且已设置 rerequestedAt,被取代的 conclusion 和时间信息保持不变,直到拥有该运行的应用作出响应为止。如需读取已被取代的尝试,请使用 获取检查运行 并传入该尝试自身的 ID。可按检查名称和状态筛选。支持分页。
筛选器适用于折叠后的集合,因此一次运行以其最近一次尝试的状态进行匹配,筛选器不会重新呈现已被取代的尝试。页面 token 会嵌入它们签发时所用的筛选条件,因此在不同筛选条件下重放的 token 会被拒绝;当筛选条件更改时请重新开始分页。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。第一页时为空。它编码了限定在此提交及下述筛选条件范围内的最后返回的检查运行 ID;若在不同筛选条件下重用同一 token,将返回 InvalidArgument (HTTP 400)。后续请求中的 pageSize 仅作用于该页;省略则沿用上一页的页面大小。checkName string
checkRuns[].name 匹配。省略则列出任意名称下的运行。status string
queued、in_progress、completed、rerequested。其他任何值将返回 InvalidArgument (HTTP 400) 。省略以列出任意状态的运行。响应字段
checkRuns 数组
checkRuns[].id string
checkRuns[].repository 对象
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner 对象
checkRuns[].repository.owner.slug string
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type string
team、user。未知时省略。checkRuns[].checkSuite 对象
checkRuns[].checkSuite.id string
checkRuns[].sha string
checkRuns[].key string
checkRuns[].name string
checkRuns[].status string
checkRuns[].conclusion string
status 为 completed 时读取。checkRuns[].detailsUrl string
checkRuns[].externalUpdatedAt string
checkRuns[].startedAt string
checkRuns[].completedAt string
checkRuns[].createdAt string
checkRuns[].updatedAt string
checkRuns[].externalId string
checkRuns[].actor 对象
actor。checkRuns[].actor.user 对象
checkRuns[].actor.user.id string
checkRuns[].actor.user.email string
checkRuns[].actor.user.displayName string
checkRuns[].actor.user.handle string
@ 前缀。仅在该资料公开可见时提供;否则省略。checkRuns[].actor.app 对象
checkRuns[].actor.app.id string
checkRuns[].actor.app.displayName string
checkRuns[].actor.serviceAccount 对象
checkRuns[].actor.serviceAccount.id string
checkRuns[].output 对象
checkRuns[].output.title string
checkRuns[].output.summary string
checkRuns[].output.text string
checkRuns[].deadlineAt string
checkRuns[].isRerequestable boolean
checkRuns[].rerequestedAt string
status 为 rerequested,该运行保持在该提交最新的检查状态并显示为待处理,conclusion 和时间信息仍保留被取代的结果,因此在该应用响应之前,必需的检查将阻止合并。checkRuns[].rerequestedBy 对象
actor 相同的主体变体。只要设置了 rerequestedAt 即存在,并会与其一并清除。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}列出提交的检查套件
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/check-suites列出针对某次提交上报的检查套件。仅返回每个上报主体和套件键对应的最新尝试;被替代的尝试将被省略,且 提交检查运行 定义哪次尝试是最新的。可通过其自身 ID 使用 获取检查套件 读取已被替代的尝试。仅返回套件元数据 (不包含嵌入的运行) 。支持分页。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。对于第一页为空。该游标编码了限定于此提交的最后一次看到的 check-suite id。后续请求中的 pageSize 将应用于该页;省略此参数则沿用之前的页面大小。响应字段
checkSuites 数组
checkSuites[].id string
checkSuites[].repository 对象
checkSuites[].repository.id string
checkSuites[].repository.name string
checkSuites[].repository.owner 对象
checkSuites[].repository.owner.slug string
checkSuites[].repository.owner.id string
checkSuites[].repository.owner.type string
team、user。未知时省略。checkSuites[].sha string
checkSuites[].key string
checkSuites[].name string
checkSuites[].detailsUrl string
checkSuites[].createdAt string
checkSuites[].updatedAt string
checkSuites[].externalId string
checkSuites[].actor object
checkSuites[].actor.user object
checkSuites[].actor.user.id string
checkSuites[].actor.user.email string
checkSuites[].actor.user.displayName string
checkSuites[].actor.user.handle string
@ 前缀。仅在该资料公开可见时显示;否则省略。checkSuites[].actor.app 对象
checkSuites[].actor.app.id string
checkSuites[].actor.app.displayName string
checkSuites[].actor.serviceAccount 对象
checkSuites[].actor.serviceAccount.id string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/check-suites' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "checkSuites": [ { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } } ]}提交和内容
提交将 commit 中的 Git 对象元数据与仓库顶层关系分开。列表响应不包含 stats;获取提交包含整个提交的聚合 stats。修改的文件仅通过分页的列出提交文件集合返回。author 和 committer 是记录在提交中的 Git 身份,而非 Origin 用户对象。
比较仅提供摘要:绝不会嵌入提交列表或文件 diff。status 的值仅为 identical、ahead、behind 或 diverged;aheadBy 和 behindBy 表示提交数量。baseCommit、headCommit 和 mergeBaseCommit 使用精简的提交投影 (不含 stats 或文件) 。
列出提交
/v1/origin/repos/{ownerSlug}/{repoName}/commits列出指定分支或起始引用上的提交。
列表结果省略 stats。对于聚合统计,请使用 获取提交;对于分页的文件差异,请使用 列出提交文件。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
sha string
HEAD) 。留空则使用仓库的默认分支。pageSize integer
pageToken string
nextPageToken 的不透明游标。第一页时为空。该游标编码了起始引用、遍历位置和电子邮件筛选条件;因此在提供 token 时,sha、pageSize、authorEmails 和 committerEmails 会被忽略。经过筛选的页面可能包含少于 pageSize 个提交,甚至不包含任何提交,但 nextPageToken 仍会被设置。请持续翻页,直到该值为空。authorEmails 数组
committerEmails 数组
authorEmails 采用相同的规范化规则,且同样最多支持 100 个电子邮件;留空表示不筛选。同时设置两个筛选条件时,提交须同时匹配两个列表。每页最多扫描 1,000 个提交来查找匹配项。响应字段
commits 数组
commits[].sha string
commits[].commit 对象
commits[].commit.author 对象
commits[].commit.author.name string
commits[].commit.author.email string
commits[].commit.author.date string
commits[].commit.committer 对象
commits[].commit.committer.name string
commits[].commit.committer.email string
commits[].commit.committer.date string
commits[].commit.message string
commits[].commit.tree 对象
commits[].commit.tree.sha string
commits[].parents 数组
commits[].parents[].sha string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "commits": [ { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } } ]}获取提交
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}按 SHA 或引用返回单个提交,并包含整个提交的汇总统计 stats。它不包括已更改的文件;请使用 列出提交文件。
author 和 committer 是提交中记录的 Git 身份,而不是 Origin 的用户对象。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
HEAD) 。缩写 SHA 的解析方式与 获取 Git 提交 中相同。响应字段
sha string
commit 对象
commit.author 对象
commit.author.name string
commit.author.email string
commit.author.date string
commit.committer 对象
commit.committer.name string
commit.committer.email string
commit.committer.date string
commit.message string
commit.tree 对象
commit.tree.sha string
parents 数组
parents[].sha string
stats object
stats.additions integer
stats.deletions 整数
stats.total 整数
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 }}列出提交中的文件
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/files列出某次提交中修改的文件。
sha 可以是提交 SHA、分支、标签或诸如 HEAD 的符号引用。结果默认返回 30 个文件,最多为 100 个。分页令牌会固定已解析的提交和文件游标;在后续请求中,sha 必须与该令牌匹配。每个文件包含 filename、status、additions、deletions、changes、patch,以及在重命名或复制时的 previousFilename。二进制文件的 patch 为空。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
HEAD) 。缩写 SHA 的解析方式与 获取 Git 提交 中相同。查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页为空。该令牌固定了解析的提交和文件游标,因此后续请求中的 sha 必须与该令牌匹配。后续请求中的 pageSize 仅作用于该页;省略则沿用先前的页面大小。响应字段
files 数组
files[].filename string
files[].status string
files[].additions 整数
files[].deletions integer
files[].changes integer
files[].patch string
files[].previousFilename string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}比较提交
/v1/origin/repos/{ownerSlug}/{repoName}/compare/{basehead}比较相对于其合并基的提交、引用或标签。basehead 为 "{base}...{head}";包含 "/" 的引用必须使用其 SHA。
base 和 head 均可为 SHA、分支、标签或诸如 HEAD 的符号引用。响应为非分页摘要:status 为 identical、ahead、behind 或 diverged;三个提交对象为精简形式,省略 stats 和文件。不返回 totalCommits、嵌入的 commits 或 files 字段。无关联的历史将返回 404。
路径参数
ownerSlug string 必填
repoName string 必填
basehead string 必填
"{base}...{head}",其中任一修订可以是 SHA、分支、标签或符号引用 (例如 HEAD) 。响应字段
status string
aheadBy 整数
behindBy 整数
baseCommit 对象
baseCommit.sha string
baseCommit.commit 对象
baseCommit.commit.author object
baseCommit.commit.author.name string
baseCommit.commit.author.email string
baseCommit.commit.author.date string
baseCommit.commit.committer 对象
baseCommit.commit.committer.name string
baseCommit.commit.committer.email string
baseCommit.commit.committer.date string
baseCommit.commit.message string
baseCommit.commit.tree 对象
baseCommit.commit.tree.sha string
baseCommit.parents 数组
baseCommit.parents[].sha string
headCommit 对象
headCommit.sha string
headCommit.commit 对象
headCommit.commit.author 对象
headCommit.commit.author.name string
headCommit.commit.author.email string
headCommit.commit.author.date string
headCommit.commit.committer 对象
headCommit.commit.committer.name string
headCommit.commit.committer.email string
headCommit.commit.committer.date string
headCommit.commit.message string
headCommit.commit.tree 对象
headCommit.commit.tree.sha string
headCommit.parents 数组
headCommit.parents[].sha string
mergeBaseCommit 对象
mergeBaseCommit.sha string
mergeBaseCommit.commit 对象
mergeBaseCommit.commit.author 对象
mergeBaseCommit.commit.author.name string
mergeBaseCommit.commit.author.email string
mergeBaseCommit.commit.author.date string
mergeBaseCommit.commit.committer 对象
mergeBaseCommit.commit.committer.name string
mergeBaseCommit.commit.committer.email string
mergeBaseCommit.commit.committer.date string
mergeBaseCommit.commit.message string
mergeBaseCommit.commit.tree 对象
mergeBaseCommit.commit.tree.sha string
mergeBaseCommit.parents 数组
mergeBaseCommit.parents[].sha string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/compare/BASE...HEAD' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "status": "ahead", "aheadBy": 2, "behindBy": 0, "baseCommit": { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }, "headCommit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }, "mergeBaseCommit": { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }}列出比较中的文件
/v1/origin/repos/{ownerSlug}/{repoName}/compare/{basehead}/files列出一次比较中修改的文件:head 与 base 和 head 的合并基点之间的 diff。
basehead 为 "{base}...{head}";包含 "/" 的引用必须使用其 SHA。文件列表始终与 比较提交 中的摘要一致,因此 identical 或 behind 比较会返回空列表,而无关联的历史记录会返回 404。结果默认返回 30 个文件,最多为 100 个。每个文件包含与 列出提交文件 相同的字段。
路径参数
ownerSlug string 必填
repoName string 必填
basehead string 必填
"{base}...{head}",其中任一修订版本都可以是 SHA、分支、标签或诸如 HEAD 的符号引用。查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。第一页为空。该令牌绑定到已解析的比较和文件游标,因此后续请求中的 basehead 必须与该令牌匹配。Origin 会在每一页重新解析比较;如果自令牌发放以来其提交已发生变动,请求将返回 InvalidArgument (HTTP 400) ,且必须从第一页重新开始列出。后续请求中的 pageSize 仅作用于该页;省略该参数则沿用之前的页面大小。响应字段
files 数组
files[].filename string
files[].status string
files[].additions integer
files[].deletions integer
files[].changes integer
files[].patch string
files[].previousFilename string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/compare/BASE...HEAD/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}获取内容
/v1/origin/repos/{ownerSlug}/{repoName}/contents返回指定引用中文件或目录的内容。通过 path 查询参数传入文件路径 (支持嵌套路径) ;省略或留空则返回代码仓库根目录。解码后大于 1 MiB 的文件会因 FailedPrecondition (HTTP 400) 被拒绝。
文件包含 base64 内容。目录在 entries 中包含直接子项。目录条目是仅包含 type、name、path、sha 和 size 的子项;获取子项路径以读取其内容。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
path string
ref string
HEAD) 。留空表示使用代码仓库的默认分支。响应字段
type string
encoding string
size string
name string
path string
sha string
content string
entries array
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/contents' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "type": "file", "encoding": "base64", "size": "312", "name": "telemetry.ts", "path": "src/telemetry.ts", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo="}批量获取内容
/v1/origin/repos/{ownerSlug}/{repoName}/contents:batchGet一次请求返回某引用下若干明确路径的内容。每个请求的路径都会返回一个结果以标明是否找到;已找到的路径具有与 GetContents 相同的 Content 结构 (文件为 base64,目录为直接的 entries,符号链接作为文件) 。路径必须精确匹配,不支持通配符或模式,最多可请求 20 个路径;重复项会被移除。响应结果按首次出现的请求顺序保留。如果单个文件超过 Get Contents 的 1 MiB 限制,整个批次将以 FailedPrecondition (HTTP 400) 失败。由于路径列表在请求体中传输,因此使用 POST。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
paths 数组 必填
ref string
HEAD) 。留空表示仓库的默认分支。响应字段
results array
results[].path string
results[].found 布尔值
results[].content 对象
results[].content.type string
results[].content.encoding string
results[].content.size string
results[].content.name string
results[].content.path string
results[].content.sha string
results[].content.content string
results[].content.entries array
resolvedCommitSha string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/contents:batchGet' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "paths": [ "src/telemetry.ts" ], "ref": "main"}'响应结构:
{ "results": [ { "path": "src/telemetry.ts", "found": true, "content": { "type": "file", "encoding": "base64", "size": "312", "name": "telemetry.ts", "path": "src/telemetry.ts", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo=" } } ], "resolvedCommitSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}使用 grep 搜索内容
/v1/origin/repos/{ownerSlug}/{repoName}:grep在指定引用处搜索代码仓库中文件的文本内容,返回匹配的行以及所请求的相邻上下文行。搜索以行为单位:模式不会跨换行符匹配,返回的每条结果都是一行。每次请求都会扫描整个代码仓库,因此没有分页,也没有游标;仅当 limitHit 为 false 时,响应才是完整的。若代码仓库为空且没有任何引用,则不返回任何匹配,且 limitHit 为 false。由于搜索参数通过请求体传递,因此使用 POST。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
ref string
HEAD) 。留空表示仓库的默认分支。query string 必填
literal。空白字符同样有效,会按原样参与搜索。当 literal 为 false 时,不区分大小写的匹配通过在模式开头添加 (?i) 实现 (例如 (?i)launch) ,全词匹配则通过在两侧添加 \b 实现 (例如 \blaunch\b) 。空模式将返回 InvalidArgument (HTTP 400) 。UTF-8 最大长度:4096 字节。literal boolean
query 作为精确文本搜索,而非正则表达式。caseInsensitive boolean
literal 为 true 时应用。正则表达式搜索会忽略此选项;请在 query 中以 (?i) 开头。wholeWord boolean
literal 为 true 时生效。正则表达式搜索时会被忽略;应在模式两侧添加 \b。contextBefore integer
contextAfter integer
filterPath string
includes 数组
/ 的模式可在任意深度匹配,* 仅在单个路径段内匹配,** 可跨路径段匹配。只要存在任一 include,未匹配其中任何一项的路径都不会被搜索。最多 20 个条目。每个模式的最大 UTF-8 大小:4096 字节。excludes array
includes 相同。排除优先于包含,排除某个目录会同时排除其下的所有内容。最多 20 个条目。每个模式的 UTF-8 大小上限为 4096 字节。maxResults 整数
响应字段
matches 数组
matches[].path string
matches[].lineNumber 整数
matches[].line string
matches[].kind string
match、context。matches[].submatches 数组
line 中的位置。上下文行上始终为空。当 limitHit 为 true 时,最后一个匹配行可能只包含部分匹配项。完全落在 line 之后的范围会被省略,而超出 line 边界的范围会被缩减为剩余的字节。matches[].submatches[].start integer
matches[].submatches[].end integer
limitHit boolean
maxResults。缩小 query、filterPath 或 glob 列表,以在更小的文件集合中进行搜索。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME:grep' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "main", "query": "emitLaunchTelemetry\\(", "contextBefore": 1, "contextAfter": 1, "includes": [ "*.ts" ], "excludes": [ "**/node_modules/**" ], "maxResults": 50}'{ "matches": [ { "path": "src/telemetry.ts", "lineNumber": 11, "line": "export function emitLaunchTelemetry(stage: string): void {", "kind": "match", "submatches": [ { "start": 16, "end": 37 } ] }, { "path": "src/telemetry.ts", "lineNumber": 12, "line": " console.log(\"launch\", stage);", "kind": "context", "submatches": [] } ], "limitHit": false}Git 数据
底层 git 对象。读取需要 repository:contents:read,空代码仓库将返回 409。Create Commit From Files 和 Create Git Ref 会写入 git 对象,需要 repository:contents:write。
除了分支和标签,获取 Git 引用 还可读取 PR 在 pull/{pullNumber}/merge (会被规范化为 refs/pull/{pullNumber}/merge) 处的合并预览:即把该 PR 当前 head 合并到其 base 分支在上次刷新时的 tip 所生成的提交。源站会在 PR 创建、head 被推送、变更目标分支以及被重新打开时刷新该预览;刷新发生在对应的 pull_request.* webhook 事件发布之前,且受限于有限的时间预算。若刷新未能及时完成,则沿用此前的引用,事件仍会照常发布。源站不会因 base 分支自行推进而刷新该预览,并且在合并存在冲突时会删除该引用,因此对一个开启中的 PR 返回 404 意味着存在冲突或预览尚未准备好。每个 PR 版本还会在 version.potentialMergeCommit 中给出各自的测试合并结果,可通过其 state 区分上述两种情况;参见 PR。PR 的 mergeCommitSha 则是另一个提交,仅在合并完成后才会设置。
获取 Blob
/v1/origin/repos/{ownerSlug}/{repoName}/git/blobs/{sha}根据 SHA 返回 Git blob 对象。默认响应为 JSON,content 包含 MIME 封装的 base64 内容。在 REST 接口中传递 Accept: application/vnd.origin.raw+json (或 application/vnd.origin.raw) ,即可改为获取原始 blob 字节。解码后大于 4 MiB 的 blob 将被拒绝;较大文件请通过 Git HTTPS 克隆代码仓库来获取。空仓库将返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
响应字段
sha string
size integer
encoding string
content string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/blobs/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "size": 312, "encoding": "base64", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo="}获取 Git 提交
/v1/origin/repos/{ownerSlug}/{repoName}/git/commits/{sha}根据 SHA(或可解析的修订版本)返回 Git 提交对象。这是底层 Git 数据库的提交形态(扁平的 author/message/tree),而不是位于 /commits/{sha} 下的更高级别 GetCommit 资源。sha 可接受提交 SHA、分支、标签或符号引用(例如 HEAD)。空仓库将返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
HEAD 的符号引用。缩写 SHA 至少需包含 5 个十六进制字符,且仅在提交对象范围内解析;若没有任何提交匹配该缩写,或匹配的提交不止一个,则解析失败。响应字段
sha string
author 对象
author.name string
author.email string
author.date string
committer 对象
committer.name string
committer.email string
committer.date string
message string
tree 对象
tree.sha string
parents 数组
parents[].sha string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/commits/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ]}从文件创建 commit
/v1/origin/repos/{ownerSlug}/{repoName}/git/commits:createFromFiles根据内联文件更改在分支上创建提交,并将该分支推进到该提交。
更改会应用到 expectedHeadSha 所指向的 tree 上,该 tree 将成为新 commit 的 parent。以下情况均返回 FailedPrecondition (HTTP 400) :branch 已移动或不存在;一组更改未对 tree 产生任何变化;删除 tree 中并不存在的 path;写入操作被 push 规则集拦截;代码仓库的内容是从其他 host mirror 而来。
单个请求最多可包含 1,000 项文件更改,每个文件最大 8 MiB,内容总计最大 32 MiB。超出限制、路径重复或字段格式有误都会返回 InvalidArgument (HTTP 400) ,并在 google.rpc.BadRequest 的字段校验错误中指明出问题的 files[i] 条目。
该分支必须已存在。请先通过 Create Git Ref 创建分支,然后再向其提交。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
targetBranch string 必填
<branch>、heads/<branch> 或 refs/heads/<branch>。该分支必须已存在。HEAD 在任何写法下都会被拒绝。expectedHeadSha string 必填
message string 必填
author object 必填
author.name string 必填
author.email string 必填
committer object
author。committer.name string
committer 时必填。committer.email string
committer 时必填。files 数组 必填
files[].path string 必填
/ 作为分隔符,例如 docs/changelog.md。files[].content string
files[].encoding 编码。将创建该文件或替换其内容。files[].content 与 files[].delete 只能设置其中一个。files[].delete boolean
true。files[].content 和 files[].delete 二者必须且只能设置其一。files[].encoding string
files[].content 的编码方式。允许的值:utf-8 (默认值) 、base64。删除操作会忽略此字段。files[].mode string
files[].content 的文件模式。允许的值:file (默认值) 、executable、symlink (此时内容即为链接目标) 。删除操作会忽略此字段。响应字段
sha string
treeSha string
previousHeadSha string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/commits:createFromFiles' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "targetBranch": "feature/login", "expectedHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "message": "Add login telemetry", "author": { "name": "Jane Doe", "email": "[email protected]" }, "files": [ { "path": "src/login/telemetry.ts", "content": "export const LOGIN_EVENT = 1;" }, { "path": "assets/login.png", "content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "encoding": "base64" }, { "path": "src/login/legacy.ts", "delete": true } ]}'响应结构:
{ "sha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "treeSha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8", "previousHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}获取 Git 引用
/v1/origin/repos/{ownerSlug}/{repoName}/git/ref/{ref}按名称获取单个 Git 引用。ref 通常为 heads/<branch> 或 tags/<tag> (可带或不带前导 refs/) ,也可以是符号引用 HEAD。仅支持精确匹配;如需按前缀匹配,请使用 ListMatchingGitRefs。空仓库返回 409 Conflict。
pull/<number>/merge 是 PR 的合并预览:一个将其当前 head 合并到上次刷新时其 base 分支最新提交而产生的提交。它与 PR 的 mergeCommitSha 并非同一个提交,后者仅在 PR 合并后才会设置。PR 的 version.potentialMergeCommit 会报告每个版本的测试合并结果:当某个版本是最新版本且其 state 为 prepared 时,其 sha 就是此引用指向的提交。
源站会在创建 PR、推送其 head、变更其目标分支以及重新打开 PR 时刷新该预览,刷新发生在对应的 pull_request.* webhook 事件发布之前,并在有限的时间预算内完成。若刷新未能及时完成,则保留此前的引用,事件仍会照常发布。源站不会仅因 base 分支有新提交而刷新它;当合并存在冲突时会删除该引用,因此对一个 open 状态的 PR 返回 404 意味着合并存在冲突,或预览尚未准备好。
路径参数
ownerSlug string 必填
repoName string 必填
ref string 必填
heads/<branch> 或 tags/<tag>;可接受前导 refs/,并会将其规范化。也接受符号引用 HEAD (返回为 ref: "HEAD",并附带最新提交) ,以及用于 PR 合并预览的 pull/<number>/merge。按完整引用名称精确匹配。响应字段
ref string
object object
object.type 为 "tag",object.sha 为标签对象的 SHA。object.sha string
object.type string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/ref/REF' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}创建 Git Ref
/v1/origin/repos/{ownerSlug}/{repoName}/git/refs创建指向现有 commit 的分支引用。
只能创建分支引用。tag 或任何其他引用 namespace,以及并非仓库中某个 commit 完整 hex SHA 的 sha,均返回 InvalidArgument (HTTP 400) 。若要创建的分支已指向该 sha,则操作成功并返回现有引用;若该分支已存在但指向其他 commit,则返回 AlreadyExists (HTTP 409 Conflict) 。若创建操作被 push 规则集阻止,或该代码仓库的内容镜像自其他 host,则返回 FailedPrecondition (HTTP 400) 。
Path Parameters
ownerSlug string 必填
repoName string 必填
Request Body
ref string 必填
refs/heads/<branch> 或 heads/<branch>。sha string 必填
Response Fields
ref string
object object
object.type 为 "commit"。object.sha string
object.type string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/refs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "refs/heads/feature/login", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}'响应结构:
{ "ref": "refs/heads/feature/login", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}删除 Git 引用
/v1/origin/repos/{ownerSlug}/{repoName}/git/refs/{ref}删除分支引用。响应体为空。
仅可删除分支引用。不存在的分支将返回 404。代码仓库的默认分支、受删除规则保护的分支,以及内容从其他托管服务镜像而来的代码仓库,均会返回 FailedPrecondition (HTTP 400)。以被删除分支为 head 的 PR 将被关闭,与推送删除后的行为一致。若分支的 tip 在删除请求进行中发生变化,则会以 FailedPrecondition (HTTP 400) 或 Aborted (HTTP 409 Conflict) 失败;可重试以删除新的 tip。
路径参数
ownerSlug string 必填
repoName string 必填
ref string 必填
refs/heads/<branch> 或 heads/<branch>。响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/refs/REF' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content列出匹配的 Git 引用
/v1/origin/repos/{ownerSlug}/{repoName}/git/matching-refs列出名称以指定前缀开头的 Git 引用。REST 响应会解包为 JSON 数组 (通过 response_body) 。会保留 ref 的尾部斜杠 (heads/ → refs/heads/) 。符号引用 HEAD 会被精确匹配 (它不在 refs/ 下) 。空仓库返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
ref string
heads/<prefix> 或 tags/<prefix>;可接受前导 refs/,并会将其规范化。留空时列出所有引用 (REST 绑定中不包含尾部路径段) 。响应字段
响应为数组。每个项包含:
ref string
object object
object.type 为 "tag",object.sha 为标签对象的 SHA。object.sha string
object.type string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/matching-refs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "refs": [ { "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" } } ]}按路径列出匹配的 Git 引用
/v1/origin/repos/{ownerSlug}/{repoName}/git/matching-refs/{ref}列出名称以指定前缀开头的 Git 引用。REST 响应会解包为 JSON 数组 (通过 response_body) 。会保留 ref 尾部斜杠 (heads/ → refs/heads/) 。符号引用 HEAD 必须完全匹配 (不位于 refs/ 下) 。空仓库返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
ref string 必填
heads/<prefix> 或 tags/<prefix>;支持前导 refs/,并会将其规范化。为空时列出所有引用 (REST 绑定中不带尾部路径段) 。响应字段
响应为一个数组。每个项包含:
ref string
object object
object.type 为 "tag",object.sha 为标签对象 SHA。object.sha string
object.type string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/matching-refs/REF' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "refs": [ { "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" } } ]}获取标签
/v1/origin/repos/{ownerSlug}/{repoName}/git/tags/{sha}按 SHA 返回带注释的 Git 标签对象。轻量标签不属于标签对象,返回 NotFound。空仓库返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
响应字段
sha string
tag string
message string
tagger object
tagger.name string
tagger.email string
tagger.date string
object object
object.sha string
object.type string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/tags/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "sha": "e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2", "tag": "v1.2.0", "message": "Release v1.2.0", "tagger": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}获取树
/v1/origin/repos/{ownerSlug}/{repoName}/git/trees/{sha}根据 SHA 或可解析的修订版本返回 Git 树对象。sha 可接受树 SHA、提交 SHA、分支、标签或诸如 HEAD 的符号引用。将 recursive=true (或 1) 设置为遍历整个树;省略该参数或传入任何其他值则仅列出直接子项。递归列表在达到 100,000 个条目或 7 MiB 时会被截断,并设置 truncated=true。空仓库返回 409 Conflict。
路径参数
ownerSlug string 必填
repoName string 必填
sha string 必填
HEAD 的符号引用。查询参数
recursive boolean
true 和 1 启用递归;省略该参数或传入任何其他值 (包括 false 和 0) 时,仅列出直接子项。响应字段
sha string
tree array
tree[].path string
tree[].mode string
tree[].type string
tree[].sha string
tree[].size integer
int32 可确保 REST JSON 输出为数字;单个 blob 超过 2 GiB 时无法表示。truncated boolean
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/trees/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8", "tree": [ { "path": "src/telemetry.ts", "mode": "100644", "type": "blob", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "size": 312 } ], "truncated": false}Grants
一条 grant 将一个 principal 绑定到一个代码仓库或一个 owner,并授予一项权限。这些端点用于读取、设置和移除直接作用于某个 resource 上的 grant,从而让访问权限的更改可以像代码一样脚本化并接受评审。写入操作复用代码库权限 UI 背后的检查逻辑,并记录相同的 repository.access_changed 和 namespace.access_changed 审计事件。关于 principal 的类型、两套权限层级,以及 owner 级 grant 与代码仓库级 grant 如何相互作用,请阅读 Origin Grants API。
列出代码仓库授权
/v1/origin/repos/{ownerSlug}/{repoName}/grants列出在某个代码仓库上直接获得权限的用户、群组及所属团队群组。不包含从该代码仓库所有者继承的权限。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。第一页时为空。后续请求中的 pageSize 作用于该页;若省略该参数,则沿用上一页的页面大小。响应字段
grants 数组
pageSize 条。grants[].user 对象
user、group 或 teamGroup 中恰有一个存在。grants[].user.id string
user_。grants[].user.email string
grants[].user.displayName string
grants[].user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。grants[].group 对象
grants[].group.id string
grp_ 为前缀。grants[].teamGroup 对象
grants[].teamGroup.kind string
members、admins。grants[].permission string
repository 对象
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "grants": [ { "group": { "id": "grp_01k2ja2000e0080000000000n2" }, "permission": "admin" }, { "teamGroup": { "kind": "admins" }, "permission": "admin" }, { "teamGroup": { "kind": "members" }, "permission": "write" }, { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "read" } ], "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "nextPageToken": ""}更新或插入代码仓库授权
/v1/origin/repos/{ownerSlug}/{repoName}/grants设置用户、群组或所属团队群组在某个仓库上直接拥有的权限,替换此前直接授予该主体的任何权限。重复授予该主体已拥有的权限会成功但不产生变更。用户必须是该仓库所有者所属团队或组织的活跃成员。群组必须是所有者团队拥有的群组,或该团队所属组织中的活跃群组;否则请求将返回 FailedPrecondition (HTTP 400)。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
user object
user、group 和 teamGroup 中有且仅有一个存在。user.id string
user_。user.email string
user.displayName string
user.handle string
@ 前缀。仅当该配置文件公开可见时才会返回,否则将被省略。group 对象
group.id string
grp_ 为前缀。teamGroup 对象
teamGroup.kind string
members、admins。permission string 必填
read、write、admin。custom 将返回 InvalidArgument (HTTP 400) ;自定义策略不在此 API 的范围内。响应字段
user object
user、group 和 teamGroup 中有且仅有一个存在。user.id string
user_。user.email string
user.displayName string
user.handle string
@ 前缀。仅当该配置文件公开可见时才会返回,否则将被省略。group 对象
group.id string
grp_。teamGroup 对象
teamGroup.kind string
members、admins。permission string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "user": { "id": "user_01k2ja2000e0080000000000c3" }, "permission": "write"}'响应结构:
{ "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "write"}删除仓库授权
/v1/origin/repos/{ownerSlug}/{repoName}/grants移除用户、群组或所属团队群组直接在某个代码仓库上持有的权限。从仓库所有者继承的权限不受影响,因此所属团队群组会回退到其所有者级别的默认值。若移除的权限并非该 principal 直接持有,请求仍会成功,但不会产生任何变更。响应体为空。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
user object
user、group 或 teamGroup 中有且仅有一个存在。user.id string
user_。user.email string
user.displayName string
user.handle string
@ 前缀。仅在该配置文件公开可见时存在,否则省略。group object
group.id string
grp_。teamGroup object
teamGroup.kind string
members、admins。响应字段
请求成功时不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "group": { "id": "grp_01k2ja2000e0080000000000n2" }}'响应:
204 No Content列出命名空间授权
/v1/origin/owners/{ownerSlug}/grants列出已获准访问某个所有者的对象:用户、群组,以及该所有者所属团队内置的管理员和成员群组。每项授权包含其在该所有者名下所有仓库上授予的权限。针对单个仓库的授权不包含在内;请使用 List Repository Grants 查看这些授权。
路径参数
ownerSlug string 必填
查询参数
pageSize integer
pageToken string
next_page_token 的不透明游标。请求第一页时留空。后续请求中的 pageSize 仅作用于所请求的页面;省略该参数则沿用上一页的每页数量。响应字段
grants 数组
pageSize。grants[].user object
user、group 和 teamGroup 中有且仅有一个存在。grants[].user.id string
user_。grants[].user.email string
grants[].user.displayName string
grants[].user.handle string
@ 前缀。仅当该配置文件公开可见时才会返回,否则将省略。grants[].group 对象
grants[].group.id string
grp_。grants[].teamGroup 对象
grants[].teamGroup.kind string
members, admins.grants[].permission string
PERMISSION_READ、PERMISSION_CONTRIBUTOR、PERMISSION_WRITE、PERMISSION_ADMIN、PERMISSION_CUSTOM。PERMISSION_CUSTOM 表示 custom policy,Upsert Namespace Grant 不接受该值。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/owners/{ownerSlug}/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "grants": [ { "group": { "id": "grp_01k2ja2000e0080000000000n2" }, "permission": "PERMISSION_ADMIN" }, { "teamGroup": { "kind": "admins" }, "permission": "PERMISSION_ADMIN" }, { "teamGroup": { "kind": "members" }, "permission": "PERMISSION_CONTRIBUTOR" }, { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "PERMISSION_WRITE" } ], "nextPageToken": ""}更新或插入 Namespace Grant
/v1/origin/owners/{ownerSlug}/grants设置用户、群组或归属团队群组直接在某个 owner 上持有的权限,并替换此前直接授予该 principal 的权限。若重复授予 principal 已持有的权限,请求会成功但不产生任何变更。出现以下情况时,请求返回 FailedPrecondition (HTTP 400):该用户不是归属团队或其组织的活跃成员;该群组既不归属于该团队,也不是其组织中的活跃群组;或该写入操作会导致该 owner 不再有任何 admin。
路径参数
ownerSlug string 必填
请求体
user object
user、group 或 teamGroup 中恰有一个存在。user.id string
user_ 为前缀。user.email string
user.displayName string
user.handle string
@ 前缀。仅当该配置文件公开可见时才会返回,否则将被省略。group 对象
group.id string
grp_。teamGroup 对象
teamGroup.kind string
members、admins。permission string 必填
PERMISSION_READ、PERMISSION_CONTRIBUTOR、PERMISSION_WRITE、PERMISSION_ADMIN。其中 PERMISSION_READ、PERMISSION_CONTRIBUTOR 和 PERMISSION_WRITE 会对该 owner 的内部仓库授予相应级别的权限,而 PERMISSION_ADMIN 用于管理 owner 本身。PERMISSION_CUSTOM 将返回 InvalidArgument (HTTP 400) 。响应字段
user object
user、group 和 teamGroup 中有且仅有一个存在。user.id string
user_ 为前缀。user.email string
user.displayName string
user.handle string
@ 前缀。仅在该个人资料公开可见时存在;否则省略。group 对象
group.id string
grp_ 为前缀。teamGroup 对象
teamGroup.kind string
members、admins。permission string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "user": { "id": "user_01k2ja2000e0080000000000c3" }, "permission": "PERMISSION_WRITE"}'响应结构:
{ "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "PERMISSION_WRITE"}删除 Namespace 授权
/v1/origin/owners/{ownerSlug}/grants移除用户、群组或所属团队群组直接在某个所有者上持有的权限。代码仓库授权不受影响。若移除的权限 principal 并未直接持有,请求仍会成功,但不产生任何变更;若移除后该所有者将不再有 admin,则返回 FailedPrecondition (HTTP 400) 。响应体为空。
路径参数
ownerSlug string 必填
请求体
user object
user、group 或 teamGroup 三者中有且仅有一个存在。user.id string
user_。user.email string
user.displayName string
user.handle string
@ 前缀。仅当该配置文件公开可见时存在,否则省略。group object
group.id string
grp_。teamGroup object
teamGroup.kind string
members、admins。响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "group": { "id": "grp_01k2ja2000e0080000000000n2" }}'响应:
204 No Content标签
标签定义归属于一个代码仓库,并通过名称标识。为 PR 设置标签属于另一项功能;请参阅设置 PR 标签。
列出标签
/v1/origin/repos/{ownerSlug}/{repoName}/labels列出代码仓库中定义的标签,按名称排序。
页面 token 与签发它们的代码仓库绑定。将 token 用于其他代码仓库,或使用任何其他格式错误的 token,都会返回 InvalidArgument (HTTP 400) 。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
pageSize integer
pageToken string
nextPageToken 的不透明游标。获取第一页时省略。后续请求中的 pageSize 仅作用于该页;省略则沿用上一页的页面大小。响应字段
labels array
labels[].id string
labels[].name string
labels[].color string
# 的六位十六进制颜色值。labels[].description string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}创建标签
/v1/origin/repos/{ownerSlug}/{repoName}/labels在代码仓库中创建标签。
如果名称已被该代码仓库中的其他标签使用,将返回 AlreadyExists (HTTP 409 Conflict) 。如果 color 不是六位十六进制字符、name 超过 50 个字符,或 description 超过 255 个字符,将返回 InvalidArgument (HTTP 400) 。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
name string 必填
color string 必填
# 的六位十六进制颜色值。大写输入会以小写形式存储。description string
响应字段
id string
name string
color string
# 的六位十六进制颜色值。description string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "bug", "color": "d73a4a", "description": "Something isn'\''t working"}'响应结构:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working"}获取标签
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}按名称获取单个代码仓库标签。
名称不存在时返回 404。labelName 为空时返回 InvalidArgument (HTTP 400) 。
路径参数
ownerSlug string 必填
repoName string 必填
labelName string 必填
响应字段
id string
name string
color string
# 的六位十六进制颜色值。description string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working"}删除标签
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}按名称删除代码仓库标签。响应体为空。
删除标签也会将其从所有分配给它的 PR 中移除。名称不存在时返回 404。labelName 为空时返回 InvalidArgument (HTTP 400) 。
路径参数
ownerSlug string 必填
repoName string 必填
labelName string 必填
响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content更新标签
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}更新由当前名称指定的代码仓库标签。
未提供的字段保持不变;如果请求未提供这三个字段中的任何一个,则返回标签当前的状态。重命名为已被其他标签使用的名称时,返回 AlreadyExists (HTTP 409 Conflict) 。未知的 labelName 返回 404。
路径参数
ownerSlug string 必填
repoName string 必填
labelName string 必填
请求体
name string
color string
# 的六位十六进制颜色值。未提供则保持不变。description string
响应字段
id string
name string
color string
# 的六位十六进制颜色值。description string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "color": "b60205"}'响应结构:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "b60205", "description": "Something isn't working"}PR
已关闭或合并的 PR 还可能包含 closedAt、mergedAt 和 mergeCommitSha。将 head.ref 和 base.ref 视为不透明的 源站 引用 string;它们可能是简短的分支名称,也可能是完全限定的 refs/heads/… 值。
version 是该 PR 最新的编号修订版本。当 head 被推送、PR 被重新指向另一个 base,或 PR 在关闭期间 head 发生移动、随后被重新打开时,源站 会记录一个新版本,每个版本都有各自的 headSha、baseSha 和 diff 统计信息。若重新打开时记录了新版本,则会发送 pull_request.head_ref.pushed,与推送时发送的事件相同。base 分支自行推进不会记录任何内容,因此 version.baseSha (以及与其镜像的 base.sha) 是记录该版本时解析出的 base tip,在记录下一个版本之前,可能落后于该分支的当前 tip。使用 Get Git Ref 读取分支的当前 tip。
mergeCommitSha 是合并写入 base 分支的提交:合并后会设置,合并前未设置。合并前的预览是 pull/{pullNumber}/merge 引用,是另一个提交;参见 Git data。
version.potentialMergeCommit 报告 源站 对该版本进行测试合并的结果:状态为 prepared、遇到 merge_conflict,或仍为 unknown;准备完成后,还会提供合并提交的 sha 及其所基于的 baseSha。该字段仅描述对应版本,因此 PR 合并后仍会继续报告它。pull_request.* webhook 负载会携带事件发生时的该值。事件只会在一定的时间预算内等待准备完成,因此事件中可能显示 unknown,而稍后调用 Get Pull Request 时显示 prepared;此时请重新读取该 PR,或等待下一个事件。
评审 verdict 可以是 approve、request_changes 或 comment。未提交的草稿评审没有 submittedAt。当决定仍有效时,dismissal 不存在。被驳回的评审仍会显示在评审列表中。被较新决定自动取代的评审会附带由服务器生成的消息。
评论会提供用于分组的 thread 引用。回复时,创建评论请求仍接受标量 threadId command 参数。使用 Update Pull Request Thread 解决或重新打开线程。
列出拉取请求
/v1/origin/repos/{ownerSlug}/{repoName}/pulls列出仓库中的拉取请求,可按源分支、目标分支、作者、创建时间范围和状态筛选。每个拉取请求均包含其分配的标签。
结果可按创建顺序或最后更新时间排序,通过 sortBy 选择,默认最新的排在前面。将 direction=asc 设为升序即可改为相反顺序。分页令牌会包含生成时使用的排序和筛选条件,因此在不同排序或筛选条件下重放令牌会被拒绝;任一条件发生变化时,请重新开始分页。
路径参数
ownerSlug string 必填
repoName string 必填
查询参数
head string
state string
open (默认值) 、closed、merged、all。closed 涵盖所有不再处于打开状态的拉取请求,包括已合并的请求;merged 则仅包含已合并的请求。任何其他值都会返回 InvalidArgument (HTTP 400) 。pageSize 整数
pageToken string
nextPageToken 的不透明游标。首页请省略该参数。后续请求中的 pageSize 仅作用于当前请求的页;省略则沿用上一页的每页大小。author string
pullRequests[].author.user.id、pullRequests[].author.app.id 或 pullRequests[].author.serviceAccount.id 中返回的值完全一致 (user_…、app_… 或 sa_…) ;也可以传入用户的确切电子邮件地址。电子邮件匹配不区分大小写。应用和服务账户没有电子邮件身份,因此只有用户作者可以通过电子邮件地址进行筛选。没有拉取请求的作者会返回空列表;电子邮件地址无法唯一匹配到某个用户时,也会返回空列表。任何其他值 (包括共享的 origin-cursor-managed-actor ID) 都会返回 InvalidArgument (HTTP 400) 。base string
main) 或完全限定的引用 (refs/heads/main)。省略此项可列出所有基础分支。direction string
sortBy 指定的方向排序。"desc" 为默认值:当 sortBy=created 时,最近创建的项目优先返回;当 sortBy=updated 时,最近更新的项目优先返回。"asc" 则相反。任何其他值会返回 InvalidArgument (HTTP 400)。since string
2026-08-01T00:00:00Z。仅返回在该时间点或之后创建的拉取请求。时间戳格式错误时将返回 InvalidArgument (HTTP 400) 。until string
since 相同,均为 RFC 3339。仅返回在该时刻或之前创建的拉取请求。时间戳格式错误时会返回 InvalidArgument (HTTP 400) 。sortBy string
created (创建顺序,默认值) 或 updated (最后更新时间) 。任何其他值都会返回 InvalidArgument (HTTP 400) 。headSha string
head.sha,以区分二者。其他筛选条件仍然适用,state 默认为 open,因此请传入 state=all,以获取已合并和已关闭的拉取请求。格式错误、缩写或未知的 SHA 均不会匹配任何内容。stackId string
pullRequests[].stack.id 返回的值。仅返回该堆栈的成员,并按请求的排序顺序而非堆栈顺序排列,因此需根据每个成员的 stack.parentPullRequest 重建堆栈。state 仍默认为 open,这会排除已合并的成员;若要获取整个堆栈,请传入 state=all。格式正确但不对应本仓库中任何堆栈的 ID 将返回空列表,任何其他值均会返回 InvalidArgument (HTTP 400)。响应字段
pullRequests 数组
pullRequests[].id string
pullRequests[].number string
pullRequests[].state string
pullRequests[].draft boolean
pullRequests[].merged 布尔值
pullRequests[].title string
pullRequests[].body string
pullRequests[].head 对象
pullRequests[].head.ref string
pullRequests[].head.sha string
pullRequests[].base 对象
pullRequests[].base.ref string
pullRequests[].base.sha string
pullRequests[].author 对象
pullRequests[].author.user 对象
pullRequests[].author.user.id string
pullRequests[].author.user.email string
pullRequests[].author.user.displayName string
pullRequests[].author.user.handle string
@ 前缀。仅在该个人资料公开可见时返回;否则省略。pullRequests[].author.app 对象
pullRequests[].author.app.id string
pullRequests[].author.app.displayName string
pullRequests[].author.serviceAccount 对象
pullRequests[].author.serviceAccount.id string
pullRequests[].createdAt string
pullRequests[].updatedAt string
pullRequests[].closedAt string
pullRequests[].mergedAt string
pullRequests[].mergeCommitSha string
pull/<number>/merge 引用使用获取 Git 引用读取。pullRequests[].additions 整数
pullRequests[].deletions 整数
pullRequests[].changedFiles 整数
pullRequests[].labels 数组
pullRequests[].labels[].id string
pullRequests[].labels[].name string
pullRequests[].labels[].color string
# 的六位十六进制颜色值。pullRequests[].labels[].description string
pullRequests[].stack 对象
pullRequests[].stack.id string
stackId 传入 列出拉取请求 以读取其他成员。pullRequests[].stack.parentPullRequest 对象
pullRequests[].stack.parentPullRequest.id string
pullRequests[].stack.parentPullRequest.number string
pullRequests[].stack.parentPullRequest.repository 对象
repository 相同的 id、name 和 owner 字段。分支栈不会跨越代码仓库,因此这始终是该拉取请求自身的代码仓库。pullRequests[].version 对象
pullRequests[].version.number string
pullRequests[].version.headSha string
pullRequests[].version.baseSha string
pullRequests[].version.createdAt string
pullRequests[].version.potentialMergeCommit 对象
headSha 合并到基础分支最新提交上所生成的提交,以及该测试合并的准备进度。每个版本都有此字段。此字段仅描述当前版本,即使拉取请求已合并,仍可读取;该提交与 mergeCommitSha 不同。对于堆叠式拉取请求,基础分支是父拉取请求的分支,因此测试合并仅涵盖此拉取请求在其之上的更改。pullRequests[].version.potentialMergeCommit.state string
unknown、prepared、merge_conflict。unknown 表示测试合并尚未准备好:该版本仍在等待准备,或准备过程已超时或失败。每个新版本的初始状态都是 unknown,因此不会沿用其他版本的提交。prepared 表示测试合并已生成,sha 和 baseSha 用于描述该合并。merge_conflict 表示将 headSha 合并到基础分支的最新提交时发生冲突,因此没有测试合并;这是获取拉取请求的可合并性报告的 merge_conflict 阻塞状态。重新打开拉取请求会再次准备该版本。将无法识别的值视为 unknown。pullRequests[].version.potentialMergeCommit.sha string
baseSha,第二个父提交是该版本的 headSha。仅当 state 为 prepared 时存在。此版本为最新版本时,pull/{pullNumber}/merge 引用指向该提交。此后仍可通过 获取提交 按 SHA 读取该提交,但无法通过 Git 按 SHA 获取。pullRequests[].version.potentialMergeCommit.baseSha string
state 为 prepared 时才会返回。它可能比 pullRequests[].version.baseSha 更新;如果基础分支只是向前推进,Origin 不会刷新该值。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "pullRequests": [ { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "add-telemetry-schema", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "stack": { "id": "stk_01k2ja2000e0080000000000s1", "parentPullRequest": { "id": "pr_01k2ja2000e0080000000000d3", "number": "16", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } } }, "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } } ]}获取拉取请求
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}返回单个拉取请求,包括其已分配的标签。
已关闭或已合并的拉取请求还可能包含 closedAt、mergedAt 和 mergeCommitSha。将 head.ref 和 base.ref 视为不透明的 Origin 引用字符串;它们可以是短分支名称,也可以是完全限定的 refs/heads/… 值。
路径参数
ownerSlug 字符串 必填
repoName string 必填
pullNumber string 必填
响应字段
id string
number string
state string
draft boolean
merged boolean
title string
body string
head 对象
head.ref string
head.sha string
base 对象
base.ref string
base.sha string
author 对象
author.user 对象
author.user.id 字符串
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀) 。仅当该个人资料公开可见时才会显示;否则省略。author.app 对象
author.app.id string
author.app.displayName string
author.serviceAccount 对象
author.serviceAccount.id string
createdAt string
updatedAt string
closedAt string
mergedAt string
mergeCommitSha string
pull/<number>/merge 引用,使用获取 Git 引用读取。additions 整数
deletions 整数
changedFiles 整数
labels array
labels[].id string
labels[].name string
labels[].color string
# 的六位十六进制颜色值。labels[].description string
stack 对象
stack.id string
stackId 传给 List Pull Requests 即可读取其他成员。stack.parentPullRequest 对象
stack.parentPullRequest.id string
stack.parentPullRequest.number string
stack.parentPullRequest.repository 对象
repository 相同的 id、name 和 owner 字段。分支栈不会跨仓库,因此这里始终是该拉取请求自身所在的代码仓库。version 对象
version.number string
version.headSha string
version.baseSha string
version.createdAt string
version.potentialMergeCommit 对象
headSha 合并到基分支最新提交上的那个提交,以及该测试合并的准备进度。每个版本都包含此信息。它仅描述当前版本,在拉取请求合并后仍可读取;它与 mergeCommitSha 是不同的提交。对于堆叠式拉取请求,基分支是父级拉取请求的分支,因此测试合并只涵盖此拉取请求在该分支基础上的更改。version.potentialMergeCommit.state string
unknown、prepared、merge_conflict。unknown 表示测试合并尚未准备好:该版本正在等待准备,或者准备过程超时或失败。每个新版本最初都处于 unknown 状态,因此不会沿用其他版本的提交。prepared 表示测试合并已生成,sha 和 baseSha 用于描述该合并。merge_conflict 表示将 headSha 合并到基分支的最新提交时发生冲突,因此未生成测试合并;获取 PR 的可合并性 会将这种情况报告为 merge_conflict 阻塞因素。重新打开 PR 后,会再次为该版本准备测试合并。将无法识别的值视为 unknown。version.potentialMergeCommit.sha string
baseSha,第二个父级为该版本的 headSha。仅当 state 为 prepared 时存在。在此版本仍为最新版本期间,pull/{pullNumber}/merge 引用指向该提交。此后仍可通过获取提交按 SHA 读取该提交,但无法通过 Git 按 SHA 获取。version.potentialMergeCommit.baseSha string
state 为 prepared 时提供。它可能比 version.baseSha 更新;如果基分支只是向前推进,Origin 不会刷新此值。curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "add-telemetry-schema", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "stack": { "id": "stk_01k2ja2000e0080000000000s1", "parentPullRequest": { "id": "pr_01k2ja2000e0080000000000d3", "number": "16", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } } }, "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z", "potentialMergeCommit": { "state": "prepared", "sha": "c7b6a5948372615049f8e7d6c5b4a3928170605f", "baseSha": "5e2d1c0b9a8f7e6d5c4b3a2918070605f4e3d2c1" } }}创建拉取请求
/v1/origin/repos/{ownerSlug}/{repoName}/pulls创建一个从 head 合并到 base 的拉取请求。
可选参数 parent_pull_number 可将此更改叠加到同一代码仓库中另一个处于开放或草稿状态的 PR。
title 超过 256 个字符,或 body 超过 65,536 个字符时,将返回 InvalidArgument (HTTP 400) 。两项限制均按 Unicode 代码点计算。
如果 head 与 base 没有共同历史记录,则返回 InvalidArgument (HTTP 400),且不会创建任何内容。如果后续推送导致某个未关闭的拉取请求的 head 与其 base 不再有共同历史记录,Origin 会关闭该拉取请求并发送 pull_request.closed;之后相关的推送不会重新打开该请求。
路径参数
ownerSlug 字符串 必填
repoName string 必填
请求体
title string 必填
body string
head string 必填
base string 必填
InvalidArgument (HTTP 400) 。draft 布尔值
parentPullRequest 对象
clear 时,将返回 InvalidArgument (HTTP 400)。parentPullRequest.number string
parentPullRequest.id string
id 返回的值。响应字段
id string
number string
state string
draft 布尔值
merged boolean
title string
body string
head 对象
head.ref string
head.sha string
base 对象
base.ref string
base.sha string
author 对象
author.user 对象
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该个人资料公开可见时返回;否则省略。author.app 对象
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt string
closedAt string
mergedAt string
mergeCommitSha string
pull/<number>/merge 引用并使用 获取 Git 引用 读取。additions 整数
deletions 整数
changedFiles 整数
labels 数组
labels[].id string
labels[].name string
labels[].color string
# 的六位十六进制颜色值。labels[].description string
stack 对象
stack.id string
stackId 传递给 列出拉取请求 以读取其他成员。stack.parentPullRequest 对象
stack.parentPullRequest.id string
stack.parentPullRequest.number string
stack.parentPullRequest.repository 对象
id、name 和 owner 字段与检查运行 (check run) 的 repository 相同。堆栈不会跨仓库,因此这始终是该拉取请求所属的仓库。version object
version.number string
version.headSha string
version.baseSha string
version.createdAt string
version.potentialMergeCommit object
headSha 合并到基础分支顶端所生成的提交,以及该测试合并的准备进度。每个版本都会显示此字段。它仅描述此版本,在拉取请求合并后仍可读取;该提交不同于 mergeCommitSha。对于堆叠式拉取请求,基础分支是父级拉取请求的分支,因此测试合并仅涵盖此拉取请求在该分支之上的更改。version.potentialMergeCommit.state string
unknown、prepared、merge_conflict。unknown 表示测试合并尚未准备好:该版本仍在等待准备,或准备过程超时或失败。每个新版本的初始状态都是 unknown,因此不会沿用其他版本的提交。prepared 表示测试合并已生成,sha 和 baseSha 描述了该测试合并。merge_conflict 表示将 headSha 合并到基础分支的最新提交时发生冲突,因此没有测试合并;获取拉取请求的可合并性 会将此情况报告为 merge_conflict 阻塞因素,重新打开拉取请求会再次准备该版本。将无法识别的值视为 unknown。version.potentialMergeCommit.sha string
baseSha,第二个父提交是该版本的 headSha。仅当 state 为 prepared 时返回。当此版本为最新版本时,pull/{pullNumber}/merge 引用指向该提交。此后仍可通过 获取提交 按 SHA 读取,但无法通过 Git 按 SHA 获取。version.potentialMergeCommit.baseSha string
state 为 prepared 时返回。它可能比 version.baseSha 更新;基础分支仅向前推进时,源站不会更新它。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": "add-telemetry", "base": "main", "draft": false}'响应结构:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}更新拉取请求
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}更新拉取请求的标题、正文、基础分支、栈父级和/或生命周期状态。
省略的字段保持不变。已提供的字段按以下顺序应用:元数据,然后是重新打开/草稿/准备审查,然后是基础分支,然后是堆栈父项,最后是关闭操作。关闭操作最后执行,因此同一请求中的重新指定目标仍能看到处于打开状态的更改;重新打开操作在基础分支之前执行,因此已关闭的拉取请求可以重新指定目标;堆栈父项在基础分支之后执行,因此显式指定的父项优先于基础分支更改所推导出的父项。如果后续步骤失败,前面的步骤可能已经提交。
title 长于 256 个字符,或 body 长于 65,536 个字符,则返回 InvalidArgument (HTTP 400) 。这两个限制均按 Unicode 代码点计数。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
title string
body string
state string
"open" 或 "closed"。"closed" 会关闭拉取请求。未带 draft: true 的 "open" 会将其标记为可供审查,包括发布已有草稿。若拉取请求在关闭期间其 head 发生变化,重新打开时会记录新的 version 并发送 pull_request.head_ref.pushed。已合并状态不可写;请使用 MergePullRequest。draft 布尔值
true 将拉取请求标记为草稿;false 将其标记为可供审查 (若当前已关闭,则会重新打开,并可能记录一个新的 version) 。当 state 为 "closed" 时忽略。base string
InvalidArgument (HTTP 400) 。parentPullRequest 对象
number 或 id 会将此拉取请求堆叠在该父项之上,并替换任何现有父项;clear 则会移除父项。省略此字段可保持堆栈不变。空选择器、clear: false 或设置多个成员会返回 InvalidArgument (HTTP 400) 。这只是建立关联:不会重写任何分支;只有同时发送 base 时,才会重新指定 base。Origin 会在应用 base 后应用此更改,因此显式指定的父项优先于由 base 更改推导出的父项。parentPullRequest.number string
parentPullRequest.id string
id 字段中返回。parentPullRequest.clear 布尔值
true。响应字段
id string
number string
state string
draft 布尔值
merged 布尔值
title string
body string
head 对象
head.ref string
head.sha string
base 对象
base.ref string
base.sha string
author 对象
author.user 对象
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。author.app 对象
author.app.id string
author.app.displayName string
author.serviceAccount 对象
author.serviceAccount.id string
createdAt string
updatedAt string
closedAt string
mergedAt string
mergeCommitSha string
pull/<number>/merge 引用。additions 整数
deletions 整数
changedFiles 整数
labels 数组
labels[].id string
labels[].name string
labels[].color string
# 的六位十六进制颜色值。labels[].description string
stack 对象
stack.id string
stackId 传递给 列出拉取请求 以读取其他成员。stack.parentPullRequest 对象
stack.parentPullRequest.id string
stack.parentPullRequest.number string
stack.parentPullRequest.repository 对象
repository 相同的 id、name 和 owner 字段。分支栈不会跨越代码仓库,因此这始终是该拉取请求自身的代码仓库。version 对象
version.number string
version.headSha string
version.baseSha string
version.createdAt string
version.potentialMergeCommit 对象
headSha 合并到基准分支最新提交上所生成的提交,以及该测试合并的准备进度。每个版本都包含此字段。它仅描述此版本,即使拉取请求合并后仍可读取;该提交与 mergeCommitSha 不同。对于堆叠式拉取请求,基准分支是父级拉取请求的分支,因此测试合并仅涵盖此拉取请求在该分支基础上所做的更改。version.potentialMergeCommit.state string
unknown、prepared、merge_conflict。unknown 表示测试合并尚未准备就绪:该版本仍在等待准备,或准备过程已超时或失败。每个新版本的初始状态都是 unknown,因此不会沿用其他版本的提交。prepared 表示测试合并已生成,sha 和 baseSha 用于描述该合并。merge_conflict 表示将 headSha 合并到基础分支的最新提交时发生冲突,因此未生成测试合并;获取拉取请求的可合并性 会将此情况报告为 merge_conflict 阻塞因素。重新打开拉取请求后,会再次为该版本准备测试合并。将无法识别的值视为 unknown。version.potentialMergeCommit.sha string
baseSha,第二个父提交是该版本的 headSha。仅当 state 为 prepared 时提供。当此版本是最新版本时,pull/{pullNumber}/merge 引用指向该提交。之后仍可通过 获取提交 按 SHA 读取该提交,但无法通过 Git 按 SHA 获取。version.potentialMergeCommit.baseSha string
state 为 prepared 时提供。它可能比 version.baseSha 更新;如果基准分支只是向前推进,源站不会刷新它。curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "state": "open", "draft": false, "base": "main"}'响应结构:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}列出拉取请求评论
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/comments按时间顺序列出拉取请求中的每条评论,可选择限定在某个创建时间窗口内。每条评论都包含其完整线程:id、差异锚点和解决状态。无需发起第二个请求,即可按 thread.id 对扁平响应进行分组。
页面 token 内嵌了签发时所依据的筛选条件,因此在不同筛选条件下重放的 token 会被拒绝;筛选条件发生更改时请重新开始分页。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
查询参数
pageSize 整数
pageToken string
nextPageToken 的不透明游标。请求第一页时请省略。后续请求中的 pageSize 仅对该页生效;省略则沿用上一页的分页大小。since string
2026-08-01T00:00:00Z。仅返回在该时刻或之后创建的评论。时间戳格式错误时返回 InvalidArgument (HTTP 400) 。until string
since 相同的 RFC 3339 格式。仅返回在该时刻或之前创建的评论。时间戳格式不正确时返回 InvalidArgument (HTTP 400) 。threadIds 数组
InvalidArgument (HTTP 400)。响应字段
comments 数组
comments[].id string
comments[].thread 对象
comments[].thread.id string
comments[].thread.version 对象
comments[].thread.version.number string
comments[].thread.version.headSha string
comments[].thread.version.baseSha string
comments[].thread.path string
comments[].thread.side string
left、right。常规讨论线程中不设置。comments[].thread.startLine 整数
side 版本中锚定范围的起始行。文件级和一般讨论线程为 0。comments[].thread.endLine 整数
0。comments[].thread.resolvedAt string
comments[].thread.createdAt string
comments[].thread.updatedAt string
comments[].body string
comments[].author 对象
comments[].author.user 对象
comments[].author.user.id string
comments[].author.user.email string
comments[].author.user.displayName string
comments[].author.user.handle string
@ 前缀。仅在该资料公开可见时提供;否则省略。comments[].author.app 对象
comments[].author.app.id string
comments[].author.app.displayName string
comments[].author.serviceAccount 对象
comments[].author.serviceAccount.id string
comments[].createdAt string
comments[].updatedAt string
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner 对象
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team、user。未知时省略。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/comments' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "comments": [ { "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" } ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }}获取拉取请求评论
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/comments/{commentId}根据稳定的 Origin ID 返回单条拉取请求评论。位于已授权仓库之外的评论,或调用方不可见的待审评论,将返回 404。
路径参数
ownerSlug string 必填
repoName string 必填
commentId string 必填
响应字段
id string
thread object
thread.id string
thread.version object
thread.version.number string
thread.version.headSha string
thread.version.baseSha string
thread.path string
thread.side string
left、right。常规讨论线程不设置此字段。thread.startLine integer
side 版本中锚定范围的起始行。文件级别和常规讨论线程为 0。thread.endLine integer
0。thread.resolvedAt string
thread.createdAt string
thread.updatedAt string
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该个人资料公开可见时存在;否则省略。author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/comments/COMMENT_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}删除 PR 评论
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/comments/{commentId}通过其稳定的 Origin ID 删除 PR 评论。响应体为空。
评论作者始终可以删除自己的评论。其他调用方必须拥有代码仓库写入权限,repository:contents:write 会授予此权限;否则将收到 PermissionDenied (HTTP 403)。删除线程中的最后一条评论会移除该线程;删除其他任何评论 (包括发起该线程的评论) 时,线程及其剩余评论将保留。线程是否已解决不影响此操作。该评论的表情回应和编辑历史也会随之删除。
未知 ID、已删除的评论以及其他代码仓库中的评论均返回 404。格式错误的 ID 返回 InvalidArgument (HTTP 400)。
路径参数
ownerSlug string 必填
repoName string 必填
commentId string 必填
响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/comments/COMMENT_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content创建拉取请求评论
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/comments在 Origin 拉取请求上创建一条评论。评论恰好针对以下四种目标之一:threadId 用于回复现有讨论线程,无论是常规讨论还是内联讨论;inline 用于在拉取请求版本的差异中,针对某个行范围开启新讨论线程;file 用于在该差异中的整个文件上开启新讨论线程;如果以上三项均未提供,则开启一个新的常规讨论线程。正文超过 65,536 个字符时,将返回 InvalidArgument (HTTP 400) 错误。
inline 锚点必须引用该版本的 diff。path 必须属于该 diff,且锚定侧必须有内容,因此在新增文件上将 left 设为锚点,或在已删除文件上将 right 设为锚点,都会被拒绝并返回 InvalidArgument (HTTP 400)。修改文件中的任意行都可以作为锚点,且范围不局限于 diff 的 hunks。范围必须在锚定侧的文件行数范围内;left 对应 base 提交中的文件,right 对应 head 中的文件。超出文件最后一行的范围会被拒绝并返回 InvalidArgument (HTTP 400)。锚点无效时,Origin 不会退而发布一般讨论评论。
file 锚点仅包含路径。Origin 会根据文件的变更类型确定侧:已删除文件使用 base 版本,其他情况使用 head 版本,并通过 thread.side 返回。删除时发送已删除文件的路径,其他所有变更均发送 head 路径。diff 之外的路径会被拒绝并返回 InvalidArgument (HTTP 400) ,重命名文件重命名前的源路径也会被拒绝。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
body string 必填
threadId string
versionNumber 一起使用。inline 对象
threadId 一起使用。inline.path string 必填
inline.side string 必填
left 表示文件的 base 版本,right 表示 head 版本。inline.startLine integer 必填
side 版本中锚定范围的首行 (从 1 开始计数) 。该范围不得超出该文件的末尾。inline.endLine 整数
startLine。单行锚定时可省略。file 对象
threadId 或 inline 一起使用。file.path string 必填
versionNumber string
0 或未设置表示调用时的最新版本。仅对新线程有意义。响应字段
id string
thread object
thread.id string
thread.version 对象
thread.version.number string
thread.version.headSha string
thread.version.baseSha string
thread.path string
thread.side string
left、right。常规讨论线程不设置此字段。thread.startLine 整数
side 版本中锚定范围的第一行。文件级和常规讨论线程为 0。thread.endLine 整数
0。thread.resolvedAt string
thread.createdAt string
thread.updatedAt string
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该资料公开可见时提供;否则省略。author.app object
author.app.id string
author.app.displayName string
author.serviceAccount 对象
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/comments' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Should the retry budget be configurable?"}'响应结构:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}更新拉取请求评论
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/comments/{commentId}根据稳定的 Origin id 更新拉取请求评论。
替换评论内容。该评论必须属于路径中指定的仓库、对调用方可见,并且由该调用方创建。跨仓库的评论以及隐藏的待审评论会返回 404;归属于其他主体的可见评论会返回 403。超过 65,536 字符的评论内容会以 InvalidArgument (HTTP 400) 被拒绝。
路径参数
ownerSlug 字符串 必填
repoName string 必填
commentId string 必填
请求体
body string 必填
响应字段
id string
thread object
thread.id string
thread.version object
thread.version.number string
thread.version.headSha string
thread.version.baseSha string
thread.path string
thread.side string
left、right。常规讨论线程不设置此字段。thread.startLine 整数
side 版本中锚定范围的起始行。文件级别和常规讨论线程使用 0。thread.endLine 整数
0。thread.resolvedAt string
thread.createdAt string
thread.updatedAt string
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅当该个人资料公开可见时才会显示;否则省略。author.app object
author.app.id string
author.app.displayName string
author.serviceAccount 对象
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/comments/COMMENT_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Should the retry budget be configurable?"}'响应结构:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}更新拉取请求线程
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/threads/{threadId}解决或重新打开拉取请求的评论线程,并返回该线程更新后的状态。再次解决已解决的线程,或再次打开已打开的线程,均不会产生任何效果。
该线程必须属于路径中指定的代码仓库;存储在其他代码仓库中的线程将返回 404。可以使用 创建拉取请求评论 回复已解决的线程,这不会重新打开该线程。
路径参数
ownerSlug string 必填
repoName string 必填
threadId string 必填
请求体
resolved boolean 必填
true 表示将该线程标记为已解决;false 表示重新打开该线程。响应字段
id string
version object
version.number string
version.headSha string
version.baseSha string
path string
side string
left、right。一般讨论线程不设置此值。startLine 整数
side 版本中锚定范围的起始行。文件级线程和综合讨论线程为 0。endLine 整数
0。resolvedAt string
createdAt string
updatedAt string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/threads/THREAD_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "resolved": true}'响应结构:
{ "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "resolvedAt": "2026-08-03T10:00:00Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-03T10:00:00Z"}列出拉取请求的提交
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/commits列出 PR 中的提交。
以精简的 Commit 对象形式返回该拉取请求的提交 (不含 stats) 。结果默认返回 30 条,最大为 100 条,整体最多可见 250 条提交。页面令牌会固定拉取请求版本和提交游标;若令牌与当前的 head 或 base 不再匹配,则返回 400。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。首页请求时留空。该 token 与代码仓库、拉取请求版本和提交偏移量绑定。后续请求中的 pageSize 作用于该页;省略时沿用上一页的每页数量。响应字段
commits 数组
commits[].sha string
commits[].commit 对象
commits[].commit.author 对象
commits[].commit.author.name string
commits[].commit.author.email string
commits[].commit.author.date string
commits[].commit.committer 对象
commits[].commit.committer.name string
commits[].commit.committer.email string
commits[].commit.committer.date string
commits[].commit.message string
commits[].commit.tree 对象
commits[].commit.tree.sha string
commits[].parents 数组
commits[].parents[].sha string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/commits' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "commits": [ { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } } ]}列出拉取请求文件
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/files列出拉取请求中已更改的文件。
返回文件名、状态、行数统计、补丁以及可选的原文件名。结果默认返回 30 个文件,最多 100 个。页面令牌会固定拉取请求的版本和文件游标;若令牌与当前的 head 或 base 不再匹配,则返回 400。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
查询参数
pageSize 整数
pageToken string
next_page_token 的不透明游标。第一页为空。该 token 与代码仓库、拉取请求版本和变更文件游标绑定。后续请求中的 pageSize 适用于该页;若省略,则沿用上一页的每页数量。响应字段
files 数组
files[].filename string
files[].status string
files[].additions 整数
files[].deletions 整数
files[].changes 整数
files[].patch string
files[].previousFilename string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}列出 PR 标签
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels列出分配给 PR 的所有标签,按名称排序。
响应包含完整的已分配标签列表,而非分页结果,因此此端点不接受分页参数。一个 PR 最多可有 100 个标签。找不到的 PR 返回 404。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
响应字段
labels array
labels[].id string
labels[].name string
labels[].color string
# 的六位十六进制颜色。labels[].description string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}设置 PR 标签
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels将 PR 上的所有标签替换为指定的标签。
空列表会移除所有已分配的标签。标签必须已存在于代码仓库中;标签名称或 PR 不存在时将返回 404。一个 PR 最多可拥有 100 个标签,因此指定超过 100 个标签将返回 FailedPrecondition (HTTP 400) 。响应会列出替换后分配的标签,并按名称排序。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
labels array
响应字段
labels array
id、name、color 和 description。curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "labels": [ "bug" ]}'响应结构:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}添加 PR 标签
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels向 PR 添加现有代码仓库标签。
已分配给 PR 的标签会保留。标签必须已存在于代码仓库中;未知的标签名称或 PR 会返回 404。请求必须指定 1 到 100 个标签,且一个 PR 最多可拥有 100 个标签,因此会使标签总数超过此限制的请求将返回 FailedPrecondition (HTTP 400)。响应会列出请求中指定的标签,而非 PR 的完整标签集;请使用列出 PR 标签获取完整标签集。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
labels array 必填
响应字段
labels array
id、name、color 和 description。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "labels": [ "bug" ]}'响应结构:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}移除 PR 的所有标签
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels移除 PR 中的所有标签。
PR 不含任何标签时,请求成功。未找到的 PR 返回 404。响应体为空。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
响应字段
请求成功时不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content移除 PR 标签
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels/{labelName}从 PR 中移除一个标签。
如果标签未分配给该 PR,或 PR 不存在,均会返回 404。响应会列出 PR 上剩余的标签,并按名称排序。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
labelName string 必填
响应字段
labels array
id、name、color 和 description。curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}合并拉取请求
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/merge将拉取请求合并到其基础分支。
对于堆叠式拉取请求,合并从根节点到目标节点、以当前拉取请求编号结尾的整个前缀,而不仅仅是当前拉取请求。仅支持原生 Origin 仓库;不支持镜像仓库。
合并会合入该 PR 最新 version 的 head 提交。如果 head 分支已越过该提交 (例如已有推送完成,但源站尚未将其记录为新版本) ,请求将返回 Aborted (HTTP 409 Conflict) ,与 expectedHeadSha 过期时的响应相同,且不会合并任何内容。请等 获取 PR 在 version.headSha 中返回新的 head 后再重试。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
expectedHeadSha string
ABORTED (HTTP 409 Conflict) ,且不会合并任何内容。非完整提交 SHA 的值将被拒绝,并返回 InvalidArgument (HTTP 400) 。省略此项则合并当前提交头。如果拉取请求已合并,则不会进行此项检查,并返回幂等成功。mergeMethod string
merge (创建合并提交) 和 squash (创建单个压缩提交) 。如果仓库不允许所选方式,则会返回 FailedPrecondition (HTTP 400) ;如果值为其他内容,则会返回 InvalidArgument (HTTP 400) 。省略此项则使用仓库的默认方式:如果仓库允许合并提交,则创建合并提交;否则使用压缩方式;如果基分支要求线性历史记录,则使用压缩方式。响应字段
mergeCommitSha string
pull/<number>/merge 引用,使用 获取 Git 引用 获取。mergedPullNumbers 数组
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.state string
pullRequest.draft boolean
pullRequest.merged boolean
pullRequest.title string
pullRequest.body string
pullRequest.head 对象
pullRequest.head.ref string
pullRequest.head.sha string
pullRequest.base 对象
pullRequest.base.ref string
pullRequest.base.sha string
pullRequest.author 对象
pullRequest.author.user 对象
pullRequest.author.user.id string
pullRequest.author.user.email string
pullRequest.author.user.displayName string
pullRequest.author.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。pullRequest.author.app 对象
pullRequest.author.app.id string
pullRequest.author.app.displayName string
pullRequest.author.serviceAccount 对象
pullRequest.author.serviceAccount.id string
pullRequest.createdAt string
pullRequest.updatedAt string
pullRequest.closedAt string
pullRequest.mergedAt string
pullRequest.mergeCommitSha string
pull/<number>/merge 引用使用 获取 Git 引用 读取。pullRequest.additions 整数
pullRequest.deletions 整数
pullRequest.changedFiles 整数
pullRequest.labels 数组
pullRequest.labels[].id string
pullRequest.labels[].name string
pullRequest.labels[].color string
#。pullRequest.labels[].description string
pullRequest.stack 对象
pullRequest.stack.id string
stackId 传递给 列出拉取请求 以读取其他成员。pullRequest.stack.parentPullRequest 对象
pullRequest.stack.parentPullRequest.id string
pullRequest.stack.parentPullRequest.number string
pullRequest.stack.parentPullRequest.repository 对象
repository 相同的 id、name 和 owner 字段。分支栈不会跨仓库,因此这里始终是该拉取请求自身所在的仓库。pullRequest.version 对象
pullRequest.version.number string
pullRequest.version.headSha string
pullRequest.version.baseSha string
pullRequest.version.createdAt string
pullRequest.version.potentialMergeCommit 对象
headSha 合并到基础分支最新提交后生成的提交,以及测试合并的准备进度。每个版本都会包含此信息。它仅描述此版本,且在拉取请求合并后仍可读取;它与 mergeCommitSha 是不同的提交。对于堆叠式拉取请求,基础分支是父级拉取请求的分支,因此测试合并仅涵盖此拉取请求基于该分支所做的更改。pullRequest.version.potentialMergeCommit.state string
unknown、prepared、merge_conflict。unknown 表示测试合并尚未就绪:该版本正在等待准备,或准备已超时或失败。每个新版本的初始状态均为 unknown,因此绝不会带有其他版本的提交。prepared 表示测试合并已存在,其信息由 sha 和 baseSha 给出。merge_conflict 表示将 headSha 合并到基础分支顶端时发生冲突,因此不存在测试合并;获取 PR 可合并性 会将此情况报告为 merge_conflict 阻塞因素,重新打开该 PR 会重新准备该版本。遇到无法识别的值时,应按 unknown 处理。pullRequest.version.potentialMergeCommit.sha string
baseSha,第二个父提交是该版本的 headSha。仅当 state 为 prepared 时才会提供。此版本为最新版本期间,pull/{pullNumber}/merge 引用指向该提交。此后仍可通过 获取提交 根据 SHA 读取该提交,但无法通过 Git 根据 SHA 获取。pullRequest.version.potentialMergeCommit.baseSha string
state 为 prepared 时提供。该提交可能比 pullRequest.version.baseSha 更新;如果基础分支只是向前推进,Origin 不会刷新此值。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/merge' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "expectedHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "mergeMethod": "squash"}'响应结构:
{ "mergeCommitSha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "mergedPullNumbers": [ "17" ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "closed", "draft": false, "merged": true, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "closedAt": "2026-08-03T10:15:00Z", "mergedAt": "2026-08-03T10:15:00Z", "mergeCommitSha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } }}获取 PR 的可合并性
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/mergeability返回该拉取请求 (PR) 是否可以合并;如果不能,则列出阻止合并的条件。该判定基于 Merge Pull Request 强制的相同条件,因此 mergeable 判定表示针对相同分支头发起的合并预计会成功。对于堆叠式拉取请求,判定涵盖从堆栈根到当前请求的所有拉取请求,每个阻塞项都会注明其所属的拉取请求。
总计超过 200 个拉取请求的栈 (包括已合并的祖先) 会返回 FailedPrecondition (HTTP 400) 。
此操作处于预览版,在合约定型之前,其结构可能会发生变化。解析响应时请容忍未知字段和未知枚举值;将无法识别的 verdict 视为 blocked;当无法识别 blockers[].kind 时,请渲染 blockers[].message。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
查询参数
expectedHeadSha string
Aborted (HTTP 409 Conflict) 而不是结果。若值不是完整的提交 SHA,则返回 InvalidArgument (HTTP 400) 。响应字段
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner 对象
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team、user。未知时省略。verdict string
evaluatedPullRequests 中每个 PR 的总体结论。允许的取值:mergeable,表示合并 pullRequest 即可将它们全部合入;以及 blocked。遇到无法识别的取值,按 blocked 处理。blockers 数组
verdict 为 mergeable 时为空。每个拉取请求每种类型最多一个阻塞项,但 required_checks 按每个状态各有一个,rule_failure 和 ruleset_error 则按每个不同消息各有一个。blockers[].pullRequest 对象
evaluatedPullRequests 中的拉取请求。包含与 pullRequest 相同的字段。blockers[].kind string
draft、closed、merged、merge_conflict、required_checks、required_approvals、codeowner_approval、behind_base、needs_restack、restack_pending、conflict_check_pending、invalid_stack、ruleset_error、rule_failure。类别会随着时间增加;如果某个阻塞项的类别在您的客户端版本之后才被引入,则解码时其 kind 会保持未设置,但仍然会造成阻塞。blockers[].message string
kind 时应渲染此内容。blockers[].requiredChecks 对象
required_checks 阻止器上。blockers[].requiredChecks.state string
missing、pending、failing、action_required。blockers[].requiredChecks.checks 数组
blockers[].requiredChecks.checks[].name string
blockers[].requiredChecks.checks[].owner 对象
actor 相同。blockers[].requiredChecks.checks[].checkRun 对象
headSha 上满足此要求的检查运行。若尚未报告任何检查运行,则会省略,状态为 missing。它仅包含 id、name 和 checkSuite.id,因为只需 repository:pull_requests:read 即可读取此操作;而运行的状态、结论、输出和详情 URL 则需要 repository:checks:read,请通过 Get Check Run 读取这些信息。blockers[].requiredApprovals 对象
required_approvals 阻塞因素上设置。blockers[].requiredApprovals.requiredCount integer
blockers[].requiredApprovals.approvedCount 整数
blockers[].codeownerApproval 对象
codeowner_approval 阻塞。blockers[].codeownerApproval.requirements 数组
blockers[].codeownerApproval.requirements[].owners 数组
blockers[].codeownerApproval.requirements[].paths 数组
blockers[].mergeConflict 对象
merge_conflict 阻塞因素上设置。blockers[].mergeConflict.conflictedPaths 数组
blockers[].mergeConflict.truncated 布尔值
blockers[].mergeConflict.inheritedFromDownstack 布尔值
blockers[].stackShape 对象
invalid_stack 阻塞因素上设置。blockers[].stackShape.reason string
partially_merged、cycle、missing_parent、cross_repository_parent、base_branch_missing。blockers[].stackShape.relatedPullRequests 数组
pullRequest 相同。evaluatedPullRequests 数组
pullRequest 时将合入的 PR,按分支栈根节点在前、pullRequest 在后的顺序排列。已合并的祖先 PR 属于历史记录,不会列出。未加入分支栈的 PR 仅包含一个元素。每个元素均包含与 pullRequest 相同的字段。headSha string
pullRequest 的 head commit。baseRef string
baseSha string
evaluatedAt 时 baseRef 指向的顶端提交。之后推送到 baseRef 可能会改变判定。如果无法确定基础分支 (例如在分支栈无效时) ,则该值为空。evaluatedAt string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/mergeability' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "verdict": "blocked", "blockers": [ { "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "kind": "required_approvals", "message": "已批准的评审数为 0;需要 1 个。请请求评审并等待获得所需的批准。", "requiredApprovals": { "requiredCount": 1, "approvedCount": 0 } }, { "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "kind": "required_checks", "message": "必需的状态检查正在等待中。请等待检查完成,或修复未通过的检查。", "requiredChecks": { "state": "pending", "checks": [ { "name": "ci / build", "owner": { "app": { "id": "app_01k2ja2000e0080000000000e5", "displayName": "Launch CI" } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000f6", "name": "ci / build", "checkSuite": { "id": "crg_01k2ja2000e0080000000000f7" } } } ] } } ], "evaluatedPullRequests": [ { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } } ], "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseRef": "main", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "evaluatedAt": "2026-08-02T14:45:00Z"}列出 PR 请求的审阅人
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewers列出当前被请求对某个 PR 进行评审的用户和群组。
当某个用户提交评审后,针对该用户的直接请求会被清除;当群组中的任一当前成员提交评审后,针对该群组的请求会被清除。未提交的草稿评审会使请求保持待处理状态;在提交评审后再次请求评审,该审阅人会重新出现在此列表中。没有可读公开标识符的群组将被省略。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
响应字段
users array
users[].id string
user_…) ,与组织 API 使用的格式相同。users[].email string
users[].displayName string
users[].handle string
@ 前缀。仅当该配置文件公开可见时存在;否则将被省略。groups array
groups[].id string
grp_…) 。curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "users": [ { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } ], "groups": [ { "id": "grp_01k2ja2000e0080000000000n2" } ]}请求拉取请求审阅者
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewers请求指定用户和群组对某个 PR 进行评审,并返回本次调用所请求的审阅人。
标识符会按仓库的审阅者候选项通过 public id、用户电子邮件或群组 slug 进行解析。显示名称不参与解析。未知或歧义的标识符会返回 InvalidArgument (HTTP 400) 并指明该标识符;在 users 和 groups 中至少要有一个非空条目。
对已请求过的审阅人再次发起请求会刷新请求时间戳,因此已提交评审的审阅人会重新变为待处理状态。若某审阅人不属于该仓库的候选人,则返回 PermissionDenied (HTTP 403)。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
users array
user_… ID 或电子邮件在该仓库中唯一匹配一个用户候选项。groups array
grp_... id、限定组 slug 或组 slug 唯一匹配此仓库的组候选项。响应字段
users array
users[].id string
user_…) ,与组织 API 使用的格式相同。users[].email string
users[].displayName string
users[].handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。groups array
groups[].id string
grp_…) 。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "users": [ "user_01k2ja2000e0080000000000c3" ], "groups": [ "grp_01k2ja2000e0080000000000n2" ]}'响应结构:
{ "users": [ { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } ], "groups": [ { "id": "grp_01k2ja2000e0080000000000n2" } ]}移除 PR 请求的审阅人
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewers移除某个 PR 上对指定用户和群组的评审请求。响应体为空。
标识符会按公开 id、用户电子邮件或群组 slug 解析为该代码仓库的审阅候选人。显示名称无法解析。未知或存在歧义的标识符将返回 InvalidArgument (HTTP 400) 并指明该标识符,且 users 与 groups 中至少需要有一个非空条目。
移除当前未被请求的用户或群组不会产生任何效果。若标识符为稳定的公开 id (user_… 或 grp_…) ,即使其已不再是审阅候选人,仍会被接受,因此可以清除已离开该代码仓库的审阅人。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
users array
user_… id 或电子邮件唯一匹配该代码仓库的一个用户候选项。groups array
grp_… id、限定群组 slug 或群组 slug 唯一匹配该代码仓库的一个群组候选项。响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "users": [ "user_01k2ja2000e0080000000000c3" ], "groups": [ "grp_01k2ja2000e0080000000000n2" ]}'响应:
204 No Content列出拉取请求评审
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews列出拉取请求上已提交的评审,按 submitted_at 升序排列。待处理的评审将被省略。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
查询参数
pageSize 整数
pageToken string
nextPageToken 的不透明游标。请求第一页时请省略。后续请求中的 pageSize 作用于该页;省略则沿用之前的每页大小。响应字段
reviews 数组
reviews[].id string
reviews[].author 对象
reviews[].author.user 对象
reviews[].author.user.id string
reviews[].author.user.email string
reviews[].author.user.displayName string
reviews[].author.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。reviews[].author.app 对象
reviews[].author.app.id string
reviews[].author.app.displayName string
reviews[].author.serviceAccount 对象
reviews[].author.serviceAccount.id string
reviews[].verdict string
reviews[].body string
reviews[].submittedAt string
reviews[].pullRequestVersion 对象
reviews[].pullRequestVersion.number string
reviews[].pullRequestVersion.headSha string
reviews[].pullRequestVersion.baseSha string
reviews[].dismissal 对象
reviews[].dismissal.dismissedBy 对象
reviews[].dismissal.dismissedBy.user 对象
reviews[].dismissal.dismissedBy.user.id string
reviews[].dismissal.dismissedBy.user.email string
reviews[].dismissal.dismissedBy.user.displayName string
reviews[].dismissal.dismissedBy.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。reviews[].dismissal.dismissedBy.app 对象
reviews[].dismissal.dismissedBy.app.id string
reviews[].dismissal.dismissedBy.app.displayName string
reviews[].dismissal.dismissedBy.serviceAccount 对象
reviews[].dismissal.dismissedBy.serviceAccount.id string
reviews[].dismissal.dismissedAt string
reviews[].dismissal.message string
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner 对象
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team、user。未知时省略。nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "reviews": [ { "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } } ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }}创建拉取请求审查
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews创建并提交对拉取请求的审查,可选择在同一原子请求中一并提交其评论。每条评论与创建拉取请求评论使用相同的目标:comments[].inline 指定行范围,comments[].file 指定整个文件,comments[].threadId 用于回复,若均不指定则为一般讨论。
评审会立即提交。新的 approve 或 request_changes 评审将取代调用者在同一拉取请求上先前的有效决策评审,并将其撤销。拉取请求的作者不能对自己的拉取请求执行 approve。当调用者在该拉取请求上有未提交的草稿评审时,会返回 FAILED_PRECONDITION 错误。
设置了 comments 时,在写入任何内容之前,会根据已审核版本的 diff 验证每个锚点,使用与 Create Pull Request Comment 相同的 diff 内检查。如果有一条评论验证失败,整个请求将以 InvalidArgument (HTTP 400) 失败,且不会发布任何内容。评论会与审查结果一同原子性地变为可见:在审查提交之前,任何评论或事件都不可被观察到;提交后,每条评论都会与审查事件一道触发各自的 pull_request.comment.created webhook。
该操作不包含幂等键,因此在发生结果不确定的传输故障后重试可能会创建第二个评审。在重试之前请调用列出拉取请求评审。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
请求体
verdict string 必填
PULL_REQUEST_REVIEW_VERDICT_UNSPECIFIED、approve、request_changes、comment。body string
versionNumber string
PullRequestVersion.number) 。省略时,将在调用时评审最新版本。评论会锚定到同一版本。comments 数组
comments[].body string 必填
comments[].inline 对象
comments[].inline.path string 必填
comments[].inline.side string 必填
left 表示文件的基础版本,right 表示 head 版本。comments[].inline.startLine 整数 必填
side 版本中锚定范围的起始行 (行号从 1 开始) 。该范围不得超出该文件的末尾。comments[].inline.endLine 整数
startLine。对于单行锚点可省略。comments[].threadId string
comments[].inline、comments[].file 和此字段以新建一个常规讨论线程。comments[].file 对象
file 相同。不能与 comments[].inline 或 comments[].threadId 一起使用。comments[].file.path string 必填
响应字段
id string
author 对象
author.user 对象
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该资料公开可见时存在;否则省略。author.app 对象
author.app.id string
author.app.displayName string
author.serviceAccount 对象
author.serviceAccount.id string
verdict string
body string
submittedAt string
pullRequestVersion 对象
pullRequestVersion.number string
pullRequestVersion.headSha string
pullRequestVersion.baseSha string
dismissal 对象
dismissal.dismissedBy 对象
dismissal.dismissedBy.user 对象
dismissal.dismissedBy.user.id string
dismissal.dismissedBy.user.email string
dismissal.dismissedBy.user.displayName string
dismissal.dismissedBy.user.handle string
@ 前缀。仅在该资料公开可见时显示;否则省略。dismissal.dismissedBy.app 对象
dismissal.dismissedBy.app.id string
dismissal.dismissedBy.app.displayName string
dismissal.dismissedBy.serviceAccount 对象
dismissal.dismissedBy.serviceAccount.id string
dismissal.dismissedAt string
dismissal.message string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "versionNumber": "3"}'响应结构:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }}更新拉取请求审查
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews/{reviewId}更新评审内容。仅评审作者可以更新;其他调用方将收到 PERMISSION_DENIED。不属于指定拉取请求的评审将返回 NOT_FOUND。
未提交的草稿评审同样可以更新;草稿的响应中不含 submitted_at。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
reviewId string 必填
请求体
body string 必填
响应字段
id string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
verdict string
body string
submittedAt string
pullRequestVersion 对象
pullRequestVersion.number string
pullRequestVersion.headSha string
pullRequestVersion.baseSha string
dismissal 对象
dismissal.dismissedBy object
dismissal.dismissedBy.user 对象
dismissal.dismissedBy.user.id string
dismissal.dismissedBy.user.email string
dismissal.dismissedBy.user.displayName string
dismissal.dismissedBy.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。dismissal.dismissedBy.app 对象
dismissal.dismissedBy.app.id string
dismissal.dismissedBy.app.displayName string
dismissal.dismissedBy.serviceAccount 对象
dismissal.dismissedBy.serviceAccount.id string
dismissal.dismissedAt string
dismissal.message string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews/REVIEW_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Approving. The telemetry schema matches the spec."}'响应结构:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }}关闭拉取请求评审
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews/{reviewId}/dismissals撤销已提交的评审,使其裁定不再计入拉取请求的评审状态。评审本身会被保留,并继续出现在 ListPullRequestReviews 中,且 dismissal 已设置。
撤销评审不要求操作者是该评审的作者;只需拥有对该代码仓库拉取请求评审的写入权限即可。
只有 approve 和 request_changes 两种评审可以被撤销,且仅能撤销一次:对 comment 评审、未提交的草稿评审或已被撤销的评审的调用会返回 FAILED_PRECONDITION,重复调用将保留第一次的撤销。不属于指定拉取请求的评审会返回 NOT_FOUND。
路径参数
ownerSlug string 必填
repoName string 必填
pullNumber string 必填
reviewId string 必填
请求体
message string 必填
响应字段
id string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
verdict string
body string
submittedAt string
pullRequestVersion 对象
pullRequestVersion.number string
pullRequestVersion.headSha string
pullRequestVersion.baseSha string
dismissal 对象
dismissal.dismissedBy 对象
dismissal.dismissedBy.user 对象
dismissal.dismissedBy.user.id string
dismissal.dismissedBy.user.email string
dismissal.dismissedBy.user.displayName string
dismissal.dismissedBy.user.handle string
@ 前缀。仅在该个人资料公开可见时提供;否则省略。dismissal.dismissedBy.app 对象
dismissal.dismissedBy.app.id string
dismissal.dismissedBy.app.displayName string
dismissal.dismissedBy.serviceAccount 对象
dismissal.dismissedBy.serviceAccount.id string
dismissal.dismissedAt string
dismissal.message string
curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews/REVIEW_ID/dismissals' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "message": "Superseded by a newer review."}'响应结构:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "dismissal": { "dismissedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "dismissedAt": "2026-08-02T15:00:00Z", "message": "Superseded by a newer review." }}规则集
列出规则集
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets列出代码仓库中配置的所有规则集。
每个代码仓库的规则集数量有限,因此会在单个响应中返回完整集合,此端点不进行分页。repository 仅在响应中出现一次,用于描述所有规则集共享的代码仓库。
路径参数
ownerSlug string 必填
repoName string 必填
响应字段
rulesets 数组
rulesets[].id string
rulesets[].name string
rulesets[].description string
rulesets[].enforcement string
active、evaluate、disabled。rulesets[].kind string
merge_branch、push_branch、push_tag、push_repository。rulesets[].includedRefNames 数组
~ALL 和 ~DEFAULT_BRANCH 两个标记。rulesets[].excludedRefNames 数组
rulesets[].includedRefNames 相同的模式语言。rulesets[].rules 数组
rulesets[].rules[].id string
rulesets[].rules[].ruleType string
pull_request、require_status_checks、require_branch_up_to_date、deletion 或 non_fast_forward。rulesets[].rules[].parameters 对象
rulesets[].rules[].ruleType。rulesets[].bypassActors 数组
rulesets[].bypassActors[].id string
rulesets[].bypassActors[].bypassMode string
always、pull_request_only。rulesets[].bypassActors[].user 对象
user、team、app 或 originRole 中恰有且仅有一个存在。rulesets[].bypassActors[].user.id string
rulesets[].bypassActors[].team 对象
rulesets[].bypassActors[].team.organizationPublicId string
rulesets[].bypassActors[].team.groupPublicId string
rulesets[].bypassActors[].app 对象
rulesets[].bypassActors[].app.id string
app_。rulesets[].bypassActors[].originRole 对象
rulesets[].bypassActors[].originRole.role string
namespace_admin、repository_admin、repository_write。repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team、user。未知时省略。curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "rulesets": [ { "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ] } ], "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }}创建规则集
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets创建代码仓库规则集。
响应中包含已存储的规则集,其中包括 Origin 为每条规则和绕过主体分配的 ID。空的 name 会被拒绝,并返回 InvalidArgument (HTTP 400) 。
路径参数
ownerSlug string 必填
repoName string 必填
请求体
name string 必填
description string
enforcement string 必填
active、evaluate、disabled。kind string 必填
merge_branch、push_branch、push_tag、push_repository。includedRefNames 数组
~ALL 与 ~DEFAULT_BRANCH。条目数超过 64 将返回 InvalidArgument (HTTP 400) 。excludedRefNames 数组
includedRefNames 相同的模式语言,最多可包含 64 项。rules 数组
ruleType 和可选的 parameters;Origin 会为每条规则分配 id。条目数超过 20 个将被拒绝并返回 InvalidArgument (HTTP 400) 。bypassActors array
bypassMode,以及 user、team、app 或 originRole 中的一个;Origin 为每个主体分配 id。条目数超过 15 个时将被拒绝并返回 InvalidArgument (HTTP 400) 。响应字段
id string
name string
description string
enforcement string
active、evaluate、disabled。kind string
merge_branch、push_branch、push_tag、push_repository。includedRefNames 数组
~ALL 和 ~DEFAULT_BRANCH。excludedRefNames 数组
includedRefNames 相同的模式语法。rules 数组
rules[].id string
rules[].ruleType string
pull_request、require_status_checks、require_branch_up_to_date、deletion 或 non_fast_forward。rules[].parameters 对象
rules[].ruleType。bypassActors array
bypassActors[].id string
bypassActors[].bypassMode string
always、pull_request_only。bypassActors[].user 对象
user、team、app 或 originRole 中有且仅有一个存在。bypassActors[].user.id string
bypassActors[].team object
bypassActors[].team.organizationPublicId string
bypassActors[].team.groupPublicId string
bypassActors[].app 对象
bypassActors[].app.id string
app_ 为前缀。bypassActors[].originRole 对象
bypassActors[].originRole.role string
namespace_admin、repository_admin、repository_write。curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}'响应结构:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}获取规则集
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}根据稳定的 Origin ID 返回单个代码仓库规则集。
未知的代码仓库和未知的规则集都会返回 404,可通过返回的消息加以区分。
路径参数
ownerSlug string 必填
repoName string 必填
rulesetId string 必填
响应字段
id string
name string
description string
enforcement string
active、evaluate、disabled。kind string
merge_branch、push_branch、push_tag、push_repository。includedRefNames 数组
~ALL 和 ~DEFAULT_BRANCH。excludedRefNames 数组
includedRefNames 相同。rules 数组
rules[].id string
rules[].ruleType string
pull_request、require_status_checks、require_branch_up_to_date、deletion 或 non_fast_forward。rules[].parameters 对象
rules[].ruleType。bypassActors array
bypassActors[].id string
bypassActors[].bypassMode string
always、pull_request_only。bypassActors[].user 对象
user、team、app 或 originRole 中有且仅有一个。bypassActors[].user.id string
bypassActors[].team 对象
bypassActors[].team.organizationPublicId string
bypassActors[].team.groupPublicId string
bypassActors[].app 对象
bypassActors[].app.id string
app_ 为前缀。bypassActors[].originRole 对象
bypassActors[].originRole.role string
namespace_admin、repository_admin、repository_write。curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}更新规则集
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}更新现有的代码仓库规则集。
该请求会替换整个规则集配置。rules 和 bypassActors 会被完全替换,而不会合并;Origin 会为已存储的条目分配新的 ID,因此请发送所有要保留的规则和绕过主体。
路径参数
ownerSlug string 必填
repoName string 必填
rulesetId string 必填
请求体
name string 必填
description string
enforcement string 必填
active、evaluate、disabled。kind string 必填
merge_branch、push_branch、push_tag、push_repository。includedRefNames 数组
~ALL 和 ~DEFAULT_BRANCH。超过 64 个条目的值会被拒绝,并返回 InvalidArgument (HTTP 400) 。excludedRefNames 数组
includedRefNames 使用相同的模式语法,且同样最多 64 项。rules 数组
ruleType 和可选的 parameters;Origin 会为每条规则分配 id。条目数超过 20 个将被拒绝,返回 InvalidArgument (HTTP 400) 。bypassActors 数组
bypassMode,以及 user、team、app 或 originRole 中的恰好一个;Origin 会为每个主体分配 id。超过 15 个条目将被拒绝,返回 InvalidArgument (HTTP 400) 。响应字段
id string
name string
description string
enforcement string
active、evaluate、disabled。kind string
merge_branch、push_branch、push_tag、push_repository。includedRefNames 数组
~ALL 和 ~DEFAULT_BRANCH。excludedRefNames 数组
includedRefNames 相同的模式语言。rules 数组
rules[].id string
rules[].ruleType string
pull_request、require_status_checks、require_branch_up_to_date、deletion 或 non_fast_forward。rules[].parameters 对象
rules[].ruleType。bypassActors 数组
bypassActors[].id string
bypassActors[].bypassMode string
always、pull_request_only。bypassActors[].user 对象
user、team、app 或 originRole 中仅存在一个。bypassActors[].user.id string
bypassActors[].team 对象
bypassActors[].team.organizationPublicId string
bypassActors[].team.groupPublicId string
bypassActors[].app 对象
bypassActors[].app.id string
app_ 为前缀。bypassActors[].originRole 对象
bypassActors[].originRole.role string
namespace_admin、repository_admin、repository_write。curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}'响应结构:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}删除规则集
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}根据稳定的 源站 ID 删除代码仓库规则集。响应体为空。
未知代码仓库和未知规则集均返回 404,消息会区分二者。存储在其他代码仓库中的规则集会被视为未知规则集。空 rulesetId 返回 InvalidArgument (HTTP 400)。
路径参数
ownerSlug string 必填
repoName string 必填
rulesetId string 必填
响应字段
成功的请求不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No ContentSSH 证书颁发机构
SSH 证书颁发机构是所有者所信任的公钥:由它签发的用户证书可用于认证该所有者仓库上的 Git over SSH 操作,因此所属团队的成员无需注册 SSH 密钥即可通过 SSH 使用 git。这些端点用于列出所有者信任的证书颁发机构、添加和移除证书颁发机构,以及设置所有者是否强制要求使用证书。证书颁发机构隶属于团队拥有的所有者;添加时的重复检查仅在该所有者范围内进行,而不是针对整个源站,因此多个所有者可以信任同一个证书颁发机构。
列出操作支持安装令牌和用户令牌。添加、移除证书颁发机构以及设置证书要求,需要使用具有 namespace:settings:write 权限的 Cherri Code 用户凭据;不支持应用令牌和安装令牌。
列出 SSH 证书颁发机构
/v1/origin/owners/{ownerSlug}/ssh-certificate-authorities列出所有者在通过 SSH 使用 git 时信任的 SSH 证书颁发机构 (按从新到旧排列) ,并返回该所有者是否要求使用证书。响应不分页,会返回全部颁发机构。
路径参数
ownerSlug string 必填
响应字段
certificateAuthorities array
certificateAuthorities[].id string
certificateAuthorityId 参数传入。certificateAuthorities[].name string
certificateAuthorities[].keyType string
ssh-ed25519。certificateAuthorities[].fingerprint string
SHA256:<base64>,与 ssh-keygen -l 的输出格式一致。certificateAuthorities[].publicKey string
<key_type> <base64>,不含注释。certificateAuthorities[].createdAt string
requireCertificates boolean
curl --request GET \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/ssh-certificate-authorities' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应结构:
{ "certificateAuthorities": [ { "id": "nsca_01k2ja2000e0080000000000s5", "name": "Acme production CA", "keyType": "ssh-ed25519", "fingerprint": "SHA256:D5vlIclvaSZlwq4gmckavfLE7n7F542Eyhk/PvXkRq0", "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwoQNzBuiWhDF4EKwRyt8h48XRY7Bc4yWbQ9s3Tnj7Q", "createdAt": "2026-08-02T14:45:00Z" } ], "requireCertificates": true}添加 SSH 证书颁发机构
/v1/origin/owners/{ownerSlug}/ssh-certificate-authorities为所有者添加一个受信任的 SSH 证书颁发机构,并返回该机构。之后,所属团队的成员无需注册 SSH 密钥,即可使用该机构签发的用户证书,通过 SSH 对该所有者的仓库执行 git 操作。
publicKey 是该颁发机构自身的公钥,格式为一行 OpenSSH authorized_keys。如果传入的是证书、不支持的密钥类型或小于 2048 位的 RSA 密钥,则返回 InvalidArgument (HTTP 400) 。如果该所有者已添加过此密钥,则返回 AlreadyExists (HTTP 409 Conflict) ;该检查仅限于当前所有者,因此多个所有者可以信任同一颁发机构。颁发机构只能添加到团队拥有的所有者;对其他任何所有者均返回 FailedPrecondition (HTTP 400) 。
调用方必须是持有 namespace:settings:write 的 Cherri Code 用户凭据。不接受应用令牌和安装令牌。
路径参数
ownerSlug string 必填
请求体
publicKey string 必填
authorized_keys (<key_type> <base64> [comment]) 。支持的密钥类型包括 ssh-ed25519、ecdsa-sha2-nistp256、ecdsa-sha2-nistp384、ecdsa-sha2-nistp521,以及模数不少于 2048 位的 ssh-rsa。不接受证书。name string 必填
响应字段
id string
certificateAuthorityId 传入。name string
keyType string
ssh-ed25519。fingerprint string
SHA256:<base64>,与 ssh-keygen -l 的输出格式一致。publicKey string
<key_type> <base64>,不含注释。createdAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/ssh-certificate-authorities' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwoQNzBuiWhDF4EKwRyt8h48XRY7Bc4yWbQ9s3Tnj7Q acme-ssh-ca", "name": "Acme production CA"}'响应结构:
{ "id": "nsca_01k2ja2000e0080000000000s5", "name": "Acme production CA", "keyType": "ssh-ed25519", "fingerprint": "SHA256:D5vlIclvaSZlwq4gmckavfLE7n7F542Eyhk/PvXkRq0", "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwoQNzBuiWhDF4EKwRyt8h48XRY7Bc4yWbQ9s3Tnj7Q", "createdAt": "2026-08-02T14:45:00Z"}删除 SSH 证书颁发机构
/v1/origin/owners/{ownerSlug}/ssh-certificate-authorities/{certificateAuthorityId}从所有者中移除一个 SSH 证书颁发机构。该颁发机构签发的所有证书都将随之失效。若所有者要求使用证书,则无法移除其最后一个颁发机构,请求将返回 FailedPrecondition (HTTP 400) 。响应体为空。
调用方必须使用持有 namespace:settings:write 权限的 Cherri Code 用户凭据。不接受 App 令牌和安装令牌。
路径参数
ownerSlug string 必填
certificateAuthorityId string 必填
id。响应字段
请求成功时不返回响应体。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/ssh-certificate-authorities/CERTIFICATE_AUTHORITY_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'响应:
204 No Content设置 SSH 证书要求
/v1/origin/owners/{ownerSlug}/ssh-certificate-authorities:setRequirement设置所有者是否要求使用 SSH 证书,并返回该所有者的此项设置。启用该要求后,所有者仓库上的 Git over SSH 操作仅接受由其证书颁发机构签发的证书:用户注册的 SSH 密钥将被拒绝,通过 HTTPS 使用的用户 API 密钥也会被拒绝。启用证书要求前,必须至少已列出一个证书颁发机构,否则请求将返回 FailedPrecondition (HTTP 400) 。若设置值与当前值相同,请求会成功,但不做任何更改。
调用方必须是持有 namespace:settings:write 的 Cherri Code 用户凭据。不接受应用令牌和安装令牌。
路径参数
ownerSlug string 必填
请求体
requireCertificates boolean 必填
响应字段
requireCertificates boolean
curl --request POST \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/ssh-certificate-authorities:setRequirement' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "requireCertificates": true}'响应结构:
{ "requireCertificates": true}Webhooks
源站 会向应用已注册的 HTTPS webhook URL 发送已签名的 HTTP POST 请求,内容类型为 application/json。
投递至少一次。使用 webhook-id 对重试请求去重,持久化接收请求,快速返回 2xx,并异步处理事件。
源站 等待接收方响应请求头的时间为 10 秒。该时限涵盖 DNS 解析、建立连接、TLS 握手以及直至响应返回的耗时,并适用于每一次尝试。超出该时限的尝试会被记录为传输错误,并按 重试 计划进行重试。反复失败可能会自动禁用投递。
若要在任何真实事件到达接收方之前确认其是否正常工作,请调用 Ping Webhook。
源站 会为镜像仓库投递事件,安装事件负载会在所选代码仓库数组中列出这些代码仓库。投递不会扩大安装可调用的范围:请参阅 镜像仓库。
请求头
| 请求头 | 描述 |
|---|---|
content-type | application/json |
user-agent | Cherri Code-Origin-Webhook/1.0 |
webhook-id | 稳定的投递 ID 和幂等键。 |
webhook-timestamp | 签名中包含的 Unix 时间戳。 |
webhook-signature | v1ed,BASE64_SIGNATURE |
webhook-event-type | 用于路由的事件 slug。 |
webhook-event-id | 从已签名请求体中镜像的底层 Origin 事件 ID。 |
webhook-app-id | 目标应用 ID。 |
webhook-installation-id | 目标安装 ID。 |
路由请求头仅为方便起见。验证签名后,应以请求体为准。
签名验证
请在解析前使用原始请求体。构造:
lowercaseHex(SHA-256("<webhook-id>.<webhook-timestamp>.<raw-request-body>"))使用有效的源站 JWKS 密钥,验证该十六进制摘要的 UTF-8 字节所对应的 Ed25519 签名。拒绝与当前时间相差超过五分钟的时间戳。
Standard Webhooks 库无法验证源站的 webhook 投递。虽然这些请求头沿用了 Standard Webhooks 的命名,但源站签名的是 SHA-256 摘要,而非被签名的内容本身,并且使用的是 Standard Webhooks 规范中未定义的 v1ed 版本标签。请按上述构造方式进行验证,具体可参考以下示例。
import { createHash, createPublicKey, verify, type JsonWebKeyInput,} from "node:crypto";export async function verifyOriginWebhook( body: Buffer, headers: Record<string, string | undefined>): Promise<boolean> { const id = headers["webhook-id"]; const timestamp = Number(headers["webhook-timestamp"]); const signature = headers["webhook-signature"] ?.split(/\s+/) .find((value) => value.startsWith("v1ed,")); const now = Math.floor(Date.now() / 1000); if ( !id || !signature || !Number.isInteger(timestamp) || Math.abs(now - timestamp) > 300 ) { return false; } const digest = createHash("sha256") .update(`${id}.${timestamp}.`) .update(body) .digest("hex"); // 生产环境中请缓存此响应。 const { keys } = await fetch( "https://api.cursor.com/v1/origin/keys" ).then((response) => response.json()) as { keys: JsonWebKeyInput[]; }; return keys.some((jwk) => { try { return verify( null, Buffer.from(digest), createPublicKey({ key: jwk, format: "jwk" }), Buffer.from(signature.slice(5), "base64") ); } catch { return false; } });}投递封装
每个请求都会将事件负载连同投递、应用和安装身份信息一并封装:
{ "deliveryId": "whd_01...", "appId": "app_01...", "installationId": "i_01...", "event": { "id": "evt_01...", "type": "pull_request.comment.created", "eventTime": "2026-07-01T10:03:00Z", "payload": {} }}deliveryId 在重试时保持不变。event.id 标识底层域名事件。
重试
对于传输错误、429 和 5xx 响应,源站最多重试七次。其他 4xx 响应不会重试。
第一次尝试为原始发送。其后的六次重试依次等待 5 秒、30 秒、1 分钟、2 分钟、4 分钟和 8 分钟。
若接收方在每次尝试中都失败,则会在约 16 分钟内收到七次 POST。每次尝试的 webhook-id 保持不变,请据此去重。
自动禁用
所有者可以在应用设置中暂停该应用的 webhook 投递。此外,当接收端在 72 小时窗口内至少 20 轮投递失败、该窗口内没有任何一次投递成功,且失败涉及多个安装方命名空间时,源站也会自动将其禁用。
投递将一直停止,直到所有者手动恢复。此时 Batch Redeliver Webhook Deliveries 会返回 FailedPrecondition (HTTP 400) ,并且不会将任何内容加入队列。API 没有提供表示暂停状态的字段,因此请将该 FailedPrecondition 作为判断依据。
通过 Update App 清除应用的 webhookUrl 则是另一项独立操作。它会取消待投递的事件,即使之后重新设置 URL,这些投递也不会恢复。
恢复
使用 应用 JWT 查询 GET /app/webhook/deliveries。可按投递状态、事件类型、安装、时间范围或页面 token 进行筛选。delivered=false 会返回接收方从未以 2xx 状态码确认的所有投递记录。投递记录可查询七天,因此请在此时间窗口内恢复。
使用 POST /app/webhook/deliveries:batchRedeliver 可将最多 100 个投递 ID 加入重新投递队列。该操作会对 ID 去重,并返回每个投递的结果。已暂停或自动禁用的应用会以 FailedPrecondition (HTTP 400) 拒绝该调用,且不会有任何内容加入队列。
Webhooks 参考
这里列出 源站 投递的所有事件,并逐个字段说明每个事件的负载。有关订阅机制、请求头、签名验证、投递封装、重试计划和自动禁用,请参见 Webhooks。
事件
| 事件 | 触发时机 |
|---|---|
repository.created | 创建代码仓库时。 |
repository.deleted | 删除代码仓库时。 |
repository.pushed | 推送导致一个或多个引用发生更改。 |
repository.metadata.updated | 代码仓库的默认分支发生更改时。 |
pull_request.created | PR 创建时。 |
pull_request.head_ref.pushed | PR 的头部引用推进时。 |
pull_request.base_ref.updated | base 引用或解析后的基础提交发生更改时。 |
pull_request.metadata.updated | 标题或描述发生更改时。 |
pull_request.closed | PR 未合并即关闭时,包括因推送导致其头部与 base 之间没有共同历史而由 源站 关闭的情况。 |
pull_request.merged | PR 合并时。 |
pull_request.reopened | 已关闭的 PR 重新打开时。 |
pull_request.published | 草稿 PR 变为开放状态时。 |
pull_request.label.added | 为 PR 分配标签时。 |
pull_request.label.removed | 取消分配 PR 的标签时,包括标签定义被删除的情况。 |
pull_request.comment.created | 创建可见的 PR 评论时。 |
pull_request.comment.reaction.added | 在 PR 评论中添加回应时。再次添加反应者已有的回应时,会再次投递此事件。 |
pull_request.comment.reaction.removed | 从 PR 评论中移除回应时。移除反应者未添加的回应时,不会投递任何事件。 |
pull_request.review.submitted | 提交任意决定的评审时。 |
pull_request.review.dismissed | 已提交的评审被明确撤销或被后续评审取代时。 |
pull_request.reviewer.added | 请求审阅人时。 |
pull_request.reviewer.removed | 移除审阅人时。 |
pull_request.reviewer.rerequested | 再次请求审阅人时。 |
repository.check_run.created | 创建检查运行时。 |
repository.check_run.completed | 检查运行完成时。 |
repository.check_run.rerequested | 已完成的检查运行被重新请求时。仅投递给拥有该运行的应用。 |
installation.created | 安装应用时。 |
installation.updated | 权限范围、代码仓库选择或所有者 namespace 的 slug 发生更改时。 |
installation.suspended | 安装被暂停时。 |
installation.unsuspended | 已暂停的安装恢复时。 |
installation.deleted | 卸载应用时。 |
每个事件的负载结构都在 事件负载 中逐字段说明。
五个 installation.* 事件会发送给应用本身,而非代码仓库订阅。源站 始终会发送这些事件,因此它们不会出现在应用的可选择事件列表中。本表中的其他所有事件都是代码仓库范围的订阅。
新建的应用默认不订阅任何代码仓库范围的事件。请在应用设置中选择所需事件,或通过 Create App 或 Update App 的 events 字段进行设置。源站 仅会将事件投递给同时满足以下条件的应用:已订阅该事件、已设置 Webhook URL,且其安装覆盖该代码仓库并具备该事件所需的作用域。否则既不会投递,也不会报错:不发送任何内容,列出 Webhook 投递记录 中也不会出现相应记录。
对于从 GitHub 镜像而来的代码仓库,源站 不会投递 repository.pushed。这些推送归 GitHub 所有,并由其发送自己的推送 Webhook,因此 源站 再投递一次会造成重复。对原生 源站 仓库以及出站镜像的推送会照常投递,镜像状态不会影响任何其他事件。对于从 GitHub 镜像而来的代码仓库,repository.deleted 会被投递:停止同步只会删除 Cherri Code 侧的代码仓库,GitHub 不会为此发送任何事件。
事件负载
每个事件的投递封装会在 payload 字段中携带该事件的负载对象。结构相同的事件属于同一负载系列;下面每个系列均列出了使用该负载的事件、其字段以及一个示例负载,这些内容均由 OpenAPI 规范生成。在该规范中,每个负载 schema 的 x-origin-webhook-events 扩展字段列出了使用该负载的事件。
代码仓库已创建
repository.created负载字段
repository 对象
repository.id string
repository.name string 必填
repository.fullName string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。repository.defaultBranch string
repository.createdAt string
repository.updatedAt string
repository.pushedAt string
repository.cloneUrl string
repository.mirror 对象
repository.mirror.source string
github。repository.mirror.sourceId string
repository.mirror.status string
inbound 或 outbound。repository.visibility string
internal 或 private。取值为 internal、private 之一。repository.allowMergeCommit boolean
repository.allowSquashMerge boolean
repository.deleteBranchOnMerge boolean
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "main", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-01T09:30:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" }}代码仓库已删除
repository.deleted负载字段
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。deletedAt string
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "deletedAt": "2026-08-03T08:15:00Z"}代码仓库推送
repository.pushed一次原子推送,可能同时更新多个引用。没有 commits 数组;每个引用更新仅附带尽力提供的 tip 元数据。
负载字段
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。refUpdates 数组
refUpdates[].ref string
refs/heads/main 或 refs/tags/v3.14.1。refUpdates[].before string
ref 上最近一次提交的 SHA。若该引用是刚刚创建的,则为全零 (0000000000000000000000000000000000000000)。refUpdates[].after string
ref 上最新 commit 的 SHA。若该引用已被删除,则为全零 (0000000000000000000000000000000000000000) 。refUpdates[].created boolean
refUpdates[].deleted 布尔值
refUpdates[].forced 布尔值
refUpdates[].headCommit 对象
refUpdates[].headCommit.sha string
refUpdates[].headCommit.author 对象
refUpdates[].headCommit.author.name string
refUpdates[].headCommit.author.email string
refUpdates[].headCommit.author.date string
refUpdates[].headCommit.committer 对象
refUpdates[].headCommit.committer.name string
refUpdates[].headCommit.committer.email string
refUpdates[].headCommit.committer.date string
refUpdates[].headCommit.message string
pushedAt string
pusher 对象
pusher.user object
pusher.user.id string
pusher.user.email string 必填
pusher.user.displayName string
pusher.user.handle string
pusher.user.performedVia 对象
pusher.user.performedVia.app 对象
pusher.user.performedVia.app.id string
pusher.user.performedVia.app.displayName string
pusher.app 对象
pusher.app.id string
pusher.app.displayName string
pusher.serviceAccount 对象
pusher.serviceAccount.id string
refUpdatesCount 整数
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "refUpdates": [ { "ref": "refs/heads/add-telemetry", "before": "5c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d", "after": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "created": false, "deleted": false, "forced": false, "headCommit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry" } } ], "pushedAt": "2026-08-02T14:45:00Z", "pusher": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "refUpdatesCount": 1}代码仓库元数据已更新
repository.metadata.updated包含完整的代码仓库 snapshot,不含 delta,也没有执行更新的 actor。可对比前后两次 snapshot,或重新 fetch 该代码仓库,以查看发生了哪些变更。
负载字段
repository 对象
repository.id string
repository.name string 必填
repository.fullName string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。repository.defaultBranch string
repository.createdAt string
repository.updatedAt string
repository.pushedAt string
repository.cloneUrl string
repository.mirror 对象
repository.mirror.source string
github。repository.mirror.sourceId string
repository.mirror.status string
inbound 或 outbound。repository.visibility string
internal 或 private。取值为 internal、private 之一。repository.allowMergeCommit boolean
repository.allowSquashMerge boolean
repository.deleteBranchOnMerge boolean
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "release", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-03T08:15:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git", "pushedAt": "2026-08-02T14:45:00Z" }}拉取请求事件
pull_request.createdpull_request.publishedpull_request.reopenedpull_request.closedpull_request.mergedpull_request.metadata.updatedpull_request.head_ref.pushedpull_request.base_ref.updatedpull_request.stack_parent.updated一次拉取请求生命周期变更。生命周期操作是信封的 event.type;没有单独的操作字段。
负载字段
pullRequest object
GetPullRequest 读取。pullRequest.id string
pullRequest.number string
pullRequest.state string
pullRequest.draft boolean
pullRequest.merged boolean
pullRequest.title string
pullRequest.body string
pullRequest.head object
pullRequest.head.ref string
pullRequest.head.sha string
base,这是该版本的 base_sha,可能落后于分支当前的最新提交 (参见 PullRequestVersion) 。pullRequest.base object
pullRequest.base.ref string
pullRequest.base.sha string
base,这是该版本的 base_sha,可能落后于分支当前的最新提交 (参见 PullRequestVersion) 。pullRequest.author object
pullRequest.author.user 对象
pullRequest.author.user.id string
pullRequest.author.user.email string 必填
pullRequest.author.user.displayName string
pullRequest.author.user.handle string
pullRequest.author.user.performedVia object
pullRequest.author.user.performedVia.app object
pullRequest.author.user.performedVia.app.id string
pullRequest.author.user.performedVia.app.displayName string
pullRequest.author.app 对象
pullRequest.author.app.id string
pullRequest.author.app.displayName string
pullRequest.author.serviceAccount object
pullRequest.author.serviceAccount.id string
pullRequest.createdAt string
pullRequest.updatedAt string
pullRequest.closedAt string
pullRequest.mergedAt string
pullRequest.mergeCommitSha string
pull/\<number>/merge 引用 (参见 GetGitRef) ,它指向另一个提交。pullRequest.additions 整数
pullRequest.deletions 整数
pullRequest.changedFiles 整数
pullRequest.stack 对象
pullRequest.stack.id string
stack_id 传递给 ListPullRequests,以列出该堆栈的成员。pullRequest.stack.parentPullRequest 对象
pullRequest.stack.parentPullRequest.id string
pullRequest.stack.parentPullRequest.number string
pullRequest.stack.parentPullRequest.repository 对象
pullRequest.stack.parentPullRequest.repository.id string
pullRequest.stack.parentPullRequest.repository.name string
pullRequest.stack.parentPullRequest.repository.owner 对象
pullRequest.stack.parentPullRequest.repository.owner.slug string
pullRequest.stack.parentPullRequest.repository.owner.id string
pullRequest.stack.parentPullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。pullRequest.version object
pullRequest.version.number string
pullRequest.version.headSha string
pullRequest.version.baseSha string
pullRequest.version.createdAt string
pullRequest.version.potentialMergeCommit object
state)。此版本对应的合并提交:其第二个父提交为 head_sha;第一个父提交为测试合并的 base_sha,即准备时基础分支的最新提交,该提交可能比此版本的 base_sha 更新。pull/\<number>/merge 引用仅指向最新版本的提交;较早的提交仍可通过 API (GetCommit) 按 SHA 读取,但无法通过 git 按 SHA 获取。此字段不同于 PullRequest.merge_commit_sha,后者仅在合并后设置。此字段设置在 PullRequest.version 和 PullRequestWebhook.version 上。pullRequest.version.potentialMergeCommit.state string
unknown。无法识别的值必须视为 unknown。取值为 unknown、prepared、merge_conflict 之一。pullRequest.version.potentialMergeCommit.sha string
state 为 prepared 时设置:这是一个有两个父提交的测试合并提交,第二个父提交是该版本的 head_sha,第一个父提交是 base_sha;当此版本为最新版本时,它是 pull/\<number>/merge 指向的提交;此后仍可通过 SHA 读取。pullRequest.version.potentialMergeCommit.baseSha string
state 为 prepared 时设置:记录准备时基准分支的最新提交;可能比该版本的 base_sha 更新;如果只是基准分支向前推进,则不会刷新;重新打开时会重新准备。repository object
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "add-telemetry-schema", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "stack": { "id": "stk_01k2ja2000e0080000000000s1", "parentPullRequest": { "id": "pr_01k2ja2000e0080000000000d3", "number": "16", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } } }, "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } }, "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }}拉取请求标签事件
pull_request.label.addedpull_request.label.removedPR 所分配标签的变更。可通过 ListPullRequestLabels 读取当前标签集合。
负载字段
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner 对象
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。label 对象
label.id string
label.name string
label.color string
# 的六位十六进制颜色值。label.description string
actor object
actor.user 对象
actor.user.id string
actor.user.email string 必填
actor.user.displayName string
actor.user.handle string
actor.user.performedVia 对象
actor.user.performedVia.app 对象
actor.user.performedVia.app.id string
actor.user.performedVia.app.displayName string
actor.app object
actor.app.id string
actor.app.displayName string
actor.serviceAccount 对象
actor.serviceAccount.id string
event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "label": { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" }, "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}拉取请求评论
pull_request.comment.created在拉取请求上创建的评论。随评审一同提交的评论会在评审提交时发送,每条评论对应一个事件。
负载字段
pullRequest object
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team 或 user 之一。comment object
comment.thread.id。线程的解决状态不属于该事件;请使用 GetPullRequestComment 读取。comment.id string
comment.thread 对象
comment.thread.id string
comment.thread.version 对象
PullRequestReview.pull_request_version) 。comment.thread.version.number string
comment.thread.version.headSha string
comment.thread.version.baseSha string
comment.thread.path string
comment.thread.side string
left 或 right。comment.thread.startLine integer
side 版本中锚定范围的起始行。文件级线程和一般讨论线程为 0。comment.thread.endLine 整数
comment.thread.resolvedAt string
comment.thread.createdAt string
comment.thread.updatedAt string
comment.body string
comment.author object
comment.author.user object
comment.author.user.id string
comment.author.user.email string 必填
comment.author.user.displayName string
comment.author.user.handle string
comment.author.user.performedVia object
comment.author.user.performedVia.app object
comment.author.user.performedVia.app.id string
comment.author.user.performedVia.app.displayName string
comment.author.app 对象
comment.author.app.id string
comment.author.app.displayName string
comment.author.serviceAccount 对象
comment.author.serviceAccount.id string
comment.createdAt string
comment.updatedAt string
event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "comment": { "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }}拉取请求评论表情回应事件
pull_request.comment.reaction.addedpull_request.comment.reaction.removed在拉取请求评论上添加或移除表情回应。信封的 event.type 表示该操作。添加操作至少会送达一次:如果回应者在评论上再次添加已有的回应,则会针对相同的 (comment, reactor, content) 再次送达 pull_request.comment.reaction.added;如果移除回应者并未添加的回应,则不会送达任何事件。
负载字段
pullRequest object
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。comment object
comment.id string
comment.thread 对象
comment.thread.id string
reaction 对象
reaction.content string
thumbs_up、thumbs_down、laugh、hooray、confused、heart、rocket、eyes 之一。reaction.reactor 对象
reaction.reactor.user 对象
reaction.reactor.user.id string
reaction.reactor.user.email string 必填
reaction.reactor.user.displayName string
reaction.reactor.user.handle string
reaction.reactor.user.performedVia 对象
reaction.reactor.user.performedVia.app object
reaction.reactor.user.performedVia.app.id string
reaction.reactor.user.performedVia.app.displayName string
reaction.reactor.app 对象
reaction.reactor.app.id string
reaction.reactor.app.displayName string
reaction.reactor.serviceAccount 对象
reaction.reactor.serviceAccount.id string
event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "comment": { "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6" } }, "reaction": { "content": "thumbs_up", "reactor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }}拉取请求评审事件
pull_request.review.submittedpull_request.review.dismissed负载字段
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner 对象
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。review 对象
review.dismissal。review.id string
review.author 对象
review.author.user 对象
review.author.user.id string
review.author.user.email string 必填
review.author.user.displayName string
review.author.user.handle string
review.author.user.performedVia 对象
review.author.user.performedVia.app 对象
review.author.user.performedVia.app.id string
review.author.user.performedVia.app.displayName string
review.author.app 对象
review.author.app.id string
review.author.app.displayName string
review.author.serviceAccount 对象
review.author.serviceAccount.id string
review.verdict string
approve、request_changes、comment 之一。review.body string
review.submittedAt string
review.pullRequestVersion 对象
review.pullRequestVersion.number string
review.pullRequestVersion.headSha string
review.pullRequestVersion.baseSha string
review.dismissal 对象
review.dismissal.dismissedBy 对象
review.dismissal.dismissedBy.user 对象
review.dismissal.dismissedBy.user.id string
review.dismissal.dismissedBy.user.email string 必填
review.dismissal.dismissedBy.user.displayName string
review.dismissal.dismissedBy.user.handle string
review.dismissal.dismissedBy.user.performedVia 对象
review.dismissal.dismissedBy.user.performedVia.app 对象
review.dismissal.dismissedBy.user.performedVia.app.id string
review.dismissal.dismissedBy.user.performedVia.app.displayName string
review.dismissal.dismissedBy.app 对象
review.dismissal.dismissedBy.app.id string
review.dismissal.dismissedBy.app.displayName string
review.dismissal.dismissedBy.serviceAccount 对象
review.dismissal.dismissedBy.serviceAccount.id string
review.dismissal.dismissedAt string
review.dismissal.message string
event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "review": { "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } }}拉取请求审阅人事件
pull_request.reviewer.addedpull_request.reviewer.removedpull_request.reviewer.rerequestedPR 的请求审阅人发生变更。可使用 ListPullRequestRequestedReviewers 读取当前待评审的审阅人集合。
负载字段
pullRequest 对象
pullRequest.id string
pullRequest.number string
pullRequest.repository 对象
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。reviewer 对象
reviewer.user 对象
reviewer.user.id string
reviewer.user.email string 必填
reviewer.user.displayName string
reviewer.user.handle string
reviewer.user.performedVia 对象
reviewer.user.performedVia.app 对象
reviewer.user.performedVia.app.id string
reviewer.user.performedVia.app.displayName string
reviewer.group 对象
grp_…) 。目前仅含 id。reviewer.group.id string
createdVia string
manual、codeowners 之一。createdBy object
createdBy.user object
createdBy.user.id string
createdBy.user.email string 必填
createdBy.user.displayName string
createdBy.user.handle string
createdBy.user.performedVia 对象
createdBy.user.performedVia.app 对象
createdBy.user.performedVia.app.id string
createdBy.user.performedVia.app.displayName string
createdBy.app 对象
createdBy.app.id string
createdBy.app.displayName string
createdBy.serviceAccount 对象
createdBy.serviceAccount.id string
createdAt string
event.payload 示例:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "reviewer": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdVia": "codeowners", "createdAt": "2026-08-02T14:45:00Z"}检查运行事件
repository.check_run.createdrepository.check_run.updatedrepository.check_run.completedOrigin check-run 生命周期事件的已提交快照。
负载字段
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team 或 user。checkSuite 对象
checkSuite.id string
checkSuite.repository 对象
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner 对象
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team 或 user。checkSuite.sha string
checkSuite.key string
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId string
checkSuite.actor 对象
checkSuite.actor.user 对象
checkSuite.actor.user.id string
checkSuite.actor.user.email string 必填
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
checkSuite.actor.user.performedVia 对象
checkSuite.actor.user.performedVia.app 对象
checkSuite.actor.user.performedVia.app.id string
checkSuite.actor.user.performedVia.app.displayName string
checkSuite.actor.app 对象
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount 对象
checkSuite.actor.serviceAccount.id string
checkRun object
checkRun.id string
checkRun.repository 对象
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner 对象
checkRun.repository.owner.slug string
checkRun.repository.owner.id string
checkRun.repository.owner.type string
team 或 user。 仅输出;未知时不设置。取值为 team 或 user。checkRun.checkSuite 对象
checkRun.checkSuite.id string
checkRun.sha string
checkRun.key string
checkRun.name string
checkRun.status string
failing 表示某次运行仍在进行,但所属应用已确定它无法通过:对于门禁和必需检查仍处于待处理状态,尚无 conclusion,可向读取方发出预警。rerequested 表示某次运行已完成,且已请求重新运行,但所属应用尚未响应:对读取方而言处于待处理状态 (呈现方式类似 queued) ,conclusion 和耗时仍描述被取代的那次尝试。仅由 Origin 在重新请求时 (RerequestCheckRun) 设置;应用无法发布此状态。取值为 queued、in_progress、completed、rerequested、failing 之一。checkRun.conclusion string
status 为 completed 或 rerequested 时存在。对于 rerequested 的运行,它表示已被取代的尝试的裁决:应将该运行视为待处理,仅当 status == completed 时读取 conclusion。可能的值为 success、failure、neutral、cancelled、skipped、timed_out、action_required 或 stale。checkRun.detailsUrl string
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
PostCheckRunResponse.outcome) ,则此时间不会更新,因此无法区分这两种情况。RFC 3339 时间戳。checkRun.externalId string
CheckRunInput.external_id:建议每次执行使用一个) 。checkRun.actor object
actor。checkRun.actor.user 对象
checkRun.actor.user.id string
checkRun.actor.user.email string 必填
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
checkRun.actor.user.performedVia 对象
checkRun.actor.user.performedVia.app 对象
checkRun.actor.user.performedVia.app.id string
checkRun.actor.user.performedVia.app.displayName string
checkRun.actor.app 对象
checkRun.actor.app.id string
checkRun.actor.app.displayName string
checkRun.actor.serviceAccount 对象
checkRun.actor.serviceAccount.id string
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
timed_out 的情况 (参见 CheckRunInput.deadline_at) 。RFC 3339 时间戳。checkRun.isRerequestable boolean
CheckRunInput.is_rerequestable)。checkRun.rerequestedAt string
status 为 rerequested,该运行在此提交的 CI 状态中仍为 pending (conclusion 和时间信息沿用已被取代的结果) ;所属应用会发布其通过声明 is_rerequestable 所承诺的运行来作出响应——可以是具有相同 key 的新运行,也可以是对此运行的更新 (这会清除此字段) ——之后便可再次请求该运行。RFC 3339 时间戳。checkRun.rerequestedBy 对象
rerequested_at 时存在;所属应用响应时会与其一并清除。checkRun.rerequestedBy.user 对象
checkRun.rerequestedBy.user.id string
checkRun.rerequestedBy.user.email 字符串 必填
checkRun.rerequestedBy.user.displayName string
checkRun.rerequestedBy.user.handle string
checkRun.rerequestedBy.user.performedVia 对象
checkRun.rerequestedBy.user.performedVia.app 对象
checkRun.rerequestedBy.user.performedVia.app.id string
checkRun.rerequestedBy.user.performedVia.app.displayName string
checkRun.rerequestedBy.app 对象
checkRun.rerequestedBy.app.id string
checkRun.rerequestedBy.app.displayName string
checkRun.rerequestedBy.serviceAccount 对象
checkRun.rerequestedBy.serviceAccount.id string
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }}已请求重新运行检查
repository.check_run.rerequestedrepository.check_run.rerequested webhook 负载,仅投递给拥有该 check run 的应用。要响应此请求,请针对相同的 head SHA 和 key 提交一个新的 run——可以是全新的 run (新的 external_id) ,也可以更新被重新请求的 run。在响应请求的提交清除 rerequested_at 之前,该 run 会显示 status: rerequested (其 conclusion 和时间信息仍是已被取代的结果) 。每次被接受的重新请求都会产生一个事件;run 在得到响应后可以再次被请求,因此只需根据事件 id 对重复投递去重;check_run.rerequested_at 记录尚未处理的请求标记。负载不包含拉取请求上下文 (check runs 关联到 (repository, sha)) :需要拉取请求信息的消费者可通过自身的 head 映射,根据 check_run.sha 查找对应的拉取请求,或使用 ListPullRequests 并筛选出其构建所针对的 head 分支。
负载字段
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。checkSuite 对象
checkSuite.id string
checkSuite.repository 对象
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner 对象
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。checkSuite.sha string
checkSuite.key string
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId string
checkSuite.actor 对象
checkSuite.actor.user 对象
checkSuite.actor.user.id string
checkSuite.actor.user.email string 必填
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
checkSuite.actor.user.performedVia 对象
checkSuite.actor.user.performedVia.app 对象
checkSuite.actor.user.performedVia.app.id string
checkSuite.actor.user.performedVia.app.displayName string
checkSuite.actor.app 对象
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount 对象
checkSuite.actor.serviceAccount.id string
checkRun object
status: rerequested) ;check_run.rerequested_at 记录时间戳,check_run.rerequested_by 记录发起请求的主体。checkRun.id string
checkRun.repository 对象
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner 对象
checkRun.repository.owner.slug string
checkRun.repository.owner.id string
checkRun.repository.owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。checkRun.checkSuite 对象
checkRun.checkSuite.id string
checkRun.sha string
checkRun.key string
checkRun.name string
checkRun.status string
failing 表示运行仍在进行中,但所属应用已确定它无法通过:对于关卡和必需检查仍处于待处理状态,尚无 conclusion,可向读取方提前发出警告。rerequested 表示某次已完成的运行已被请求重新运行,但所属应用尚未响应:对读取方而言处于待处理状态 (渲染方式与 queued 相同) ,且 conclusion 和各项时间仍描述已被取代的那次尝试。仅在重新请求时由 Origin 设置 (RerequestCheckRun) ;应用无法设置此状态。取值为 queued、in_progress、completed、rerequested、failing 之一。checkRun.conclusion string
status 为 completed 或 rerequested 时存在。对于 rerequested 的运行,它表示被取代尝试的判定:应将该运行视为待处理,仅在 status == completed 时读取 conclusion。取值为 success、failure、neutral、cancelled、skipped、timed_out、action_required、stale 之一。checkRun.detailsUrl string
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
PostCheckRunResponse.outcome) ,因此无法区分这两种情况。RFC 3339 时间戳。checkRun.externalId string
CheckRunInput.external_id:建议每次执行使用一个) 。checkRun.actor object
actor。checkRun.actor.user 对象
checkRun.actor.user.id string
checkRun.actor.user.email 字符串 必填
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
checkRun.actor.user.performedVia 对象
checkRun.actor.user.performedVia.app 对象
checkRun.actor.user.performedVia.app.id string
checkRun.actor.user.performedVia.app.displayName string
checkRun.actor.app 对象
checkRun.actor.app.id string
checkRun.actor.app.displayName string
checkRun.actor.serviceAccount 对象
checkRun.actor.serviceAccount.id string
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
timed_out 而过期的情况 (参见 CheckRunInput.deadline_at) 。RFC 3339 时间戳。checkRun.isRerequestable boolean
CheckRunInput.is_rerequestable)。checkRun.rerequestedAt string
status 为 rerequested,该运行在提交的 CI 状态中仍为 pending (conclusion 和计时信息沿用被取代的结果) ;所属应用通过发布其承诺提交的运行并声明 is_rerequestable 来响应——可以是具有相同 key 的新运行,也可以是对该运行的更新 (这会清除此字段) 。此后,该运行可以再次被重新请求。RFC 3339 时间戳。checkRun.rerequestedBy 对象
rerequested_at 已设置时存在;在所属应用响应时会与其一并被清除。checkRun.rerequestedBy.user 对象
checkRun.rerequestedBy.user.id string
checkRun.rerequestedBy.user.email string 必填
checkRun.rerequestedBy.user.displayName string
checkRun.rerequestedBy.user.handle string
checkRun.rerequestedBy.user.performedVia 对象
checkRun.rerequestedBy.user.performedVia.app 对象
checkRun.rerequestedBy.user.performedVia.app.id string
checkRun.rerequestedBy.user.performedVia.app.displayName string
checkRun.rerequestedBy.app 对象
checkRun.rerequestedBy.app.id string
checkRun.rerequestedBy.app.displayName string
checkRun.rerequestedBy.serviceAccount 对象
checkRun.rerequestedBy.serviceAccount.id string
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:10:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "rerequested", "conclusion": "failure", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:10:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "1 of 129 tests failed.", "text": "FAIL telemetry.spec.ts > flushes queued events on shutdown" }, "isRerequestable": true, "rerequestedAt": "2026-08-02T15:10:00Z", "rerequestedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }}安装已创建
installation.created负载字段
installation 对象
installation.id string
installation.appId string
app.id 取值相同。installation.target 对象
installation.target.slug string
installation.target.id string
installation.target.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.repoSelectionMode string
all 或 selected。installation.repositories 数组
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner 对象
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.scopes 数组
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy 对象
installation.installedBy.id string
installation.installedBy.email string 必填
installation.installedBy.displayName string
installation.installedBy.handle string
installation.installedBy.performedVia 对象
installation.installedBy.performedVia.app 对象
installation.installedBy.performedVia.app.id string
installation.installedBy.performedVia.app.displayName string
app object
app.id string
app.displayName string
event.payload 示例:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}安装已更新
installation.updated负载字段
installation 对象
installation.id string
installation.appId string
app.id 取值相同。installation.target 对象
installation.target.slug string
installation.target.id string
installation.target.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.repoSelectionMode string
all 或 selected。installation.repositories 数组
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner 对象
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.scopes 数组
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string 必填
installation.installedBy.displayName string
installation.installedBy.handle string
installation.installedBy.performedVia 对象
installation.installedBy.performedVia.app object
installation.installedBy.performedVia.app.id string
installation.installedBy.performedVia.app.displayName string
app object
app.id string
app.displayName string
event.payload 示例:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}安装已暂停
installation.suspended负载字段
installation 对象
installation.id string
installation.appId string
app.id 取值相同。installation.target 对象
installation.target.slug string
installation.target.id string
installation.target.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.repoSelectionMode string
all 或 selected。installation.repositories 数组
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner 对象
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.scopes 数组
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string 必填
installation.installedBy.displayName string
installation.installedBy.handle string
installation.installedBy.performedVia 对象
installation.installedBy.performedVia.app object
installation.installedBy.performedVia.app.id string
installation.installedBy.performedVia.app.displayName string
app object
app.id string
app.displayName string
event.payload 示例:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "suspendedAt": "2026-08-03T08:15:00Z" }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}安装已恢复
installation.unsuspended负载字段
installation 对象
installation.id string
installation.appId string
app.id 取值相同。installation.target 对象
installation.target.slug string
installation.target.id string
installation.target.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.repoSelectionMode string
all 或 selected。installation.repositories 数组
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner 对象
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.scopes 数组
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string 必填
installation.installedBy.displayName string
installation.installedBy.handle string
installation.installedBy.performedVia object
installation.installedBy.performedVia.app object
installation.installedBy.performedVia.app.id string
installation.installedBy.performedVia.app.displayName string
app object
app.id string
app.displayName string
event.payload 示例:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}安装已删除
installation.deleted负载字段
installation 对象
installation.id string
installation.appId string
app.id 取值相同。installation.target 对象
installation.target.slug string
installation.target.id string
installation.target.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.repoSelectionMode string
all 或 selected。installation.repositories 数组
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner 对象
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type string
team 或 user。仅输出;未知时不设置。取值为 team、user 之一。installation.scopes 数组
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy 对象
installation.installedBy.id string
installation.installedBy.email string 必填
installation.installedBy.displayName string
installation.installedBy.handle string
installation.installedBy.performedVia 对象
installation.installedBy.performedVia.app 对象
installation.installedBy.performedVia.app.id string
installation.installedBy.performedVia.app.displayName string
app object
app.id string
app.displayName string
event.payload 示例:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "deletedAt": "2026-08-03T08:15:00Z" }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}检查运行注释
repository.check_run.annotations.created一次 CreateCheckRunAnnotations 请求向检查运行追加了注释 (repository.check_run.annotations.created) 。注释只能追加,不能单独编辑或删除,因此 .created 就是注释的整个生命周期;一次请求对应一个事件。check_run 是引用,不是快照:如需获取该检查运行的状态、结论和输出,请调用 GetCheckRun。annotations 按请求顺序排列;如果 Origin 为确保请求体能够正常投递而限制了列表长度,其条目数可能少于 annotations_count。可通过 ListCheckRunAnnotations 分页获取其余注释。与其他检查运行 Webhook 一样,负载不包含拉取请求上下文:可根据 sha 查找对应的拉取请求。
负载字段
repository 对象
repository.id string
repository.name string
repository.owner 对象
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team 或 user。 仅输出;未知时不设置。取值为 team 或 user。checkRun object
checkRun.id string
checkRun.name string
checkRun.checkSuite 对象
checkRun.checkSuite.id string
sha string
annotations array
annotations[].id string
annotations[].checkRunId string
annotations[].annotationLevel string
notice、warning、failure 之一。annotations[].message string
annotations[].title string
annotations[].rawDetails string
annotations[].createdAt string
annotations[].updatedAt string
annotations[].location 对象
path、start_line 和 end_line。path 为规范化路径,且相对于代码仓库根目录;行号和列号均为从 1 开始计数的正整数,且首尾均包含在内;columns 仅适用于单行范围。annotations[].location.path string 必填
annotations[].location.startLine integer 必填
annotations[].location.endLine 整数 必填
annotations[].location.columns 对象
annotations[].location.columns.startColumn integer
annotations[].location.columns.endColumn integer
annotationsCount integer
createdAt string
event.payload 示例:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "name": "unit-tests", "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "annotations": [ { "id": "cra_01k2ja2000e0080000000000v1", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42, "columns": { "startColumn": 5, "endColumn": 31 } } }, { "id": "cra_01k2ja2000e0080000000000v2", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "failure", "message": "Three tests failed in telemetry.test.ts.", "title": "Test failures", "rawDetails": "FAIL telemetry.test.ts flushes on shutdown (expected 1 call, received 0)", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z" } ], "annotationsCount": 2, "createdAt": "2026-08-02T14:45:00Z"}