Skip to main content
TroopyDocs
Open Troopy
Troopy

API reference / Tests and incidents

Run tests

Runs tests of the library at a place to test: the ones named in tests, or else every active test (only the main path with smoke). On production, only tests that change no data run. The QA tester runs each test in its own browser, one after the other, and reports what passed and what failed, with pictures. Answers 202: poll statusUrl. A workspace starts 300 test runs a day, and an organization works on 2 at one time: the others wait in the queue.

post/api/v1/test-runs

Authorization

HeaderAuthorization: Bearer <API key>
Or the headerX-API-Key: <API key>
API keyMake one in Troopy under Settings > API keys. It acts as you, in its workspace.

Other ways to call it

CLItroopy tests run
MCP tooltroopy_run_tests
Rate limit20 calls in 60 seconds, for each key
RetriesSend an Idempotency-Key header. A retry with the same key gets the first answer back, and the operation runs one time.

Body

application/json
environment*string

The place to test

testsarray<string>

The tests to run, by id. Left out: every active test

At most 50 items

smokeboolean

Without tests: only the tests of the main path

Response

202 · application/json
data*object
18 properties
id*string

A 24-character id

kind*enum<string>

ticket: a change. review: Troopy's code review of a change. screens: the blind critic's look at the pictures of a change. cases: tests of the library. explore: a look for problems. first_users: the QA tester tries it as 5 kinds of new user. check: whether the place loads

ticketreviewscreenscasesexplorefirst_userscheck

status*enum<string>

queuedrunningdonecanceled

waitingFor*enum<string> | null

In the queue: a QA tester to hire, one of the workspace's 2 places, the computer, a release that reaches Production, or a Claude plan that is out of usage

qaslotcomputerdeployplan

verdict*enum<string> | null

When done: fail when a part failed, blocked when a part couldn't be checked, pass only when each part passed

passfailblocked

error*string | null

Why it ended early: its place didn't load or is gone, or its ticket moved on

environment*object | null

The place, as it was when the run started: a place to test, or a preview of a ticket's change. Null when it reads only the code of the change

4 properties
id*string | null

Null for the preview of a ticket's change, which is no place of the workspace

name*string
kind*enum<string>

productionstagingpreview

url*string
note*string | null

What Troopy noted on the way, like a preview that didn't load

ticket*object | null

The engineering ticket whose change it tests: its key, its pull request, and the commit tested

5 properties
id*string

A 24-character id

key*string
repo*string
pr*integer
sha*string
progress*object

Its parts: one for each test, or one for a ticket or a look

2 properties
done*integer
total*integer
trigger*enum<string> | null

schedule: its place's schedule started it. release: a release started it. null: a person, the API or a ticket

schedulerelease

release*object | null

A check after a release: the tickets that the release took live

1 properties
tickets*array<object>
2 properties
id*string

A 24-character id

key*string
replayed*integer

Parts that replayed a test's recording whole, with no AI

replaying*boolean

Troopy replays a part now, with no AI

createdBy*object

Who wrote it

3 properties
type*enum<string>

personagentapi

id*string
name*string
createdAt*string

ISO 8601 date and time

finishedAt*string | null
statusUrl*string

Errors

400 invalid_inputFix the field named in detail. Each operation's schema is in /api/v1/openapi.json.
401 unauthorizedSend an API key as `Authorization: Bearer tr_live_...`. Create one in Troopy under Settings.
403 forbiddenThe key lacks a scope this operation needs, or its owner lacks the role. detail says which; create a key with the scope, or ask an organization owner or admin.
409 conflictThis Idempotency-Key was used for a different request, or that request is still running. Use a new key for a new request.
429 rate_limitedWait the number of seconds in Retry-After, then retry.