BrowserStack Screenshot API Authentication and Access Key Setup
Find your BrowserStack username and access key, authenticate screenshot API requests, and troubleshoot 401 errors and key rotation.
BrowserStack’s Screenshots API uses HTTP Basic Auth: pass your BrowserStack username and access key together as the username/password pair. Find both under Account > Settings, then use curl -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" with the Screenshots API endpoint. The API is available on Automate plans that include browsers; Live-only subscribers can use BrowserStack’s Screenshots webpage instead. BrowserStack Screenshots API reference · BrowserStack access-key guide.
1. Find your BrowserStack username and access key
- Sign in to BrowserStack.
- Open Account > Settings and locate your username and access key. Depending on the current dashboard layout, key rotation is under the profile menu, Account & Profile > My Profile > Authentication & Security.
- Copy the values into a secret manager or environment variables. Do not paste real credentials into source code, tickets, screenshots, or shell commands that may be saved in shell history.
Use the username and access key as a pair. The access key by itself is not the full Basic Auth credential. BrowserStack’s API reference documents the curl form as -u "USERNAME:ACCESS_KEY", and says unauthorized requests return HTTP 401.
2. Make an authenticated request with cURL
Set environment variables in your terminal session, then request the Screenshots API resource:
export BROWSERSTACK_USERNAME="YOUR_USERNAME"
export BROWSERSTACK_ACCESS_KEY="YOUR_ACCESS_KEY"
curl --fail-with-body \
--user "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
https://www.browserstack.com/screenshots
This is an authentication check using the endpoint shown in BrowserStack’s reference. For a screenshot job, submit a JSON body to POST /screenshots. The reference describes the job response as containing a job_id and per-screenshot states; retrieve status and results with GET /screenshots/<JOB-ID>.json.
Submit a screenshot job
The following example uses browser target values from the API reference only to show the request shape. Its examples include legacy versions, so query the browser inventory endpoint and use values currently returned for your account before running a real job.
curl --fail-with-body \
--user "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-X POST \
-d '{
"url": "https://example.com",
"wait_time": 5,
"quality": "compressed",
"browsers": [
{
"os": "Windows",
"os_version": "7",
"browser": "chrome",
"browser_version": ""
}
]
}' \
https://www.browserstack.com/screenshots
Replace the illustrative browser target with a supported combination from GET /screenshots/browsers.json. Then use the returned job_id to poll for the result:
curl --fail-with-body \
--user "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-H 'Accept: application/json' \
"https://www.browserstack.com/screenshots/JOB_ID.json"
3. Send Basic Auth from Python
Python’s requests library supports Basic Auth with an auth=(username, password) tuple. This example submits a screenshot job and prints the response for its job identifier.
import os
import requests
username = os.environ["BROWSERSTACK_USERNAME"]
access_key = os.environ["BROWSERSTACK_ACCESS_KEY"]
response = requests.post(
"https://www.browserstack.com/screenshots",
auth=(username, access_key),
headers={"Accept": "application/json"},
json={
"url": "https://example.com",
"wait_time": 5,
"quality": "compressed",
"browsers": [
{
"os": "Windows",
"os_version": "7",
"browser": "chrome",
"browser_version": "<VERSION_FROM_BROWSER_LIST>",
}
],
},
timeout=60,
)
response.raise_for_status()
job = response.json()
print(job.get("job_id"), job)
To check job status, make an authenticated GET request to https://www.browserstack.com/screenshots/<JOB-ID>.json with the same auth tuple. Add bounded retries for transient network failures; do not blindly repeat the job-creation POST after a timeout because the first request may have been accepted even if its response was lost.
4. Send Basic Auth from Node.js
This Node.js example uses the built-in fetch API and encodes the Basic Auth pair. Keep both environment variables out of client-side code.
const username = process.env.BROWSERSTACK_USERNAME;
const accessKey = process.env.BROWSERSTACK_ACCESS_KEY;
if (!username || !accessKey) throw new Error('Set BrowserStack credentials');
const auth = Buffer.from(`${username}:${accessKey}`).toString('base64');
const response = await fetch('https://www.browserstack.com/screenshots', {
method: 'POST',
headers: {
Authorization: `Basic ${auth}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
url: 'https://example.com',
wait_time: 5,
quality: 'compressed',
browsers: [{
os: 'Windows',
os_version: '7',
browser: 'chrome',
browser_version: '<VERSION_FROM_BROWSER_LIST>',
}],
}),
signal: AbortSignal.timeout(60000),
});
if (!response.ok) {
throw new Error(`BrowserStack returned ${response.status}: ${await response.text()}`);
}
const job = await response.json();
console.log(job.job_id, job);
Node’s fetch is available in current Node.js releases. If your runtime lacks it, use an HTTP client that supports Basic Auth headers; preserve the same Authorization: Basic base64(username:access_key) behavior.
5. Configure screenshot jobs without stale browser values
Authentication is the same for the browser inventory, job submission, and job-result requests. The API reference documents these job inputs and settings:
| Field | Purpose and notes |
|---|---|
url |
Page address to capture. Use a fully qualified URL such as https://example.com. |
browsers |
List of OS/browser combinations. Discover currently available values using GET /screenshots/browsers.json; the reference’s sample inventory is old. |
os, os_version, browser, browser_version |
Select a browser target. The accepted combinations depend on the available inventory. |
device |
Required for a mobile device target. |
orientation |
For a device orientation, use portrait or landscape; the documented default is portrait. |
mac_res, win_res |
Resolution settings for macOS or Windows browsers. The reference lists defaults and a finite set of supported values; verify against current API documentation. |
quality |
Screenshot quality, documented as Original or Compressed, with Compressed as the default. |
wait_time |
Delay before capture in seconds. The reference documents a default of 5 and values 2, 5, 10, 15, 20, or 60. |
local |
Set for a local page when a Local Testing connection has been set up; documented default is false. |
callback_url |
Optional public URL to receive completed results. Otherwise retrieve the job with GET /screenshots/<JOB-ID>.json. |
These parameter names and values come from BrowserStack’s Screenshots API reference, which does not show a current version date in the reviewed material. Treat the reference as the documented shape, and check current account documentation for supported browser versions and any changed constraints before building a long-lived integration.
6. Rotate or reset an access key
Dashboard rotation
- Open the profile menu, then Account & Profile > My Profile.
- Under Authentication & Security, select the rotate icon next to Access Key.
- Confirm the rotation, copy the new key, and update every service, CI secret, and local development environment that uses the old one.
- Deploy the updated secret and verify an authenticated request before removing any temporary recovery measures.
Rotation invalidates the old key. Integrations using it stop working until they are updated.
Optional organization auto-rotation
Auto-rotation is disabled by default. A Group Owner or Group Admin with authentication permissions can enable it in Settings > Permissions > Authentication & Security Settings. Documented intervals are 30, 60, 90, 180, and 365 days. BrowserStack says it emails users 14 days before a scheduled rotation. Plan to update dependent integrations before the scheduled date; a notification alone does not make applications pick up the new secret.
Automate reset API: scope it carefully
BrowserStack also documents an Automate-specific key reset endpoint. This is a separate management route from the general dashboard rotation flow; use it only when its Automate scope fits your account and operational process. The response contains old and new key fields, so treat the response as sensitive and avoid logging it.
curl --user "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X PUT \
-d '{}' \
https://api.browserstack.com/automate/recycle_key.json
BrowserStack’s reset guide also describes using an API client such as Postman: choose PUT, set Authorization to Basic Auth, and provide the username and current access key. Prefer the dashboard as the broadly documented management path unless you specifically need the Automate reset endpoint.
7. Troubleshooting authentication and access
| Symptom | Likely cause | What to do |
|---|---|---|
| 401 Unauthorized | Missing or incorrect username/access-key pair, malformed Basic Auth, or stale key after rotation. | Check both values in Account > Settings, ensure the pair is sent as Basic Auth, and replace the old key in the integration after rotation. BrowserStack explicitly documents 401 for unauthorized requests. |
| Works locally but fails in CI | The CI secret is missing, has whitespace/newline characters, or still contains the previous key. | Update the CI secret store, check variable names and scope, and rerun a minimal authenticated request without printing the credential. |
| No access to the API | The subscription may be Live-only. | Confirm the account has an Automate plan that includes browsers. BrowserStack says Live-only subscribers can use the Screenshots webpage. |
| Browser target rejected or missing | The sample OS/browser/version is no longer available or does not form a supported combination. | Query GET /screenshots/browsers.json with Basic Auth and select returned values. Do not copy old version numbers from an example blindly. |
| Job was created, but the client timed out | The request may have reached BrowserStack but its response did not reach your client. | Before resubmitting, check whether you received or recorded a job ID through your application logs or callback flow. Add timeouts and retry logic to retrieval; use care with retries on job creation to avoid accidental duplicate work. |
| Key rotation broke several services | Rotation invalidated the old key before all dependents were updated. | Inventory integrations, update their secret stores, deploy, and verify each one. For future rotations, coordinate the rollout and monitor the documented rotation schedule. |
8. Security, performance, reliability, and cost considerations
- Keep secrets server-side. Never ship the BrowserStack access key in browser JavaScript, a mobile app, or a public repository. Use environment variables or a secret manager and restrict who can read them.
- Avoid credential leakage. Do not enable verbose HTTP tracing in production or print Authorization headers and key-reset response bodies. If a key is exposed, rotate it and update dependents.
- Separate submission from polling. A screenshot job returns a job identifier and may initially show pending states. Poll its result endpoint with a bounded interval and an overall deadline, or provide a callback URL that your system can receive.
- Use a deliberate wait. The documented wait choices range from 2 to 60 seconds. Longer waits can help pages whose content appears after load, but add time to each capture; choose based on when the target page becomes screenshot-ready.
- Budget for browser combinations. A job can request multiple OS/browser combinations. Keep the matrix to the targets you need, and consult your BrowserStack plan and current product terms for applicable usage and pricing; the supplied API reference does not establish a per-screenshot price.
- Make retries selective. Retry transient failures when retrieving a known job, with backoff and a maximum deadline. A timed-out POST can have succeeded remotely, so do not automatically create another job without checking for the first result.
9. FAQ
Can I authenticate with only the access key?
No. The documented Screenshots API pattern sends the BrowserStack username and access key together using HTTP Basic Auth.
Is the screenshot key different from my Automate key?
The API reference describes authentication with the account username and access key. The Automate reset guide says the same access key is used for Automate and Local Testing; use the account credentials shown in your BrowserStack settings.
Can a Live-only account call the Screenshots API?
BrowserStack says the API is available on Automate plans that include browsers. Live-only subscribers can use the Screenshots webpage workflow.
Does rotating a key update my CI integrations automatically?
No. Rotation invalidates the old key; update the secret in each integration that uses it.
Or skip the browser setup
If your goal is to capture a webpage image rather than run BrowserStack’s cross-browser screenshot workflow, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. AI agents can take screenshots through the MCP server. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation, then sign up for 1,000 free screenshots a month with no card.


