---
title: API Usage
description: Learn how to authenticate and work with the Mergify REST API.
---

Mergify provides a RESTful API for integrating with your merge queues, CI
Insights, and Workflow Automation.

All API requests should be directed to: `https://api.mergify.com/v1`

The API is entirely documented in the [API Reference](/api).

## Authentication

The Mergify API supports three authentication methods, all using Bearer
tokens: **Application Keys** (generated from your dashboard), **GitHub
Personal Access Tokens**, and **Mergify User Tokens**.

### Creating an Application Key

A key belongs to an organization, so start from the organization you want it to
reach:

1. Open the [dashboard](https://dashboard.mergify.com) and select the
   organization.

2. Go to **Settings → Developer → Application Keys**.

3. Click **Add Key**, name the key, and pick its scope.

4. Click **Create**.

<Image src={applicationKeysCreate} alt="Create application keys" />

The scope selector only appears if you are an admin of the GitHub
organization. Everyone else creates `ci` keys, and creating, renaming, or
deleting an `admin` key from an account that is not an org admin fails with
`403`.

The key appears once, in a banner above the list. Copy it before you leave the
page: reloading does not bring it back, and there is no way to recover it. If
you lose one, delete the key and create another.

<Image src={applicationKeysToken} alt="Application key token" />

### Application Key Scopes

Application keys have two scopes, picked when you create the key:

- `admin`: the whole API, except uploading results, setting [Merge Queue
  Scopes](/merge-queue/scopes), and the mid-run flaky-detection and
  test-selection reads below, which need a `ci` key.

- `ci`: uploading CI and test results, setting Merge Queue Scopes, and the reads
  a job makes while it runs: the list of
  [quarantined](/test-insights/quarantine) tests, and the
  [flaky-detection](/ci-insights/flaky-test-detection) and test-selection data
  the test framework integrations fetch mid-run.

A `ci` key reaches nothing else in Test Insights. Browsing tests, their
executions and their failures, and adding or removing a quarantine, are answered
with `403` and need an `admin` key, a GitHub personal access token, or a user
token. A `ci` key sits in CI configuration, where a build log or a workflow
file can reach it, so it carries only what an unattended job needs.

A key belongs to a GitHub account, not to a repository or to the person who
created it. It works on every repository of that account and carries no GitHub
repository role, so the [Features
Permissions](/security#features-permissions) table does not restrict it.

### Using the API Key

With the provided API key, you're set to make authenticated requests
against the Mergify API. For example, to validate the authenticity of your
token, you can retrieve your application's information:

```bash
curl -H "Accept: application/json" \
     -H "Authorization: Bearer <my-application-api-key>" \
     https://api.mergify.com/v1/application
```

Response:

```json
{
    "id": "e155518c-ca1b-443c-9be9-fe90fdab7345",
    "name": "my application",
    "scope": "ci",
    "account_scope": {
        "id": 123456,
        "login": "Mergifyio"
    }
}
```

The `scope` field tells you which of the two scopes above the key holds.

### Using a GitHub Personal Access Token

As an alternative to application keys, you can authenticate to the Mergify
API using a **GitHub Personal Access Token (PAT)** as a Bearer
token. This is useful when integrating with tools that already have a
GitHub token available, such as CI environments.

You must have logged in to
the [Mergify dashboard](https://dashboard.mergify.com) at least
once using GitHub OAuth before using this method. The PAT is only used to
verify your GitHub identity: all permissions are based on your Mergify
account, not the PAT's scopes.

**Accepted token formats:**

- `ghp_*`: [classic personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic)
- `github_pat_*`: [fine-grained personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token)
- `gho_*`: GitHub OAuth user tokens

Tokens issued to a GitHub App rather than to a user (`ghu_*`, `ghs_*`) are not
accepted. A job that only has an app installation token needs an application
key instead.

Example:

```bash
curl -H "Accept: application/json" \
     -H "Authorization: Bearer <github-personal-access-token>" \
     https://api.mergify.com/v1/repos/<owner>/<repository>/queues
```

:::note
  The PAT is used solely for identity verification. The token's GitHub
  scopes do not affect what you can access in the Mergify API; permissions
  are determined by your Mergify user account and its associated
  organizations.
:::

### Using a Mergify User Token

Mergify also issues user tokens of its own, recognizable by their `mut_`
prefix and obtained through the OAuth 2.0 device authorization grant. Run
[`mergify auth login`](/cli/usage#authentication) to get one. Send it as a
Bearer token, the same way as the credentials above.

A user token identifies the person it was issued to. It reaches exactly what
its owner's dashboard session reaches, and nothing on GitHub directly, so
holding one grants no access its owner does not already have.

:::caution
  Four endpoints refuse a PAT and a user token alike, and need an application
  key. `GET /application` describes the key it was called with, so it accepts either
  scope. The `PUT` on `/repos/{owner}/{repository}/commits/{sha}/scopes` and the
  `PUT` and `POST` on `/repos/{owner}/{repository}/pulls/{number}/scopes` need a
  `ci` key. Everything else takes a PAT, a user token, or an `admin` key; each
  endpoint in the [API Reference](/api) lists the credentials it accepts.
:::

### Revoking an Application Key

If, for any reason, you need to revoke an application key:

1. Open **Settings → Developer → Application Keys** in the
   [dashboard](https://dashboard.mergify.com).

2. Click the delete icon on the key's row, and confirm.

<Image src={applicationKeysDelete} alt="Delete application key" />

The key is removed, revoking any access it provided.

## Pagination

Endpoints that return lists of items use cursor-based pagination. Paginated
responses include a `Link` header
([RFC 5988](https://www.rfc-editor.org/rfc/rfc5988)) with URLs
for navigating between pages.

**Query parameters:**

- `per_page`: Number of items per page, from 1 to 100. Most paginated endpoints
  default to 10. On others, pagination is opt-in: they have no default and
  return the whole list in a single response until you pass `per_page`. Where
  pagination is opt-in, the endpoint's entry in the
  [API Reference](/api) says so.

- `cursor`: Opaque cursor for the current page. Extract this from the `Link` header; do not construct it manually.

**Link header example:**

```http
Link: <https://api.mergify.com/v1/repos/<owner>/<repository>/logs?cursor=abc&per_page=20>; rel="next",
  <https://api.mergify.com/v1/repos/<owner>/<repository>/logs?cursor=def&per_page=20>; rel="prev"
```

The `Link` header may include the following relations:

- `next`: The next page of results
- `prev`: The previous page of results

Each relation appears only when that page exists: `next` is absent on the last
page, `prev` on the first. The two are independent, and a middle page carries
both. When neither applies — a result set that fits on a single page — the
`Link` header is omitted entirely.

To iterate through all pages, follow the `rel="next"` link
until it is no longer present in the response. To get back to the first page,
call the endpoint again without a `cursor`.

Each link carries the query parameters of the request it came from, so following
one keeps the filters you set. On an endpoint whose `start` and `end` default to
a window ending at the current time, the resolved bounds are pinned into the
links too: iterating with `rel="next"` keeps serving the window the first page
was built from, instead of resolving a fresh one against a later clock and
dropping the oldest items on the way. A bound you passed yourself is echoed back
as you sent it.

## Error Handling

The API uses standard HTTP status codes to indicate the success or failure
of a request.

| Status Code | Meaning | Description |
|-------------|---------|-------------|
| `200` | OK | The request succeeded. |
| `201` | Created | The resource was created. |
| `204` | No Content | The request succeeded and the response has no body. |
| `403` | Forbidden | The credential was refused, or is valid but lacks permission for this resource. |
| `404` | Not Found | The requested resource does not exist. |
| `409` | Conflict | The request conflicts with the current state of the resource. |
| `422` | Unprocessable Entity | The request body or parameters are invalid. |
