Environments & Variables
Every request in your RecipeBox API collection currently starts with the literal string
https://api.recipebox.example.com. That's fine until RecipeBox actually
has more than one server — a dev-api for testing in progress, a staging-api
for pre-release sign-off, and the real api in production. Hardcoding the URL means
editing every single request by hand every time you switch targets, which is slow and guarantees
you'll eventually test the wrong environment by mistake. Postman solves this with
Environments and Variables.
The Problem With Hardcoded URLs
| Target | Base URL |
|---|---|
| Dev | https://dev-api.recipebox.example.com |
| Staging | https://staging-api.recipebox.example.com |
| Production | https://api.recipebox.example.com |
With a hardcoded URL in every request, moving the RecipeBox API collection from dev to
staging means opening every request, editing the domain, and hoping you didn't miss one. Multiply
that by dozens of requests and it becomes a real source of bugs — a test that silently keeps hitting
dev while you think you're verifying staging.
Creating an Environment
An Environment is a named set of key/value pairs that only apply when that environment is selected in the top-right environment dropdown. Create one for each RecipeBox target:
- Click the Environments tab in the sidebar → +.
- Name it
RecipeBox Dev. - Add a variable: key
baseUrl, initial value and current value both set to https://dev-api.recipebox.example.com. - Save, then repeat to create
RecipeBox StagingandRecipeBox Prod, each with its ownbaseUrl. - Select
RecipeBox Devfrom the environment dropdown in the top-right corner of Postman.
Using {{baseUrl}} in a Request
Variables are referenced with double curly braces. Edit the Get Recipe By ID request
from the Recipes folder and replace the hardcoded host with {{baseUrl}}:
// Before — hardcoded, only ever hits production
GET https://api.recipebox.example.com/recipes/42
// After — resolves using whichever environment is selected
GET {{baseUrl}}/recipes/42
With RecipeBox Dev selected, {{baseUrl}} resolves to
https://dev-api.recipebox.example.com, so the request actually goes to
https://dev-api.recipebox.example.com/recipes/42. Switch the dropdown to
RecipeBox Staging and the exact same request — no editing required — now hits staging
instead. Postman even shows unresolved variables in orange/red in the URL bar so you can spot a typo
like {{baseUrl} (missing brace) before you send anything.
Environment vs Collection vs Global Variables
Postman actually has several variable scopes, and they can all define a variable with the same name. When that happens, the more specific scope wins. From lowest to highest priority:
| Scope | Where it's defined | Typical use for RecipeBox |
|---|---|---|
| Global | Workspace-wide, in the Globals environment; available to every collection | A value that's genuinely the same everywhere, e.g. a shared support email used in a test assertion |
| Collection | On the RecipeBox API collection itself (Edit → Variables tab) | recipeId — a value set at runtime by one request and read by another (see the next lesson) |
| Environment | Inside RecipeBox Dev / Staging / Prod | baseUrl, token — anything that legitimately differs per target |
| Local | Set with pm.variables.set() in a script; exists only for the current request/collection run | A throwaway value needed only inside one script |
Priority order when names collide (highest wins): Local > Environment > Collection > Global.
For RecipeBox, this is why baseUrl belongs in the environment, not the
collection: it's the one value that's genuinely different for dev, staging, and production, and the
environment dropdown is the single switch that changes it everywhere at once. A value like
recipeId, on the other hand, belongs at the collection level — it's set by one
request and needs to be visible to another request regardless of which environment happens to be
active.
pm.test().