Demo practice website — this is a sandbox for learning QA & automation testing.
API Testing Playground

A real REST API to practise against

Base URL: https://qatestology.com — everything below is live. Read endpoints are open; write endpoints authenticate with a bearer token (each curl below fetches its own — nothing to paste from your browser).

How auth works here — copy, paste, run

Every auth-required endpoint shows a two-step curl: log in as a demo account → capture the token from the JSON response → call the endpoint with Authorization: Bearer $TOKEN. Copy → paste in a terminal → it just works. Nothing to grab from your browser.

Demo accounts (also pre-filled on the Sign in page): demo.seeker@qatestology.com · demo.employer@qatestology.com · pw Demo@1234

Tip: click Check in UI after Try it to jump to the page where the data change shows up. For bearer-token deep-dive, see Level 7's Authentication section.

#

Auth

POST/api/auth/register

Create a new account. Response returns a bearer token in the JSON body — use it in an Authorization header.

request body (JSON)
curl example
curl -X POST 'https://qatestology.com/api/auth/register' \
  -H 'Content-Type: application/json' \
  -d '{ "name": "Test User", "email": "test+mtc0sl4l@example.com", "password": "GoodPass1!", "role": "job_seeker"}'

Registration signs you in — dashboard shows the new session.

POST/api/auth/login

Sign in with email + password. Response body includes a bearer `token` you can pass as Authorization header.

request body (JSON)
curl example
curl -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{ "email": "demo.seeker@qatestology.com", "password": "Demo@1234"}'

You're now logged in — see your dashboard.

GET/api/auth/me auth

Return the currently authenticated user.

curl example
# 1. Log in as the demo seeker — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.seeker@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X GET 'https://qatestology.com/api/auth/me' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Same session, rendered as UI.

#

Seeker profile

GET/api/profile/seeker auth

Fetch the current seeker's profile.

curl example
# 1. Log in as the demo seeker — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.seeker@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X GET 'https://qatestology.com/api/profile/seeker' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

The profile page reads exactly this endpoint.

PUT/api/profile/seeker auth

Create or update the seeker's profile. Skills must come from GET /api/skills/catalog. Any fake data you send here will appear on the profile page.

request body (JSON)
curl example
# 1. Log in as the demo seeker — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.seeker@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X PUT 'https://qatestology.com/api/profile/seeker' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "headline": "Automation Engineer", "location": "Bengaluru", "years_experience": 3, "skills": ["Selenium WebDriver", "Playwright"], "tools": ["Jenkins", "Postman"], "phone": "+91 9876543210", "linkedin": "https://linkedin.com/in/your-handle", "github": "https://github.com/your-handle"}'

Refresh the profile page to see the new values you just PUT.

#

Jobs (public)

GET/api/jobs

List all active jobs, newest first. Optional query: ?q=playwright&skill=k6

curl example
curl -X GET 'https://qatestology.com/api/jobs' \
  -H 'Accept: application/json'

The public jobs list renders this exact response.

GET/api/jobs/{job_id}

Fetch a single job by ID. Replace {job_id} in the path (or use one auto-filled from a prior call).

curl example
curl -X GET 'https://qatestology.com/api/jobs/{job_id}' \
  -H 'Accept: application/json'

See the job detail page for this exact id.

#

Employer jobs

POST/api/jobs auth

Create a new job posting. Requires role=employer, approved & verified. On success the response's job_id auto-fills into related endpoints below.

request body (JSON)
curl example
# 1. Log in as the demo employer — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.employer@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X POST 'https://qatestology.com/api/jobs' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "title": "Automation QA Engineer", "description": "Selenium/Playwright automation for a fintech product.", "location": "Remote", "job_type": "Full-time", "experience_min": 2, "experience_max": 5, "required_skills": ["Selenium WebDriver", "Java"], "nice_to_have": ["Playwright"], "salary_currency": "INR", "salary_min": 1200000, "salary_max": 2000000, "salary_period": "yearly", "salary_visible": true, "salary_range": "₹12L – ₹20L / year"}'

The job page is generated from the doc you just created.

PUT/api/jobs/{job_id} auth

Edit a posting (only inside the 7-day window after creation).

request body (JSON)
curl example
# 1. Log in as the demo employer — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.employer@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X PUT 'https://qatestology.com/api/jobs/{job_id}' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "title": "Automation QA Engineer (updated)", "description": "Updated JD…", "location": "Bengaluru", "job_type": "Full-time", "experience_min": 3, "experience_max": 6, "required_skills": ["Selenium WebDriver"], "nice_to_have": [], "salary_currency": "INR", "salary_min": 1500000, "salary_max": 2500000, "salary_period": "yearly", "salary_visible": true, "salary_range": "₹15L – ₹25L / year"}'

See the edited title/JD live on the job page.

DELETE/api/admin/jobs/{job_id} auth

Admin-only. Soft-close a job. Pass ?hard=true to purge the job + its applications.

curl example
# 1. Log in as the demo employer — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.employer@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X DELETE 'https://qatestology.com/api/admin/jobs/{job_id}' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Closed/purged jobs disappear from the public list.

#

Applications

POST/api/jobs/{job_id}/apply auth

Seeker applies to a job. Multipart body — optional field `resume` for a per-application resume.

curl example
# 1. Log in as the demo seeker — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.seeker@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X POST 'https://qatestology.com/api/jobs/{job_id}/apply' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

The dashboard's applications tab shows the new row.

GET/api/applications/mine auth

List the current seeker's applications.

curl example
# 1. Log in as the demo seeker — this returns a bearer token in the body
TOKEN=$(curl -s -X POST 'https://qatestology.com/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo.seeker@qatestology.com","password":"Demo@1234"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# 2. Call the endpoint with the bearer token
curl -X GET 'https://qatestology.com/api/applications/mine' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

The dashboard's applications tab renders this endpoint.

Tip · every response returns real data — feel free to spin up bots against this endpoint suite as long as you don't spam other users.