The caller's open review requests or open pull requests, across every workspace
GET/api/user/pulls
getUserPulls
Account-scoped (every workspace). `filter` is `review_requested` (default; newest request first) or `authored` (most recently updated first). At most 100 rows; `truncated` says more exist. Every row is one the caller can read — the same decision the PR page makes, asked per repo — so a revoked grant or a repo gone private drops its rows.
Authentication is not described for this operation in the spec — that does not mean it is public. Check tokens and scopes.
curl
curl -X GET 'https://neosource.dev/api/user/pulls'fetch
fetch("https://neosource.dev/api/user/pulls", {
method: "GET",
});Query parameters
filter`review_requested` (open PRs the caller is a requested reviewer on) or `authored` (the caller's own open PRs). **Omitted means `review_requested`**, the page's first section.
Responses
200The caller's pull requests
application/json
403Forbidden — one of: forbidden, needs_scope
application/json
Standard errors
Bodies documented once for the whole API — see standard errors.
- 400Bad Request — one of: invalid_input
- 429Rate limited — retry after the `Retry-After` header
- 500Internal server error
- 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
- 504Gateway timeout — the request exceeded the server's handling budget
Schemas
Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.
PullRequestChecksRollup
One PR's CI roll-up, keyed by its repo-scoped `number`. Deliberately NOT a field on [`PullRequestResponse`]. A PR's title, branches and author change when somebody edits them; its check state changes every few seconds while a run is in flight. Folding the second into the first would make every CI heartbeat invalidate the whole list payload — the client would refetch titles and branches to learn that a dot went green, and a prerendered snapshot would bake in a verdict that expires before anyone reads it. Two payloads, two cache postures.
checks_summaryrequiredhead_commitThe head the roll-up was computed against (40-char Git OID hex), or `null` before the first push resolves one. Present so a client can tell "checked, nothing ran" from "there is nothing to check yet".
numberrequiredRepo-scoped PR number — the join key back to the list payload.
queue_candidateThe merge-queue candidate (40-char Git OID hex) `checks_summary` was computed against: the PR's live queue entry is speculative, frozen on the PR's current head, and its candidate has reported at least one check. `null` when the roll-up is the head's.
workflowsThe roll-up split by workflow, over the same commit and the same collapse as `checks_summary`: each workflow's newest surviving run, in row order (by path, then id). What a PR row paints one icon per.
items
PullRequestResponse
author_display_nameauthor_github_loginLast-seen GitHub login for authors with a linked GitHub identity (always set for ghosts).
author_handleAuthor fields resolved at read time (route-layer enrichment via the ghost-safe authors projection — plans/github-metadata-import.md §7), exactly as on [`crate::IssueResponse`]. Filled on every READ — list, detail, and both context packs. `None` on a mutation receipt (the caller already has the row it just wrote) or when the account row is gone.
author_idrequiredauthor_kind- one of
auto_merge_enabled_atWhen auto-merge was armed (ms since epoch); set together with `auto_merge_enabled_by`.
auto_merge_enabled_byAccount id that armed auto-merge (merge-when-green); `null` = off. On an OPEN PR this means "will merge, as this account, the moment the merge gate reports mergeable". Cleared automatically when the head advances (new commits disarm).
change_idrequired32-byte durable change identity (hex). Survives force-push / rebase.
created_atrequireddescriptionrequireddraftrequiredhead_commit40-char Git OID hex of the source branch's current tip, or `null` before the first push resolves one.
merge_commit40-char Git OID hex of the commit the merge minted, or `null` when it minted none: an import, or a merge whose source was already reachable from the target.
merge_method- one of
merge_queue- one of
merged_atWhen the merge landed (ms since epoch). Unlike `updated_at` this never moves again, so it is the field to render as "merged <when>".
merged_byAccount credited with the merge, `null` until the PR merges — and also on a merged GitHub mirror, whose upstream merger the import payload does not carry. For a merge made with a service token this is the token's OWNER; the token itself is recorded in the operation log, not here.
merged_by_display_namemerged_by_github_loginmerged_by_handleMerger fields resolved at read time, exactly as the `author_*` group above and through the same batched projection call. `None` on a mutation receipt, on an unmerged PR, and when the account row is gone.
merged_by_kind- one of
merged_via- one of
mirror_head_repoFor a fork mirror, the GitHub `owner/name` of the fork the head lives in — a non-null value means "no local branch" (fork diff renders off the pinned OID). `null` for native PRs and same-repo mirrors.
numberrequiredoriginrequiredparent_pr_idParent PR id when this PR is part of a stack (its `target_branch` matches another open PR's `source_branch`). `None` for a non-stacked PR or for the bottom of a stack.
pr_idrequiredrepo_idrequiredsource_branchrequiredsource_repo_idRepo the source branch lives in. Equals `repo_id` for a same-repo PR; the contributor's fork for a fork PR. `null` once the source repository was deleted — such a pull request is kept as history but can never merge.
statusrequiredtarget_branchrequiredtitlerequiredupdated_atrequired