Tunnel
Manage the secure tunnels that let the grid reach your staging and internal environments.
- Endpoint
- api.testingbot.com
- Version
- v1
- Format
- JSON
- Auth
- HTTP Basic
GET
/v1/tunnel/list
List active tunnels
Returns every TestingBot Tunnel currently running under the account. Use this to monitor running tunnels in CI dashboards or to find a tunnel ID before tearing it down.Response fields
-
idinteger - Unique numeric tunnel ID.
-
identifierstring -
The
--tunnel-identifierthe tunnel was started with, or null when it was started without one. Use this to tell concurrent tunnels on the same account apart. -
statestring - Tunnel lifecycle state (READY, STOPPED, …).
-
private_ipstring - Internal IP of the tunnel VM.
-
ipstring - Public IP of the tunnel VM.
-
requested_attimestamp - When the tunnel was requested.
-
user_idinteger - ID of the user the tunnel belongs to.
Request
$ curl "https://api.testingbot.com/v1/tunnel/list" \
-u key:secret
var client = new TestingBotClient(key, secret);
var tunnels = await client.Tunnels.ListAsync();
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_tunnels
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.tunnel.get_tunnels()
$api = new TestingBot\TestingBotAPI($key, $secret);
$api->getTunnels();
TestingbotREST restApi = new TestingbotREST(key, secret);
ArrayList<TestingbotTunnel> tunnels = restApi.getTunnels();
const TestingBot = require('testingbot-api');
const api = new TestingBot({
api_key: "your-tb-key",
api_secret: "your-tb-secret"
});
const tunnels = await api.getTunnelList();
Response
[
{
"id": 1,
"identifier": "my-ci-tunnel",
"state": "READY",
"ip": "xx",
"private_ip": "xx",
"requested_at": "2026-05-13 01:34:23"
}
]
DELETE
/v1/tunnel/{id}
Stop a tunnel
Tears down a running tunnel. Use this in CI teardown steps to release the slot for the next run; idle tunnels also self-terminate after the configured timeout.Arguments
-
idinteger required - Numeric tunnel ID to stop.
Request
$ curl "https://api.testingbot.com/v1/tunnel/{id}" \
-X DELETE \
-u key:secret
var client = new TestingBotClient(key, secret);
await client.Tunnels.StopAsync(tunnelId);
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.delete_tunnel(tunnel_id)
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.tunnel.delete_tunnel(tunnel_id)
$api = new TestingBot\TestingBotAPI($key, $secret);
$api->deleteTunnel($tunnelID);
TestingbotREST restApi = new TestingbotREST(key, secret);
boolean success = restApi.deleteTunnel(tunnelId);
const TestingBot = require('testingbot-api');
const api = new TestingBot({
api_key: "your-tb-key",
api_secret: "your-tb-secret"
});
await api.deleteTunnel(tunnelId);
Response
{
"success": true
}
GET
/v1/tunnel
Get the user's active tunnel
Returns the first active tunnel for the authenticated account (regardless of ID). Convenience endpoint when you only run one tunnel at a time.Response fields
-
idinteger - Unique numeric tunnel ID.
-
statestring - Tunnel lifecycle state (READY, STOPPED, …).
-
private_ipstring - Internal IP of the tunnel VM, used to chain the tunnel with BrowserMob.
-
ipstring -
Public IP of the tunnel VM. Only present once
stateis READY. -
versionstring - Latest tunnel client version TestingBot supports.
Request
$ curl "https://api.testingbot.com/v1/tunnel" \
-u key:secret
var client = new TestingBotClient(key, secret);
var tunnel = await client.Tunnels.GetActiveAsync();
$client = new TestingBot\Client($key, $secret);
$tunnel = $client->tunnels()->getActive();
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTunnel tunnel = restApi.getTunnel();
const TestingBot = require('testingbot-api');
const api = new TestingBot({
api_key: "your-tb-key",
api_secret: "your-tb-secret"
});
const tunnel = await api.getTunnel();
DELETE
/v1/tunnel
Stop the user's active tunnel
Tears down whichever tunnel is currently active on the account, without needing to specify an ID. Useful when you only ever run one tunnel and want a simple cleanup call.Request
$ curl -X DELETE "https://api.testingbot.com/v1/tunnel" \
-u key:secret
var client = new TestingBotClient(key, secret);
await client.Tunnels.StopActiveAsync();
$client = new TestingBot\Client($key, $secret);
$client->tunnels()->deleteActive();
TestingbotREST restApi = new TestingbotREST(key, secret);
boolean success = restApi.deleteTunnel();
const TestingBot = require('testingbot-api');
const api = new TestingBot({
api_key: "your-tb-key",
api_secret: "your-tb-secret"
});
await api.deleteActiveTunnel();
POST
/v1/tunnel/create
Create a tunnel
Launches a new TestingBot Tunnel VM and returns its connection metadata. Most users start tunnels via the tunnel client/CLI rather than this endpoint directly.Request
$ curl -X POST "https://api.testingbot.com/v1/tunnel/create" \
-u key:secret
var client = new TestingBotClient(key, secret);
var tunnel = await client.Tunnels.CreateAsync();
$client = new TestingBot\Client($key, $secret);
$tunnel = $client->tunnels()->create();
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTunnel tunnel = restApi.createTunnel();
GET
/v1/tunnel/isalive-check
Liveness check
Unauthenticated ping endpoint used by the tunnel binary itself to confirm it can reach the TestingBot API. Always returns{ success: true }.
Response fields
-
successboolean - Whether the operation succeeded.
-
errorsobject -
Validation errors keyed by field name. Only present when
successis false. -
errorstring -
Single human-readable reason, used by the older endpoints in place of
errors. Only present whensuccessis false.
GET
/v1/tunnel/{id}
Get a specific tunnel
Returns the current state of a tunnel by ID. Returns 500 with the underlying error if the tunnel is in a transition state or no longer exists.Arguments
-
idinteger required - Numeric tunnel ID returned by /v1/tunnel/list or /v1/tunnel/create.
Response fields
-
idinteger - Unique numeric tunnel ID.
-
statestring - Tunnel lifecycle state (READY, STOPPED, …).
-
private_ipstring - Internal IP of the tunnel VM, used to chain the tunnel with BrowserMob.
-
ipstring -
Public IP of the tunnel VM. Only present once
stateis READY. -
versionstring - Latest tunnel client version TestingBot supports.
Request
$ curl "https://api.testingbot.com/v1/tunnel/{id}" \
-u key:secret
var client = new TestingBotClient(key, secret);
var tunnel = await client.Tunnels.GetAsync(tunnelId);
$client = new TestingBot\Client($key, $secret);
$tunnel = $client->tunnels()->get($tunnelId);
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTunnel tunnel = restApi.getTunnel(tunnelId);
const TestingBot = require('testingbot-api');
const api = new TestingBot({
api_key: "your-tb-key",
api_secret: "your-tb-secret"
});
const tunnel = await api.getTunnelById(tunnelId);