Skip to main content

User & Team Management

Your own account and credentials, plus everything needed to provision team members and service accounts from a script.

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

Get your user info

Returns the data associated with the authenticated account: name, plan, billing details, remaining credits, and concurrency caps.

Response fields

id integer
Unique numeric user ID. Also the path param for team endpoints (e.g. /users/:id) and the parent_id reference on team members.
first_name string
Given name on the account.
last_name string
Family name on the account.
seconds integer
Remaining test seconds (credit balance) on the account; -1 means unlimited (e.g. Live plans).
last_login timestamp
ISO-8601 timestamp of the most recent dashboard login.
plan string
Subscription plan name (e.g. "Free Trial", "Live - 5 Sessions - Unlimited", "Automated Pro ..."). For a sub-account this is the team owner's plan.
max_concurrent integer
Maximum number of parallel VM-based sessions allowed by the plan. For a sub-account this is the team owner's cap.
max_concurrent_mobile integer
Maximum number of parallel physical device sessions allowed by the plan. For a sub-account this is the team owner's cap.
company string
Optional company name for billing.
street string
Billing address line.
city string
Billing city.
country string
Billing country.
vat string
VAT number (EU only).
read_only boolean
Whether this account has read-only access within the team.
roles array of string
Roles held by the account: "admin" and/or "owner".
current_vm_concurrency integer
VM-based sessions this account is running right now.
current_physical_concurrency integer
Physical-device sessions this account is running right now.
GET /v1/user
Request
$ curl "https://api.testingbot.com/v1/user" \
-u key:secret
var client = new TestingBotClient(key, secret);
var user = await client.User.GetAsync();
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_user_info
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.user.get_user_information()
$api = new TestingBot\TestingBotAPI($key, $secret);
$api->getUserInfo();
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotUser user = restApi.getUserInfo();
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const userInfo = await api.getUserInfo();
Response
{
    "first_name": "Steven",
    "last_name": "King",
    "seconds": 17745,
    "plan": "small",
    "max_concurrent": 10,
    "max_concurrent_mobile": 2,
    "company": "companyName",
    "street": "companyStreet",
    "city": "companyCity",
    "country": "companyCountry",
    "vat": "ifInEurope"
}
PUT /v1/user

Update your user info

Updates the authenticated account. Only first_name and last_name are mutable through this endpoint; other profile fields require the dashboard.

Arguments

user[first_name] string
New given name.
user[last_name] string
New family name.

Response fields

success boolean
Whether the update was applied.
user object
Updated user object. Only present when success is true.
errors object
Validation errors keyed by field name. Only present when success is false.
PUT /v1/user
Request
$ curl "https://api.testingbot.com/v1/user" \
-X PUT \
-d "user[first_name]=new" \
-u key:secret
var client = new TestingBotClient(key, secret);
await client.User.UpdateAsync(new UserUpdate { FirstName = "Bruno", LastName = "Mars" });
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.update_user_info({ "first_name" => 'new' })
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.user.update_user_information({'user[first_name]': 'new'})
$api = new TestingBot\TestingBotAPI($key, $secret);
$api->updateUserInfo(array('first_name' => 'new'));
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotUser user = restApi.updateUserInfo(TestingBotUser);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const newUserData = { first_name: 'new' };
await api.updateUserInfo(newUserData);
Response
{
  "success": true,
  "user": {
    "first_name": "new",
    "last_name": "King",
    "seconds": 17745,
    "last_login": "2011-08-06T16:47:04Z"
  }
}
GET /v1/user/keys

Get your API key and secret

Returns the API client key and secret for the authenticated account. Useful for confirming the credentials currently in use, but never embed this response in client-side code.

Response fields

key string
API client key.
secret string
API client secret. Treat as a password: never embed it in client-side code.
GET /v1/user/keys
Request
$ curl "https://api.testingbot.com/v1/user/keys" \
-u key:secret
var client = new TestingBotClient(key, secret);
var keys = await client.User.GetKeysAsync();
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_user_keys
$client = new TestingBot\Client($key, $secret);
$keys = $client->user()->keys();
TestingbotREST restApi = new TestingbotREST(key, secret);
JsonElement keys = restApi.getUserKeys();
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const { key, secret } = await api.getUserKeys();
GET /v1/team-management

