API / create-origin-pull-request-comment-via-api

API

Create an Origin Pull Request Comment via the API

Post a comment on a pull request with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/comments. Official reference: Origin API → Create Pull Request Comment (OpenAPI OriginService_CreatePullRequestComment). Changelog notes: September 9, 2026 (inline range past end of file → InvalidArgument), September 2, 2026 (file anchor for whole-file threads), August 29, 2026 (inline + versionNumber), August 24, 2026 (body length cap).

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:write. Availability: Early Beta per the API overview.

The comment targets exactly one of: an existing thread (threadId — a reply on general-discussion and inline threads alike), a new inline thread on the version's diff (inline), a new file-level thread (file), or, with none of those, a new general-discussion thread. file, inline, and threadId are mutually exclusive. Pull request number is a JSON string (protobuf 64-bit encoding).

Cost: 5 points against the principal budget (ordinary write).

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)

Request body

Field Required Meaning
body yes Comment text; max 65,536 Unicode code points
threadId no Existing thread id to reply to. Cannot be combined with versionNumber
inline no Diff anchor for a new inline thread (path, side, startLine, optional endLine)
file no Anchor for a new file-level thread (path only; side derived from change kind)
versionNumber no Pull request version to file a new thread against. 0 or unset = latest at call time. Only for new threads; rejected with threadId

Inline anchor (inline)

Field Required Meaning
path yes File path in the pull request version's diff
side yes left (base) or right (head)
startLine yes First 1-based line on that side
endLine no Inclusive last line; omit for a single-line anchor; must be ≥ startLine

The path must be part of that version's diff on a side the file has content on — left on an added file or right on a deleted file returns InvalidArgument (HTTP 400). Any line of a changed file can anchor (including outside hunks), but the range must fit the file on the anchored side (left at base, right at head). A range past the last line returns InvalidArgument (HTTP 400). Invalid anchors never fall back to a general-discussion comment.

File anchor (file)

Field Required Meaning
path yes Deleted path for a deletion; head path otherwise. Pre-rename source path on a rename is rejected

Origin sets thread.side from the change kind (base for deletions, head otherwise). A path outside the diff returns InvalidArgument (HTTP 400).

A body longer than 65,536 code points returns InvalidArgument (HTTP 400). A missing or unreachable pull returns 404. A 404 never distinguishes a missing pull from one your installation cannot reach.

curl --request POST \
  --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments' \
  --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "body": "Should the retry budget be configurable?"
}'

Inline thread on a line range:

curl --request POST \
  --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments' \
  --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "body": "Should the retry budget be configurable?",
  "inline": {
    "path": "src/telemetry/retry.ts",
    "side": "right",
    "startLine": 42,
    "endLine": 45
  },
  "versionNumber": "3"
}'

File-level thread:

curl --request POST \
  --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments' \
  --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "body": "This module needs a design doc link.",
  "file": {
    "path": "src/telemetry/retry.ts"
  },
  "versionNumber": "3"
}'

Reply to an existing thread:

curl --request POST \
  --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/17/comments' \
  --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "body": "Agreed — make it configurable.",
  "threadId": "cth_01k2ja2000e0080000000000s6"
}'

Response

200 returns a PullRequestComment: id, nested thread, body, author, createdAt, updatedAt. A reply may carry the thread id alone; a new general-discussion thread carries id and timestamps; a new inline thread carries the full anchor. Read Get or List Pull Request Comments for complete thread state including resolvedAt.

{
  "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"
}

Resolve or reopen the thread with Update Pull Request Thread. Base URL: https://api.cursor.com/v1/origin.