GitHub Async Merge API: When Is a Pull Request Actually Merged?

The pull request has already merged, but your bot's async merge request still says enqueued. When is it safe to start the deployment?

GitHub Async Merge API: When Is a Pull Request Actually Merged?
TLDR
  • A 202 response accepts background work. Save the UUID and retrieve the result.
  • An enqueued result is final for that request; it does not later turn into merged.
  • After queue entry, check the PR’s actual merge state before starting work that depends on the merge.

Save the UUID when your request is accepted

A merge bot should not treat HTTP 202 as permission to start a deployment. GitHub’s async merge API, generally available since October 1, separates request acceptance from the background operation’s outcome. GitHub now recommends this route for programmatic PR merges.

Submit to PUT /repos/OWNER/REPO/pulls/NUMBER/merge-async, retain details.uuid, and retrieve the result with GET /repos/OWNER/REPO/pulls/NUMBER/merge-async/UUID.

The critical transition is enqueued. According to the result endpoint documentation, that is a completed queue-entry request. Its result remains enqueued even after the queue eventually merges the PR. Continuing to poll the same UUID will not tell you when that happens.

Branch on the response body, not just the HTTP code

The operation has one in-progress state and three terminal outcomes. Each needs a different next step in your automation.

StateMeaningNext step
pendingBackground processing continues.Poll the same request UUID again.
mergedThe PR reached the base branch.Record the returned merge commit OID and proceed.
enqueuedThe PR entered a merge queue.Track the PR’s eventual merge separately.
failedThe operation failed.Read the failure message and address its cause.

For a queued PR, use the merge check endpoint: GET /repos/OWNER/REPO/pulls/NUMBER/merge. A merged PR returns 204. The documented unmerged response is 404, but an incorrect path or inaccessible repository also needs to be ruled out before treating a 404 as an unmerged PR.

For example, a “ready to deploy” notification belongs after the actual merge check, not immediately after queue admission. Entering the queue still leaves validation work ahead.

Reuse pending requests and account for result expiration

If another async request is already pending for the PR, submission returns 409 with that request’s UUID and merge options. Follow the existing request rather than repeatedly submitting new work. A PR already merged or already queued can instead return 200 immediately; its body still determines which outcome occurred.

Request results remain available for 24 hours after their most recent update. The UUID endpoint returns 404 after expiration. A worker resuming later must inspect the PR’s current state rather than infer that an expired request means the merge was undone.

New commits matter too. If you omit sha, GitHub uses the PR head at submission time and cancels the merge if a push changes it before execution. Branch protection and repository rules are evaluated during background processing, after the initial basic state checks. Your bot needs to handle a failed outcome even after successful acceptance.

A stack request includes open PRs below the selected entry

The stack API reference requires the async endpoint for stacked PRs. The operation includes the selected PR and its open downstack dependencies. The group is merged together, queued together, or not processed.

The default merge_action uses a queue if the target branch has one, and merges directly otherwise. The same client code must therefore support both merged and enqueued outcomes.

Queue entry is still provisional at the PR level. GitHub’s merge queue documentation explains that failed required checks can remove a PR from the queue. Define completion around the merged PR, not the accepted request.