# Defects API

Source: https://docs.qualflare.com/docs/api/defects · Last updated: 2026-11-03

List, read, create and update the defects of a Qualflare project over the REST API, with severity, status and category filters and every defect field.

The Defects API lets you list, read, create and update defects in a Qualflare project over REST at `https://api.qualflare.com/api/v1/defects`, authenticated with a project access token.

|               |                                                                                                                                                    |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Base path** | `/api/v1/defects` and `/api/v1/defect/{seq}`                                                                                                       |
| **Reads**     | Any token. Token creator: (requires the Viewer role or higher in the project)                                                                      |
| **Writes**    | Creating and updating defects: a token created with **Allow writes**. Token creator: (requires the Editor role or higher in the project)           |
| **Pages**     | 14 defects per page, newest first, as `items` and `paging`                                                                                         |
| **Limits**    | [Rate limits and request sizes](https://docs.qualflare.com/docs/api/limits)                                                                        |
| **Errors**    | [Errors and status codes](https://docs.qualflare.com/docs/api/errors)                                                                              |
| **CLI**       | `qf <identifier> defects list`, `qf <identifier> defect get <seq>` ([Defects commands](https://docs.qualflare.com/docs/cli/read-commands#defects)) |
| **MCP**       | `list_defects`, `get_defect`, `create_defect`, `update_defect` ([MCP server reference](https://docs.qualflare.com/docs/api/mcp-reference))         |

The four endpoints, each with its own section below:

| Endpoint                       | What it does                                                                               |
| ------------------------------ | ------------------------------------------------------------------------------------------ |
| **GET** `/api/v1/defects`      | [List defects](https://docs.qualflare.com/docs/api/defects#list-defects)     |
| **GET** `/api/v1/defect/{seq}` | [Get a defect](https://docs.qualflare.com/docs/api/defects#get-defect)       |
| **POST** `/api/v1/defects`     | [Create a defect](https://docs.qualflare.com/docs/api/defects#create-defect) |
| **PUT** `/api/v1/defect/{seq}` | [Update a defect](https://docs.qualflare.com/docs/api/defects#update-defect) |

## List defects

List defects returns one page of the project's defects, newest first unless you sort them.

**GET** `/api/v1/defects`

Needs a project access token whose creator has the Viewer role or higher in the project.

| Name            | Type             | Default | Required | Description                                                                                                                                                                                                                                             |
| --------------- | ---------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `page`          | `query`, integer | `1`     | No       | Page number, 1 to 1,000                                                                                                                                                                                                                                 |
| `severity[]`    | `query`, string  |         | No       | `low`, `medium`, `high` or `critical`. Repeat it for more, up to 10                                                                                                                                                                                     |
| `status[]`      | `query`, string  |         | No       | `active`, `action_required`, `false_positive`, `closed` or `reopened`. Repeat it for more, up to 10                                                                                                                                                     |
| `environment[]` | `query`, string  |         | No       | An environment identifier. Repeat it for more, up to 50                                                                                                                                                                                                 |
| `category[]`    | `query`, string  |         | No       | `assertion_failure`, `locator_failure`, `timeout`, `flaky`, `environment_error`, `precondition_failure`, `script_error`, `data_error`, `ci_infrastructure`, `regression`, `unknown`, `low_value_case` or `redundant_case`. Repeat it for more, up to 50 |
| `sortBy`        | `query`, string  | `seq`   | No       | `seq`, `name`, `severity`, `status`, `category`, `environment`, `createdAt` or `updatedAt`                                                                                                                                                              |
| `sortDir`       | `query`, boolean |         | No       | `true` sorts in descending order, `false` in ascending order. Left out, the list comes newest first without `sortBy`, and in ascending order with it                                                                                                    |

```bash
curl -sS -g "https://api.qualflare.com/api/v1/defects?severity[]=critical&status[]=active" \
  -H "Authorization: Bearer $QF_TOKEN"
```

Returns `200`: A page of defects: `items` and `paging`, 14 defects per page.

* The filter names end in `[]` and can repeat: `severity[]=high&severity[]=critical`. The curl example passes `-g` so curl sends the brackets as they are.
* `category[]` takes the [categories](https://docs.qualflare.com/docs/defects#categories) Qualflare gives defects, and `environment[]` an environment identifier.

## Get a defect

Get a defect returns one defect by its number, and for a defect from a failure cluster, that cluster's label, status and severity.

**GET** `/api/v1/defect/{seq}`

Needs a project access token whose creator has the Viewer role or higher in the project.

| Name  | Type            | Default | Required | Description       |
| ----- | --------------- | ------- | -------- | ----------------- |
| `seq` | `path`, integer |         | Yes      | The defect number |

```bash
curl -sS "https://api.qualflare.com/api/v1/defect/7" \
  -H "Authorization: Bearer $QF_TOKEN"
```

Returns `200`: The defect.

```json
{
  "seq": 7,
  "name": "Checkout total ignores the coupon",
  "severity": "high",
  "status": "active",
  "category": "unknown",
  "rootCauses": [],
  "automation": "manual",
  "isClosed": false,
  "description": "The order total stays at the full price after a valid coupon is applied.",
  "expected": "The total drops by 10%.",
  "actual": "The total is unchanged.",
  "teamSeq": 2,
  "teamName": "Payments",
  "environmentId": 3,
  "environmentName": "Staging",
  "clusterId": null,
  "clusterLabel": null,
  "clusterStatus": null,
  "clusterSeverity": null,
  "closedAt": null,
  "reopenedAt": null,
  "reopenedReason": null,
  "createdAt": "2026-10-28T09:30:05Z",
  "updatedAt": "2026-10-28T10:02:44Z"
}
```

* A number that isn't a defect of the project answers `404` with `defect not found`.

## Create a defect

Create a defect files a new defect in the project.

**POST** `/api/v1/defects`

Needs a project access token created with Allow writes, whose creator has the Editor role or higher in the project.

| Name             | Type           | Default | Required | Description                                                             |
| ---------------- | -------------- | ------- | -------- | ----------------------------------------------------------------------- |
| `name`           | `body`, string |         | Yes      | 1 to 128 characters; the API accepts 255, but longer text fails to save |
| `severity`       | `body`, string |         | Yes      | `low`, `medium`, `high` or `critical`                                   |
| `environmentUid` | `body`, string |         | No       | An environment identifier, up to 100 characters                         |
| `description`    | `body`, string |         | No       | Up to 10,000 characters                                                 |
| `expected`       | `body`, string |         | No       | The expected result, up to 10,000 characters                            |
| `actual`         | `body`, string |         | No       | The actual result, up to 10,000 characters                              |

```bash
curl -sS -X POST "https://api.qualflare.com/api/v1/defects" \
  -H "Authorization: Bearer $QF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Checkout total ignores the coupon", "severity": "high", "environmentUid": "staging"}'
```

Returns `201`: The new defect.

* `name` and `severity` are required. `name` holds up to 128 characters (the API accepts 255, but longer text fails to save). `environmentUid` is an environment identifier; `description`, `expected` and `actual` take up to 10,000 characters each.
* A new defect starts `active`, in the `unknown` category.
* An `environmentUid` that isn't an environment of the project answers `400` with `environment not found`, here and in [Update a defect](https://docs.qualflare.com/docs/api/defects#update-defect).

## Update a defect

Update a defect changes the fields you send and returns the defect.

**PUT** `/api/v1/defect/{seq}`

Needs a project access token created with Allow writes, whose creator has the Editor role or higher in the project.

| Name             | Type            | Default | Required | Description                                                              |
| ---------------- | --------------- | ------- | -------- | ------------------------------------------------------------------------ |
| `seq`            | `path`, integer |         | Yes      | The defect number                                                        |
| `name`           | `body`, string  |         | No       | Up to 128 characters; the API accepts 255, but longer text fails to save |
| `description`    | `body`, string  |         | No       | Up to 10,000 characters                                                  |
| `severity`       | `body`, string  |         | No       | `low`, `medium`, `high` or `critical`                                    |
| `status`         | `body`, string  |         | No       | `active`, `action_required`, `false_positive` or `closed`                |
| `expected`       | `body`, string  |         | No       | Up to 10,000 characters                                                  |
| `actual`         | `body`, string  |         | No       | Up to 10,000 characters                                                  |
| `environmentUid` | `body`, string  |         | No       | An environment identifier, up to 100 characters                          |

```bash
curl -sS -X PUT "https://api.qualflare.com/api/v1/defect/7" \
  -H "Authorization: Bearer $QF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "closed"}'
```

Returns `200`: The updated defect.

* `status` takes `active`, `action_required`, `false_positive` or `closed`; `reopened` can't be sent. A reopened defect goes back to `active`.
* A number that isn't a defect of the project answers `404` with `defect not found`.

> **Warning:** A create can't be retried safely: if a `POST` succeeded but you didn't get the answer, a retry creates a second defect.

## Defect fields

Every defect the Defects API returns has these fields:

| Field                                              | Type             | Notes                                                                                                                                                   |
| -------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `seq`                                              | integer          | The defect number in the project                                                                                                                        |
| `name`                                             | string           | Up to 128 characters                                                                                                                                    |
| `severity`                                         | string           | `low`, `medium`, `high` or `critical`                                                                                                                   |
| `status`                                           | string           | `active`, `action_required`, `false_positive` or `closed` ([Defect statuses](https://docs.qualflare.com/docs/defects#defect-statuses))                  |
| `category`                                         | string           | One of the 13 values `category[]` takes in [List defects](https://docs.qualflare.com/docs/api/defects#list-defects)                       |
| `rootCauses`                                       | array of strings | The root causes recorded for the defect                                                                                                                 |
| `automation`                                       | string           | `manual` or `automated`                                                                                                                                 |
| `isClosed`                                         | boolean          | `true` for a closed defect                                                                                                                              |
| `description`, `expected`, `actual`                | string           | The description, expected result and actual result, or `null`                                                                                           |
| `teamSeq`, `teamName`                              | integer, string  | The owning team, or `null`                                                                                                                              |
| `environmentId`, `environmentName`                 | integer, string  | The defect's environment, or `null`                                                                                                                     |
| `clusterId`                                        | integer          | The [failure cluster](https://docs.qualflare.com/docs/api/failure-clusters) the defect came from, or `null`                                             |
| `clusterLabel`, `clusterStatus`, `clusterSeverity` | string           | That cluster's label, status and severity on [Get a defect](https://docs.qualflare.com/docs/api/defects#get-defect); `null` in list items |
| `closedAt`                                         | string           | When the defect was closed or marked false positive, or `null` while it is open                                                                         |
| `reopenedAt`, `reopenedReason`                     | string           | When and why the defect was last reopened, or `null`                                                                                                    |
| `createdAt`, `updatedAt`                           | string           | RFC 3339 timestamps                                                                                                                                     |

## CLI and MCP equivalents

The qf CLI and the MCP server run the same reads, and the MCP server the same writes, so they return the same JSON:

| REST                           | qf command and MCP tool                          |
| ------------------------------ | ------------------------------------------------ |
| **GET** `/api/v1/defects`      | `qf <identifier> defects list`; `list_defects`   |
| **GET** `/api/v1/defect/{seq}` | `qf <identifier> defect get <seq>`; `get_defect` |
| **POST** `/api/v1/defects`     | No qf command; `create_defect`                   |
| **PUT** `/api/v1/defect/{seq}` | No qf command; `update_defect`                   |

## Related

* **Guides:** [Defects](https://docs.qualflare.com/docs/defects)
* **Reference:** [Failure clusters API](https://docs.qualflare.com/docs/api/failure-clusters)
* **CLI/API:** [Qualflare API](https://docs.qualflare.com/docs/api)
