🌐 US-Proxy
class="support dark:bg-midnight overscroll-none" itemscope itemtype="http://schema.org/WebPage"> Skip to main content

TestingBot API Documentation

Access and modify all your TestingBot data through our comprehensive REST API. Build powerful integrations and automate your testing workflows.

Endpoint
api.testingbot.com
Version
v1
Format
JSON
Auth
HTTP Basic

API Reference

The reference is split by resource. Every endpoint below is authenticated with the API key and secret described in Authentication.

API Clients

There are several open source client libraries available to easily interact with the TestingBot API:

Authentication

Every TestingBot API request is authenticated with your API key and API secret using HTTP Basic Auth over HTTPS. The only unauthenticated endpoint is GET /v1/browsers.

1 · Find your credentials

Sign in to TestingBot and open Account → Account Info. You'll find:

key string
Your public API client key. Safe to share between your CI and the TestingBot grid; not a secret on its own.
secret string sensitive
Treat this like a password. Never commit it to git, never paste it into screenshots, never embed it in client-side code. Use environment variables or a secret manager in CI.

2 · Send credentials on every request

Pass the credentials as the standard Authorization header. Most HTTP clients accept a user:password tuple and handle the Base64 encoding for you — examples on the right.

3 · Verify it works

Hit GET /v1/user. A JSON response with your name and plan means auth is set up correctly. A 401 Unauthorized means the key or secret is wrong.

Best practice. Store credentials in environment variables — TESTINGBOT_KEY and TESTINGBOT_SECRET — and inject them into your CI/CD pipeline as secrets. Rotate the secret immediately if it leaks (Account → Reset API credentials).
Authentication Examples
Authenticated request
$ curl https://api.testingbot.com/v1/user \
  -u "$TESTINGBOT_KEY:$TESTINGBOT_SECRET"
using TestingBot.Api;

// reads TESTINGBOT_KEY / TESTINGBOT_SECRET from the environment
using var client = TestingBotClient.FromEnvironment();

var user = await client.User.GetAsync();
require 'testingbot'
api = TestingBot::Api.new(
  ENV['TESTINGBOT_KEY'],
  ENV['TESTINGBOT_SECRET']
)
api.get_user_info
import os, testingbotclient
tb = testingbotclient.TestingBotClient(
  os.environ['TESTINGBOT_KEY'],
  os.environ['TESTINGBOT_SECRET']
)
tb.user.get_user_information()
$api = new TestingBot\TestingBotAPI(
  getenv('TESTINGBOT_KEY'),
  getenv('TESTINGBOT_SECRET')
);
$api->getUserInfo();
TestingbotREST restApi = new TestingbotREST(
  System.getenv("TESTINGBOT_KEY"),
  System.getenv("TESTINGBOT_SECRET")
);
TestingbotUser user = restApi.getUserInfo();
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key:    process.env.TESTINGBOT_KEY,
  api_secret: process.env.TESTINGBOT_SECRET
});

const userInfo = await api.getUserInfo();

Reducing response size

Any endpoint accepts an optional omit query parameter to drop fields you don't need from the JSON response. Pass a comma-separated list of field names. This is handy for trimming large payloads, for example skipping the embedded report and report_xml on App Automate run details.

omit string
Comma-separated field names to exclude. Matching is by field name and applies anywhere it appears in the response, including inside data list items and nested objects. Unknown names are ignored.
Note. omit never affects whether a request succeeds, only the shape of the body. Omitting nothing returns the full, default response.
omit example
Skip heavy fields on a run
$ curl "https://api.testingbot.com/v1/app-automate/maestro/12/45?omit=report,report_xml" \
  -u "$TESTINGBOT_KEY:$TESTINGBOT_SECRET"
Response
{
  "id": 45,
  "status": "DONE",
  "success": true,
  "created_at": "2026-06-01T10:00:00.000Z"
}

Rate limits

Requests are counted in a rolling five-minute window. Authenticated requests count against your API key, so one busy CI job cannot spend a colleague's budget, and a key that leaks is capped rather than free.

2000 requests / 5 minutes per API key
Roughly 6 requests per second sustained. Applies to every authenticated endpoint.
300 requests / 5 minutes per IP
For requests sent without credentials, which can only reach the public endpoints such as GET /v1/browsers.

Every tunnel endpoint is exempt. Tunnels are infrastructure rather than a data surface: the client polls while a tunnel boots, and the tunnel VM itself reports readiness, so a limit there would stall provisioning rather than stop abuse.

Sending a test webhook delivery has its own, much tighter allowance of 20 per 5 minutes per API key, on top of the limit above. Each call makes TestingBot perform an outbound request to a URL you choose, and verifying a webhook is a setup-time action rather than something to do in bulk.

Every API response carries your current usage, so you can slow down before you are cut off rather than after:

X-RateLimit-Limit integer
Requests allowed in the current window.
X-RateLimit-Remaining integer
Requests left in the current window.
X-RateLimit-Reset integer
UNIX timestamp at which the window resets and the allowance returns to full.
Going over. Requests past the limit return 429 Too Many Requests with a Retry-After header giving the seconds to wait. The body is JSON in the usual shape, so an SDK surfaces it as an API error rather than a parse failure. Retrying after Retry-After is always safe.
rate limit headers
On every response
X-RateLimit-Limit: 2000
X-RateLimit-Remaining: 1994
X-RateLimit-Reset: 1785736800
Over the limit
{
  "error": "429 Too Many Requests. Retry in 300 seconds."
}
Was this page helpful?
Last updated