Get team concurrency info

Returns allowed vs current concurrent session counts for the team across both VMs and physical mobile devices, plus how many sessions are waiting for a free slot. Poll this before fanning out a parallel build. Counts are team-wide and come from the Hub, so they match what the dashboard shows.

Response fields

concurrency object
Allowed vs current concurrency caps for the team, split in VM and physical device sessions.
GET /v1/team-management
Request
$ curl "https://api.testingbot.com/v1/team-management" \
-u key:secret
var client = new TestingBotClient(key, secret);
var concurrency = await client.Team.GetConcurrencyAsync();
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_team
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.get_concurrency()
$client = new TestingBot\Client($key, $secret);
$team = $client->teamManagement()->get();
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTeam team = restApi.getTeam();
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const teamInfo = await api.getTeam();
Response
{
  "concurrency": {
    "allowed": { "vms": 10, "physical": 2 },
    "current": { "vms": 10, "physical": 1 },
    "queued":  { "vms": 3,  "physical": 0 }
  }
}
GET /v1/team-management/users

List users in your team

Paginated list of all sub-accounts in the team. Requires admin role on the calling account.

Arguments

offset integer
Skip this many users from the start of the result set.
count integer max=500
Number of users to return .

Response fields

data array of team member objects
Team member accounts.
meta meta object
GET /v1/team-management/users
Request
$ curl "https://api.testingbot.com/v1/team-management/users" \
-u key:secret
var client = new TestingBotClient(key, secret);
var members = await client.Team.ListUsersAsync();
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_users_in_team(0, 10)
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.get_users(offset=0, limit=10)
$client = new TestingBot\Client($key, $secret);
$members = $client->teamManagement()->listUsers(0, 10);
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTeamMemberCollection members = restApi.getTeamMembers();
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const users = await api.getUsersInTeam();
Response
{
  "data": [
    {
      "id": 337,
      "first_name": "test",
      "last_name": "user",
      "seconds": 12000,
      "plan": "Free Trial",
      "max_concurrent": 2,
      "max_concurrent_mobile": 2
    }
  ],
  "meta": { "offset": 0, "count": 1, "total": 1 }
}
GET /v1/team-management/users/:id

Get a specific team user

Returns the user record for a specific team member. Admins can fetch any team member; non-admins can only fetch themselves.

Arguments

id integer required
Numeric ID of the team user to fetch.

Response fields

id integer
Unique numeric user ID. Also the path param for team endpoints (e.g. /users/:id) and the parent_id reference on team members.
first_name string
Given name on the account.
last_name string
Family name on the account.
seconds integer
Remaining test seconds (credit balance) on the account; -1 means unlimited (e.g. Live plans).
last_login timestamp
ISO-8601 timestamp of the most recent dashboard login.
plan string
Subscription plan name (e.g. "Free Trial", "Live - 5 Sessions - Unlimited", "Automated Pro ..."). For a sub-account this is the team owner's plan.
max_concurrent integer
Maximum number of parallel VM-based sessions allowed by the plan. For a sub-account this is the team owner's cap.
max_concurrent_mobile integer
Maximum number of parallel physical device sessions allowed by the plan. For a sub-account this is the team owner's cap.
company string
Optional company name for billing.
street string
Billing address line.
city string
Billing city.
country string
Billing country.
vat string
VAT number (EU only).
read_only boolean
Whether this account has read-only access within the team.
roles array of string
Roles held by the account: "admin" and/or "owner".
current_vm_concurrency integer
VM-based sessions this account is running right now.
current_physical_concurrency integer
Physical-device sessions this account is running right now.
GET /v1/team-management/users/:id
Request
$ curl "https://api.testingbot.com/v1/team-management/users/:id" \
-u key:secret
var client = new TestingBotClient(key, secret);
var member = await client.Team.GetUserAsync(userId);
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.get_user_in_team(user_id)
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.get_user(user_id)
$client = new TestingBot\Client($key, $secret);
$member = $client->teamManagement()->getUser($userId);
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTeamMember member = restApi.getTeamMember(userId);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const user = await api.getUserFromTeam(userId);
Response
{
  "id": 337,
  "first_name": "test",
  "last_name": "user",
  "seconds": 12000,
  "plan": "Free Trial",
  "max_concurrent": 2,
  "max_concurrent_mobile": 2
}
POST /v1/team-management/users

