
Selenium API Testing: What Works and What Doesn't
Selenium can't test APIs on its own. Selenium WebDriver automates a browser the way a user would; it has no method for sending a GET or POST to a REST endpoint and asserting on the JSON. For API testing in a Selenium project, you add an HTTP library next to it (REST Assured in Java, requests in Python, HttpClient in C#) and, since Selenium 4, you can use WebDriver BiDi to watch the API calls the browser makes during a UI test. This guide shows both, with working code, as of Selenium 4.51 (October 2026).
Is Selenium an API or a framework?
Both words get used, and that's where the confusion around "Selenium API" starts:
- The Selenium API is the WebDriver client library: the classes and methods you call, such as
driver.get(),findElement()andclick(). It talks to browsers through the W3C WebDriver protocol. - Selenium is not a test framework. It has no test runner, assertions or reporting. You pair it with JUnit or TestNG (Java), pytest (Python) or NUnit/xUnit (C#).
- Selenium is not an API testing tool. It drives browsers, not HTTP endpoints.
Selenium's own docs say so: they list checking HTTP response codes as a discouraged practice, because WebDriver is meant to act like a user, and recommend asserting on what the page shows instead.
Three ways to combine Selenium and API testing
| Goal | Tool | Where it runs |
|---|---|---|
| Test REST endpoints directly (status, JSON, schema) | REST Assured, requests, HttpClient |
Your test code, no browser |
| Set up test data or log in fast before a UI test | Same HTTP library, plus Selenium cookies | Test code, then browser |
| Check the API calls the browser makes during a UI flow | Selenium WebDriver BiDi network events | Browser |
1. Test the API directly with REST Assured (Java)
For a Java Selenium project, REST Assured is the standard choice. The current release is 6.1.0 on Maven Central.
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>6.1.0</version>
<scope>test</scope>
</dependency>
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
import org.junit.jupiter.api.Test;
class UsersApiTest {
@Test
void getUserReturnsJson() {
given()
.baseUri("https://jsonplaceholder.typicode.com")
.accept("application/json")
.when()
.get("/users/1")
.then()
.statusCode(200)
.contentType("application/json")
.body("id", equalTo(1))
.body("email", containsString("@"));
}
}
This runs in milliseconds because no browser starts. Put API tests like this in the same Maven or Gradle module as your Selenium tests and run them first: if the API is down, the UI tests will fail anyway.
2. Use the API to set up a UI test (Python)
The most useful Selenium-plus-API pattern is skipping slow UI steps. Log in or create data through the API, then hand the session cookie to the browser:
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
BASE = "https://app.example.com"
# 1. Log in through the API (fast, no browser)
session = requests.Session()
resp = session.post(f"{BASE}/api/login",
json={"email": "test@example.com", "password": "test-password"})
assert resp.status_code == 200
# 2. Give the session cookie to the browser
driver = webdriver.Chrome()
driver.get(BASE) # must be on the domain before adding its cookie
for c in session.cookies:
driver.add_cookie({"name": c.name, "value": c.value, "path": "/"})
# 3. Start the UI test already signed in
driver.get(f"{BASE}/dashboard")
assert driver.find_element(By.TAG_NAME, "h1").text == "Dashboard"
driver.quit()
Swap the endpoint, payload and cookie handling for your app's auth. If your app uses a token in localStorage instead of a cookie, set it with driver.execute_script("localStorage.setItem('token', arguments[0])", token) and reload.
3. Watch the browser's API calls with WebDriver BiDi (Java)
Selenium 4 supports WebDriver BiDi, a W3C protocol that lets your test subscribe to browser events, including network responses. You enable it with the webSocketUrl capability. This example, adapted from the Selenium docs' network events test, waits for a response and checks its status:
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true); // enables BiDi
FirefoxDriver driver = new FirefoxDriver(options);
try (Network network = new Network(driver)) {
CompletableFuture<ResponseDetails> future = new CompletableFuture<>();
network.onResponseCompleted(r -> {
if (r.getRequest().getUrl().contains("/api/")) future.complete(r);
});
driver.get("https://app.example.com/orders");
ResponseDetails response = future.get(5, TimeUnit.SECONDS);
assertEquals(200L, response.getResponseData().getStatus());
} finally {
driver.quit();
}
Use this to catch a UI that looks fine while a background call fails, or to confirm the frontend sent the right request. Don't use it as your main API test suite: it only sees traffic that the page happens to trigger, and BiDi coverage still varies by language binding (the Selenium docs track the network module's progress in issue #13993). The older Chrome DevTools Protocol route (NetworkInterceptor) works only in Chromium browsers, and Selenium describes its CDP support as temporary.
How to set up a Selenium API testing framework
- Keep two layers. An
apipackage with HTTP clients and API tests, and auipackage with page objects and Selenium tests. Share config (base URLs, test accounts) between them. - Write API clients once. Wrap endpoints in small methods (
createOrder(),login()) that both the API tests and the UI test setup call. - Run API tests first in CI. They're fast and tell you whether the UI run is worth starting.
- Seed and clean data through the API, not through the UI. It makes UI tests shorter and less flaky.
- Keep UI tests for user journeys. Validation rules, error codes and edge cases belong in the API layer, where each test runs in milliseconds instead of seconds.
When to use something other than Selenium
- Playwright has API testing built in: its
requestfixture sends HTTP requests and can share cookies with the browser context, and you can log in through the API and save the state for UI tests (Playwright API testing docs). If you're starting a new project and want UI and API tests in one tool, it's the simpler option. - Postman or Bruno for exploring APIs and sharing collections with a team. See free alternatives to Postman.
- pytest + requests or REST Assured alone if you only need API tests and no browser at all.
More options are in our testing tools and API tools categories. For endpoints to practice against, try the fake data and testing APIs list.
FAQ
Can Selenium be used for API testing?
Not by itself. Selenium automates browsers. Use REST Assured, requests or another HTTP client for API tests, and use Selenium for the UI. Selenium 4's BiDi network events can observe API calls the browser makes, but that's a complement to API tests, not a replacement.
What is the Selenium API?
It's the WebDriver client library you call from Java, Python, C#, JavaScript or Ruby (methods such as get, findElement and click). It sends commands to the browser over the W3C WebDriver protocol, and since Selenium 4 also over WebDriver BiDi.
How do I do API testing with Selenium in Java?
Add REST Assured as a test dependency in the same project, write API tests with given().when().get().then(), and call the same endpoints from your Selenium tests' setup to create data or log in.
Can Selenium read the HTTP status code of a page?
WebDriver Classic can't. With WebDriver BiDi enabled (webSocketUrl capability), you can subscribe to network response events and read getResponseData().getStatus(). Selenium recommends checking the page content instead for most UI tests.
Is Playwright better than Selenium for API testing?
For tests that mix UI and API, yes: Playwright includes an HTTP client that shares cookies with the browser. Selenium supports more languages and has a long-established grid ecosystem, so existing Selenium suites usually add REST Assured or requests rather than migrating.