Project Brief — Full Postman Collection for a Pet Store API

10 min read

You've spent six chapters learning Postman from "click Send" to "wired into GitHub Actions." The capstone is the part where you put it all together. The scenario is realistic, the deliverables map to what a working QA engineer ships in their first month on a job, and every artefact you produce should be reusable in your next project. Read this brief carefully — the next lesson walks through how to attack it, and the third gives you a checklist to grade your own work. The whole project should take 6–10 hours of focused work, spread over a few sessions.

The scenario

You've just been hired as the QA engineer at PetStore — a small-but-growing online marketplace for pets and pet supplies. The backend team has shipped a REST API that the website, the iOS app, and the partner integrations all consume. There are no automated API tests in place. Your manager hands you the API spec on day one and says: "Build me a Postman test suite for this API. I want it to run locally, in CI on every PR, and on a schedule against production. Take a week. What does that look like?"

Your job over the rest of this capstone is to answer that question concretely — collection, environments, tests, CI workflow, the lot.

The API surface

PetStore exposes the following endpoints. Treat this list as the spec; you'll design tests against it. For practice you can run against the public Swagger Petstore — the shapes are similar — or stand up a local mock server using Postman's mock feature (Chapter 4 Lesson 4).

Authentication

  • POST /users/register — create a new user account. Body: { email, password, name }. Returns 201 and the user object.
  • POST /users/login — exchange credentials for a JWT access token. Returns 200, { token, user }. 30-minute token lifetime.
  • GET /users/me — get the authenticated user's profile. Requires Bearer token.

Pets

  • GET /pets — list pets. Supports ?status=available|pending|sold, ?categoryId=, ?_page=, ?_limit=. Anonymous-accessible.
  • GET /pets/:id — fetch one pet. Anonymous-accessible.
  • POST /pets — create a pet. Auth required. Body: { name, categoryId, status, price }.
  • PUT /pets/:id — replace a pet. Auth required. Owner only.
  • DELETE /pets/:id — remove a pet. Auth required. Owner only.

Categories

  • GET /categories — list pet categories (Dogs, Cats, Reptiles, …). Anonymous.
  • GET /categories/:id — one category with its pets.

Orders

  • POST /orders — create an order. Body: { petId, quantity }. Auth required.
  • GET /orders/:id — fetch one order. Auth required (owner or admin).
  • DELETE /orders/:id — cancel an order. Owner only.

Roles

  • guest — no auth. Can browse /pets, /categories.
  • user — authenticated. Can manage their own pets and orders.
  • admin — privileged. Can read any user's order; can delete any pet.

Token lifecycle

Tokens last 30 minutes. The collection's pre-request script should detect expiry and re-login automatically (the pattern from Chapter 3 Lesson 4 and Chapter 4 Lesson 3). A long-running suite cannot rely on a token surviving the whole run.

Your nine deliverables

Each one maps directly onto a chapter you've already studied. The map is the project — produce the nine and you've shown end-to-end Postman fluency.

PetStore Capstone
  • – Folders by feature: Auth / Pets / Orders / Categories
  • – Verb-first request names
  • – Collection-level Bearer auth
  • – Local: localhost:3000
  • – Staging: staging.petstore.api
  • – Production: read-only smoke
  • – 30+ assertions
  • – Status, body, header, schema
  • – At least 5 negative cases
  • – Register → Login → Create Pet → Create Order → Verify
  • – Token + ids passed through {{vars}}
  • – pets-data.csv with 10 rows
  • – Mix of valid + invalid inputs
  • – Per-row expectedStatus
  • Bearer token at collection level –
  • Pre-request script refreshes when expired –
  • package.json npm script –
  • htmlextra HTML report –
  • JUnit XML for CI dashboards –
  • .github/workflows/api-tests.yml –
  • Secrets via --env-var –
  • Report uploaded as artifact –
  • Collection-level description –
  • Per-request descriptions and saved examples –
  • Published documentation URL –

If you can produce every leaf on that map, you've genuinely finished the course — not just consumed it. Walk through them in the order below; each one feeds the next.

Detailed deliverables

1. A well-organised Postman collection

A single collection named PetStore API Tests with folders by feature:

PetStore API Tests/
├── Auth/
│   ├── POST Register
│   ├── POST Login
│   └── GET Me
├── Categories/
│   ├── GET All Categories
│   └── GET Category by ID
├── Pets/
│   ├── GET All Pets
│   ├── GET Pet by ID
│   ├── GET Pets by Status
│   ├── POST Create Pet
│   ├── PUT Update Pet
│   └── DELETE Pet
├── Orders/
│   ├── POST Create Order
│   ├── GET Order by ID
│   └── DELETE Order
└── CRUD Chain/
    ├── 1. POST Register
    ├── 2. POST Login (extracts token)
    ├── 3. POST Create Pet (extracts petId)
    ├── 4. POST Create Order (uses petId, extracts orderId)
    ├── 5. GET Verify Order (uses orderId)
    └── 6. DELETE Order (cleanup)

Verb-first names, descriptive, no environment names baked into request titles.

2. Three environments

  • LocalbaseUrl = http://localhost:3000, full read/write.
  • StagingbaseUrl = https://staging.petstore.api, full read/write.
  • ProductionbaseUrl = https://api.petstore.com, read-only smoke only.

Each environment contains: baseUrl, testEmail, testPassword, plus space for the auto-set authToken, tokenExpiry, userId. Real secrets in Current value only; placeholders in Initial value.