Create a user in your team

Provisions a new sub-account inside the team, copying the caller's subscription level and assigning a slice of the credit pool. Requires an upgraded plan and admin role.

Arguments

email string required
Email address for the new account; must be unique across TestingBot.
password string required
Initial password for the new user.
first_name string
New user's given name.
last_name string
New user's family name.
concurrency integer
Max parallel VM sessions (≤ team owner's maxParallel).
concurrencyPhysical integer
Max parallel physical-device sessions (≤ team owner's maxParallelDevice).
POST /v1/team-management/users
Request
$ curl -X POST -u key:secret \
  https://api.testingbot.com/v1/team-management/users \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "first_name": "Bruno",
    "last_name": "Mars",
    "email": "bmars@example.com",
    "password": "$bmaRs*RULES"
  }'
var client = new TestingBotClient(key, secret);
var member = await client.Team.CreateUserAsync(new TeamMemberCreate
{
    Email = "bmars@example.com",
    Password = "$bmaRs*RULES",
    FirstName = "Bruno",
    LastName = "Mars"
});
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.create_user_in_team({ first_name: 'Bruno', last_name: 'Mars', email: 'bmars@example.com', password: '$bmaRs*RULES' })
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.create_user(email='bmars@example.com', password='$bmaRs*RULES', first_name='Bruno', last_name='Mars')
$client = new TestingBot\Client($key, $secret);
$member = $client->teamManagement()->createUser([
    'email' => 'bmars@example.com',
    'password' => '$bmaRs*RULES',
    'first_name' => 'Bruno',
    'last_name' => 'Mars',
]);
TestingbotREST restApi = new TestingbotREST(key, secret);
Map<String, Object> params = new HashMap<>();
params.put("first_name", "Bruno");
params.put("last_name", "Mars");
params.put("email", "bmars@example.com");
params.put("password", "$bmaRs*RULES");
TestingbotTeamMember member = restApi.createTeamMember(params);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const userData = {
  first_name: 'John',
  last_name: 'Doe',
  email: 'john@example.com',
  password: 'StrongPassword!'
};

const result = await api.createUserInTeam(userData);
Response
{
  "id": 337,
  "first_name": "Bruno",
  "last_name": "Mars",
  "seconds": 12000,
  "plan": "Free Trial",
  "max_concurrent": 2,
  "max_concurrent_mobile": 2
}
PUT /v1/team-management/users/:id

Update a user in your team

Updates a team user's profile and credit allocation. Credit fields cannot exceed the team owner's remaining balance.

Arguments

id integer required
Numeric ID of the team user to update.
first_name string
New given name.
last_name string
New family name.
email string
New email address.
password string
New password.
credits integer
Allocated VM credit seconds (≤ team owner's remaining VM credits).
device_credits integer
Allocated physical-device credit seconds (≤ team owner's remaining device credits).
concurrency integer
Max parallel VM sessions for this user.
concurrencyPhysical integer
Max parallel physical-device sessions for this user.

Response fields

id integer
Unique numeric user ID. Also the path param for team endpoints (e.g. /users/:id) and the parent_id reference on team members.
first_name string
Given name on the account.
last_name string
Family name on the account.
seconds integer
Remaining test seconds (credit balance) on the account; -1 means unlimited (e.g. Live plans).
last_login timestamp
ISO-8601 timestamp of the most recent dashboard login.
plan string
Subscription plan name (e.g. "Free Trial", "Live - 5 Sessions - Unlimited", "Automated Pro ..."). For a sub-account this is the team owner's plan.
max_concurrent integer
Maximum number of parallel VM-based sessions allowed by the plan. For a sub-account this is the team owner's cap.
max_concurrent_mobile integer
Maximum number of parallel physical device sessions allowed by the plan. For a sub-account this is the team owner's cap.
company string
Optional company name for billing.
street string
Billing address line.
city string
Billing city.
country string
Billing country.
vat string
VAT number (EU only).
read_only boolean
Whether this account has read-only access within the team.
roles array of string
Roles held by the account: "admin" and/or "owner".
current_vm_concurrency integer
VM-based sessions this account is running right now.
current_physical_concurrency integer
Physical-device sessions this account is running right now.
PUT /v1/team-management/users/:id
Request
$ curl -X PUT -u key:secret \
  https://api.testingbot.com/v1/team-management/users/:id \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "first_name": "Bruno",
    "last_name": "Mars"
  }'
var client = new TestingBotClient(key, secret);
var member = await client.Team.UpdateUserAsync(userId, new TeamMemberUpdate { FirstName = "Bruno", LastName = "Mars" });
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.update_user_in_team(user_id, { first_name: 'Bruno', last_name: 'Mars' })
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.update_user(user_id, first_name='Bruno', last_name='Mars')
$client = new TestingBot\Client($key, $secret);
$client->teamManagement()->updateUser($userId, ['first_name' => 'Bruno']);
TestingbotREST restApi = new TestingbotREST(key, secret);
Map<String, Object> params = new HashMap<>();
params.put("first_name", "Bruno");
params.put("last_name", "Mars");
TestingbotTeamMember member = restApi.updateTeamMember(userId, params);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const result = await api.updateUserInTeam(userId, { first_name: 'Jane', last_name: 'Smith' });
Response
{
  "id": 337,
  "first_name": "Bruno",
  "last_name": "Mars",
  "seconds": 12000,
  "plan": "Free Trial"
}
POST /v1/team-management/users/:id/reset-keys

Reset credentials for a team user

Rotates both the API key and secret for a team user. The old credentials stop working immediately, so any deployed automation using them must be updated.

Arguments

id integer required
Numeric ID of the team user whose credentials to rotate.
POST /v1/team-management/users/:id/reset-keys
Request
$ curl -X POST -u key:secret \
  https://api.testingbot.com/v1/team-management/users/:id/reset-keys
var client = new TestingBotClient(key, secret);
var reset = await client.Team.ResetUserKeysAsync(userId);
require 'testingbot'
api = TestingBot::Api.new(key, secret)
api.reset_credentials(user_id)
import testingbotclient
tb = testingbotclient.TestingBotClient(key, secret)
tb.team.reset_keys(user_id)
$client = new TestingBot\Client($key, $secret);
$credentials = $client->teamManagement()->resetUserKeys($userId);
TestingbotREST restApi = new TestingbotREST(key, secret);
TestingbotTeamCredentialReset reset = restApi.resetTeamMemberKeys(userId);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const result = await api.resetCredentials(userId);
Response
{
  "success": true,
  "client_key": "d69e0800xc32ed2f059b7a630ee255b"
}
GET /v1/team-management/service-accounts

List service accounts

Returns the team's API-only service accounts, each with its own key and secret. Service accounts run tests on the grid and REST API but cannot sign in to the dashboard. Admin only.

Arguments

offset integer
Skip this many service accounts from the start of the result set.
count integer
Number of service accounts to return.

Response fields

data array of service account objects
Service accounts for this team.
meta meta object
GET /v1/team-management/service-accounts
Request
$ curl "https://api.testingbot.com/v1/team-management/service-accounts" \
-u key:secret
Response
{
  "data": [
    {
      "id": 412,
      "identifier": "ci-runner",
      "key": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "secret": "f0e9d8c7b6a5948372615f4e3d2c1b0a",
      "created_at": "2026-06-05T10:08:35Z"
    }
  ],
  "meta": { "offset": 0, "count": 10, "total": 1 }
}
GET /v1/team-management/service-accounts/:id

Get a service account

Returns a single service account, including its key and secret. Admin only.

Arguments

id integer required
Numeric ID of the service account.

Response fields

id integer
Unique numeric service-account ID.
identifier string
Human-friendly label shown on the dashboard and test detail pages.
key string
TestingBot API key (username) for this service account.
secret string
TestingBot API secret for this service account. Store it as a CI secret.
created_at timestamp
When the service account was created.
GET /v1/team-management/service-accounts/:id
Request
$ curl "https://api.testingbot.com/v1/team-management/service-accounts/:id" \
-u key:secret
Response
{
  "id": 412,
  "identifier": "ci-runner",
  "key": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "secret": "f0e9d8c7b6a5948372615f4e3d2c1b0a",
  "created_at": "2026-06-05T10:08:35Z"
}
POST /v1/team-management/service-accounts

Create a service account

Creates a new API-only service account with its own generated key and secret. The identifier is a label (min 3 characters, unique within the team) shown next to the account's tests on the dashboard. Admin only.

Arguments

identifier string required min=3 characters
Human-friendly label for the service account (min 3 characters, unique within the team).
POST /v1/team-management/service-accounts
Request
$ curl -X POST -u key:secret \
  https://api.testingbot.com/v1/team-management/service-accounts \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "identifier": "ci-runner"
  }'
Response
{
  "id": 412,
  "identifier": "ci-runner",
  "key": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "secret": "f0e9d8c7b6a5948372615f4e3d2c1b0a",
  "created_at": "2026-06-05T10:08:35Z"
}
PUT /v1/team-management/service-accounts/:id

Update a service account

Renames a service account by changing its identifier. The key and secret are unchanged. Admin only.

Arguments

id integer required
Numeric ID of the service account to update.
identifier string required min=3 characters
New identifier (min 3 characters, unique within the team).

Response fields

id integer
Unique numeric service-account ID.
identifier string
Human-friendly label shown on the dashboard and test detail pages.
key string
TestingBot API key (username) for this service account.
secret string
TestingBot API secret for this service account. Store it as a CI secret.
created_at timestamp
When the service account was created.
PUT /v1/team-management/service-accounts/:id
Request
$ curl -X PUT -u key:secret \
  https://api.testingbot.com/v1/team-management/service-accounts/:id \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "identifier": "nightly-regression"
  }'
