---
title: "GET /v1/origin/search/pulls"
method: GET
path: "/v1/origin/search/pulls"
tags: ["OriginService"]
---

# GET /v1/origin/search/pulls

`GET /v1/origin/search/pulls`

## Request

- Base URL: `https://api.cursor.com`
- URL: `https://api.cursor.com/v1/origin/search/pulls`
- Auth: HTTP bearer

Searches pull requests with a pull request search query, in one
 namespace (an org or a user): across the repositories the query names
 with `repo:`, `org:` or `user:`, or across `repo` when it names none.
 Returns the same `PullRequest` items as `ListPullRequests`, most relevant
 first unless `sort`, or the query's `sort:`, orders them.

 A query whose `repo:`, `org:` and `user:` name more than one namespace,
 or one that names none when `repo` is not set, is rejected with
 INVALID_ARGUMENT and a field violation on `q`; add `org:NAME` to search
 one namespace.

 Search matches review state as well as pull request fields, so every
 caller needs both `repository:pull_requests:read` and
 `repository:pull_requests:reviews:read`, and search covers only
 repositories that grant the caller both. That check runs before the
 search, so neither results nor `total_count` reflect any other
 repository. A repository named with `repo:` that does not grant both is
 skipped. App installation tokens are rejected with PERMISSION_DENIED.

 Searching with `org:` or `user:` needs a user credential that is not
 limited to specific repositories, or a service account: a managed
 account searches its owner's namespace, and a custom account the
 repositories in its owner's namespace that its API key is scoped to. A
 session token limited to specific repositories and a custom account
 whose key has no repository scope are rejected with PERMISSION_DENIED.

 A mirrored repository whose pull requests live on its upstream source is
 searched only when `repo:` or `repo` names it, and only when that source
 is not a self-hosted enterprise server; mirrors of one are skipped. The
 caller needs the same access as for any other repository. Its pull
 requests come from the search index and carry fewer fields; see
 `PullRequest`. A search of such a repository accepts fewer qualifiers and
 sorts; see `q`.

 A page holds at most `page_size` results and can hold fewer while
 `next_page_token` is set. Each request also counts against the caller's
 pull request search rate limit, which is separate from the public API
 quota: a user's searches share one budget across every credential, and
 each service account has its own, keyed by its `sa_` id.

 A query that does not parse, or asks for something search cannot answer,
 is rejected with INVALID_ARGUMENT naming its problems; see `q`.
 FAILED_PRECONDITION means one of four things, each named in the error
 message: search is not enabled for the caller; the caller can read too
 many repositories in the named org or user to search at once, so the
 query needs `repo:` in place of `org:` and `user:` (`repo:` alone for a
 service account whose API key names too many repositories); the caller
 belongs to too many teams to search `review-requested:@me`,
 `team-review-requested-user:@me` or `review-involves:@me`; or the search
 names more than 10 mirrored repositories whose pull requests live on
 their upstream source.

 UNAVAILABLE means search cannot answer now, including when the upstream
 source of a named mirrored repository cannot say which of its
 repositories that mirror holds. Retry the request.

## Query parameters

- `q` string
- `repo` string
- `pageSize` integer
- `pageToken` string
- `sort` string
- `order` string

## Response `200`

OK

