Free practice ยท API testingAll roadmaps โ†’

API testing practice lab

Learn API testing the only way that sticks โ€” by sending real requests. Fire off calls to safe public sandboxes right here, watch the status codes and responses, then work the graded challenges below. No setup, no keys.

Try it live

Uses dummyjson.com, jsonplaceholder and httpbin.org โ€” all safe to hammer.

Practice challenges

Work top to bottom. Each one loads into the runner โ€” try to predict the status code before you Send.

Beginner

  1. Beginner

    Your first GET request

    Fetch product #1 from DummyJSON and read its title and price.

    Assert: Status is 200, and the body has a title and a price field.

  2. Beginner

    Read a status code

    Ask for a post that doesn't exist and see what the server says.

    Assert: Status is 404 (Not Found) โ€” not every request succeeds, and that's the point.

  3. Beginner

    Query parameters

    Get only the posts written by userId 2.

    Assert: Every item in the array has userId = 2.

Intermediate

  1. Intermediate

    Create with POST

    Send a new post with a JSON body and check what comes back.

    Assert: Status is 201 (Created) and the response echoes your data with a new id.

  2. Intermediate

    See exactly what you send

    POST a small JSON body to httpbin and find it in the response.

    Assert: The data you sent appears back under the response's json key, with your Content-Type header.

  3. Intermediate

    Search & pagination

    Search DummyJSON products for 'phone', 5 per page.

    Assert: You get a total count, and the products array has at most 5 items (limit).

Advanced

  1. Advanced

    Auth: get a token, then use it

    First run 'Login โ†’ get a token', copy the accessToken from the response, paste it into the runner's Bearer token box, then run 'Use the token'.

    Assert: Login returns 200 with an accessToken; /auth/me returns your logged-in user.

  2. Advanced

    Drill into nested JSON

    Fetch cart #1 and reach the first product's title deep inside the response.

    Assert: total is greater than 0, and products[0].title exists.

  3. Advanced

    A full CRUD flow (in Postman)

    On restful-booker, create a booking (POST), read it (GET), update it (PUT with an auth token), then delete it (DELETE). It has no CORS, so use Postman for this one.

    Assert: Create returns a bookingid; the GET matches; after DELETE, the GET returns 404.

    Do this one in Postman

Now do it in code

The exact same requests, in the three frameworks QA teams hire for. This is what the API kits drill โ€” same endpoints as the runner above, so you can compare click-by-click with line-by-line.

GET & assert status + field
import { test, expect } from '@playwright/test';

test('get a product', async ({ request }) => {
  const res = await request.get('https://dummyjson.com/products/1');
  expect(res.status()).toBe(200);
  const body = await res.json();
  expect(body).toHaveProperty('title');
});
POST a JSON body โ†’ 201
test('create a post', async ({ request }) => {
  const res = await request.post('https://jsonplaceholder.typicode.com/posts', {
    data: { title: 'my first API test', body: 'learning by doing', userId: 1 },
  });
  expect(res.status()).toBe(201);
  expect((await res.json()).id).toBeTruthy();
});
Query parameters
test('filter by userId', async ({ request }) => {
  const res = await request.get('https://jsonplaceholder.typicode.com/posts', {
    params: { userId: 2 },
  });
  const posts = await res.json();
  expect(posts.every((p) => p.userId === 2)).toBeTruthy();
});
Auth: login โ†’ token โ†’ use it
test('auth flow', async ({ request }) => {
  const login = await request.post('https://dummyjson.com/auth/login', {
    data: { username: 'emilys', password: 'emilyspass' },
  });
  const { accessToken } = await login.json();
  const me = await request.get('https://dummyjson.com/auth/me', {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  expect(me.status()).toBe(200);
});
Assert nested JSON
test('nested json', async ({ request }) => {
  const res = await request.get('https://dummyjson.com/carts/1');
  const cart = await res.json();
  expect(cart.total).toBeGreaterThan(0);
  expect(cart.products[0].title).toBeTruthy();
});

Ready to go deeper?

The full path โ€” HTTP & Postman, RestAssured, schema validation, auth flows and CI โ€” is mapped in the roadmaps, with kits to practice against.