
List Origin Pull Request Comments via the API
List every comment on a pull request in chronological order with GET https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/comments. Official reference: Origin API → List Pull Request Comments (OpenAPI OriginService_ListPullRequestComments). Changelog notes: September 4, 2026 (threadIds filter), September 3, 2026 (since / until), August 29, 2026 (full thread object on each comment), September 16, 2026 (OpenAPI schema renamed Thread → CommentThread; wire JSON unchanged).
Origin is in Early Beta and subject to change. Authenticate with an installation access token (oit_…) or a user access token that carries repository:pull_requests:reviews:read. Availability: Early Beta per the API overview.
Each comment includes its thread — id, filed-against version, diff anchor (path, side, startLine, endLine), resolvedAt, and thread timestamps — so you can group the flat list into threads by thread.id. Pull request number is a JSON string (protobuf 64-bit encoding).
Cost: 1 point against the principal budget (ordinary read).
Path parameters
| Param | Required | Meaning |
|---|---|---|
ownerSlug |
yes | Owning entity's unique slug |
repoName |
yes | Repo name, unique to the owner |
pullNumber |
yes | Pull request number within the repository (string on the wire) |
Query parameters
| Param | Required | Meaning |
|---|---|---|
pageSize |
no | Max comments to return. Defaults to 30; maximum 100 |
pageToken |
no | Opaque cursor from a previous response's nextPageToken. Empty for the first page |
since |
no | Inclusive RFC 3339 lower bound on comment creation time (e.g. 2026-08-01T00:00:00Z). Malformed timestamps return InvalidArgument (HTTP 400). Page tokens embed the bound — restart pagination when it changes |
until |
no | Inclusive RFC 3339 upper bound on comment creation time. Same validation and page-token rules as since |
threadIds |
no | Restrict to comments in these threads. Empty or omitted returns every comment. Duplicates ignored; at most 20 distinct ids. An empty id or more than 20 returns InvalidArgument (HTTP 400). Page tokens embed the id set — restart pagination when the filter changes |
A missing or unreachable pull returns 404. A 404 never distinguishes a missing pull from one your installation cannot reach.
curl --request GET \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments?pageSize=30' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'
Track new comments since a watermark:
curl --request GET \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments?since=2026-08-01T00:00:00Z' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'
Response
200 returns comments (chronological), a pullRequest reference, and nextPageToken (empty when there is no next page).
{
"comments": [
{
"id": "cmt_01k2ja2000e0080000000000e5",
"thread": {
"id": "cth_01k2ja2000e0080000000000s6",
"version": {
"number": "3",
"headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
"baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8",
"createdAt": "2026-08-01T09:30:00Z"
},
"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": "jane@acme.dev"
}
},
"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"
}
}
},
"nextPageToken": ""
}
Group by thread.id. thread.path is empty on general-discussion threads; resolvedAt is unset while the thread is open. Create, get, and update comments, and resolve or reopen a thread, are separate write/read operations under the reviews scopes.
Base URL: https://api.cursor.com/v1/origin.