About the Sauce REST APIs
Sauce Labs exposes a set of REST API endpoints that let you perform operations, manage accounts, and retrieve data programmatically so you can use the Sauce platform in the way that best suits your business logic.
You can check the current accessibility of any Sauce Labs system on the Sauce Labs Systems Status page.
What You'll Need
- A Sauce Labs account (Log in or sign up for a free trial license)
- Username and access key of your Sauce Labs user account.
- Alternatively, you can use the credentials of a service account. The username and access key for a service account are provided during its creation.
Accessing the APIs
The Sauce Labs APIs are REST-based. Each endpoint is structured as a resource-oriented URL that accepts inline query parameters and form-encoded request bodies, and returns JSON-encoded responses.
Each endpoint is formed by a {base-url} prefix (which depends on the data-center associated with your Sauce Labs account) plus the version for the given method. The following table provides the base URLs for each data center.
| Data Center | API Base URL |
|---|---|
| Asia South | https://api.asia-south-2.saucelabs.com/ |
| Europe | https://api.eu-central-1.saucelabs.com/ |
| US East | https://api.us-east-4.saucelabs.com/ |
| US West | https://api.us-west-1.saucelabs.com/ |
Authentication
The request examples throughout the API documentation utilize variables in place of Sauce Labs authentication credentials. Consider setting your credentials as environment variables so that you can simply copy, paste, and run the code examples rather than manually passing your credentials for each call.
The Sauce Labs API uses API keys to authenticate requests. You can view and manage your API key under your Sauce Labs User Settings.
Alternatively, you can use the username and access key of a service account to authenticate API requests. Service account credentials are generated during account creation.
You can send these credentials in two ways:
- Basic Auth: send your username and access key with every request.
- Access token: exchange your username and access key for a short-lived token.
All requests must use HTTPS. Calls made over HTTP or without proper authentication will fail.
Basic Auth
Authentication is performed via HTTP Basic Auth. Provide your username as the basic username and your API key as the password.
curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
--request GET 'https://api.us-west-1.saucelabs.com/team-management/v1/teams'
Access Tokens
An access token is a short-lived credential. You send it in an Authorization: Bearer header. A token can do everything that the access key it came from can do.
Use access tokens when your network removes Basic Auth headers. They also keep your access key out of every request.
Get an Access Token
Send a POST request to the /auth/oauth2/token endpoint of your data center, with grant_type=client_credentials. Send your username and access key in one of two ways:
- In the form body, as
client_idandclient_secret. Use this when your network removes Basic Auth headers. - In a Basic Auth header. Most OAuth client libraries do this by default.
Don't use both in the same request.
curl -X POST 'https://api.us-west-1.saucelabs.com/auth/oauth2/token' \
-d grant_type=client_credentials \
-d client_id="$SAUCE_USERNAME" \
-d client_secret="$SAUCE_ACCESS_KEY"
curl -X POST 'https://api.us-west-1.saucelabs.com/auth/oauth2/token' \
-u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" \
-d grant_type=client_credentials
{
"access_token": "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
A few rules for the token request:
- Send the fields as a form (
application/x-www-form-urlencoded), not as JSON. A JSON body returns400with"error": "invalid_request". - Never put your username or access key in the URL. Such a request is refused.
- Don't send a
scopeparameter. A token always has the full access of its account, and a request with a scope returns400with"error": "invalid_scope".
A wrong username or access key returns 401 with "error": "invalid_client".
You can use the username and access key of a service account in the same way. A token works in every data center, not only in the one that issued it.
Discovery
OAuth 2.0 client libraries can read the token endpoint from the discovery document of your data center (RFC 8414), so you don't need to configure the URL by hand.
curl 'https://api.us-west-1.saucelabs.com/.well-known/oauth-authorization-server'
The document lists the token endpoint, the supported grant type (client_credentials), the supported client authentication methods (client_secret_post, client_secret_basic) and the location of the public signing keys (/.well-known/jwks.json).
Use an Access Token
This example gets a token and then calls the API with it. It uses jq to read the token from the response.
SAUCE_API_TOKEN=$(curl -s -X POST 'https://api.us-west-1.saucelabs.com/auth/oauth2/token' \
-d grant_type=client_credentials \
-d client_id="$SAUCE_USERNAME" \
-d client_secret="$SAUCE_ACCESS_KEY" | jq -r .access_token)
curl -L -X GET 'https://api.us-west-1.saucelabs.com/team-management/v1/teams' \
-H "Authorization: Bearer $SAUCE_API_TOKEN"
Access tokens work with the REST APIs. To run tests, keep your username and access key in the sauce:options capabilities.
Access Token Lifetime
- A token is valid for about 1 hour. The
expires_invalue gives the exact number of seconds. - Access tokens don't come with a refresh token. When a token expires, request a new one the same way.
- Request a new token a few minutes before the old one expires, so that no request fails.
- Reuse one token for all calls and parallel workers until it is close to expiry. The token endpoint is rate limited: if it returns
429, wait the number of seconds in theRetry-Afterheader. - If you regenerate your access key, tokens you already have keep working until they expire.
- If your account is deactivated, its tokens stop working right away.
Expired or Invalid Access Tokens
The API returns 401 with a WWW-Authenticate header that contains error="invalid_token".
Request a new token and try the request once more. Don't retry in a loop. If the new token fails too, check your username and access key.
Check Your Credentials
The /auth/v1/identity endpoint tells you whether a credential works and whose it is. It accepts an access token and Basic Auth.
curl -L -X GET 'https://api.us-west-1.saucelabs.com/auth/v1/identity' \
-H "Authorization: Bearer $SAUCE_API_TOKEN"
{
"sub": "usr_7c21e3a0-5d2b-4f7e-9a41-3b8c2d6e1f90",
"username": "john.smith",
"organization": "9f3b2a17-6c4d-4e8a-b5f2-0d1e7c9a8b34",
"auth_method": "oauth_token",
"credential_id": "cred_7c21e3a0-5d2b-4f7e-9a41-3b8c2d6e1f90",
"expires_at": "2026-11-02T10:15:00Z"
}
A credential that doesn't work returns 401. For all response fields, see Get Your Identity.
Versioning
The API is versioned via the URL, and different endpoints may be at different stages of release, The currently published version of each endpoint is visible in its URL, for example:
https://api.us-west-1.saucelabs.com/rest/v1/{username}/jobshttps://api.us-west-1.saucelabs.com/v2/performance/metrics/
Methods
Unspecified method requests default to GET. All other supported request types (PUT; POST; DELETE: PATCH) require setting the Content-Type header to application/json.
Status Codes
Sauce Labs uses conventional HTTP response codes to indicate the success or failure of an API request. In general, status codes in the 2xx range indicate success, 4xx indicate client-errors (e.g., invalid request), and 5xx indicate server-errors at Sauce Labs (which are rare). The following table provides a summary of response codes returned by the APIs.
| Code | Description |
|---|---|
200 - OK | The request was processed successfully. |
201 - Created | The request has been fulfilled, resulting in the creation of a new resource. Typically returned for POST, PUT, or PATCH requests that pass data values for the purpose of creating or updating records. |
400 - Bad Request | The request was not acceptable, often due to missing or improperly formatted parameters. This code may be accompanied by additional information in the form of a body payload or a message attribute of the response code. |
401 - Unauthorized | The authentication credentials were missing or not valid. |
403 - Forbidden | The authenticated user does not have permission to perform the request. |
404 - Not Found | The requested resource does not exist. This can refer to the endpoint itself (check for typos in the request URL), or the requested data (the job ID does not match any existing records, for example). This code may be accompanied by additional information in the form of a body payload or message attribute of the response code. |
429 - Too many requests | The number of requests has exceeded the rate limit for the API. |
500 - Internal Server Error | The Sauce Labs server was not responsive. |
Following are some sample error responses that include additional detail.
<!doctype html>
<html lang="en">
<head>
<title>Not Found</title>
</head>
<body>
<h1>Not Found</h1>
<p>The requested resource was not found on this server.</p>
</body>
</html>
{
"detail": "Not found."
}
{
"verify_password": ["This field is required."]
}
Rate Limits
The Sauce Labs REST API imposes rate limits on some endpoints to prevent over-utilization.
For example:
- Incoming authenticated API requests have rate limits imposed against the individual account.
- Incoming unauthenticated API requests have rate limits imposed against the IP addresses.
If you exceed the rate limit, requests will return a 429 response code, indicating that the allowable number of requests has been exceeded.
Rate Limit Breakdown
| REST API Endpoint | Rate Limit | Authenticated |
|---|---|---|
| All authenticated request endpoints | 10 requests per second, or 3,500 requests per hour | ✔️ |
| All unauthenticated request endpoints | 2 requests per minute |
JSON Response Formatting
The request examples throughout the API documentation are appended with | json_pp as a convenience to return the response in a more readable format, so you don’t need to install additional tools.
You can remove the | json_pp reference from your requests to have responses returned as raw JSON, or you can specify a different syntax formatter of your choosing, such as JQ.