API Practice

Meaningful REST APIs for Playwright / RestAssured / Postman practice — JSON request & response validation, status codes, and Basic Auth.

Base URL: https://lebyy.com/practice/api
Example GET: https://lebyy.com/practice/api/courses
Public resource: https://lebyy.com/practice/api/courses (no auth) — GET, POST, PUT, PATCH, DELETE
Protected resource: https://lebyy.com/practice/api/learners — Basic Auth api_learner / Lebyy@Api1
Reset seed data: POST https://lebyy.com/practice/api/reset (no auth)

Live check

Confirms the API is reachable on this host (needs PHP on the server).

Click “Ping API root” to verify.

1) Public APIs — Courses (no authorization)

Use these for basic CRUD + JSON schema / field assertions. Resource model: Lebyy course catalog.

Method Endpoint How to use Sample request body Sample response Status
GET https://lebyy.com/practice/api/courses List all courses. Assert count and data array. No body
{
  "count": 4,
  "data": [
    {
      "id": 1,
      "title": "Playwright Mastery",
      "category": "Web",
      "level": "Intermediate",
      "price": 19.99,
      "language": "English",
      "active": true
    }
  ]
}
200
GET https://lebyy.com/practice/api/courses/1 Get a single course by id. Assert title/price fields. No body
{
  "id": 1,
  "title": "Playwright Mastery",
  "category": "Web",
  "level": "Intermediate",
  "price": 19.99,
  "language": "English",
  "active": true
}
200
POST https://lebyy.com/practice/api/courses Create a course. Required: title, category, level, price.
{
  "title": "Selenium Grid Workshop",
  "category": "Web",
  "level": "Advanced",
  "price": 29.99,
  "language": "English",
  "active": true
}
{
  "id": 5,
  "title": "Selenium Grid Workshop",
  "category": "Web",
  "level": "Advanced",
  "price": 29.99,
  "language": "English",
  "active": true
}
201
PUT https://lebyy.com/practice/api/courses/5 Full replace of a course. Send all required fields.
{
  "title": "Selenium Grid Workshop",
  "category": "Web",
  "level": "Advanced",
  "price": 27.5,
  "language": "English",
  "active": false
}
{
  "id": 5,
  "title": "Selenium Grid Workshop",
  "category": "Web",
  "level": "Advanced",
  "price": 27.5,
  "language": "English",
  "active": false
}
200
PATCH https://lebyy.com/practice/api/courses/5 Partial update — send only fields to change.
{
  "price": 22.0,
  "active": true
}
{
  "id": 5,
  "title": "Selenium Grid Workshop",
  "category": "Web",
  "level": "Advanced",
  "price": 22.0,
  "language": "English",
  "active": true
}
200
DELETE https://lebyy.com/practice/api/courses/5 Delete a course. Assert deleted object in response. No body
{
  "message": "Deleted successfully",
  "deleted": {
    "id": 5,
    "title": "Selenium Grid Workshop",
    "category": "Web",
    "level": "Advanced",
    "price": 22.0,
    "language": "English",
    "active": true
  }
}
200

2) Basic Auth APIs — Learners

Same CRUD verbs, but every call needs HTTP Basic Auth. Missing/wrong credentials → 401.

Header: Authorization: Basic base64(api_learner:Lebyy@Api1)
In Playwright: httpCredentials: { username: 'api_learner', password: 'Lebyy@Api1' }
Method Endpoint How to use Sample request body Sample response Status
GET https://lebyy.com/practice/api/learners List learners (auth required). No body
{
  "count": 3,
  "data": [
    {
      "id": 1,
      "name": "Priya Sharma",
      "email": "priya.sharma@example.com",
      "courseId": 1,
      "status": "enrolled",
      "progress": 42
    }
  ]
}
200
GET https://lebyy.com/practice/api/learners/1 Get one learner by id. No body
{
  "id": 1,
  "name": "Priya Sharma",
  "email": "priya.sharma@example.com",
  "courseId": 1,
  "status": "enrolled",
  "progress": 42
}
200
POST https://lebyy.com/practice/api/learners Enroll a learner. Required: name, email, courseId.
{
  "name": "Kiran Kumar",
  "email": "kiran.kumar@example.com",
  "courseId": 3,
  "status": "enrolled",
  "progress": 0
}
{
  "id": 4,
  "name": "Kiran Kumar",
  "email": "kiran.kumar@example.com",
  "courseId": 3,
  "status": "enrolled",
  "progress": 0
}
201
PUT https://lebyy.com/practice/api/learners/4 Replace learner record (all required fields).
{
  "name": "Kiran Kumar",
  "email": "kiran.kumar@example.com",
  "courseId": 3,
  "status": "enrolled",
  "progress": 55
}
{
  "id": 4,
  "name": "Kiran Kumar",
  "email": "kiran.kumar@example.com",
  "courseId": 3,
  "status": "enrolled",
  "progress": 55
}
200
PATCH https://lebyy.com/practice/api/learners/4 Update progress/status only.
{
  "status": "completed",
  "progress": 100
}
{
  "id": 4,
  "name": "Kiran Kumar",
  "email": "kiran.kumar@example.com",
  "courseId": 3,
  "status": "completed",
  "progress": 100
}
200
DELETE https://lebyy.com/practice/api/learners/4 Remove learner. Auth still required. No body
{
  "message": "Deleted successfully",
  "deleted": { "id": 4, "name": "Kiran Kumar", "...": "..." }
}
200
GET https://lebyy.com/practice/api/learners (no auth) Negative test — call without credentials. No body
{
  "error": true,
  "status": 401,
  "message": "Unauthorized. Use Basic Auth: api_learner / Lebyy@Api1"
}
401

3) Utility

Method Endpoint How to use Sample request body Sample response Status
GET https://lebyy.com/practice/api/ (API root) Discover resources & auth hints. No body
{
  "name": "Lebyy Practice API",
  "version": "1.0",
  "resources": { "courses": {}, "learners": {}, "reset": {} }
}
200
POST https://lebyy.com/practice/api/reset Restore seed courses + learners after destructive tests. No body
{
  "message": "Seed data restored",
  "courses": 4,
  "learners": 3
}
200

Playwright example (public POST)

const base = 'https://lebyy.com/practice/api';

test('create course', async ({ request }) => {
  const res = await request.post(base + '/courses', {
    data: {
      title: 'CI/CD for QA',
      category: 'DevOps',
      level: 'Intermediate',
      price: 12.99
    }
  });
  expect(res.status()).toBe(201);
  const body = await res.json();
  expect(body).toMatchObject({
    title: 'CI/CD for QA',
    category: 'DevOps',
    price: 12.99,
    active: true
  });
  expect(body.id).toBeGreaterThan(0);
});