Merge a pull request
POST/api/repos/{owner}/{repo}/pulls/{number}/merge
mergePullRequest
Merges an open pull request. `method` selects how it lands — `merge` for a two-parent merge commit, `squash` for a single commit carrying the whole change. Omit it to use the repository's `default_merge_method`; a method missing from its `allowed_merge_methods` is rejected with 400 rather than downgraded. `squash` is also refused for a pull request with stacked children, whose diffs would otherwise show this change a second time. Every merge goes through the target's merge queue. A pull request that is ready and current merges in this request (`status: merged`); one that is behind, or still waiting on requirements, is queued and returned open with `merge_queue` describing its progress. A refusal the queue reaches at once — a red required check, a moved head, no workflow declaring `on: merge_group` to build the candidate — is 409 with the reason; a refusal reached later surfaces in `merge_queue.state`.
Requires authentication using a bearer token or a session cookie — see tokens and scopes.
curl
curl -X POST 'https://neosource.dev/api/repos/OWNER/REPO/pulls/NUMBER/merge' \
-H 'Authorization: Bearer $NEOSOURCE_TOKEN' \
-H 'Content-Type: application/json' \
-d '{}'fetch
fetch("https://neosource.dev/api/repos/OWNER/REPO/pulls/NUMBER/merge", {
method: "POST",
headers: {
Authorization: "Bearer $NEOSOURCE_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});neo
neo pr merge NUMBER OWNER/REPOPath parameters
ownerrequiredRepository owner or organization slug.
reporequiredRepository name.
numberrequiredChange request number.
Request bodyrequired
application/json
Responses
200Merged
application/json
Standard errors
Bodies documented once for the whole API — see standard errors.
- 400Bad Request — one of: invalid_input
- 401Authentication required
- 403Forbidden — one of: forbidden
- 404Not Found — one of: not_found
- 409Conflict — one of: already_exists, conflict, non_fast_forward, github_sync_active
- 423Locked — one of: busy
- 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.
MergeMethod
How a pull request's commits land on its target branch. A repo carries two settings over this enum (`migrations/20260820120000_repo_merge_methods.sql`): the set it *permits* (`RepoRecord::allowed_merge_methods`, never empty) and the one the merge path reaches for when the request names none (`RepoRecord::default_merge_method`, always a member of that set — enforced by the settings route, which is the only place both columns are visible at once). `Default` is [`MergeMethod::Merge`] to match the column default, which is itself the pre-existing behaviour of every repo: before this setting existed, a merge always minted a two-parent commit. `Rebase` is deliberately absent rather than merely unimplemented — it replays N commits, can conflict per commit, and rewrites the SHAs the stacked-PR re-parent invariant leans on (`plans/archive/pr-merge-methods-2026-08.md` §"Not doing"). Adding it later is one `ALTER TYPE merge_method ADD VALUE` plus an arm here, which is why the stored shape is an enum array and not a pair of booleans.
"merge""squash"
MergeQueueState
"queued""testing""merging""ejected"