# Merge a pull request

> Land a pull request on the repository's main branch.

<div class="g1t-endpoint"><span class="g1t-method" data-method="post">POST</span><code>/repos/{owner}/{name}/pulls/{number}/merge</code></div>

Merging needs the Write role or higher, and only once it is marked ready and its acceptance checks have passed. Merging resolves the issue it was made for: the issue closes recording this pull request, and the other pull requests still in progress for that issue close as superseded. Where the repository has a merge queue, it joins the queue instead of landing at once. If main has moved since the pull request was opened, it is brought up to date first and lands when that is done; a repository that requires pull requests to be up to date refuses instead, so pull main into its fork or branch, push, and merge again. Check status in the result to see whether it has landed.

A draft, or one whose checks have not passed, answers `409`. A pull request still `open` in the response has not landed yet: `landing` is true on it while it is brought up to date, and [get the merge queue](/reference/api/pull-requests/get-merge-queue/) shows it waiting in the [merge queue](/guides/merge-queue/). Merging records the pull request in the issue's `resolved_by` and sets `superseded_by` on the pull requests it closes.

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`pull_request`](/reference/mcp/#pull_request) with `action` `merge`, and the same inputs
- **Scope:** An access token needs [`pull_requests:write`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `owner` | string | Yes | The workspace that owns the repository. |
| `name` | string | Yes | The repository's name. |
| `number` | integer | Yes | The number shown after the #. Issues and pull requests share one sequence. |

## Body parameters

Send a JSON object. Names are `snake_case`, as in responses; the `camelCase` spelling is accepted too.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `keep_issue_open` | boolean | No | Set when this pull request is only part of the work: the issue stays open and the other pull requests for it are left alone. |
| `ignore_checks` | boolean | No | Merge although the acceptance checks have not passed. |

## Example request

```sh
curl -X POST https://api.g1t.sh/repos/flagon-io/hello/pulls/14/merge \
  -H "Authorization: Bearer $G1T_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keep_issue_open": false
  }'
```

## Example response

A successful request answers `200` with:

```json
{
  "id": "pr_01m43smh3vexsr5pmp60qwv0vs",
  "repo_id": "rep_01m3m5q6p0e2qaw6mmjahk0qrr",
  "number": 14,
  "issue": 12,
  "title": "Greeting should name the caller",
  "body": "Reads a name from the first argument. `hello ana` prints \"Hello, ana!\".",
  "agent": "claude-code",
  "runtime": "external",
  "status": "merged",
  "fork": {
    "namespace": "pulls",
    "name": "pr_01m43smh3vexsr5pmp60qwv0vs"
  },
  "fork_repo_id": "rep_01m43smh5xd7aw2kq9tv0b4c8e",
  "branch": null,
  "head_commit": "9f2c4e1a7b3d5f60812a4c6e8b0d2f4a6c8e0b13",
  "merge_base": "3a7e9c1b5d2f4a6c8e0b2d4f6a8c0e2b4d6f8a1c",
  "merged_by": "syntaqx",
  "merged_at": "2026-10-01T18:52:17.093Z",
  "superseded_by": null,
  "check_status": "passed",
  "files": [
    {
      "path": "src/main.rs",
      "additions": 6,
      "deletions": 2
    }
  ],
  "assignees": [],
  "reviewers": [
    "ana"
  ],
  "author": {
    "id": "usr_01kkntcg1eeb98j62xjm7eh09p",
    "username": "syntaqx",
    "kind": "user",
    "verified": false,
    "workspaces": []
  },
  "created_at": "2026-10-01T18:20:02.117Z",
  "updated_at": "2026-10-01T18:52:17.093Z"
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change or an agent token outside its repository. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 409 | `conflict` | The request conflicts with the current state. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
