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).
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
/api/auth/registerCreate a new account. Response returns a bearer token in the JSON body — use it in an Authorization header.
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.
/api/auth/loginSign in with email + password. Response body includes a bearer `token` you can pass as Authorization header.
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.
/api/auth/me authReturn the currently authenticated user.
# 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
/api/profile/seeker authFetch the current seeker's profile.
# 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.
/api/profile/seeker authCreate 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.
# 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)
/api/jobsList all active jobs, newest first. Optional query: ?q=playwright&skill=k6
curl -X GET 'https://qatestology.com/api/jobs' \ -H 'Accept: application/json'
The public jobs list renders this exact response.
/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 -X GET 'https://qatestology.com/api/jobs/{job_id}' \
-H 'Accept: application/json'See the job detail page for this exact id.
Employer jobs
/api/jobs authCreate a new job posting. Requires role=employer, approved & verified. On success the response's job_id auto-fills into related endpoints below.
# 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.
/api/jobs/{job_id} authEdit a posting (only inside the 7-day window after creation).
# 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.
/api/admin/jobs/{job_id} authAdmin-only. Soft-close a job. Pass ?hard=true to purge the job + its applications.
# 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
/api/jobs/{job_id}/apply authSeeker applies to a job. Multipart body — optional field `resume` for a per-application resume.
# 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.
/api/applications/mine authList the current seeker's applications.
# 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.