---
title: "Land the branch on the default branch with a merge commit (any member)"
description: "Any member may merge, agents included (like `gh pr merge`). Reviews\nare not a gate. Merges in one repo run one at a time. The merge commit\nis authored as the user. The gate: every required check (the repo's `required_checks`;\nwith none set, every reported context) is `success` on the branch\nhead. `force=1` merges past red or missing checks, and the merge is\nrecorded as forced.\n"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.gitpando.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Pando API › merges

`POST /v1/monorepos/{owner}/{monorepo}/repos/{repo}/branches/{branch}/merge`

Any member may merge, agents included (like `gh pr merge`). Reviews
are not a gate. Merges in one repo run one at a time. The merge commit
is authored as the user. The gate: every required check (the repo's `required_checks`;
with none set, every reported context) is `success` on the branch
head. `force=1` merges past red or missing checks, and the merge is
recorded as forced.

## Authentication

Requires one of the following:

- `credential`, http, header `Authorization`
- `session`, apiKey, in cookie

## Path parameters

- `mergeBranch.path.owner` (string, required) — The monorepo's owner, a namespace (a person's login or an organization). Matched without case.
  - pattern `^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,38}$`
- `mergeBranch.path.monorepo` (string, required) — The monorepo's name within its owner (or an old name). Matched without case.
  - pattern `^[a-z0-9](?:[a-z0-9._]|-(?!-)){0,38}$`
- `mergeBranch.path.repo` (string, required) — The repo's `name` (`projects-web`).
- `mergeBranch.path.branch` (string, required) — The branch name, `/` encoded as `%2F`.

## Query parameters

- `mergeBranch.query.force` (string, optional)
  - one of `"0"`, `"1"`; default `"0"`

## Request body

- `mergeBranch.message` (string, optional) — The merge commit message. Default "<title>\n\n<description>\n\nMerge branch '<branch>'", or "Merge branch '<branch>'" with no title.
- `mergeBranch.expected_head` (string, optional) — Refuse with 409 `head_moved` unless the branch head is this sha. When it is the head Pando recorded for the branch (every push is recorded before git is told it landed), the merge uses the recorded heads and reads no refs, which is faster; exactly this commit is merged.

## Example request

```json
{
  "message": "string",
  "expected_head": "string"
}
```

## Code samples

### cURL

```curl
curl --request POST \
  --url https://app.gitpando.com/v1/monorepos/string/string/repos/string/branches/string/merge \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "message": "string",
  "expected_head": "string"
}
'
```

### TypeScript

```typescript
const url = 'https://app.gitpando.com/v1/monorepos/string/string/repos/string/branches/string/merge';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', Authorization: 'Bearer <token>'},
  body: JSON.stringify({message: 'string', expected_head: 'string'})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://app.gitpando.com/v1/monorepos/string/string/repos/string/branches/string/merge"

payload = {
    "message": "string",
    "expected_head": "string"
}
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <token>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

Merged, or already in the default branch.

#### Example

```json
{
  "status": "merged",
  "branch": "string",
  "head": "string",
  "sha": "string",
  "base_before": "string",
  "merge_base": "string",
  "forced": true,
  "merged_by": "string",
  "closes": [
    0
  ]
}
```

- `mergeBranch.response.200.status` (string, required)
  - one of `"merged"`, `"up_to_date"`
- `mergeBranch.response.200.branch` (string, required)
- `mergeBranch.response.200.head` (string, required) — The branch head that was merged.
- `mergeBranch.response.200.sha` (string, optional) — The merge commit (or the default branch head for `up_to_date`).
- `mergeBranch.response.200.base_before` (string, optional) — The default branch head before the merge.
- `mergeBranch.response.200.merge_base` (string, optional)
- `mergeBranch.response.200.forced` (boolean, optional)
- `mergeBranch.response.200.merged_by` (string, optional)
- `mergeBranch.response.200.closes` (array<integer>, optional) — `merged`: the open issues this merge closes, decided as it lands (the branch's links, the keywords in the merge message and the merged commits). Each closes about a second later in its own step (`issue.closed`, naming the merge); one a person closed meanwhile is left as it is.

### 409

`conflict` (with `paths`: files changed differently on both sides; merge the default branch into the branch, push, and merge again), `head_moved`, or `ref_moved` (retry).

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "paths": [
      "string"
    ],
    "checks": {
      "sha": "string",
      "state": "success",
      "required": [
        "string"
      ],
      "checks_unknown": "string",
      "missing": [
        "string"
      ],
      "statuses": [
        {
          "sha": "string",
          "context": "string",
          "state": "pending",
          "target_url": "string",
          "description": "string",
          "creator": "string",
          "app": "string",
          "created_at": "2019-08-24T14:15:22Z"
        }
      ]
    }
  }
}
```