Response
{
  "id": 412,
  "identifier": "nightly-regression",
  "key": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "secret": "f0e9d8c7b6a5948372615f4e3d2c1b0a",
  "created_at": "2026-06-05T10:08:35Z"
}
POST /v1/team-management/service-accounts/:id/rotate

Rotate a service account access key

Generates a fresh key and secret for the service account. The previous key and secret stop working immediately, so update any automation using them. Admin only.

Arguments

id integer required
Numeric ID of the service account whose key and secret to rotate.
POST /v1/team-management/service-accounts/:id/rotate
Request
$ curl -X POST -u key:secret \
  https://api.testingbot.com/v1/team-management/service-accounts/:id/rotate
Response
{
  "id": 412,
  "identifier": "ci-runner",
  "key": "9f8e7d6c5b4a3i2h1g0f9e8d7c6b5a40",
  "secret": "40a5b6c7d8e9f0g1h2i3a4b5c6d7e8f9",
  "created_at": "2026-06-05T10:08:35Z"
}
DELETE /v1/team-management/service-accounts/:id

Delete a service account

Permanently deletes the service account. Its key and secret stop working immediately. Tests it already ran stay in your history, still labelled with its identifier. Admin only.

Arguments

id integer required
Numeric ID of the service account to delete.
DELETE /v1/team-management/service-accounts/:id
Request
$ curl -X DELETE -u key:secret \
  https://api.testingbot.com/v1/team-management/service-accounts/:id
Response
{
  "success": true,
  "message": "Service account \"ci-runner\" deleted."
}
GET /v1/team-management/users/{id}/client-key

Get a team user's client key

Admin-only endpoint that returns the API client key for a specific team user. Used by tooling that impersonates team members in CI; the secret is not exposed here — use reset-keys to rotate.

Arguments

id integer required
Numeric ID of the team user whose key to fetch.

Response fields

client_key string
The API client key. The matching secret is never returned here; rotate both with reset-keys.
GET /v1/team-management/users/{id}/client-key
Request
$ curl "https://api.testingbot.com/v1/team-management/users/{id}/client-key" \
-u key:secret
var client = new TestingBotClient(key, secret);
var clientKey = await client.Team.GetUserClientKeyAsync(userId);
$client = new TestingBot\Client($key, $secret);
$clientKey = $client->teamManagement()->getUserClientKey($userId);
TestingbotREST restApi = new TestingbotREST(key, secret);
JsonElement clientKey = restApi.getTeamMemberClientKey(userId);
const TestingBot = require('testingbot-api');

const api = new TestingBot({
  api_key: "your-tb-key",
  api_secret: "your-tb-secret"
});

const { client_key } = await api.getUserClientKey(userId);
Was this page helpful?
Last updated