- SearchPullRequestsResponse
  - `pullRequests` PullRequest[]
    - `id` string: Stable Origin pull request identifier. Empty on a `SearchPullRequests` result from a mirrored repository whose pull requests live on its upstream source.
    - `number` string: Pull request number within its repository.
    - `state` string: "open" or "closed". A draft is "open"; merged and closed pull requests are both "closed".
    - `draft` boolean: Whether the pull request is still a draft.
    - `merged` boolean: Whether the pull request has been merged.
    - `title` string: Pull request title.
    - `body` string: Pull request description. Empty on a `SearchPullRequests` result from a mirrored repository whose pull requests live on its upstream source.
    - `head` PullRequestRef: One side (head or base) of a change.
      - `ref` string: The ref this side points at, as Origin records it.
      - `sha` string: Tip commit SHA of this side at the change's latest version. For `base` this is the version's `base_sha`, which can lag the branch's current tip (see `PullRequestVersion`).
    - `base` PullRequestRef: One side (head or base) of a change.
      - `ref` string: The ref this side points at, as Origin records it.
      - `sha` string: Tip commit SHA of this side at the change's latest version. For `base` this is the version's `base_sha`, which can lag the branch's current tip (see `PullRequestVersion`).
    - `author` OriginActor: A user, app, or service account that performed an externally visible action. Absent when the user or service account no longer exists. May carry only `id`, as for an app that no longer exists.
      - `user` OriginUserActor
        - `id` string
        - `email` string, required: The account's email. On pull request, review, comment, check, requested reviewer, and mergeability responses it is empty unless the caller holds `repository:members:read` on the repository.
        - `displayName` string: Human-readable display name: the account's first and last name, each trimmed, joined with a space — exactly the name the product UI renders. Omitted when the account has no name; never synthesized from the email, the id, or any other field.
        - `handle` string: The user's claimed profile handle (the identity behind cursor.com /@handle), without the @ prefix. Present only while the user's profile is publicly visible; omitted for users without a claimed handle and for non-public profiles.
        - `performedVia` OriginUserActorPerformedViaActor: Identifies an actor that acted on behalf of the user.
          - `app` OriginAppActor
            - `id` string
            - `displayName` string: The app's registered display name, never empty when present. Omitted when the app cannot be resolved.
          - `serviceAccount` OriginServiceAccountActor
            - `id` string
            - `type` 'bugbot' | 'automations' | 'agent_serve' | 'agent' | 'grok_bot' | 'env_builds': Which product or feature the account acts for. Unset when this API does not categorize the account or it no longer exists. New values may be added: decode with unknown enum values ignored, and treat an unset or unrecognized type as an unknown product, never as an error.
            - `displayName` string: The product name Cursor shows for the account, such as a Grok bot's name; never empty when present. A Grok bot whose name cannot be read is named "Grok Bot". Omitted when the account has no product name.
      - `app` OriginAppActor
        - `id` string
        - `displayName` string: The app's registered display name, never empty when present. Omitted when the app cannot be resolved.
      - `serviceAccount` OriginServiceAccountActor
        - `id` string
        - `type` 'bugbot' | 'automations' | 'agent_serve' | 'agent' | 'grok_bot' | 'env_builds': Which product or feature the account acts for. Unset when this API does not categorize the account or it no longer exists. New values may be added: decode with unknown enum values ignored, and treat an unset or unrecognized type as an unknown product, never as an error.
        - `displayName` string: The product name Cursor shows for the account, such as a Grok bot's name; never empty when present. A Grok bot whose name cannot be read is named "Grok Bot". Omitted when the account has no product name.
    - `createdAt` string, date-time: When the pull request was opened.
    - `updatedAt` string, date-time: When the pull request was last updated.
    - `closedAt` string, date-time: When the pull request was closed or merged; unset while open.
    - `mergedAt` string, date-time: When the pull request was merged; unset unless merged.
    - `mergeCommitSha` string: SHA of the commit the merge wrote to the base branch; set once merged, unset before. The pre-merge preview is the `pull/<number>/merge` ref (see GetGitRef), a different commit.
    - `additions` integer: Lines added by the pull request's latest version.
    - `deletions` integer: Lines deleted by the pull request's latest version.
    - `changedFiles` integer: Files changed by the pull request's latest version.
    - `labels` Label[]: Labels currently assigned to this pull request, sorted by name. Empty when none are assigned. A pull request can have at most 100 labels.
      - `id` string
      - `name` string
      - `color` string: Six-character hex color without a leading `#`.
      - `description` string
    - `stack` PullRequestStackMembership: Membership of a pull request in a stack: a chain of dependent pull requests in one repository, each stacked on the one it builds upon.
      - `id` string: Stable stack identifier. Pass it as `stack_id` to `ListPullRequests` to list the stack's members.
      - `parentPullRequest` PullRequestReference: Stable identity and display coordinates for an Origin pull request.
        - `id` string: Immutable Origin change id.
        - `number` string
        - `repository` RepositoryReference: Stable identity and display coordinates for a repository.
          - `id` string
          - `name` string
          - `owner` Owner: The owner of a repo.
            - `slug` string: Unique URL-friendly name of the owner.
            - `id` string: Unique ID of the owner namespace.
            - `type` 'team' | 'user': `team` or `user`. Output-only; unset when unknown.
    - `webUrl` string: Web URL for this pull request on Cursor.
    - `autoMerge` PullRequestAutoMerge: Auto-merge ("merge when ready") armed on a pull request: Origin lands the pull request on the enabler's behalf once it is mergeable, and for a stacked pull request only once it is the lowest open member of its stack.
      - `enabledBy` OriginActor: A user, app, or service account that performed an externally visible action. Absent when the user or service account no longer exists. May carry only `id`, as for an app that no longer exists.
        - `user` OriginUserActor
          - `id` string
          - `email` string, required: The account's email. On pull request, review, comment, check, requested reviewer, and mergeability responses it is empty unless the caller holds `repository:members:read` on the repository.
          - `displayName` string: Human-readable display name: the account's first and last name, each trimmed, joined with a space — exactly the name the product UI renders. Omitted when the account has no name; never synthesized from the email, the id, or any other field.
          - `handle` string: The user's claimed profile handle (the identity behind cursor.com /@handle), without the @ prefix. Present only while the user's profile is publicly visible; omitted for users without a claimed handle and for non-public profiles.
          - `performedVia` OriginUserActorPerformedViaActor: Identifies an actor that acted on behalf of the user.
            - `app` OriginAppActor
              - …
            - `serviceAccount` OriginServiceAccountActor
              - …
        - `app` OriginAppActor
          - `id` string
          - `displayName` string: The app's registered display name, never empty when present. Omitted when the app cannot be resolved.
        - `serviceAccount` OriginServiceAccountActor
          - `id` string
          - `type` 'bugbot' | 'automations' | 'agent_serve' | 'agent' | 'grok_bot' | 'env_builds': Which product or feature the account acts for. Unset when this API does not categorize the account or it no longer exists. New values may be added: decode with unknown enum values ignored, and treat an unset or unrecognized type as an unknown product, never as an error.
          - `displayName` string: The product name Cursor shows for the account, such as a Grok bot's name; never empty when present. A Grok bot whose name cannot be read is named "Grok Bot". Omitted when the account has no product name.
      - `enabledAt` string, date-time: When auto-merge was enabled.
      - `mergeMethod` 'merge' | 'squash': The merge method Origin lands with, as far as auto-merge decides it: the one chosen when auto-merge was enabled, otherwise the repository's default method (a merge commit when allowed, otherwise squash). Branch rules still apply when it lands: a base branch that requires linear history lands the repository default as a squash instead. Omitted only when the repository allows no merge method.
      - `commitTitle` string: Commit title chosen when auto-merge was enabled. Omitted when none was given: Origin then composes the merge commit message when it lands. It applies only when the pull request lands on its own; a stack prefix landing as one commit keeps the composed message.
      - `commitMessage` string: Commit message body chosen when auto-merge was enabled, under the same rules as the commit title.
    - `version` PullRequestVersion: A numbered revision of a change. A new version is recorded when the pull request's head is pushed or when it is retargeted to another base, each with its own head/base SHAs and diff stats. The base branch advancing on its own records nothing.
      - `number` string: Monotonic version number within the change (1-based).
      - `headSha` string: Head commit SHA for this version.
      - `baseSha` string: Base commit SHA this version is diffed against: the base branch tip as resolved when the version was recorded. It can lag the branch's current tip until the next head push or retarget.
      - `createdAt` string, date-time: When this version was created.
      - `potentialMergeCommit` PotentialMergeCommit: Origin's test merge of a pull request version and how far its preparation got: `state` says which. `base_sha` is the base branch tip the merge was attempted against, set whenever the state was computed; `sha` is the two-parent test-merge commit, set only when `state` is `prepared`, so it is absent for `unknown` and `merge_conflict`. On a `pull_request.*` event, `unknown` means the preparation had not settled when the event was sent, or failed. A later `GetPullRequest` can return another state, and no event is sent when it does. To get the test merge on demand, call `PreparePullRequestMergeRef` (`POST .../pulls/{pullNumber}/merge_ref`). For stacked pull requests the base branch is the parent's branch, so this covers only this pull request's changes on top of it. A fact about the version it is on (`PullRequestVersion.potential_merge_commit`), so it stays readable after the pull request is merged.
        - `state` 'unknown' | 'prepared' | 'merge_conflict': How far the preparation of this version got; a new version starts as `unknown` until its own preparation lands. Unrecognized values must be treated as `unknown`.
        - `sha` string: Set only when `state` is `prepared`: the two-parent test-merge commit, second parent the version's `head_sha`, first parent `base_sha`; the tip of `pull/<number>/merge` while this version is the latest; readable by SHA afterwards.
        - `baseSha` string: Set whenever the state was computed (`prepared` or `merge_conflict`): the base branch tip the merge was attempted against at preparation time; can be newer than the version's `base_sha`, not refreshed when the base merely advances; re-prepared on reopen. May be absent on a `merge_conflict` recorded before this field carried it.
  - `totalCount` integer: The number of pull requests matching the query in the searched repositories, exact up to 10,000. Only repositories where the caller can read both pull requests and their reviews are searched, so it counts nothing the caller cannot read. It counts the pull requests of a mirrored repository whose pull requests live on its upstream source only when `repo:` or `repo` names it.
  - `totalCountIsLowerBound` boolean: Set when more than `total_count` pull requests match.
  - `nextPageToken` string: Opaque cursor for the next page; empty when there are no more pages.

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `429`: Too Many Requests
- `default`: Default error response

---

[API](https://skmtc.dev/cursor/apis/cursor-origin-api.md) - [All operations](https://skmtc.dev/cursor/apis/cursor-origin-api/llms.txt) - [OpenAPI document](https://skmtc.dev/cursor/apis/cursor-origin-api/revisions/cbc1547d6ef7?raw)