- `mergeBranch.response.409.error` (object, required)
  - `mergeBranch.response.409.error.code` (string, required)
  - `mergeBranch.response.409.error.message` (string, required)
  - `mergeBranch.response.409.error.paths` (array<string>, optional)
  - `mergeBranch.response.409.error.checks` (object, optional) — GitHub's combined status, plus the required contexts and which are missing.
    - `mergeBranch.response.409.error.checks.sha` (string | null, required)
    - `mergeBranch.response.409.error.checks.state` (string, required) — `success` when the merge gate passes; `missing` when a required context has not reported; `unknown` while the required checks are (an unforced merge is refused).
      - one of `"success"`, `"pending"`, `"failure"`, `"error"`, `"missing"`, `"unknown"`
    - `mergeBranch.response.409.error.checks.required` (array | null, required) — Null while unknown.
    - `mergeBranch.response.409.error.checks.checks_unknown` (string | null, required) — Why the required checks are unknown, in plain words: "Pando couldn't read this monorepo's required checks; try again", or "pando.toml line 3: expected comma or end of structure; fix it on main, or merge with force". Null otherwise.
    - `mergeBranch.response.409.error.checks.statuses` (array<object>, required) — The latest status per context.
      - `mergeBranch.response.409.error.checks.statuses.sha` (string, required)
      - `mergeBranch.response.409.error.checks.statuses.context` (string, required)
      - `mergeBranch.response.409.error.checks.statuses.state` (string, required)
        - one of `"pending"`, `"success"`, `"failure"`, `"error"`
      - `mergeBranch.response.409.error.checks.statuses.created_at` (string, required)
        - format `date-time`
      - `mergeBranch.response.409.error.checks.statuses.target_url` (string | null, optional)
      - `mergeBranch.response.409.error.checks.statuses.description` (string | null, optional)
      - `mergeBranch.response.409.error.checks.statuses.creator` (string, optional) — The member who posted it (a login); `app:<slug>` for a status posted with a status token or by a CI integration; `hook:<hook id>` for a status token from a web hook with no app.
      - `mergeBranch.response.409.error.checks.statuses.app` (string | null, optional) — The CI service that reported it (`buildkite`, `github-actions`, ...), stamped by Pando from a status token or a CI integration, never from the body or `target_url`. Null when a member posted it with their own credential. The web shows the service's mark for a slug it knows.
    - `mergeBranch.response.409.error.checks.missing` (array<string>, optional)

### 412

