# Send CTRF reports

Source: https://docs.qualflare.com/docs/cli/ctrf · Last updated: 2026-11-03

Send a CTRF JSON report to Qualflare with qf collect or a plain HTTP POST: how statuses, suites, retries and environments map, and how to export a launch.

To send a CTRF report to Qualflare, run `qf <identifier> collect ctrf-report.json` or post the file to `/api/v1/collect/ctrf` with a project access token; either way the report becomes one launch. [CTRF](https://ctrf.io) is an open JSON format for test results; see the [glossary](https://docs.qualflare.com/docs/reference/glossary#ctrf).

## Before you begin

* A saved identifier ([Authenticate with qf login](https://docs.qualflare.com/docs/cli/authentication)) or, for HTTP, a project [access token](https://docs.qualflare.com/docs/api/access-tokens). Role of the token's creator, either way: (requires the Editor role or higher in the project)
* An environment that exists in the project. qf uses `development` unless you set `QF_ENVIRONMENT` or `--environment` ([Environments](https://docs.qualflare.com/docs/runs/environments)).
* A CTRF JSON report from your test runner's CTRF reporter.

## Upload with qf

1. Run `qf <identifier> collect ctrf-report.json`. qf recognises a CTRF report by its contents or by `ctrf` in the file name; `--format ctrf` skips the detection.
2. In CI, qf takes the branch and commit from `QF_BRANCH` and `QF_COMMIT` or the CI's own variables, not from the report ([Branch and commit detection](https://docs.qualflare.com/docs/cli/ci-cd#auto-detection)).
3. For a sharded run, qf reads the shard number from the report's `environment.shardId` ([Sharded runs](https://docs.qualflare.com/docs/cli/sharding)).

qf puts all the tests of one file in one suite, named after `results.environment.reportName`, else `<tool> (CTRF)`; each test's `suite` path becomes the case's class name.

```bash
qf ci collect ctrf-report.json --format ctrf
```

## Upload with an HTTP request

Post the file as the body, and put what CTRF can't say in the query string: the environment, the platform, the language and the CI build.

```bash
curl -sS -X POST "https://api.qualflare.com/api/v1/collect/ctrf?environment=staging&branch=main" \
  -H "Authorization: Bearer $QF_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @ctrf-report.json
```

Every query parameter, the answer and its `warnings`: [Upload a CTRF report](https://docs.qualflare.com/docs/api/collect#collect-ctrf).

## How Qualflare reads a CTRF report

### Statuses

Qualflare looks at `rawStatus` first, then `status`:

| CTRF value                                                    | Qualflare status |
| ------------------------------------------------------------- | ---------------- |
| `passed`                                                      | Passed           |
| `failed`                                                      | Failed           |
| `skipped`, or `rawStatus` `todo`, `disabled`, `ignored`       | Skipped          |
| `pending`, or `rawStatus` `notrun`, `not_run`                 | Pending          |
| `rawStatus` `broken`, `errored`, `crashed`, `error`           | Error            |
| `rawStatus` `timedout`, `timed_out`, `timeout`                | Timeout          |
| `rawStatus` `cancelled`, `canceled`, `interrupted`, `aborted` | Aborted          |
| `other` or anything else                                      | Error            |

### Suites, retries and environments

* The HTTP upload makes one suite per `suite` path, joined into one name such as `Checkout > Cards`; a test with no suite goes to a suite named after its `filePath`, else the tool's name. qf's one suite per file is under [Upload with qf](https://docs.qualflare.com/docs/cli/ctrf#upload-with-qf).
* `retryAttempts` and the test's final result become the case's attempts. With them, a test is flaky when its final status is passed and an earlier attempt failed; without them, Qualflare takes the report's `retries` and `flaky` as they are.
* Environment on the HTTP upload: the query's `environment`, else the report's `testEnvironment` turned into an id (`Staging EU` → `staging-eu`), else `development`, with a warning when it falls back.
* Branch and commit on the HTTP upload: the query's, else the report's `environment.branchName` and `environment.commit`.
* `summary` counts are ignored; Qualflare counts the tests itself.

> **Warning:** Qualflare matches tests to cases by name. A test renamed in a report that keeps its `testId` (or `id`) becomes a new case with an ID its suite already has, which fails the whole upload with `409`: no launch is saved. Give a renamed test a new `testId`.

## Export a launch as CTRF

`GET /api/v1/launch/<n>/ctrf` returns a launch as a CTRF report, with the same token access as reading the launch.

* Qualflare's own statuses survive in `rawStatus`, so uploading the export again keeps them.
* A launch with 20,000 or more case results is refused with `launch is too large to export as a single CTRF document`.
* Public report URLs don't offer it.

See [Launches API](https://docs.qualflare.com/docs/api/launches#export-ctrf).

## Verify

You should see a new launch on **Launches**, labelled with the tool in `results.tool.name`, with the report's tests in its suites.

## Troubleshoot

* `not a CTRF report: reportFormat = "<x>"` (qf only): the file is another format; pass the right `--format`.
* `CTRF report contains no tests` (HTTP): `results.tests` is empty.
* `environment "<uid>" does not exist in this project`: create it, or name an existing one in the query or with `QF_ENVIRONMENT` ([Environment mismatch](https://docs.qualflare.com/docs/cli/troubleshooting#environment-mismatch)).
* `resource already exists (cases_project_suite_uid_unique)`: a renamed test kept its `testId`, or two tests in one suite share one. Give each its own; no launch was saved.
* The launch has no branch with qf: set `QF_BRANCH` and `QF_COMMIT` ([The launch has no branch or commit](https://docs.qualflare.com/docs/cli/troubleshooting#branchcommit-not-detected)).

## Next steps

* [Supported formats](https://docs.qualflare.com/docs/cli/formats#ctrf) · [Upload results with the API](https://docs.qualflare.com/docs/api/collect) · [Sharded runs and result directories](https://docs.qualflare.com/docs/cli/sharding) · [Analyze launch results](https://docs.qualflare.com/docs/runs/analyze-results)
