Skip to main content

Ingest (CI/CD)

The ingest endpoint is the primary integration point for CI/CD pipelines. It creates a test run and populates all results in a single request — no separate "create run" + "add results" calls needed.

Endpoint

POST /api/v1/ingest
Authorization: Bearer qh_... (write scope required)
Content-Type: application/json

Request body

{
"project_id": "clxyz123",
"run_name": "CI build #442 — main branch",
"environment": "staging",
"framework": "playwright",
"results": [
{
"test_case_code": "TC-001",
"status": "PASSED",
"duration_ms": 1240
},
{
"test_case_code": "TC-002",
"status": "FAILED",
"error_message": "Assertion failed: expected 200 but got 500",
"error_stack": "Error: ...",
"duration_ms": 3800
},
{
"title": "Should load the homepage in < 2s",
"status": "PASSED",
"duration_ms": 890
}
]
}

Top-level fields

FieldRequiredDescription
project_idYesProject UUID to create the run under
run_nameNoDisplay name; defaults to timestamp if omitted
environmentNoEnvironment label (e.g., staging)
frameworkNoDefault framework for all results (overridable per result)
resultsYesArray of result objects

Result fields

Results reference existing test cases by test_case_code or test_case_id. If neither is provided, a new NativeTestResult is recorded as an unlinked result (tracked in metrics but not linked to a library test case).

Mapping tests to the library with @qa-hub tags

Tag your automated tests with a QA Hub code in the title using @qa-hub('TC-001'):

// Playwright
test("Login — invalid password @qa-hub('TC-042')", async ({ page }) => {
// ...
});
// Jest
it("should reject expired tokens @qa-hub('TC-017')", () => {
// ...
});

When the CLI parses the result file, it extracts the tag and sets test_case_code automatically before posting to /api/v1/ingest.

Response codes

CodeMeaning
201All results accepted, run created
207Partial — some results rejected. Check errors[] in the body.

207 partial response

{
"run_id": "clrun999",
"accepted": 14,
"rejected": 2,
"errors": [
{ "index": 3, "error": "test_case_code TC-999 not found in this tenant" },
{ "index": 7, "error": "invalid status value: 'pass' (use PASSED)" }
]
}

Using with the CLI

The @qa-hub/cli parses your test framework's output format and calls this endpoint automatically:

qa-hub upload \
--token qh_abc_secret \
--url https://your-qahub.com \
--project clxyz123 \
--format playwright \
--run-name "CI #442" \
playwright-results.json

Data retention

Ingested NativeTestResult rows are retained for a configurable number of days (default: 30). Trigger a sweep via:

curl -X POST https://your-qahub.com/api/v1/admin/sweep \
-H "Authorization: Bearer qh_..."