`checks_not_green`, with `checks`.

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "paths": [
      "string"
    ],
    "checks": {
      "sha": "string",
      "state": "success",
      "required": [
        "string"
      ],
      "checks_unknown": "string",
      "missing": [
        "string"
      ],
      "statuses": [
        {
          "sha": "string",
          "context": "string",
          "state": "pending",
          "target_url": "string",
          "description": "string",
          "creator": "string",
          "app": "string",
          "created_at": "2019-08-24T14:15:22Z"
        }
      ]
    }
  }
}
```

- `mergeBranch.response.412.error` (object, required)
  - `mergeBranch.response.412.error.code` (string, required)
  - `mergeBranch.response.412.error.message` (string, required)
  - `mergeBranch.response.412.error.paths` (array<string>, optional)
  - `mergeBranch.response.412.error.checks` (object, optional) — GitHub's combined status, plus the required contexts and which are missing.
    - `mergeBranch.response.412.error.checks.sha` (string | null, required)
    - `mergeBranch.response.412.error.checks.state` (string, required) — `success` when the merge gate passes; `missing` when a required context has not reported; `unknown` while the required checks are (an unforced merge is refused).
      - one of `"success"`, `"pending"`, `"failure"`, `"error"`, `"missing"`, `"unknown"`
    - `mergeBranch.response.412.error.checks.required` (array | null, required) — Null while unknown.
    - `mergeBranch.response.412.error.checks.checks_unknown` (string | null, required) — Why the required checks are unknown, in plain words: "Pando couldn't read this monorepo's required checks; try again", or "pando.toml line 3: expected comma or end of structure; fix it on main, or merge with force". Null otherwise.
    - `mergeBranch.response.412.error.checks.statuses` (array<object>, required) — The latest status per context.
      - `mergeBranch.response.412.error.checks.statuses.sha` (string, required)
      - `mergeBranch.response.412.error.checks.statuses.context` (string, required)
      - `mergeBranch.response.412.error.checks.statuses.state` (string, required)
        - one of `"pending"`, `"success"`, `"failure"`, `"error"`
      - `mergeBranch.response.412.error.checks.statuses.created_at` (string, required)
        - format `date-time`
      - `mergeBranch.response.412.error.checks.statuses.target_url` (string | null, optional)
      - `mergeBranch.response.412.error.checks.statuses.description` (string | null, optional)
      - `mergeBranch.response.412.error.checks.statuses.creator` (string, optional) — The member who posted it (a login); `app:<slug>` for a status posted with a status token or by a CI integration; `hook:<hook id>` for a status token from a web hook with no app.
      - `mergeBranch.response.412.error.checks.statuses.app` (string | null, optional) — The CI service that reported it (`buildkite`, `github-actions`, ...), stamped by Pando from a status token or a CI integration, never from the body or `target_url`. Null when a member posted it with their own credential. The web shows the service's mark for a slug it knows.
    - `mergeBranch.response.412.error.checks.missing` (array<string>, optional)

### 501

`merge_engine_unavailable`: the server-side merge engine is not wired in yet.

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "paths": [
      "string"
    ],
    "checks": {
      "sha": "string",
      "state": "success",
      "required": [
        "string"
      ],
      "checks_unknown": "string",
      "missing": [
        "string"
      ],
      "statuses": [
        {
          "sha": "string",
          "context": "string",
          "state": "pending",
          "target_url": "string",
          "description": "string",
          "creator": "string",
          "app": "string",
          "created_at": "2019-08-24T14:15:22Z"
        }
      ]
    }
  }
}
```

- `mergeBranch.response.501.error` (object, required)
  - `mergeBranch.response.501.error.code` (string, required)
  - `mergeBranch.response.501.error.message` (string, required)
  - `mergeBranch.response.501.error.paths` (array<string>, optional)
  - `mergeBranch.response.501.error.checks` (object, optional) — GitHub's combined status, plus the required contexts and which are missing.
    - `mergeBranch.response.501.error.checks.sha` (string | null, required)
    - `mergeBranch.response.501.error.checks.state` (string, required) — `success` when the merge gate passes; `missing` when a required context has not reported; `unknown` while the required checks are (an unforced merge is refused).
      - one of `"success"`, `"pending"`, `"failure"`, `"error"`, `"missing"`, `"unknown"`
    - `mergeBranch.response.501.error.checks.required` (array | null, required) — Null while unknown.
    - `mergeBranch.response.501.error.checks.checks_unknown` (string | null, required) — Why the required checks are unknown, in plain words: "Pando couldn't read this monorepo's required checks; try again", or "pando.toml line 3: expected comma or end of structure; fix it on main, or merge with force". Null otherwise.
    - `mergeBranch.response.501.error.checks.statuses` (array<object>, required) — The latest status per context.
      - `mergeBranch.response.501.error.checks.statuses.sha` (string, required)
      - `mergeBranch.response.501.error.checks.statuses.context` (string, required)
      - `mergeBranch.response.501.error.checks.statuses.state` (string, required)
        - one of `"pending"`, `"success"`, `"failure"`, `"error"`
      - `mergeBranch.response.501.error.checks.statuses.created_at` (string, required)
        - format `date-time`
      - `mergeBranch.response.501.error.checks.statuses.target_url` (string | null, optional)
      - `mergeBranch.response.501.error.checks.statuses.description` (string | null, optional)
      - `mergeBranch.response.501.error.checks.statuses.creator` (string, optional) — The member who posted it (a login); `app:<slug>` for a status posted with a status token or by a CI integration; `hook:<hook id>` for a status token from a web hook with no app.
      - `mergeBranch.response.501.error.checks.statuses.app` (string | null, optional) — The CI service that reported it (`buildkite`, `github-actions`, ...), stamped by Pando from a status token or a CI integration, never from the body or `target_url`. Null when a member posted it with their own credential. The web shows the service's mark for a slug it knows.
    - `mergeBranch.response.501.error.checks.missing` (array<string>, optional)

