The REST API starts runs and reads results for one project. It is what the GitHub Action uses, and works from any CI or script.
Basics
Section titled “Basics”- Base URL:
https://api.testmode.ai - Authentication: a project API key, as
Authorization: Bearer tmk_…(orX-Api-Key: tmk_…). - Format: JSON in, JSON out.
- Rate limit: 60 requests a minute per key; over it,
429withRetry-After. - Not for browsers: the API answers no CORS requests. Call it from servers and pipelines, where the key stays secret.
Endpoints
Section titled “Endpoints”| Method and path | Returns |
|---|---|
GET /v1/project |
The project, its environments and its test plans |
GET /v1/environments |
{ environments: [{ id, name, baseUrl, isDefault }] } |
GET /v1/test-plans |
{ testPlans: [{ id, name, description, testCaseCount }] } |
GET /v1/test-cases?tag=&search= |
{ testCases: [{ id, name, tags, enabled }], truncated }: oldest first, at most 500 |
POST /v1/runs |
The new run, with HTTP 201 |
GET /v1/runs?limit= |
{ runs: [...] }: newest first, at most 100 |
GET /v1/runs/:id |
The run with its tests |
Start a run
Section titled “Start a run”curl -X POST https://api.testmode.ai/v1/runs \ -H "Authorization: Bearer $TESTMODE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "environment": "Staging", "testPlan": "Smoke", "name": "PR #42" }'The body:
| Field | Meaning |
|---|---|
environment |
Environment id or name. Default: the project’s default environment, else the first. |
testPlan |
Test plan id or name. |
testCaseIds |
An array of test case ids. |
tags |
An array of tags: every enabled test case with any of them, at most 500. |
name |
Optional run name, up to 200 characters. |
Give exactly one of testPlan, testCaseIds or tags. Names match exactly, ignoring case; an ambiguous name is refused, so pass the id. Tags ignore case.
POST /v1/runs is not idempotent: a retry starts, and counts, a second run. A 500 that still carries id and url means the run started but couldn’t be read back: follow that run instead of posting again.
Read a run
Section titled “Read a run”curl https://api.testmode.ai/v1/runs/$RUN_ID \ -H "Authorization: Bearer $TESTMODE_API_KEY"{ "id": "…", "name": "PR #42", "status": "RUNNING", "finished": false, "totalTests": 3, "passedTests": 1, "failedTests": 0, "startedAt": "…", "finishedAt": null, "durationMs": null, "skipReason": null, "url": "https://app.testmode.ai/results/…", "tests": [ { "id": "…", "testCaseId": "…", "name": "Checkout", "status": "PASSED", "durationMs": 21000, "summary": "…", "url": "…" } ]}statusisQUEUED,RUNNING,PASSED,FAILEDorSKIPPED, for the run and for each test.finishedistrueonce the run can no longer change. Poll until then; every 15 seconds is plenty.summaryis each test’s one-line result. It names variables as{{Name}}, never their values.urlopens the run, or the test, in the app.
Errors
Section titled “Errors”Errors are { "error": "…" } with one of these statuses:
| Status | Meaning |
|---|---|
400 |
The request is invalid, such as no or several of testPlan, testCaseIds and tags, or nothing to run. |
401 |
No key, an unknown key, or an expired one. |
402 |
Not enough test runs: code: "insufficient_credits", with required and available. |
403 |
The key’s creator can no longer start runs. |
404 |
No such environment, plan, test case or run in this project. |
429 |
Over the rate limit; wait for Retry-After seconds. |
500 |
Something failed on our side. |
Related
Section titled “Related”Run tests from GitHub Actions and other CIA ready-made client for pipelines.
API keysCreate and revoke keys.
Run, test and exploration statusesWhat each status means.