Interview Insights · API Testing
Why APIs Questions Reveal More Than Any Resume Line
Quick summary — API questions
A resume line tells me what you touched; one specific API question tells me how deeply you worked with it. Resume lines for API testing are nearly identical across candidates, so I do not spend time on them. I pick a situation real API work always runs into, such as paginated lists, rate limits or an unavailable dependency, and ask how they handled it. Candidates with real experience answer with steps and trade-offs. Others answer with definitions. The question does the sorting the resume cannot.
In this guide you will learn:
- Why identical resume lines push interviewers toward situation questions
- How to test pagination properly, with working pytest code
- What 429 and rate-limit headers mean for your test suite
- How mocking isolates tests from unstable dependencies
- A method to align your resume with answers you can defend
SECTION 01Pagination: a question that sorts candidates quickly
Almost every real API has list endpoints, and almost every list endpoint is paginated. So if your resume says you tested REST APIs, I ask how you tested pagination. Candidates who have only followed tutorials say 'I checked that the list came back'. Candidates who have done real work talk about page size, the last page, empty pages, duplicates across pages and the total count.
This is a good question precisely because it is ordinary. It does not require rare knowledge, only real exposure.
| Pagination check | What can go wrong | How to test it | What it reveals about you |
|---|---|---|---|
| Page size respected | API returns more or fewer items than asked | Request page_size=10, assert len(items) <= 10 | You read the contract |
| No duplicates across pages | Unstable sort repeats items on page 2 | Collect IDs across pages, compare set and list length | You think about ordering |
| Total matches items | Reported total differs from items returned | Walk all pages and compare count with total | You test the full set, not one page |
| Beyond last page | Error or crash on page past the end | Request page = last + 1, expect empty list or 404 per contract | You test edges |
import os
import requests
BASE = os.environ["API_BASE"]
HEADERS = {"Authorization": f"Bearer {os.environ['API_TOKEN']}"}
def fetch_all_products(page_size=20):
page, ids, total = 1, [], None
while True:
r = requests.get(f"{BASE}/products",
params={"page": page, "page_size": page_size},
headers=HEADERS, timeout=10)
assert r.status_code == 200
data = r.json()
total = data["total"]
items = data["items"]
assert len(items) <= page_size
ids.extend(item["id"] for item in items)
if len(items) < page_size:
return ids, total
page += 1
def test_pages_cover_all_items_without_duplicates():
ids, total = fetch_all_products()
assert len(ids) == len(set(ids)), "duplicate items across pages"
assert len(ids) == total, "total does not match items returned""For list endpoints I checked four things.
First, page size: no page returns more than requested.
Second, I walked every page and collected the IDs. If
the list had more IDs than the set, items were repeated,
which usually means the sort order was not stable.
Third, the count of collected IDs had to equal the total
the API reported.
Fourth, I requested a page beyond the end and checked it
followed the contract - an empty list in our case.
We ran this on a test environment with fixed data,
because new items added during the run can shift pages."
The last sentence of the spoken answer is the strongest signal. Knowing that live data can shift pages during a test, and controlling for it, is something you only learn from running pagination tests for real.
SECTION 02Rate limits and 429: what it tells me about your suite
Another everyday situation: a test suite that suddenly fails with many 429 Too Many Requests responses. I ask candidates what that means and what they would do. The answer shows whether they think about the test suite as a client of the API, with its own behaviour, or just as a list of independent checks.
A good answer explains that the suite is sending requests faster than the API allows, reads any Retry-After or rate-limit headers, and adjusts. It also separates two goals: testing that the rate limit works, and making sure functional tests are not blocked by it.
| Situation | Weak response | Strong response | Why it is better |
|---|---|---|---|
| Many 429s in a CI run | Add sleep(5) everywhere | Read Retry-After, add backoff, reduce parallel workers | Targets the cause, keeps the run fast |
| Need to test the limit itself | Not my job | Separate test that sends requests until 429, then checks headers | Verifies the feature without affecting other tests |
| Shared test environment | Run whenever | Agree a separate key or quota for automation | Avoids blocking other teams |
| Flaky failures near the limit | Mark as flaky | Log response headers to confirm it is rate limiting | Diagnoses before labelling |
import time
import requests
def get_with_backoff(url, headers=None, params=None, max_retries=3):
"""Retry only on 429, honouring Retry-After when present."""
for attempt in range(max_retries + 1):
r = requests.get(url, headers=headers, params=params, timeout=10)
if r.status_code != 429:
return r
if attempt == max_retries:
return r
retry_after = r.headers.get("Retry-After")
wait = int(retry_after) if retry_after and retry_after.isdigit() \
else 2 ** attempt
time.sleep(wait)
return rdef test_rate_limit_returns_429_with_retry_after():
"""Run this on its own, never in the parallel functional suite."""
statuses = []
last = None
for _ in range(200):
last = requests.get(f"{BASE}/products",
headers=LIMIT_TEST_HEADERS, timeout=10)
statuses.append(last.status_code)
if last.status_code == 429:
break
assert 429 in statuses, "limit never reached in 200 calls"
assert "Retry-After" in last.headers
# LIMIT_TEST_HEADERS uses a dedicated test key, so hitting
# the limit does not block other tests or other teams.
# The 200-call cap is our assumption about the configured
# limit; read the real value from the API docs.
Notice that the backoff helper retries only on 429. Retrying on every error would hide real failures, such as a 500 caused by a bug. That distinction is exactly what interviewers listen for.
SECTION 03Mocking dependencies: can you isolate what you test?
Real APIs call other services: payment gateways, SMS providers, address lookups. When those dependencies are slow or down in the test environment, tests fail for reasons unrelated to the code under test. So I ask: 'The payment provider's sandbox is down. How do your tests keep running?'
Candidates who have only tested simple APIs often have no answer. Those with real experience talk about mocks or stubs, about which tests should still hit the real sandbox, and about the risk that a mock drifts away from the real provider's behaviour.
| Approach | What it does | Good for | Risk to mention |
|---|---|---|---|
| Mock in unit/component tests | Replaces the HTTP call inside the test process | Fast checks of your own logic and error handling | Does not prove the real integration works |
| Stub server (e.g. WireMock) | Runs a fake service that returns set responses | Testing the API against controlled dependency behaviour | Stubs can drift from the real provider |
| Provider sandbox | Calls the provider's test environment | End-to-end confidence before release | Slow and sometimes unavailable |
| Contract tests | Check both sides agree on request and response shape | Catching drift between mock and reality | Needs agreement from both teams |
# pip install requests responses pytest
import os
import requests
import responses
# Full charge endpoint of the provider, from the test env
PAY_URL = os.environ["PAY_URL"]
def charge(amount):
r = requests.post(PAY_URL, json={"amount": amount}, timeout=5)
if r.status_code == 503:
return {"status": "RETRY_LATER"}
r.raise_for_status()
return r.json()
@responses.activate
def test_charge_handles_provider_outage():
responses.add(responses.POST, PAY_URL, status=503)
assert charge(499) == {"status": "RETRY_LATER"}
@responses.activate
def test_charge_success():
responses.add(responses.POST, PAY_URL, status=200,
json={"status": "PAID", "id": "ch_1"})
assert charge(499)["status"] == "PAID""We split tests into layers. Most tests mock the
payment call, so they check our own handling: success,
decline, timeout and a 503 from the provider. Those run
on every commit and never depend on the sandbox.
A small set of integration tests calls the real sandbox.
They run nightly and before releases. If the sandbox is
down, those are marked as blocked, not failed, and we
note it in the report.
The risk with mocks is drift, so when the provider
changes its API we update the mocked responses from
their documentation."
The charge URL comes from an environment variable, and inside these tests the responses library intercepts calls to it, so no real network call is made. Being able to explain that interception is a quick way to show you understand how mocking works.
SECTION 04Make your resume line and your answers match
The aim is simple: every API claim on your resume should have a real situation behind it that you can describe. Use these three tabs to audit your resume, prepare situation answers and rehearse with a partner, or in an Uncodemy mock interview with a trainer.
For each API line on your resume, fill in:
CLAIM: "Automated REST API tests using Python"
Situation I can describe: pagination on /products
Tool and code I used: pytest + requests
One problem I hit: duplicates on page 2
How I fixed or reported it: logged sort-order bug
What I would add now: schema checks
If you cannot fill in 'One problem I hit', the claim
is probably bigger than your experience. Either build
that experience in a practice project, or reword the
line to match what you did.Prepare a 60-second answer for each situation:
1. Testing a paginated list endpoint
2. Suite fails with many 429 responses
3. A dependency (payment, SMS) is down
4. API returns 200 but data is wrong
5. A field changed type after a release
6. Tests pass locally, fail in CI
7. Test data from one test breaks another
8. Response is slow only for some requests
For each: what you check first, the tool or code,
and how you report the result.Give your partner your resume and this list.
They pick ANY line and ask one situation question.
Score each answer 1-3:
1 = definition only
2 = steps but no real detail
3 = steps, a real problem and a trade-off
Any line scoring 1 twice:
-> rewrite the resume line, or
-> build a small project that covers it
Repeat until every line scores 3 at least once.
SECTION 05Ways to answer API situation questions well
These habits help your answers show experience rather than definitions.
- Start with what you checked first — Opening with your first diagnostic step, such as reading the response headers, immediately shows a practical mindset.
- Name the tool and the line of code — Saying 'I used responses to mock the POST' is more convincing than 'I used mocking'.
- Include one problem you hit — Real work always involves surprises, like duplicates on page 2. Mentioning one makes your answer believable.
- State the trade-off — Every approach has a cost: mocks drift, sandboxes are slow, retries can hide bugs. Naming it shows judgement.
- Keep it under a minute — A focused answer invites a follow-up, which is where you can show more depth without rambling.
SECTION 06Interview Q&A — API questions
Q1How do you test a paginated API?
I check that each page respects the page size, walk all pages collecting IDs to confirm there are no duplicates or gaps, compare the count with the reported total, and request a page past the end to check the contract. I use fixed test data so new records do not shift pages during the run.
Q2What does a 429 status code mean and how do you handle it in tests?
429 means Too Many Requests: the client exceeded the rate limit. In functional suites I reduce parallelism and use backoff that honours Retry-After, retrying only on 429. I test the limit itself separately with a dedicated key so it does not block other tests.
Q3How do you test an API that depends on a third-party service?
Most tests mock the dependency so they can check our handling of success, errors and timeouts quickly and reliably. A smaller set calls the provider's sandbox before releases. I mention the risk of mock drift and keep mocked responses updated from the provider's documentation.
Q4What is the difference between a mock and a stub?
Both replace a real dependency. A stub returns preset responses. A mock usually also records how it was called so the test can check the interaction. In practice the terms are often used loosely, so I explain what my tool actually did.
Q5The API returns 200 but the data is wrong. How do you catch that?
By asserting on the body, not just the status: field values against expected test data, schema validation for types and required fields, and a follow-up GET after writes. I also compare against the database or source system when I have access.
SECTION 07Test yourself — API questions quiz
Five questions. No sign-up.
0 / 5Pick an answer to see why it is right or wrong.
SECTION 08Frequently asked questions
What are common API testing interview questions for experienced candidates?
Expect situation questions: how you tested pagination, handled rate limits, mocked dependencies, validated schemas, managed test data and ran API tests in CI. Interviewers look for steps, real problems you hit and trade-offs.
How do I write API tests in Python?
A common setup is pytest with the requests library. You send requests, assert on status codes and JSON fields, and use fixtures for setup such as tokens. Libraries like responses help mock HTTP calls in tests.
What is API mocking in testing?
API mocking replaces a real dependency with a fake that returns controlled responses. It makes tests faster and more reliable and lets you test error cases, but it should be combined with some real integration tests.
How do I describe API testing on my resume?
Describe what you tested and how, such as 'Automated pagination and schema checks for product APIs using pytest and requests'. Make sure every line has a real situation behind it that you can explain in the interview.
What is rate limiting in APIs?
Rate limiting restricts how many requests a client can make in a time window. When the limit is exceeded, the API typically returns 429 and may include a Retry-After header telling the client when to try again.
Does Uncodemy help with APIs interview questions?
Yes. Uncodemy's API Automation Testing Training Course in Noida (classroom and online) includes live projects, one-to-one mock interviews and resume reviews, so you practise APIs interview questions with trainer feedback before the real interview. You can book a free demo class from this page to see how the sessions work.
SECTION 09Related reads
Classroom & online · Noida
Back every API claim with real practice
Our API Automation Testing Training Course teaches API automation with Postman, REST Assured and Python, including pagination, mocking, rate limits and CI, through projects you can talk about in detail.
Talk to a counsellor for current fees- Python & REST Assured APIs
- Mocking & contract basics
- CI pipeline integration
- Resume and mock interviews