curl --request GET \
--url https://app.testorim.com/api/projects/{projectId}/runs \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.testorim.com/api/projects/{projectId}/runs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.testorim.com/api/projects/{projectId}/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.testorim.com/api/projects/{projectId}/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.testorim.com/api/projects/{projectId}/runs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.testorim.com/api/projects/{projectId}/runs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.testorim.com/api/projects/{projectId}/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"runs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"instruction": "<string>",
"status": "pending",
"passedCount": 123,
"failedCount": 123,
"skippedCount": 123,
"totalDurationMs": 123,
"hasVideo": true,
"hasTrace": true,
"createdAt": "2023-11-07T05:31:56Z",
"procedureId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"userExpectation": "pass",
"overallStatus": "passed",
"initialUrl": "<string>",
"finalUrl": "<string>",
"reportMarkdown": "<string>",
"confidenceScore": 123,
"finalScreenshotR2Key": "<string>",
"finalScreenshotUrl": "<string>",
"videoR2Key": "<string>",
"traceR2Key": "<string>",
"videoUrl": null,
"traceUrl": null,
"viewportPreset": "<string>",
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"browser": "<string>",
"attemptIndex": 123,
"parentRunId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"runKind": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z"
}
]
}{
"error": "Invalid or revoked API key"
}{
"error": "Project not found"
}{
"error": "<string>",
"retryAfter": 123
}List runs for one project
Runs belonging to a single project, newest first, in the summary shape. The project is resolved org-scoped first, so an unknown or foreign project id 404s before any run is read.
curl --request GET \
--url https://app.testorim.com/api/projects/{projectId}/runs \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.testorim.com/api/projects/{projectId}/runs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.testorim.com/api/projects/{projectId}/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.testorim.com/api/projects/{projectId}/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.testorim.com/api/projects/{projectId}/runs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.testorim.com/api/projects/{projectId}/runs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.testorim.com/api/projects/{projectId}/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"runs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"instruction": "<string>",
"status": "pending",
"passedCount": 123,
"failedCount": 123,
"skippedCount": 123,
"totalDurationMs": 123,
"hasVideo": true,
"hasTrace": true,
"createdAt": "2023-11-07T05:31:56Z",
"procedureId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"userExpectation": "pass",
"overallStatus": "passed",
"initialUrl": "<string>",
"finalUrl": "<string>",
"reportMarkdown": "<string>",
"confidenceScore": 123,
"finalScreenshotR2Key": "<string>",
"finalScreenshotUrl": "<string>",
"videoR2Key": "<string>",
"traceR2Key": "<string>",
"videoUrl": null,
"traceUrl": null,
"viewportPreset": "<string>",
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"browser": "<string>",
"attemptIndex": 123,
"parentRunId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"runKind": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z"
}
]
}{
"error": "Invalid or revoked API key"
}{
"error": "Project not found"
}{
"error": "<string>",
"retryAfter": 123
}Authorizations
Send Authorization: Bearer tst_live_….
Format (services/api-keys.ts): the literal prefix tst_live_
followed by 24 random bytes rendered as 32 base64url characters.
Only the SHA-256 hash is stored server-side. The shape check that
routes a token down the API-key path rather than the Clerk JWT path
requires the tst_live_ prefix and a total length of at least 25
characters.
Keys are minted in the dashboard at /settings/team. The same header
also accepts a Clerk session JWT, which is how the web app
authenticates, but the JWT path is out of scope for this document.
Path Parameters
Project id (UUID).
Query Parameters
Maximum rows. Default 50, clamped to 1..200. A non-numeric value falls back to 50 rather than erroring.
1 <= x <= 200Response
OK
Show child attributes
Show child attributes

