
Stack Origin Pull Requests via the API
Associate a pull request with a stack parent using parentPullRequest on Create and Update Pull Request, read the stack object on pull responses, and list a stack with stackId on List Pull Requests. Official reference: Origin API → Create / Update / List Pull Requests. Changelog: September 22, 2026.
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:write for create/update and repository:pull_requests:read for list. Availability: Early Beta per the API overview.
Breaking (2026-09-22): Create Pull Request no longer accepts parentPullNumber. A request that still sends it returns InvalidArgument (HTTP 400) naming parent_pull_number. Send parentPullRequest with a number member instead.
The edit is an association only: no branch is rewritten. base is retargeted only when you send base too. On Update, parentPullRequest applies after base, so an explicit parent wins over the one a base change would derive.
Cost: 5 points for create/update; 1 point for list.
Create with a stack parent
POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/pulls
| Field | Required | Meaning |
|---|---|---|
parentPullRequest |
no | Selector naming the stack parent. Exactly one of number or id. Do not send clear on create. |
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": "Follow-up telemetry polish",
"head": "telemetry-polish",
"base": "main",
"parentPullRequest": {
"number": "17"
}
}'
An empty selector, more than one member, or clear on create returns InvalidArgument (HTTP 400). Pull request number values are JSON strings.
Update or clear the parent
PATCH https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}
curl --request PATCH \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/18' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"parentPullRequest": {
"clear": true
}
}'
clear: false, an empty selector, or more than one member returns InvalidArgument (HTTP 400).
Read stack on responses
List, Get, Create, Update, and Merge Pull Request responses (and every pull_request.* webhook payload) carry a stack object with the stack's id and the parentPullRequest this change is stacked on. stack is absent when the pull request is not part of a stack. The root of a stack carries no parentPullRequest. A delivered stack reflects topology as of that event.
List one stack
GET https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/pulls?stackId=STACK_ID
Pass the stack id from stack.id. Members come back in the requested sort order, not stack order — rebuild the stack from each member's stack.parentPullRequest. state still defaults to open, so pass state=all for the whole stack. A well-formed id that names no stack in the repository returns an empty list. Any other value returns InvalidArgument (HTTP 400).
curl --request GET \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls?stackId=STACK_ID&state=all' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'
Related
- Create without stacking: Create an Origin Pull Request via the API (replace any leftover
parentPullNumberwithparentPullRequest). - List filters including
headSha: Filter Origin Pull Requests by Head SHA via the API.
Pitfalls
- Keep sending
parentPullNumberand Create fails loudly with 400 — migrate toparentPullRequest.number. - Listing a stack without
state=allhides closed and merged members.