3. Collection-level Bearer auth + auto-refresh

Authorization tab on the collection set to Bearer Token with Token: {{authToken}}. A collection-level Pre-request Script that checks tokenExpiry and re-logs in via pm.sendRequest if needed. The script from Chapter 4 Lesson 3 is the template.

Override on the two requests that don't need auth: POST Register and POST Login set their own Authorization to No Auth (you don't have a token yet — that's what login is for).

4. At least 30 test assertions across all requests

Mix the four assertion families learned in Chapter 3:

  • Status code — every request should assert its expected code. Includes 4xx assertions for negative cases.
  • Response body — at least one body assertion per request. Use pm.expect(...).to.have.property(...), to.be.a("number"), to.match(/regex/).
  • Headers — assert Content-Type: application/json everywhere; assert security headers where applicable.
  • JSON Schema — write at least one schema for the Pet shape and one for the Order shape; validate with tv4.validate.
  • Negative cases — at minimum: missing required field, wrong content-type, missing auth, expired token, duplicate registration, invalid id format.

5. Chained CRUD flow

A CRUD Chain folder running register → login → create pet → create order → verify → cleanup. Each Tests script extracts what the next step needs:

// Login Tests
const r = pm.response.json();
pm.collectionVariables.set("authToken", r.token);
pm.collectionVariables.set("tokenExpiry", Date.now() + 29 * 60 * 1000);
pm.collectionVariables.set("userId", r.user.id);

Run the folder via the Collection Runner. All six requests should pass green.

6. Data-driven pet creation

A pets-data.csv file with 10 rows mixing valid and invalid pet payloads:

name,categoryId,status,price,expectedStatus
Buddy,1,available,29.99,201
Whiskers,2,available,15.00,201
,,available,0,400
Bigfoot,99,available,5,400
Rex,1,sold,15,201

The POST Create Pet request body uses {{name}}, {{categoryId}}, {{status}}, {{price}}. The Tests script asserts on {{expectedStatus}}. Run via the Collection Runner with the CSV; ten iterations, ten dynamically-named test results.

7. Newman npm script

In a Git repo containing the exported collection and environment JSON:

{
  "scripts": {
    "test:api": "newman run postman/petstore.postman_collection.json -e postman/staging.postman_environment.json -r cli,htmlextra,junit --reporter-htmlextra-export reports/api-report.html --reporter-junit-export reports/results.xml --timeout-request 10000",
    "test:api:smoke": "newman run postman/petstore.postman_collection.json --folder Smoke -e postman/production.postman_environment.json --bail"
  },
  "devDependencies": {
    "newman": "^6.0.0",
    "newman-reporter-htmlextra": "^1.22.0"
  }
}

npm install, then npm run test:api. Confirm the HTML report opens in a browser.

8. GitHub Actions workflow

.github/workflows/api-tests.yml that runs on every push and pull request:

  • Checks out the repo.
  • Installs Node 20 and Newman + htmlextra.
  • Runs newman run against the staging environment with secrets pulled from GitHub Actions Secrets via --env-var.
  • Uploads reports/ as an artifact, regardless of pass/fail.

The full template from Chapter 5 Lesson 4 is your starting point.

9. Documentation

Collection-level description: a one-page markdown intro covering purpose, owners, environments, how to run.

Folder descriptions: one paragraph each.

Request descriptions: short notes on side effects, auth requirements, gotchas.

At least three saved examples per resource (200, 4xx, 5xx synthetic). Publish the docs (team-only or public — your choice).

Stretch goals

If you finish the nine deliverables and want to go further:

  • Postman Monitor — set up a hourly cloud monitor on the production smoke folder. Configure email-on-failure.
  • Postman Flow — build a visual order-lifecycle flow (login → browse pets → place order → verify) for stakeholder demos.
  • Negative-case data-driven CSV — a second data file with 15 rows of bad inputs (SQL injection, XSS, oversized strings, malformed JSON) and expected 400/422 responses.
  • JSON Schema for every endpoint — schemas for every 2xx response shape, validated with tv4 in every request's Tests tab.
  • Slack notification on CI failure — wire GitHub Actions to post to Slack when the workflow goes red.

These aren't required for the capstone but are exactly the stretch tasks that take a passing project to a portfolio-ready one.

Setting up to run

You have three realistic options for what to test against:

  • Public Petstorepetstore3.swagger.io is free, no setup, but slightly different shape from the spec above. Adapt requests as needed.
  • Local mock server — set up a Postman mock (Chapter 4 Lesson 4) with examples that match the spec. Most accurate to the brief; takes 30 minutes to seed examples.
  • Real backend — if you happen to have access to a real Petstore-style API at work, even better. The collection is portable.

Whichever you pick, document it in the collection's description so the next person knows what to point at.

How to use this brief

This document is your specification. The next lesson walks through the how — a step-by-step build sequence with the actual Postman clicks, scripts, and CLI commands. The third lesson is the rubric you use to assess your own work and a set of stretch goals for going further.

Don't try to read both ahead and then start. Read the walkthrough lesson interactively as you build — pause, click, send, verify, move on. The work is the point.

When you're done, you'll have a collection, a Git repo, a CI workflow, and a published docs page that together form a portfolio piece you can hand to an interviewer. Multiple QA engineers have landed jobs on the strength of a clean Petstore-style suite. Yours can be next.

// tip to track lessons you complete and pick up where you left off across devices.