One Request, Many Inputs: Data-Driven API Tests in Postman That Run in CI
Keep one request definition and drive it with a CSV or JSON data file. Postman’s Collection Runner runs each row as an iteration, and Newman promotes the same collection to CI with a non-zero exit code on failure.
30 Jul 2026, 04:44 UTC

When a QA team needs to verify the same endpoint for dozens of IDs, the quick fix is to duplicate requests. The result is a collection that is hard to maintain and easy to miss when the contract changes. A more sustainable approach is to keep one request definition and drive it with a CSV or JSON data file. Postman’s Collection Runner executes each row as an iteration, and the same exported collection runs unchanged in CI with Newman.
Iteration data replaces copy-paste
The Collection Runner runs requests in order, one iteration by default. Supplying a data file makes each row or object one iteration. Iteration-data variables sit at the top of Postman’s variable precedence, shadowing environment, collection and global scopes. That means a data file can override per-row values like IDs or expected status codes without editing environments between runs.
In test scripts the current row is read with pm.iterationData.get("key"). CSV headers become variable names and all values arrive as strings. A JSON array of objects preserves native types like numbers and booleans, which matters for assertions.
Assertions use pm.test with pm.expect, the Chai-style matchers Postman exposes. Each assertion is recorded per request per iteration, and the runner results view presents an iterations-by-requests matrix that makes failures easy to localize.
A minimal worked example
Problem: verify GET /users/:id returns the expected status for a set of IDs.
Collection request
- Method: GET
- URL: {{baseUrl}}/users/{{userId}}
Data file users.csv
userId,expectedStatus
1,200
999,404
Pre-request script, run in the collection or request to keep credentials out of data files
// Fetch or refresh a token into an environment variable
// Secret-type variables are masked in UI and logs
pm.sendRequest({
url: pm.environment.get("authUrl"),
method: 'POST',
header: { 'Content-Type': 'application/json' },
body: { mode: 'raw', raw: JSON.stringify({ client_id: pm.environment.get("clientId") }) }
}, function (err, res) {
if (!err && res.code === 200) {
pm.environment.set("accessToken", res.json().token);
}
});
Tests tab
const expected = Number(pm.iterationData.get("expectedStatus"));
pm.test("Status matches expectation for user " + pm.iterationData.get("userId"), function () {
pm.expect(pm.response.code).to.eql(expected);
});
pm.test("Response time is reasonable", function () {
pm.expect(pm.response.responseTime).to.be.below(500);
});
Run the collection with Collection Runner, select the data file, and start. Each row becomes an iteration. You can verify variable precedence by logging pm.variables.get("userId") and pm.iterationData.get("userId") in the Postman Console. The console is available from View in the desktop app.
Promote the same collection with Newman
Newman runs an exported collection JSON with the same data-file option. Failed assertions produce a non-zero exit code, which makes the collection usable as a smoke-test gate after deploy.
Run in a CI shell where Node.js and npm are available. Required permissions are read access to the collection and data file, and write access for reports if you generate them.
newman run collection.json -d users.csv -e env.json --reporters cli,html
Placeholders: collection.json is the exported collection, users.csv is the data file, env.json holds baseUrl and auth values from CI secret stores. Do not commit secrets in CSVs or exported collections.
Risks to note: data files committed to a repository can leak secrets. Keep credentials in CI secret stores or Postman secret variables. Tests that rely on setNextRequest or iteration state behave differently when a request is sent standalone; runner-only behavior should be called out in documentation.
Trade-off to watch
CSV convenience comes with type coercion. Every cell arrives as a string, so numeric or boolean assertions need explicit parsing, which is a frequent source of confusing test failures. JSON data files avoid that but are less convenient for non-technical editors.
Dynamic variables like {{$timestamp}}, {{$guid}} and {{$randomInt}} can be combined with data files for repeatable-but-unique payloads such as entity names or idempotency keys. Flow control with setNextRequest is possible in scripts, but it only takes effect under Collection Runner or Newman.
Limitations to verify on your installed version: the pm scripting API is long-standing but not frozen. Confirm method names like pm.iterationData.get against current documentation before publishing code samples, and cross-check UI labels against the official Postman Learning Center.
Actionable close: export the collection, store a small representative data file with expected outcomes, and add a Newman step to your pipeline that fails the build on assertion failures. Keep one source of truth for the request definition and let iteration data cover the variations.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.