### 503

`repo_busy`: the repo's write slots stayed taken for 120 s, or Artifacts stayed busy after 3 retries. `checks_unknown` (an unforced merge): .pando/pando.toml could not be read, or does not parse (the message names the line), so the required checks are unknown; nothing is kept, and the next try reads it again.

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "paths": [
      "string"
    ],
    "checks": {
      "sha": "string",
      "state": "success",
      "required": [
        "string"
      ],
      "checks_unknown": "string",
      "missing": [
        "string"
      ],
      "statuses": [
        {
          "sha": "string",
          "context": "string",
          "state": "pending",
          "target_url": "string",
          "description": "string",
          "creator": "string",
          "app": "string",
          "created_at": "2019-08-24T14:15:22Z"
        }
      ]
    }
  }
}
```

- `mergeBranch.response.503.error` (object, required)
  - `mergeBranch.response.503.error.code` (string, required)
  - `mergeBranch.response.503.error.message` (string, required)
  - `mergeBranch.response.503.error.paths` (array<string>, optional)
  - `mergeBranch.response.503.error.checks` (object, optional) — GitHub's combined status, plus the required contexts and which are missing.
    - `mergeBranch.response.503.error.checks.sha` (string | null, required)
    - `mergeBranch.response.503.error.checks.state` (string, required) — `success` when the merge gate passes; `missing` when a required context has not reported; `unknown` while the required checks are (an unforced merge is refused).
      - one of `"success"`, `"pending"`, `"failure"`, `"error"`, `"missing"`, `"unknown"`
    - `mergeBranch.response.503.error.checks.required` (array | null, required) — Null while unknown.
    - `mergeBranch.response.503.error.checks.checks_unknown` (string | null, required) — Why the required checks are unknown, in plain words: "Pando couldn't read this monorepo's required checks; try again", or "pando.toml line 3: expected comma or end of structure; fix it on main, or merge with force". Null otherwise.
    - `mergeBranch.response.503.error.checks.statuses` (array<object>, required) — The latest status per context.
      - `mergeBranch.response.503.error.checks.statuses.sha` (string, required)
      - `mergeBranch.response.503.error.checks.statuses.context` (string, required)
      - `mergeBranch.response.503.error.checks.statuses.state` (string, required)
        - one of `"pending"`, `"success"`, `"failure"`, `"error"`
      - `mergeBranch.response.503.error.checks.statuses.created_at` (string, required)
        - format `date-time`
      - `mergeBranch.response.503.error.checks.statuses.target_url` (string | null, optional)
      - `mergeBranch.response.503.error.checks.statuses.description` (string | null, optional)
      - `mergeBranch.response.503.error.checks.statuses.creator` (string, optional) — The member who posted it (a login); `app:<slug>` for a status posted with a status token or by a CI integration; `hook:<hook id>` for a status token from a web hook with no app.
      - `mergeBranch.response.503.error.checks.statuses.app` (string | null, optional) — The CI service that reported it (`buildkite`, `github-actions`, ...), stamped by Pando from a status token or a CI integration, never from the body or `target_url`. Null when a member posted it with their own credential. The web shows the service's mark for a slug it knows.
    - `mergeBranch.response.503.error.checks.missing` (array<string>, optional)


Source: https://docs.gitpando.com/api/merges/mergeBranch/index.md
